YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/* Routines to handle mallocing of results which will be freed the same time */
#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size)
{
size_t size= mem_root->block_size, alloced_size; if (!mem_root->pre_alloc ||
mem_root->pre_alloc->size != mem_root->block_size)
{
USED_MEM *mem, **prev= &mem_root->free; /* Freeunusedblocks,sothatconsequentcalls toreset_root_defaultswon'teatawaymemory.
*/ while (*prev)
{
mem= *prev; if (mem->size == size)
{ /* We found a suitable block, no need to do anything else */
mem_root->pre_alloc= mem;
DBUG_VOID_RETURN;
} if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size)
{ /* remove block from the list and free it */
*prev= mem->next;
root_free(mem_root, mem, mem->size);
} else
prev= &mem->next;
} /* Allocate new prealloc block and add it to the end of free list */ if ((mem= (USED_MEM *) root_alloc(mem_root, size, &alloced_size,
MYF(MY_WME))))
{
mem->size= alloced_size;
mem->left= alloced_size - ALIGN_SIZE(sizeof(USED_MEM));
mem->next= *prev;
*prev= mem_root->pre_alloc= mem;
TRASH_MEM(mem);
} else
mem_root->pre_alloc= 0;
}
} else #endif
mem_root->pre_alloc= 0;
length= ALIGN_SIZE(length) + REDZONE_SIZE; if ((*(prev= &mem_root->free)) != NULL)
{ if ((*prev)->left < length &&
mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP &&
(*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
{
next= *prev;
*prev= next->next; /* Remove block from free list */
next->next= mem_root->used; /* Add to used list */
mem_root->used= next;
mem_root->first_block_usage= 0;
} for (next= *prev ; next && next->left < length ; next= next->next)
prev= &next->next;
} if (! next)
{ /* Time to alloc new block */
size_t alloced_length;
/* Increase block size over time if there is a lot of mallocs */ /* when changing this logic, update root_size() to match */
block_size= (MY_ALIGN(mem_root->block_size, ROOT_MIN_BLOCK_SIZE) *
(mem_root->block_num >> 2)- MALLOC_OVERHEAD);
get_size= length + ALIGN_SIZE(sizeof(USED_MEM));
get_size= MY_MAX(get_size, block_size);
if (!(next= (USED_MEM*) root_alloc(mem_root, get_size, &alloced_length,
MYF(MY_WME | ME_FATAL))))
{ if (mem_root->error_handler)
(*mem_root->error_handler)();
DBUG_RETURN((void*) 0); /* purecov: inspected */
}
mem_root->block_num++;
DBUG_ASSERT(*prev == 0);
next->next= 0;
next->size= alloced_length;
next->left= alloced_length - ALIGN_SIZE(sizeof(USED_MEM));
*prev= next;
TRASH_MEM(next);
} else
{ /* Reset first_block_usage if we used the first block */ if (prev == &mem_root->free)
mem_root->first_block_usage= 0;
}
point= (uchar*) ((char*) next+ (next->size-next->left)); if ((next->left-= length) < mem_root->min_malloc)
{ /* Full block. Move the block from the free list to the used list */
*prev= next->next;
next->next= mem_root->used;
mem_root->used= next;
}
point+= REDZONE_SIZE;
TRASH_ALLOC(point, original_length);
DBUG_PRINT("exit",("ptr: %p", point));
DBUG_RETURN((void*) point);
}
/* iterate through (partially) free blocks, mark them free */
last= &root->free; for (next= root->free; next; next= *(last= &next->next))
{
next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
TRASH_MEM(next);
}
/* Combine the free and the used list */
*last= next=root->used;
/* now go through the used blocks and mark them free */ for (; next; next= next->next)
{
next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
TRASH_MEM(next);
}
/* Now everything is set; Indicate that nothing is used anymore */
root->used= 0;
root->first_block_usage= 0;
} #endif
/* iterate through (partially) free blocks, mark them free */ for ( ; block; prev= &block->next, block= *prev)
{
block->left= block->size - ALIGN_SIZE(sizeof(USED_MEM));
TRASH_MEM(block);
}
/* Combine the free and the used list */
*prev= block=root->used;
/* now go through the used blocks and mark them free */ for ( ; block; prev= &block->next, block= *prev)
{
block->left= block->size - ALIGN_SIZE(sizeof(USED_MEM));
TRASH_MEM(block);
}
/* restore free and used lists from savepoint */
*prev= sv->free;
root->used= sv->used;
root->first_block_usage= prev == &root->free ? sv->first_block_usage : 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.