/***************************************************************//** Inserts a created memory heap to the hash table of current allocated memory heaps. */ UNIV_INTERN void mem_hash_insert( /*============*/ mem_heap_t* heap, /*!< in: the created heap */ const char* file_name, /*!< in: file name of creation */ ulint line) /*!< in: line where created */ { mem_hash_node_t* new_node; ulint cell_no ; ut_ad(mem_heap_check(heap)); mutex_enter(&mem_hash_mutex); cell_no = ut_hash_ulint((ulint)heap, MEM_HASH_SIZE); /* Allocate a new node to the list */ new_node = ut_malloc(sizeof(mem_hash_node_t)); new_node->heap = heap; new_node->file_name = file_name; new_node->line = line; new_node->nth_heap = mem_n_created_heaps; /* Insert into lists */ UT_LIST_ADD_FIRST(list, *mem_hash_get_nth_cell(cell_no), new_node); UT_LIST_ADD_LAST(all_list, mem_all_list_base, new_node); mem_n_created_heaps++; mutex_exit(&mem_hash_mutex); }
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 */ { mem_block_t* block; mem_block_t* new_block; ulint new_size; ut_ad(mem_heap_check(heap)); block = UT_LIST_GET_LAST(heap->base); /* We have to allocate a new block. The size is always at least doubled until the standard size is reached. After that the size stays the same, except in cases where the caller needs more space. */ new_size = 2 * mem_block_get_len(block); if (heap->type != MEM_HEAP_DYNAMIC) { /* From the buffer pool we allocate buffer frames */ ut_a(n <= MEM_MAX_ALLOC_IN_BUF); if (new_size > MEM_MAX_ALLOC_IN_BUF) { new_size = MEM_MAX_ALLOC_IN_BUF; } } else if (new_size > MEM_BLOCK_STANDARD_SIZE) { new_size = MEM_BLOCK_STANDARD_SIZE; } if (new_size < n) { new_size = n; } new_block = mem_heap_create_block(heap, new_size, NULL, heap->type, heap->file_name, heap->line); if (new_block == NULL) { return(NULL); } /* Add the new block as the last block */ UT_LIST_INSERT_AFTER(list, heap->base, block, new_block); return(new_block); }
/***************************************************************//** Removes a memory heap (which is going to be freed by the caller) from the list of live memory heaps. Returns the size of the heap in terms of how much memory in bytes was allocated for the user of the heap (not the total space occupied by the heap). Also validates the heap. NOTE: This function does not free the storage occupied by the heap itself, only the node in the list of heaps. */ UNIV_INTERN void mem_hash_remove( /*============*/ mem_heap_t* heap, /*!< in: the heap to be freed */ const char* file_name, /*!< in: file name of freeing */ ulint line) /*!< in: line where freed */ { mem_hash_node_t* node; ulint cell_no; ibool error; ulint size; ut_ad(mem_heap_check(heap)); mutex_enter(&mem_hash_mutex); cell_no = ut_hash_ulint((ulint)heap, MEM_HASH_SIZE); /* Look for the heap in the hash table list */ node = UT_LIST_GET_FIRST(*mem_hash_get_nth_cell(cell_no)); while (node != NULL) { if (node->heap == heap) { break; } node = UT_LIST_GET_NEXT(list, node); } if (node == NULL) { fprintf(stderr, "Memory heap or buffer freed in %s line %lu" " did not exist.\n", innobase_basename(file_name), (ulong) line); ut_error; } /* Remove from lists */ UT_LIST_REMOVE(list, *mem_hash_get_nth_cell(cell_no), node); UT_LIST_REMOVE(all_list, mem_all_list_base, node); /* Validate the heap which will be freed */ mem_heap_validate_or_print(node->heap, NULL, FALSE, &error, &size, NULL, NULL); if (error) { fprintf(stderr, "Inconsistency in memory heap or" " buffer n:o %lu created\n" "in %s line %lu and tried to free in %s line %lu.\n" "Hex dump of 400 bytes around memory heap" " first block start:\n", node->nth_heap, innobase_basename(node->file_name), (ulong) node->line, innobase_basename(file_name), (ulong) line); ut_print_buf(stderr, (byte*)node->heap - 200, 400); fputs("\nDump of the mem heap:\n", stderr); mem_heap_validate_or_print(node->heap, NULL, TRUE, &error, &size, NULL, NULL); ut_error; } /* Free the memory occupied by the node struct */ ut_free(node); mem_current_allocated_memory -= size; mutex_exit(&mem_hash_mutex); }