summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2002-06-27 12:26:51 +0300
committerunknown <bell@sanja.is.com.ua>2002-06-27 12:26:51 +0300
commit6e0a4d3bbc2e85b78965ac533dccaa38175836ff (patch)
treeea0451695463acb4632e27fa003170aae7303dee
parentd58356a8daa49d1e9a361b9d49d3c7e59dd07ceb (diff)
downloadmariadb-git-6e0a4d3bbc2e85b78965ac533dccaa38175836ff.tar.gz
improvement in root memory allocator
-rw-r--r--include/my_alloc.h13
-rw-r--r--mysys/my_alloc.c50
2 files changed, 43 insertions, 20 deletions
diff --git a/include/my_alloc.h b/include/my_alloc.h
index 60d0d4f4b6d..31f1fb7165f 100644
--- a/include/my_alloc.h
+++ b/include/my_alloc.h
@@ -21,6 +21,8 @@
#ifndef _my_alloc_h
#define _my_alloc_h
+#define MAX_BLOCK_USAGE_BEFORE_DROP 10
+
typedef struct st_used_mem
{ /* struct for once_alloc (block) */
struct st_used_mem *next; /* Next block in use */
@@ -35,9 +37,14 @@ typedef struct st_mem_root
USED_MEM *used; /* blocks almost without free memory */
USED_MEM *pre_alloc; /* preallocated block */
/* if block have less memory it will be put in 'used' list */
- unsigned int min_malloc;
- unsigned int block_size; /* initial block size */
- unsigned int block_num; /* allocated blocks counter */
+ unsigned int min_malloc;
+ unsigned int block_size; /* initial block size */
+ 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);
} MEM_ROOT;
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index 5a6afe2fac9..f494cce8dbe 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -25,21 +25,22 @@
void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
uint pre_alloc_size __attribute__((unused)))
{
- mem_root->free=mem_root->used=0;
- mem_root->min_malloc=32;
- mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
- mem_root->error_handler=0;
+ mem_root->free= mem_root->used= 0;
+ mem_root->min_malloc= 32;
+ mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
+ mem_root->error_handler= 0;
mem_root->block_num= 0;
+ mem_root->first_block_usage= 0;
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
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)),
MYF(0))))
{
- mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
- mem_root->free->left=pre_alloc_size;
- mem_root->free->next=0;
+ mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
+ mem_root->free->left= pre_alloc_size;
+ mem_root->free->next= 0;
}
}
#endif
@@ -57,20 +58,31 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
(*mem_root->error_handler)();
return((gptr) 0); /* purecov: inspected */
}
- next->next=mem_root->used;
+ next->next= mem_root->used;
next->size= Size;
- mem_root->used=next;
+ mem_root->used= next;
return (gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)));
#else
uint get_size, block_size;
gptr point;
- reg1 USED_MEM *next;
+ reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev;
Size= ALIGN_SIZE(Size);
- prev= &mem_root->free;
- for (next= *prev ; next && next->left < Size ; next= next->next)
- prev= &next->next;
+ if ( (*(prev= &mem_root->free)) != NULL )
+ {
+ 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)
{ /* Time to alloc new block */
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)
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
*prev=next;
}
+
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)
{ /* Full block */
- *prev=next->next; /* Remove block from list */
- next->next=mem_root->used;
- mem_root->used=next;
+ *prev= next->next; /* Remove block from list */
+ next->next= mem_root->used;
+ mem_root->used= next;
+ mem_root->first_block_usage= 0;
}
return(point);
#endif
@@ -166,6 +181,7 @@ void free_root(MEM_ROOT *root, myf MyFlags)
}
else
root->block_num= 0;
+ root->first_block_usage= 0;
DBUG_VOID_RETURN;
}