📄 mem0mem.ic
字号:
/************************************************************************The memory management(c) 1994, 1995 Innobase OyCreated 6/8/1994 Heikki Tuuri*************************************************************************/#include "mem0dbg.ic"#include "mem0pool.h"/*******************************************************************Creates a memory heap block where data can be allocated. */mem_block_t*mem_heap_create_block(/*==================*/ /* out, own: memory heap block, NULL if did not succeed */ mem_heap_t* heap, /* in: memory heap or NULL if first block should be created */ ulint n, /* in: number of bytes needed for user data, or if init_block is not NULL, its size in bytes */ void* init_block, /* in: init block in fast create, type must be MEM_HEAP_DYNAMIC */ ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or MEM_HEAP_BUFFER */ const char* file_name,/* in: file name where created */ ulint line); /* in: line where created *//**********************************************************************Frees a block from a memory heap. */voidmem_heap_block_free(/*================*/ mem_heap_t* heap, /* in: heap */ mem_block_t* block); /* in: block to free *//**********************************************************************Frees the free_block field from a memory heap. */voidmem_heap_free_block_free(/*=====================*/ mem_heap_t* heap); /* in: heap *//*******************************************************************Adds a new block to a memory heap. */mem_block_t*mem_heap_add_block(/*===============*/ /* out: created block, NULL if did not succeed */ mem_heap_t* heap, /* in: memory heap */ ulint n); /* in: number of bytes user needs */UNIV_INLINEvoidmem_block_set_len(mem_block_t* block, ulint len){ ut_ad(len > 0); block->len = len;}UNIV_INLINEulintmem_block_get_len(mem_block_t* block){ return(block->len);}UNIV_INLINEvoidmem_block_set_type(mem_block_t* block, ulint type){ ut_ad((type == MEM_HEAP_DYNAMIC) || (type == MEM_HEAP_BUFFER) || (type == MEM_HEAP_BUFFER + MEM_HEAP_BTR_SEARCH)); block->type = type;}UNIV_INLINEulintmem_block_get_type(mem_block_t* block){ return(block->type);}UNIV_INLINEvoidmem_block_set_free(mem_block_t* block, ulint free){ ut_ad(free > 0); ut_ad(free <= mem_block_get_len(block)); block->free = free;}UNIV_INLINEulintmem_block_get_free(mem_block_t* block){ return(block->free);}UNIV_INLINEvoidmem_block_set_start(mem_block_t* block, ulint start){ ut_ad(start > 0); block->start = start;}UNIV_INLINEulintmem_block_get_start(mem_block_t* block){ return(block->start);}/*******************************************************************Allocates n bytes of memory from a memory heap. */UNIV_INLINEvoid*mem_heap_alloc(/*===========*/ /* out: allocated storage */ mem_heap_t* heap, /* in: memory heap */ ulint n) /* in: number of bytes; if the heap is allowed to grow into the buffer pool, this must be <= MEM_MAX_ALLOC_IN_BUF */{ mem_block_t* block; void* buf; ulint free; ut_ad(mem_heap_check(heap)); block = UT_LIST_GET_LAST(heap->base); ut_ad(!(block->type & MEM_HEAP_BUFFER) || (n <= MEM_MAX_ALLOC_IN_BUF)); /* Check if there is enough space in block. If not, create a new block to the heap */ if (mem_block_get_len(block) < mem_block_get_free(block) + MEM_SPACE_NEEDED(n)) { block = mem_heap_add_block(heap, n); if (block == NULL) { return(NULL); } } free = mem_block_get_free(block); buf = (byte*)block + free; mem_block_set_free(block, free + MEM_SPACE_NEEDED(n));#ifdef UNIV_MEM_DEBUG /* In the debug version write debugging info to the field */ mem_field_init((byte*)buf, n); /* Advance buf to point at the storage which will be given to the caller */ buf = (byte*)buf + MEM_FIELD_HEADER_SIZE;#endif#ifdef UNIV_SET_MEM_TO_ZERO memset(buf, '\0', n);#endif return(buf);}/*********************************************************************Returns a pointer to the heap top. */UNIV_INLINEbyte*mem_heap_get_heap_top(/*==================*/ /* out: pointer to the heap top */ mem_heap_t* heap) /* in: memory heap */{ mem_block_t* block; byte* buf; ut_ad(mem_heap_check(heap)); block = UT_LIST_GET_LAST(heap->base); buf = (byte*)block + mem_block_get_free(block); return(buf);} /*********************************************************************Frees the space in a memory heap exceeding the pointer given. Thepointer must have been acquired from mem_heap_get_heap_top. The firstmemory block of the heap is not freed. */UNIV_INLINEvoidmem_heap_free_heap_top(/*===================*/ mem_heap_t* heap, /* in: heap from which to free */ byte* old_top)/* in: pointer to old top of heap */{ mem_block_t* block; mem_block_t* prev_block;#ifdef UNIV_MEM_DEBUG ibool error; ulint total_size; ulint size;#endif ut_ad(mem_heap_check(heap)); #ifdef UNIV_MEM_DEBUG /* Validate the heap and get its total allocated size */ mem_heap_validate_or_print(heap, NULL, FALSE, &error, &total_size, NULL, NULL); ut_a(!error); /* Get the size below top pointer */ mem_heap_validate_or_print(heap, old_top, FALSE, &error, &size, NULL, NULL); ut_a(!error);#endif block = UT_LIST_GET_LAST(heap->base); while (block != NULL) { if (((byte*)block + mem_block_get_free(block) >= old_top) && ((byte*)block <= old_top)) { /* Found the right block */ break; } /* Store prev_block value before freeing the current block (the current block will be erased in freeing) */ prev_block = UT_LIST_GET_PREV(list, block); mem_heap_block_free(heap, block); block = prev_block; } ut_ad(block); /* Set the free field of block */ mem_block_set_free(block, old_top - (byte*)block); #ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); /* In the debug version erase block from top up */ mem_erase_buf(old_top, (byte*)block + block->len - old_top); /* Update allocated memory count */ mutex_enter(&mem_hash_mutex); mem_current_allocated_memory -= (total_size - size); mutex_exit(&mem_hash_mutex);#endif /* If free == start, we may free the block if it is not the first one */ if ((heap != block) && (mem_block_get_free(block) == mem_block_get_start(block))) { mem_heap_block_free(heap, block); }}/*********************************************************************Empties a memory heap. The first memory block of the heap is not freed. */UNIV_INLINEvoidmem_heap_empty(/*===========*/ mem_heap_t* heap) /* in: heap to empty */{ mem_heap_free_heap_top(heap, (byte*)heap + mem_block_get_start(heap)); if (heap->free_block) { mem_heap_free_block_free(heap); }} /*********************************************************************Returns a pointer to the topmost element in a memory heap. The size of theelement must be given. */UNIV_INLINEvoid*mem_heap_get_top(/*=============*/ /* out: pointer to the topmost element */ mem_heap_t* heap, /* in: memory heap */ ulint n) /* in: size of the topmost element */{ mem_block_t* block; void* buf; ut_ad(mem_heap_check(heap)); block = UT_LIST_GET_LAST(heap->base); buf = (byte*)block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n);#ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <=(ulint)((byte*)buf - (byte*)block)); /* In the debug version, advance buf to point at the storage which
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -