summaryrefslogtreecommitdiff
path: root/storage/innobase/mem/mem0mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/mem/mem0mem.c')
-rw-r--r--storage/innobase/mem/mem0mem.c298
1 files changed, 138 insertions, 160 deletions
diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
index f4fd178a39c..ccb2fd8a7b4 100644
--- a/storage/innobase/mem/mem0mem.c
+++ b/storage/innobase/mem/mem0mem.c
@@ -1,20 +1,34 @@
-/************************************************************************
-The memory management
+/*****************************************************************************
+
+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.
-(c) 1994, 1995 Innobase Oy
+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 "mach0data.h"
#include "buf0buf.h"
-#include "btr0sea.h"
#include "srv0srv.h"
#include "mem0dbg.c"
#include <stdarg.h>
@@ -84,81 +98,43 @@ UT_LIST_BASE_NODE_T(mem_block_t) mem_block_list;
#endif
-/*******************************************************************
-NOTE: Use the corresponding macro instead of this function.
-Allocates a single buffer of memory from the dynamic memory of
-the C compiler. Is like malloc of C. The buffer must be freed
-with mem_free. */
-
-void*
-mem_alloc_func_noninline(
-/*=====================*/
- /* out, own: free storage */
- ulint n, /* in: desired number of bytes */
- const char* file_name, /* in: file name where created */
- ulint line) /* in: line where created */
-{
- return(mem_alloc_func(n, file_name, line));
-}
-
-/**************************************************************************
-Duplicates a NUL-terminated string, allocated from a memory heap. */
-
+/**********************************************************************//**
+Duplicates a NUL-terminated string, allocated from a memory heap.
+@return own: a copy of the string */
+UNIV_INTERN
char*
mem_heap_strdup(
/*============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str) /* in: string to be copied */
+ 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. */
-
+/**********************************************************************//**
+Duplicate a block of data, allocated from a memory heap.
+@return own: a copy of the data */
+UNIV_INTERN
void*
mem_heap_dup(
/*=========*/
- /* out, own: a copy of the data */
- 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 */
+ 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 memory blocks and return the result, using a memory heap. */
-
-void*
-mem_heap_cat(
-/*=========*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where result is allocated */
- const void* b1, /* in: block 1 */
- ulint len1, /* in: length of b1, in bytes */
- const void* b2, /* in: block 2 */
- ulint len2) /* in: length of b2, in bytes */
-{
- void* res = mem_heap_alloc(heap, len1 + len2);
-
- memcpy(res, b1, len1);
- memcpy((char*)res + len1, b2, len2);
-
- return(res);
-}
-
-/**************************************************************************
-Concatenate two strings and return the result, using a memory heap. */
-
+/**********************************************************************//**
+Concatenate two strings and return the result, using a memory heap.
+@return own: the result */
+UNIV_INTERN
char*
mem_heap_strcat(
/*============*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* s1, /* in: string 1 */
- const char* s2) /* in: string 2 */
+ 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);
@@ -175,18 +151,17 @@ mem_heap_strcat(
}
-/********************************************************************
-Helper function for mem_heap_printf. */
+/****************************************************************//**
+Helper function for mem_heap_printf.
+@return length of formatted string, including terminating NUL */
static
ulint
mem_heap_printf_low(
/*================*/
- /* out: length of formatted string,
- including terminating NUL */
- char* buf, /* in/out: buffer to store formatted string
+ 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 */
+ const char* format, /*!< in: format string */
+ va_list ap) /*!< in: arguments */
{
ulint len = 0;
@@ -285,18 +260,18 @@ mem_heap_printf_low(
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). */
-
+required for the 'u' type).
+@return heap-allocated formatted string */
+UNIV_INTERN
char*
mem_heap_printf(
/*============*/
- /* out: heap-allocated formatted string */
- mem_heap_t* heap, /* in: memory heap */
- const char* format, /* in: format string */
+ mem_heap_t* heap, /*!< in: memory heap */
+ const char* format, /*!< in: format string */
...)
{
va_list ap;
@@ -318,26 +293,25 @@ mem_heap_printf(
return(str);
}
-/*******************************************************************
-Creates a memory heap block where data can be allocated. */
-
+/***************************************************************//**
+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(
/*==================*/
- /* out, own: memory heap block, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap or NULL if first 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, 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
+ 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 */
+ 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;
@@ -349,48 +323,45 @@ mem_heap_create_block(
}
/* In dynamic allocation, calculate the size: block header + data. */
+ len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
- 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;
+#ifndef UNIV_HOTBACKUP
+ if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
- } else if (type == MEM_HEAP_DYNAMIC) {
+ ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
- len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
- block = mem_area_alloc(len, mem_comm_pool);
+ block = mem_area_alloc(&len, mem_comm_pool);
} else {
- ut_ad(n <= MEM_MAX_ALLOC_IN_BUF);
+ len = UNIV_PAGE_SIZE;
- len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
+ 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 */
- if (len < UNIV_PAGE_SIZE / 2) {
+ buf_block = heap->free_block;
+ heap->free_block = NULL;
- 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 */
+ if (UNIV_UNLIKELY(!buf_block)) {
- block = (mem_block_t*)heap->free_block;
- heap->free_block = NULL;
- } else {
- block = (mem_block_t*)buf_frame_alloc();
+ return(NULL);
}
+ } else {
+ buf_block = buf_block_alloc(0);
}
- }
- if (block == NULL) {
- /* Only MEM_HEAP_BTR_SEARCH allocation should ever fail. */
- ut_a(type & MEM_HEAP_BTR_SEARCH);
-
- return(NULL);
+ 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;
@@ -412,25 +383,21 @@ mem_heap_create_block(
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);
}
-/*******************************************************************
-Adds a new block to a memory heap. */
-
+/***************************************************************//**
+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(
/*===============*/
- /* out: created block, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes user needs */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes user needs */
{
mem_block_t* block;
mem_block_t* new_block;
@@ -462,7 +429,7 @@ mem_heap_add_block(
new_size = n;
}
- new_block = mem_heap_create_block(heap, new_size, NULL, heap->type,
+ new_block = mem_heap_create_block(heap, new_size, heap->type,
heap->file_name, heap->line);
if (new_block == NULL) {
@@ -476,18 +443,20 @@ mem_heap_add_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 */
+ mem_heap_t* heap, /*!< in: heap */
+ mem_block_t* block) /*!< in: block to free */
{
- ulint type;
- ulint len;
- ibool init_block;
+ 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);
@@ -504,56 +473,65 @@ mem_heap_block_free(
#endif
type = heap->type;
len = block->len;
- init_block = block->init_block;
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. */
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*)block, len);
+ mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */
- if (init_block) {
- /* Do not have to free: do nothing */
-
- } else if (type == MEM_HEAP_DYNAMIC) {
+ }
+ 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);
- if (len >= UNIV_PAGE_SIZE / 2) {
- buf_frame_free((byte*)block);
- } else {
- mem_area_free(block, mem_comm_pool);
- }
+ 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 */
+ mem_heap_t* heap) /*!< in: heap */
{
- if (heap->free_block) {
+ if (UNIV_LIKELY_NULL(heap->free_block)) {
- buf_frame_free(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)
/*=========================*/