diff options
author | unknown <dlenev@brandersnatch.localdomain> | 2004-09-23 13:48:17 +0400 |
---|---|---|
committer | unknown <dlenev@brandersnatch.localdomain> | 2004-09-23 13:48:17 +0400 |
commit | 7ba5d931eb6611a1b3794d3c4378381060ac925d (patch) | |
tree | 72c836976a5eb3e3b63f565445ab8ca1ea26e4d8 /mysys/my_alloc.c | |
parent | ca65afeb72e7f514d51b7dcf2cc49e85a3b92677 (diff) | |
download | mariadb-git-7ba5d931eb6611a1b3794d3c4378381060ac925d.tar.gz |
Implementation of Monty's idea about clear_alloc_root() optimization and cleanup of work
with memory roots in THD/Statement/Item_arena.
Added assertions preventing memory allocation on bzero'ed MEM_ROOT since it is worked by
pure luck and was very ineffective.
include/my_sys.h:
Reimplementation of Monty's optimization of clear_alloc_root().
Now clear_alloc_root() can be used only for detaching memory associated with MEM_ROOT
(e.g. to avoid its freeing). It can not be used for MEM_ROOT initialization any longer
(it was bad idea anyway since memory allocation on such MEM_ROOT was very ineffective
and worked by pure luck).
Introduced ALLOC_ROOT_MIN_BLOCK_SIZE constant.
mysys/my_alloc.c:
Added description of init_alloc_root().
Added assertions to alloc_root() and reset_root_defaults() so now they can only be used
on previosly initialized MEM_ROOT. (It worked for bzeroed MEM_ROOT before but
by pure luck and very inefficiently). Calling free_root() on bzero'ed MEM_ROOT
is still ok (we can't remove this easily because of static MEM_ROOTs).
Also now using ALLOC_ROOT_MIN_BLOCK_SIZE constant inside these functions.
sql/opt_range.cc:
Fixed get_quick_select_for_ref() function to not use bzero'ed MEM_ROOT for allocation.
Also QUICK_RANGEs created in this function should be created in memory root of QUICK_SELECT.
sql/sql_class.cc:
Implementation of Monty's idea about clear_alloc_root() optimization and cleanup of work
with memory roots in THD/Statement/Item_arena.
Now we are always initing THD::transaction.mem_root and THD::mem_root in THD constructor
(without memory allocation and with minimal block size) and then later change their
parameters in THD::init_for_queries() (this is partially because we can't allocate anything
on bzero'ed memory roots anymore).
Item_arena() constructor is now trivial and is used only then Item_arena is created as backup
storage for other Item_arena (we use Item_arena(bool) now if it is part of Statement).
Both trivial Item_arena constructor and destructor are now inline.
Removed unneeded clear_alloc_root from Item_arena::restore_backup_item_arena().
sql/sql_class.h:
Both trivial Item_arena constructor and destructor are now inline.
Commented various Item_arena constructors.
Diffstat (limited to 'mysys/my_alloc.c')
-rw-r--r-- | mysys/my_alloc.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index c9784ddc9a0..f0bc62b10a0 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -22,6 +22,27 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG + +/* + Initialize memory root + + SYNOPSIS + init_alloc_root() + mem_root - memory root to initialize + block_size - size of chunks (blocks) used for memory allocation + (It is external size of chunk i.e. it should include + memory required for internal structures, thus it + should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE) + pre_alloc_size - if non-0, then size of block that should be + pre-allocated during memory root initialization. + + DESCRIPTION + This function prepares memory root for further use, sets initial size of + chunk for memory allocation and pre-allocates first block if specified. + Altough error can happen during execution of this function if pre_alloc_size + is non-0 it won't be reported. Instead it will be reported as error in first + alloc_root() on this memory root. +*/ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { @@ -29,7 +50,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, DBUG_PRINT("enter",("root: 0x%lx", mem_root)); mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; - mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; + mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; @@ -54,9 +75,9 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, SYNOPSIS reset_root_defaults() mem_root memory root to change defaults of - block_size new value of block size. Must be - greater than ~68 bytes (the exact value depends on - platform and compilation flags) + block_size new value of block size. Must be greater or equal + than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about + 68 bytes and depends on platform and compilation flags) pre_alloc_size new size of preallocated block. If not zero, must be equal to or greater than block size, otherwise means 'no prealloc'. @@ -70,7 +91,9 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, void reset_root_defaults(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) { - mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; + DBUG_ASSERT(alloc_root_inited(mem_root)); + + mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { @@ -123,6 +146,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) DBUG_ENTER("alloc_root"); DBUG_PRINT("enter",("root: 0x%lx", mem_root)); + DBUG_ASSERT(alloc_root_inited(mem_root)); + Size+=ALIGN_SIZE(sizeof(USED_MEM)); if (!(next = (USED_MEM*) my_malloc(Size,MYF(MY_WME)))) { @@ -140,6 +165,8 @@ gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size) reg1 USED_MEM *next= 0; reg2 USED_MEM **prev; + DBUG_ASSERT(alloc_root_inited(mem_root)); + Size= ALIGN_SIZE(Size); if ((*(prev= &mem_root->free)) != NULL) { |