Commit 347ca5ea authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

improvement in root memory allocator

parent 862692ca
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifndef _my_alloc_h #ifndef _my_alloc_h
#define _my_alloc_h #define _my_alloc_h
#define MAX_BLOCK_USAGE_BEFORE_DROP 10
typedef struct st_used_mem typedef struct st_used_mem
{ /* struct for once_alloc (block) */ { /* struct for once_alloc (block) */
struct st_used_mem *next; /* Next block in use */ struct st_used_mem *next; /* Next block in use */
...@@ -35,9 +37,14 @@ typedef struct st_mem_root ...@@ -35,9 +37,14 @@ typedef struct st_mem_root
USED_MEM *used; /* blocks almost without free memory */ USED_MEM *used; /* blocks almost without free memory */
USED_MEM *pre_alloc; /* preallocated block */ USED_MEM *pre_alloc; /* preallocated block */
/* if block have less memory it will be put in 'used' list */ /* if block have less memory it will be put in 'used' list */
unsigned int min_malloc; unsigned int min_malloc;
unsigned int block_size; /* initial block size */ unsigned int block_size; /* initial block size */
unsigned int block_num; /* allocated blocks counter */ unsigned int block_num; /* allocated blocks counter */
/*
first free block in queue test counter (if it exceed
MAX_BLOCK_USAGE_BEFORE_DROP block will be droped in 'used' list)
*/
unsigned int first_block_usage;
void (*error_handler)(void); void (*error_handler)(void);
} MEM_ROOT; } MEM_ROOT;
......
...@@ -25,21 +25,22 @@ ...@@ -25,21 +25,22 @@
void init_alloc_root(MEM_ROOT *mem_root, uint block_size, void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
uint pre_alloc_size __attribute__((unused))) uint pre_alloc_size __attribute__((unused)))
{ {
mem_root->free=mem_root->used=0; mem_root->free= mem_root->used= 0;
mem_root->min_malloc=32; mem_root->min_malloc= 32;
mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
mem_root->error_handler=0; mem_root->error_handler= 0;
mem_root->block_num= 0; mem_root->block_num= 0;
mem_root->first_block_usage= 0;
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
if (pre_alloc_size) if (pre_alloc_size)
{ {
if ((mem_root->free = mem_root->pre_alloc= if ((mem_root->free= mem_root->pre_alloc=
(USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)), (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
MYF(0)))) MYF(0))))
{ {
mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
mem_root->free->left=pre_alloc_size; mem_root->free->left= pre_alloc_size;
mem_root->free->next=0; mem_root->free->next= 0;
} }
} }
#endif #endif
...@@ -57,20 +58,31 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) ...@@ -57,20 +58,31 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
(*mem_root->error_handler)(); (*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */ return((gptr) 0); /* purecov: inspected */
} }
next->next=mem_root->used; next->next= mem_root->used;
next->size= Size; next->size= Size;
mem_root->used=next; mem_root->used= next;
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))); return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
#else #else
uint get_size, block_size; uint get_size, block_size;
gptr point; gptr point;
reg1 USED_MEM *next; reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev; reg2 USED_MEM **prev;
Size= ALIGN_SIZE(Size); Size= ALIGN_SIZE(Size);
prev= &mem_root->free; if ( (*(prev= &mem_root->free)) != NULL )
for (next= *prev ; next && next->left < Size ; next= next->next) {
prev= &next->next; if( (*prev)->left < Size &&
mem_root->first_block_usage++ >= MAX_BLOCK_USAGE_BEFORE_DROP )
{
next= *prev;
*prev= next->next; /* Remove block from list */
next->next= mem_root->used;
mem_root->used= next;
mem_root->first_block_usage= 0;
}
for (next= *prev ; next && next->left < Size ; next= next->next)
prev= &next->next;
}
if (! next) if (! next)
{ /* Time to alloc new block */ { /* Time to alloc new block */
block_size= mem_root->block_size*((mem_root->block_num>>2)+1); block_size= mem_root->block_size*((mem_root->block_num>>2)+1);
...@@ -89,12 +101,15 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) ...@@ -89,12 +101,15 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM)); next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
*prev=next; *prev=next;
} }
point= (gptr) ((char*) next+ (next->size-next->left)); point= (gptr) ((char*) next+ (next->size-next->left));
/*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
if ((next->left-= Size) < mem_root->min_malloc) if ((next->left-= Size) < mem_root->min_malloc)
{ /* Full block */ { /* Full block */
*prev=next->next; /* Remove block from list */ *prev= next->next; /* Remove block from list */
next->next=mem_root->used; next->next= mem_root->used;
mem_root->used=next; mem_root->used= next;
mem_root->first_block_usage= 0;
} }
return(point); return(point);
#endif #endif
...@@ -166,6 +181,7 @@ void free_root(MEM_ROOT *root, myf MyFlags) ...@@ -166,6 +181,7 @@ void free_root(MEM_ROOT *root, myf MyFlags)
} }
else else
root->block_num= 0; root->block_num= 0;
root->first_block_usage= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment