ImagingMemoryArean tata type

This commit is contained in:
Alexander 2017-09-17 20:31:13 +03:00
parent dc192be83f
commit 4951962af1

View File

@ -264,22 +264,30 @@ ImagingDelete(Imaging im)
/* ------------------ */ /* ------------------ */
/* Allocate image as an array of line buffers. */ /* Allocate image as an array of line buffers. */
#define MEMORY_BLOCK_SIZE (1024*1024) typedef struct ImagingMemoryArean {
#define MEMORY_CACHE_BLOCKS 0 int alignment;
#define MEMORY_ALIGN_LINES 1 int block_size;
int blocks_max;
typedef struct { int blocks_free;
int alignment = 1; void **blocks;
int block_size = 1024*1024;
int blocks_max = 0;
int blocks_free = 0;
void **blocks = NULL
} *ImagingMemoryArean; } *ImagingMemoryArean;
struct ImagingMemoryArean default_arena = {
.alignment = 1,
.block_size = 1024*1024,
.blocks_max = 0,
.blocks_free = 0,
.blocks = NULL
};
void void
memory_set_blocks_max(ImagingMemoryArean arena, int blocks_max) memory_set_blocks_max(ImagingMemoryArean arena, int blocks_max)
{ {
/* Free already cached blocks */
while (arena->blocks_free > blocks_max) {
arena->blocks_free -= 1;
free(arena->blocks[arena->blocks_free]);
}
arena->blocks_max = blocks_max; arena->blocks_max = blocks_max;
} }
@ -287,20 +295,17 @@ void *
memory_get_block(ImagingMemoryArean arena, int requested_size, int dirty) memory_get_block(ImagingMemoryArean arena, int requested_size, int dirty)
{ {
void *block; void *block;
if ( ! _blocks) { if (arena->blocks_free > 0) {
_blocks = calloc(sizeof(void*), MEMORY_CACHE_BLOCKS); arena->blocks_free -= 1;
} // printf("get block: %p %d; free: %d\n",
if (_blocks_free > 0) { // arena->blocks[arena->blocks_free], requested_size, arena->blocks_free);
_blocks_free -= 1; block = realloc(arena->blocks[arena->blocks_free], requested_size);
// printf("get block: %p %d; _blocks_free: %d\n",
// _blocks[_blocks_free], requested_size, _blocks_free);
block = realloc(_blocks[_blocks_free], requested_size);
if ( ! block) { if ( ! block) {
free(_blocks[_blocks_free]); free(arena->blocks[arena->blocks_free]);
return NULL; return NULL;
} }
if (block != _blocks[_blocks_free]) { if (block != arena->blocks[arena->blocks_free]) {
// printf("reallocat: %p %p\n", block, _blocks[_blocks_free]); // printf("reallocat: %p %p\n", block, arena->blocks[arena->blocks_free]);
} }
if ( ! dirty) { if ( ! dirty) {
memset(block, 0, requested_size); memset(block, 0, requested_size);
@ -311,8 +316,8 @@ memory_get_block(ImagingMemoryArean arena, int requested_size, int dirty)
} else { } else {
block = calloc(1, requested_size); block = calloc(1, requested_size);
} }
// printf("allocated: %p %d; _blocks_free: %d\n", // printf("allocated: %p %d; arena->blocks_free: %d\n",
// block, requested_size, _blocks_free); // block, requested_size, arena->blocks_free);
} }
return block; return block;
} }
@ -320,12 +325,12 @@ memory_get_block(ImagingMemoryArean arena, int requested_size, int dirty)
void void
memory_return_block(ImagingMemoryArean arena, void *block) memory_return_block(ImagingMemoryArean arena, void *block)
{ {
if (_blocks_free < MEMORY_CACHE_BLOCKS) { if (arena->blocks_free < arena->blocks_max) {
_blocks[_blocks_free] = block; arena->blocks[arena->blocks_free] = block;
_blocks_free += 1; arena->blocks_free += 1;
// printf("ret block: %p; _blocks_free: %d\n", block, _blocks_free); // printf("ret block: %p; free: %d\n", block, arena->blocks_free);
} else { } else {
// printf("fre block: %p; _blocks_free: %d\n", block, _blocks_free); // printf("fre block: %p; free: %d\n", block, arena->blocks_free);
free(block); free(block);
} }
} }
@ -338,7 +343,7 @@ ImagingDestroyArray(Imaging im)
if (im->blocks) { if (im->blocks) {
while (im->blocks[y]) { while (im->blocks[y]) {
_return_block(im->blocks[y]); memory_return_block(&default_arena, im->blocks[y]);
y += 1; y += 1;
} }
free(im->blocks); free(im->blocks);
@ -349,6 +354,7 @@ Imaging
ImagingAllocateArray(Imaging im, int dirty) ImagingAllocateArray(Imaging im, int dirty)
{ {
int y, line_in_block, current_block; int y, line_in_block, current_block;
ImagingMemoryArean arena = &default_arena;
char* p; char* p;
int linesize, lines_per_block, blocks_count; int linesize, lines_per_block, blocks_count;
@ -358,7 +364,7 @@ ImagingAllocateArray(Imaging im, int dirty)
} }
linesize = (im->linesize + arena->alignment - 1) & -arena->alignment; linesize = (im->linesize + arena->alignment - 1) & -arena->alignment;
lines_per_block = MEMORY_BLOCK_SIZE / linesize; lines_per_block = arena->block_size / linesize;
if (lines_per_block == 0) if (lines_per_block == 0)
lines_per_block = 1; lines_per_block = 1;
blocks_count = (im->ysize + lines_per_block - 1) / lines_per_block; blocks_count = (im->ysize + lines_per_block - 1) / lines_per_block;
@ -382,7 +388,7 @@ ImagingAllocateArray(Imaging im, int dirty)
if (lines_remained > im->ysize - y) { if (lines_remained > im->ysize - y) {
lines_remained = im->ysize - y; lines_remained = im->ysize - y;
} }
p = (char *)memory_get_block(lines_remained * linesize, dirty); p = memory_get_block(arena, lines_remained * linesize, dirty);
if ( ! p) { if ( ! p) {
return (Imaging) ImagingError_MemoryError(); return (Imaging) ImagingError_MemoryError();
} }