#include <my_global.h>#include <my_sys.h>#include <m_string.h>Include dependency graph for my_alloc.c:

Go to the source code of this file.
Defines | |
| #define | EXTRA_DEBUG |
| #define | TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left) |
Functions | |
| void | init_alloc_root (MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) |
| void | reset_root_defaults (MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size __attribute__((unused))) |
| gptr | alloc_root (MEM_ROOT *mem_root, unsigned int Size) |
| gptr | multi_alloc_root (MEM_ROOT *root,...) |
| static void | mark_blocks_free (MEM_ROOT *root) |
| void | free_root (MEM_ROOT *root, myf MyFlags) |
| void | set_prealloc_root (MEM_ROOT *root, char *ptr) |
| char * | strdup_root (MEM_ROOT *root, const char *str) |
| char * | strmake_root (MEM_ROOT *root, const char *str, uint len) |
| char * | memdup_root (MEM_ROOT *root, const char *str, uint len) |
| #define EXTRA_DEBUG |
Definition at line 23 of file my_alloc.c.
| #define TRASH_MEM | ( | X | ) | TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left) |
Definition at line 275 of file my_alloc.c.
Definition at line 144 of file my_alloc.c.
References ALIGN_SIZE, ALLOC_MAX_BLOCK_TO_DROP, ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP, alloc_root_inited, st_mem_root::block_num, st_mem_root::block_size, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_mem_root::error_handler, st_mem_root::first_block_usage, st_mem_root::free, st_used_mem::left, max, st_mem_root::min_malloc, my_malloc(), MY_WME, MYF, st_used_mem::next, NULL, reg1, reg2, st_used_mem::size, and st_mem_root::used.
00145 { 00146 #if defined(HAVE_purify) && defined(EXTRA_DEBUG) 00147 reg1 USED_MEM *next; 00148 DBUG_ENTER("alloc_root"); 00149 DBUG_PRINT("enter",("root: 0x%lx", mem_root)); 00150 00151 DBUG_ASSERT(alloc_root_inited(mem_root)); 00152 00153 Size+=ALIGN_SIZE(sizeof(USED_MEM)); 00154 if (!(next = (USED_MEM*) my_malloc(Size,MYF(MY_WME)))) 00155 { 00156 if (mem_root->error_handler) 00157 (*mem_root->error_handler)(); 00158 DBUG_RETURN((gptr) 0); /* purecov: inspected */ 00159 } 00160 next->next= mem_root->used; 00161 next->size= Size; 00162 mem_root->used= next; 00163 DBUG_PRINT("exit",("ptr: 0x%lx", (((char*) next)+ 00164 ALIGN_SIZE(sizeof(USED_MEM))))); 00165 DBUG_RETURN((gptr) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM)))); 00166 #else 00167 uint get_size, block_size; 00168 gptr point; 00169 reg1 USED_MEM *next= 0; 00170 reg2 USED_MEM **prev; 00171 DBUG_ENTER("alloc_root"); 00172 DBUG_PRINT("enter",("root: 0x%lx", mem_root)); 00173 DBUG_ASSERT(alloc_root_inited(mem_root)); 00174 00175 Size= ALIGN_SIZE(Size); 00176 if ((*(prev= &mem_root->free)) != NULL) 00177 { 00178 if ((*prev)->left < Size && 00179 mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP && 00180 (*prev)->left < ALLOC_MAX_BLOCK_TO_DROP) 00181 { 00182 next= *prev; 00183 *prev= next->next; /* Remove block from list */ 00184 next->next= mem_root->used; 00185 mem_root->used= next; 00186 mem_root->first_block_usage= 0; 00187 } 00188 for (next= *prev ; next && next->left < Size ; next= next->next) 00189 prev= &next->next; 00190 } 00191 if (! next) 00192 { /* Time to alloc new block */ 00193 block_size= mem_root->block_size * (mem_root->block_num >> 2); 00194 get_size= Size+ALIGN_SIZE(sizeof(USED_MEM)); 00195 get_size= max(get_size, block_size); 00196 00197 if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME)))) 00198 { 00199 if (mem_root->error_handler) 00200 (*mem_root->error_handler)(); 00201 return((gptr) 0); /* purecov: inspected */ 00202 } 00203 mem_root->block_num++; 00204 next->next= *prev; 00205 next->size= get_size; 00206 next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM)); 00207 *prev=next; 00208 } 00209 00210 point= (gptr) ((char*) next+ (next->size-next->left)); 00211 /*TODO: next part may be unneded due to mem_root->first_block_usage counter*/ 00212 if ((next->left-= Size) < mem_root->min_malloc) 00213 { /* Full block */ 00214 *prev= next->next; /* Remove block from list */ 00215 next->next= mem_root->used; 00216 mem_root->used= next; 00217 mem_root->first_block_usage= 0; 00218 } 00219 DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point)); 00220 DBUG_RETURN(point); 00221 #endif 00222 }
Here is the call graph for this function:

Definition at line 327 of file my_alloc.c.
References ALIGN_SIZE, st_mem_root::block_num, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, st_mem_root::first_block_usage, st_mem_root::free, st_used_mem::left, mark_blocks_free(), my_free, MY_KEEP_PREALLOC, MY_MARK_BLOCKS_FREE, MYF, st_used_mem::next, st_mem_root::pre_alloc, reg1, st_used_mem::size, TRASH_MEM, and st_mem_root::used.
00328 { 00329 reg1 USED_MEM *next,*old; 00330 DBUG_ENTER("free_root"); 00331 DBUG_PRINT("enter",("root: 0x%lx flags: %u", root, (uint) MyFlags)); 00332 00333 if (!root) /* QQ: Should be deleted */ 00334 DBUG_VOID_RETURN; /* purecov: inspected */ 00335 if (MyFlags & MY_MARK_BLOCKS_FREE) 00336 { 00337 mark_blocks_free(root); 00338 DBUG_VOID_RETURN; 00339 } 00340 if (!(MyFlags & MY_KEEP_PREALLOC)) 00341 root->pre_alloc=0; 00342 00343 for (next=root->used; next ;) 00344 { 00345 old=next; next= next->next ; 00346 if (old != root->pre_alloc) 00347 my_free((gptr) old,MYF(0)); 00348 } 00349 for (next=root->free ; next ;) 00350 { 00351 old=next; next= next->next; 00352 if (old != root->pre_alloc) 00353 my_free((gptr) old,MYF(0)); 00354 } 00355 root->used=root->free=0; 00356 if (root->pre_alloc) 00357 { 00358 root->free=root->pre_alloc; 00359 root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM)); 00360 TRASH_MEM(root->pre_alloc); 00361 root->free->next=0; 00362 } 00363 root->block_num= 4; 00364 root->first_block_usage= 0; 00365 DBUG_VOID_RETURN; 00366 }
Here is the call graph for this function:

| void init_alloc_root | ( | MEM_ROOT * | mem_root, | |
| uint | block_size, | |||
| uint pre_alloc_size | __attribute__((unused)) | |||
| ) |
Definition at line 47 of file my_alloc.c.
References ALIGN_SIZE, ALLOC_ROOT_MIN_BLOCK_SIZE, st_mem_root::block_num, st_mem_root::block_size, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, st_mem_root::error_handler, st_mem_root::first_block_usage, st_mem_root::free, st_used_mem::left, st_mem_root::min_malloc, my_malloc(), MYF, st_used_mem::next, st_mem_root::pre_alloc, st_used_mem::size, and st_mem_root::used.
00049 { 00050 DBUG_ENTER("init_alloc_root"); 00051 DBUG_PRINT("enter",("root: 0x%lx", mem_root)); 00052 mem_root->free= mem_root->used= mem_root->pre_alloc= 0; 00053 mem_root->min_malloc= 32; 00054 mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; 00055 mem_root->error_handler= 0; 00056 mem_root->block_num= 4; /* We shift this with >>2 */ 00057 mem_root->first_block_usage= 0; 00058 00059 #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) 00060 if (pre_alloc_size) 00061 { 00062 if ((mem_root->free= mem_root->pre_alloc= 00063 (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)), 00064 MYF(0)))) 00065 { 00066 mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); 00067 mem_root->free->left= pre_alloc_size; 00068 mem_root->free->next= 0; 00069 } 00070 } 00071 #endif 00072 DBUG_VOID_RETURN; 00073 }
Here is the call graph for this function:

| static void mark_blocks_free | ( | MEM_ROOT * | root | ) | [inline, static] |
Definition at line 279 of file my_alloc.c.
References ALIGN_SIZE, st_mem_root::first_block_usage, st_mem_root::free, st_used_mem::left, reg1, reg2, TRASH_MEM, and st_mem_root::used.
00280 { 00281 reg1 USED_MEM *next; 00282 reg2 USED_MEM **last; 00283 00284 /* iterate through (partially) free blocks, mark them free */ 00285 last= &root->free; 00286 for (next= root->free; next; next= *(last= &next->next)) 00287 { 00288 next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM)); 00289 TRASH_MEM(next); 00290 } 00291 00292 /* Combine the free and the used list */ 00293 *last= next=root->used; 00294 00295 /* now go through the used blocks and mark them free */ 00296 for (; next; next= next->next) 00297 { 00298 next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM)); 00299 TRASH_MEM(next); 00300 } 00301 00302 /* Now everything is set; Indicate that nothing is used anymore */ 00303 root->used= 0; 00304 root->first_block_usage= 0; 00305 }
Definition at line 412 of file my_alloc.c.
References alloc_root(), memcpy, and pos().
00413 { 00414 char *pos; 00415 if ((pos=alloc_root(root,len))) 00416 memcpy(pos,str,len); 00417 return pos; 00418 }
Here is the call graph for this function:

Definition at line 244 of file my_alloc.c.
References ALIGN_SIZE, alloc_root(), args, DBUG_ENTER, DBUG_RETURN, and start().
00245 { 00246 va_list args; 00247 char **ptr, *start, *res; 00248 uint tot_length, length; 00249 DBUG_ENTER("multi_alloc_root"); 00250 00251 va_start(args, root); 00252 tot_length= 0; 00253 while ((ptr= va_arg(args, char **))) 00254 { 00255 length= va_arg(args, uint); 00256 tot_length+= ALIGN_SIZE(length); 00257 } 00258 va_end(args); 00259 00260 if (!(start= (char*) alloc_root(root, tot_length))) 00261 DBUG_RETURN(0); /* purecov: inspected */ 00262 00263 va_start(args, root); 00264 res= start; 00265 while ((ptr= va_arg(args, char **))) 00266 { 00267 *ptr= res; 00268 length= va_arg(args, uint); 00269 res+= ALIGN_SIZE(length); 00270 } 00271 va_end(args); 00272 DBUG_RETURN((gptr) start); 00273 }
Here is the call graph for this function:

| void reset_root_defaults | ( | MEM_ROOT * | mem_root, | |
| uint | block_size, | |||
| uint pre_alloc_size | __attribute__((unused)) | |||
| ) |
Definition at line 93 of file my_alloc.c.
References ALIGN_SIZE, alloc_root_inited, ALLOC_ROOT_MIN_BLOCK_SIZE, st_mem_root::block_size, DBUG_ASSERT, st_mem_root::free, mem, my_free, my_malloc(), MYF, st_mem_root::pre_alloc, and st_used_mem::size.
00095 { 00096 DBUG_ASSERT(alloc_root_inited(mem_root)); 00097 00098 mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; 00099 #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) 00100 if (pre_alloc_size) 00101 { 00102 uint size= pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM)); 00103 if (!mem_root->pre_alloc || mem_root->pre_alloc->size != size) 00104 { 00105 USED_MEM *mem, **prev= &mem_root->free; 00106 /* 00107 Free unused blocks, so that consequent calls 00108 to reset_root_defaults won't eat away memory. 00109 */ 00110 while (*prev) 00111 { 00112 mem= *prev; 00113 if (mem->size == size) 00114 { 00115 /* We found a suitable block, no need to do anything else */ 00116 mem_root->pre_alloc= mem; 00117 return; 00118 } 00119 if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size) 00120 { 00121 /* remove block from the list and free it */ 00122 *prev= mem->next; 00123 my_free((gptr) mem, MYF(0)); 00124 } 00125 else 00126 prev= &mem->next; 00127 } 00128 /* Allocate new prealloc block and add it to the end of free list */ 00129 if ((mem= (USED_MEM *) my_malloc(size, MYF(0)))) 00130 { 00131 mem->size= size; 00132 mem->left= pre_alloc_size; 00133 mem->next= *prev; 00134 *prev= mem_root->pre_alloc= mem; 00135 } 00136 } 00137 } 00138 else 00139 #endif 00140 mem_root->pre_alloc= 0; 00141 }
Here is the call graph for this function:

| void set_prealloc_root | ( | MEM_ROOT * | root, | |
| char * | ptr | |||
| ) |
Definition at line 372 of file my_alloc.c.
References st_mem_root::free, st_used_mem::next, st_mem_root::pre_alloc, st_used_mem::size, and st_mem_root::used.
00373 { 00374 USED_MEM *next; 00375 for (next=root->used; next ; next=next->next) 00376 { 00377 if ((char*) next <= ptr && (char*) next + next->size > ptr) 00378 { 00379 root->pre_alloc=next; 00380 return; 00381 } 00382 } 00383 for (next=root->free ; next ; next=next->next) 00384 { 00385 if ((char*) next <= ptr && (char*) next + next->size > ptr) 00386 { 00387 root->pre_alloc=next; 00388 return; 00389 } 00390 } 00391 }
| char* strdup_root | ( | MEM_ROOT * | root, | |
| const char * | str | |||
| ) |
Definition at line 394 of file my_alloc.c.
References strlen(), and strmake_root().
00395 { 00396 return strmake_root(root, str, (uint) strlen(str)); 00397 }
Here is the call graph for this function:

Definition at line 400 of file my_alloc.c.
References alloc_root(), memcpy, and pos().
00401 { 00402 char *pos; 00403 if ((pos=alloc_root(root,len+1))) 00404 { 00405 memcpy(pos,str,len); 00406 pos[len]=0; 00407 } 00408 return pos; 00409 }
Here is the call graph for this function:

1.4.7

