summaryrefslogtreecommitdiff
path: root/storage/innodb_plugin/mem/mem0mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innodb_plugin/mem/mem0mem.c')
-rw-r--r--storage/innodb_plugin/mem/mem0mem.c555
1 files changed, 0 insertions, 555 deletions
diff --git a/storage/innodb_plugin/mem/mem0mem.c b/storage/innodb_plugin/mem/mem0mem.c
deleted file mode 100644
index ccb2fd8a7b4..00000000000
--- a/storage/innodb_plugin/mem/mem0mem.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/********************************************************************//**
-@file mem/mem0mem.c
-The memory management
-
-Created 6/9/1994 Heikki Tuuri
-*************************************************************************/
-
-#include "mem0mem.h"
-#ifdef UNIV_NONINL
-#include "mem0mem.ic"
-#endif
-
-#include "buf0buf.h"
-#include "srv0srv.h"
-#include "mem0dbg.c"
-#include <stdarg.h>
-
-/*
- THE MEMORY MANAGEMENT
- =====================
-
-The basic element of the memory management is called a memory
-heap. A memory heap is conceptually a
-stack from which memory can be allocated. The stack may grow infinitely.
-The top element of the stack may be freed, or
-the whole stack can be freed at one time. The advantage of the
-memory heap concept is that we can avoid using the malloc and free
-functions of C which are quite expensive, for example, on the Solaris + GCC
-system (50 MHz Sparc, 1993) the pair takes 3 microseconds,
-on Win NT + 100MHz Pentium, 2.5 microseconds.
-When we use a memory heap,
-we can allocate larger blocks of memory at a time and thus
-reduce overhead. Slightly more efficient the method is when we
-allocate the memory from the index page buffer pool, as we can
-claim a new page fast. This is called buffer allocation.
-When we allocate the memory from the dynamic memory of the
-C environment, that is called dynamic allocation.
-
-The default way of operation of the memory heap is the following.
-First, when the heap is created, an initial block of memory is
-allocated. In dynamic allocation this may be about 50 bytes.
-If more space is needed, additional blocks are allocated
-and they are put into a linked list.
-After the initial block, each allocated block is twice the size of the
-previous, until a threshold is attained, after which the sizes
-of the blocks stay the same. An exception is, of course, the case
-where the caller requests a memory buffer whose size is
-bigger than the threshold. In that case a block big enough must
-be allocated.
-
-The heap is physically arranged so that if the current block
-becomes full, a new block is allocated and always inserted in the
-chain of blocks as the last block.
-
-In the debug version of the memory management, all the allocated
-heaps are kept in a list (which is implemented as a hash table).
-Thus we can notice if the caller tries to free an already freed
-heap. In addition, each buffer given to the caller contains
-start field at the start and a trailer field at the end of the buffer.
-
-The start field has the following content:
-A. sizeof(ulint) bytes of field length (in the standard byte order)
-B. sizeof(ulint) bytes of check field (a random number)
-
-The trailer field contains:
-A. sizeof(ulint) bytes of check field (the same random number as at the start)
-
-Thus we can notice if something has been copied over the
-borders of the buffer, which is illegal.
-The memory in the buffers is initialized to a random byte sequence.
-After freeing, all the blocks in the heap are set to random bytes
-to help us discover errors which result from the use of
-buffers in an already freed heap. */
-
-#ifdef MEM_PERIODIC_CHECK
-
-ibool mem_block_list_inited;
-/* List of all mem blocks allocated; protected by the mem_comm_pool mutex */
-UT_LIST_BASE_NODE_T(mem_block_t) mem_block_list;
-
-#endif
-
-/**********************************************************************//**
-Duplicates a NUL-terminated string, allocated from a memory heap.
-@return own: a copy of the string */
-UNIV_INTERN
-char*
-mem_heap_strdup(
-/*============*/
- mem_heap_t* heap, /*!< in: memory heap where string is allocated */
- const char* str) /*!< in: string to be copied */
-{
- return(mem_heap_dup(heap, str, strlen(str) + 1));
-}
-
-/**********************************************************************//**
-Duplicate a block of data, allocated from a memory heap.
-@return own: a copy of the data */
-UNIV_INTERN
-void*
-mem_heap_dup(
-/*=========*/
- mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
- const void* data, /*!< in: data to be copied */
- ulint len) /*!< in: length of data, in bytes */
-{
- return(memcpy(mem_heap_alloc(heap, len), data, len));
-}
-
-/**********************************************************************//**
-Concatenate two strings and return the result, using a memory heap.
-@return own: the result */
-UNIV_INTERN
-char*
-mem_heap_strcat(
-/*============*/
- mem_heap_t* heap, /*!< in: memory heap where string is allocated */
- const char* s1, /*!< in: string 1 */
- const char* s2) /*!< in: string 2 */
-{
- char* s;
- ulint s1_len = strlen(s1);
- ulint s2_len = strlen(s2);
-
- s = mem_heap_alloc(heap, s1_len + s2_len + 1);
-
- memcpy(s, s1, s1_len);
- memcpy(s + s1_len, s2, s2_len);
-
- s[s1_len + s2_len] = '\0';
-
- return(s);
-}
-
-
-/****************************************************************//**
-Helper function for mem_heap_printf.
-@return length of formatted string, including terminating NUL */
-static
-ulint
-mem_heap_printf_low(
-/*================*/
- char* buf, /*!< in/out: buffer to store formatted string
- in, or NULL to just calculate length */
- const char* format, /*!< in: format string */
- va_list ap) /*!< in: arguments */
-{
- ulint len = 0;
-
- while (*format) {
-
- /* Does this format specifier have the 'l' length modifier. */
- ibool is_long = FALSE;
-
- /* Length of one parameter. */
- size_t plen;
-
- if (*format++ != '%') {
- /* Non-format character. */
-
- len++;
-
- if (buf) {
- *buf++ = *(format - 1);
- }
-
- continue;
- }
-
- if (*format == 'l') {
- is_long = TRUE;
- format++;
- }
-
- switch (*format++) {
- case 's':
- /* string */
- {
- char* s = va_arg(ap, char*);
-
- /* "%ls" is a non-sensical format specifier. */
- ut_a(!is_long);
-
- plen = strlen(s);
- len += plen;
-
- if (buf) {
- memcpy(buf, s, plen);
- buf += plen;
- }
- }
-
- break;
-
- case 'u':
- /* unsigned int */
- {
- char tmp[32];
- unsigned long val;
-
- /* We only support 'long' values for now. */
- ut_a(is_long);
-
- val = va_arg(ap, unsigned long);
-
- plen = sprintf(tmp, "%lu", val);
- len += plen;
-
- if (buf) {
- memcpy(buf, tmp, plen);
- buf += plen;
- }
- }
-
- break;
-
- case '%':
-
- /* "%l%" is a non-sensical format specifier. */
- ut_a(!is_long);
-
- len++;
-
- if (buf) {
- *buf++ = '%';
- }
-
- break;
-
- default:
- ut_error;
- }
- }
-
- /* For the NUL character. */
- len++;
-
- if (buf) {
- *buf = '\0';
- }
-
- return(len);
-}
-
-/****************************************************************//**
-A simple (s)printf replacement that dynamically allocates the space for the
-formatted string from the given heap. This supports a very limited set of
-the printf syntax: types 's' and 'u' and length modifier 'l' (which is
-required for the 'u' type).
-@return heap-allocated formatted string */
-UNIV_INTERN
-char*
-mem_heap_printf(
-/*============*/
- mem_heap_t* heap, /*!< in: memory heap */
- const char* format, /*!< in: format string */
- ...)
-{
- va_list ap;
- char* str;
- ulint len;
-
- /* Calculate length of string */
- len = 0;
- va_start(ap, format);
- len = mem_heap_printf_low(NULL, format, ap);
- va_end(ap);
-
- /* Now create it for real. */
- str = mem_heap_alloc(heap, len);
- va_start(ap, format);
- mem_heap_printf_low(str, format, ap);
- va_end(ap);
-
- return(str);
-}
-
-/***************************************************************//**
-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(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);
-
- ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
-
- return(block);
-}
-
-/***************************************************************//**
-Adds a new block to a memory heap.
-@return created block, NULL if did not succeed (only possible for
-MEM_HEAP_BTR_SEARCH type heaps) */
-UNIV_INTERN
-mem_block_t*
-mem_heap_add_block(
-/*===============*/
- 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, 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);
-}
-
-/******************************************************************//**
-Frees a block from a memory heap. */
-UNIV_INTERN
-void
-mem_heap_block_free(
-/*================*/
- mem_heap_t* heap, /*!< in: heap */
- mem_block_t* block) /*!< in: block to free */
-{
- ulint type;
- ulint len;
-#ifndef UNIV_HOTBACKUP
- buf_block_t* buf_block = block->buf_block;
-#endif /* !UNIV_HOTBACKUP */
-
- if (block->magic_n != MEM_BLOCK_MAGIC_N) {
- mem_analyze_corruption(block);
- }
-
- UT_LIST_REMOVE(list, heap->base, block);
-
-#ifdef MEM_PERIODIC_CHECK
- mem_pool_mutex_enter();
-
- UT_LIST_REMOVE(mem_block_list, mem_block_list, block);
-
- mem_pool_mutex_exit();
-#endif
- type = heap->type;
- len = block->len;
- block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
-
-#ifndef UNIV_HOTBACKUP
- if (!srv_use_sys_malloc) {
-#ifdef UNIV_MEM_DEBUG
- /* In the debug version we set the memory to a random
- combination of hex 0xDE and 0xAD. */
-
- mem_erase_buf((byte*)block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
-#endif /* UNIV_MEM_DEBUG */
-
- }
- if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
-
- ut_ad(!buf_block);
- mem_area_free(block, mem_comm_pool);
- } else {
- ut_ad(type & MEM_HEAP_BUFFER);
-
- buf_block_free(buf_block);
- }
-#else /* !UNIV_HOTBACKUP */
-#ifdef UNIV_MEM_DEBUG
- /* In the debug version we set the memory to a random
- combination of hex 0xDE and 0xAD. */
-
- mem_erase_buf((byte*)block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
-#endif /* UNIV_MEM_DEBUG */
- ut_free(block);
-#endif /* !UNIV_HOTBACKUP */
-}
-
-#ifndef UNIV_HOTBACKUP
-/******************************************************************//**
-Frees the free_block field from a memory heap. */
-UNIV_INTERN
-void
-mem_heap_free_block_free(
-/*=====================*/
- mem_heap_t* heap) /*!< in: heap */
-{
- if (UNIV_LIKELY_NULL(heap->free_block)) {
-
- buf_block_free(heap->free_block);
-
- heap->free_block = NULL;
- }
-}
-#endif /* !UNIV_HOTBACKUP */
-
-#ifdef MEM_PERIODIC_CHECK
-/******************************************************************//**
-Goes through the list of all allocated mem blocks, checks their magic
-numbers, and reports possible corruption. */
-UNIV_INTERN
-void
-mem_validate_all_blocks(void)
-/*=========================*/
-{
- mem_block_t* block;
-
- mem_pool_mutex_enter();
-
- block = UT_LIST_GET_FIRST(mem_block_list);
-
- while (block) {
- if (block->magic_n != MEM_BLOCK_MAGIC_N) {
- mem_analyze_corruption(block);
- }
-
- block = UT_LIST_GET_NEXT(mem_block_list, block);
- }
-
- mem_pool_mutex_exit();
-}
-#endif