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 */ { mem_block_t* block; ulint len; ut_ad((type == MEM_HEAP_DYNAMIC) || (type == MEM_HEAP_BUFFER) || (type == MEM_HEAP_BUFFER + MEM_HEAP_BTR_SEARCH)); if (heap && heap->magic_n != MEM_BLOCK_MAGIC_N) { mem_analyze_corruption((byte*)heap); } /* In dynamic allocation, calculate the size: block header + data. */ if (init_block != NULL) { ut_ad(type == MEM_HEAP_DYNAMIC); ut_ad(n > MEM_BLOCK_START_SIZE + MEM_BLOCK_HEADER_SIZE); len = n; block = init_block; } else if (type == MEM_HEAP_DYNAMIC) { len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n); block = mem_area_alloc(len, mem_comm_pool); } else { ut_ad(n <= MEM_MAX_ALLOC_IN_BUF); len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n); if (len < UNIV_PAGE_SIZE / 2) { block = mem_area_alloc(len, mem_comm_pool); } else { len = UNIV_PAGE_SIZE; if ((type & MEM_HEAP_BTR_SEARCH) && heap) { /* We cannot allocate the block from the buffer pool, but must get the free block from the heap header free block field */ block = (mem_block_t*)heap->free_block; heap->free_block = NULL; } else { block = (mem_block_t*)buf_frame_alloc(); } } } if (block == NULL) { return(NULL); } block->magic_n = MEM_BLOCK_MAGIC_N; ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name)); block->line = line; #ifdef MEM_PERIODIC_CHECK mem_pool_mutex_enter(); if (!mem_block_list_inited) { mem_block_list_inited = TRUE; UT_LIST_INIT(mem_block_list); } UT_LIST_ADD_LAST(mem_block_list, mem_block_list, block); mem_pool_mutex_exit(); #endif mem_block_set_len(block, len); mem_block_set_type(block, type); mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE); mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE); block->free_block = NULL; block->init_block = (init_block != NULL); ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); return(block); }
/***************************************************************//** Creates a memory heap block where data can be allocated. @return own: memory heap block, NULL if did not succeed (only possible for MEM_HEAP_BTR_SEARCH type heaps) */ UNIV_INTERN mem_block_t* mem_heap_create_block( /*==================*/ 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 */ 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 */ { #ifndef UNIV_HOTBACKUP buf_block_t* buf_block = NULL; #endif /* !UNIV_HOTBACKUP */ mem_block_t* block; ulint len; ut_ad((type == MEM_HEAP_DYNAMIC) || (type == MEM_HEAP_BUFFER) || (type == MEM_HEAP_BUFFER + MEM_HEAP_BTR_SEARCH)); if (heap && heap->magic_n != MEM_BLOCK_MAGIC_N) { mem_analyze_corruption(heap); } /* In dynamic allocation, calculate the size: block header + data. */ len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n); #ifndef UNIV_HOTBACKUP if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) { ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF); block = mem_area_alloc(&len, mem_comm_pool); } else { len = UNIV_PAGE_SIZE; if ((type & MEM_HEAP_BTR_SEARCH) && heap) { /* We cannot allocate the block from the buffer pool, but must get the free block from the heap header free block field */ buf_block = heap->free_block; heap->free_block = NULL; if (UNIV_UNLIKELY(!buf_block)) { return(NULL); } } else { buf_block = buf_block_alloc(NULL, 0); } block = (mem_block_t*) buf_block->frame; } ut_ad(block); block->buf_block = buf_block; block->free_block = NULL; #else /* !UNIV_HOTBACKUP */ len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n); block = ut_malloc(len); ut_ad(block); #endif /* !UNIV_HOTBACKUP */ block->magic_n = MEM_BLOCK_MAGIC_N; ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name)); block->line = line; #ifdef MEM_PERIODIC_CHECK mem_pool_mutex_enter(); if (!mem_block_list_inited) { mem_block_list_inited = TRUE; UT_LIST_INIT(mem_block_list); } UT_LIST_ADD_LAST(mem_block_list, mem_block_list, block); mem_pool_mutex_exit(); #endif mem_block_set_len(block, len); mem_block_set_type(block, type); mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE); mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE); if (UNIV_UNLIKELY(heap == NULL)) { /* This is the first block of the heap. The field total_size should be initialized here */ block->total_size = len; } else { /* Not the first allocation for the heap. This block's total_length field should be set to undefined. */ ut_d(block->total_size = ULINT_UNDEFINED); UNIV_MEM_INVALID(&block->total_size, sizeof block->total_size); heap->total_size += len; } ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); return(block); }