summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorunknown <dlenev@brandersnatch.localdomain>2004-09-23 13:48:17 +0400
committerunknown <dlenev@brandersnatch.localdomain>2004-09-23 13:48:17 +0400
commit7ba5d931eb6611a1b3794d3c4378381060ac925d (patch)
tree72c836976a5eb3e3b63f565445ab8ca1ea26e4d8 /mysys
parentca65afeb72e7f514d51b7dcf2cc49e85a3b92677 (diff)
downloadmariadb-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')
-rw-r--r--mysys/my_alloc.c37
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)
{