From 59f9fc4fe2d503af1bfb414496f3b507a91ce31b Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:04:48 +0300 Subject: [PATCH 1/4] mem0mem.ic Changes to eliminate unnecessary Purify warnings ut0mem.h Changes to eliminate unnecessary Purify warnings ut0mem.ic Changes to eliminate unnecessary Purify warnings srv0start.c Changes to eliminate unnecessary Purify warnings mem0pool.c Changes to eliminate unnecessary Purify warnings ut0mem.c Changes to eliminate unnecessary Purify warnings --- innobase/include/mem0mem.ic | 12 +++- innobase/include/ut0mem.h | 35 ++++++++-- innobase/include/ut0mem.ic | 7 -- innobase/mem/mem0pool.c | 6 +- innobase/srv/srv0start.c | 2 + innobase/ut/ut0mem.c | 132 ++++++++++++++++++++++++++++++++---- 6 files changed, 167 insertions(+), 27 deletions(-) diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index 8b8449469ef..edc3ab17f2a 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -170,7 +170,9 @@ mem_heap_alloc( buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; #endif - +#ifdef UNIV_SET_MEM_TO_ZERO + memset(buf, '\0', n); +#endif return(buf); } @@ -494,8 +496,14 @@ mem_alloc_func( ) { #ifndef UNIV_MEM_DEBUG + void* buf; - return(mem_area_alloc(n, mem_comm_pool)); + buf = mem_area_alloc(n, mem_comm_pool); + +#ifdef UNIV_SET_MEM_TO_ZERO + memset(buf, '\0', n); +#endif + return(buf); #else diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index fa46514fe16..8e5a4fda0d3 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -26,12 +26,39 @@ int ut_memcmp(void* str1, void* str2, ulint n); -void* -ut_malloc(ulint n); +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined and set_to_zero is TRUE. */ + +void* +ut_malloc_low( +/*==========*/ + /* out, own: allocated memory */ + ulint n, /* in: number of bytes to allocate */ + ibool set_to_zero); /* in: TRUE if allocated memory should be set + to zero if UNIV_SET_MEM_TO_ZERO is defined */ +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined. */ + +void* +ut_malloc( +/*======*/ + /* out, own: allocated memory */ + ulint n); /* in: number of bytes to allocate */ +/************************************************************************** +Frees a memory bloock allocated with ut_malloc. */ -UNIV_INLINE void -ut_free(void* ptr); +ut_free( +/*====*/ + void* ptr); /* in, own: memory block */ +/************************************************************************** +Frees all allocated memory not freed yet. */ + +void +ut_free_all_mem(void); +/*=================*/ UNIV_INLINE char* diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic index fc4b6bd8be5..7ae9bc8bd74 100644 --- a/innobase/include/ut0mem.ic +++ b/innobase/include/ut0mem.ic @@ -27,13 +27,6 @@ ut_memcmp(void* str1, void* str2, ulint n) return(memcmp(str1, str2, n)); } -UNIV_INLINE -void -ut_free(void* ptr) -{ - free(ptr); -} - UNIV_INLINE char* ut_strcpy(char* dest, char* sour) diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index e8c02d812c4..6c3a4adebae 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -170,7 +170,11 @@ mem_pool_create( pool = ut_malloc(sizeof(mem_pool_t)); - pool->buf = ut_malloc(size); + /* We do not set the memory to zero (FALSE) in the pool, + but only when allocated at a higher level in mem0mem.c. + This is to avoid masking useful Purify warnings. */ + + pool->buf = ut_malloc_low(size, FALSE); pool->size = size; mutex_create(&(pool->mutex)); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index c4002767226..15d99ab3001 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -916,5 +916,7 @@ innobase_shutdown_for_mysql(void) logs_empty_and_mark_files_at_shutdown(); + ut_free_all_mem(); + return((int) DB_SUCCESS); } diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 492f57670a9..ebeefe0c297 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -14,30 +14,136 @@ Created 5/11/1994 Heikki Tuuri #include "mem0mem.h" + +/* This struct is placed first in every allocated memory block */ +typedef struct ut_mem_block_struct ut_mem_block_t; + +struct ut_mem_block_struct{ + UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;/* mem block list node */ +}; + + +/* List of all memory blocks allocated from the operating system +with malloc */ +UT_LIST_BASE_NODE_T(ut_mem_block_t) ut_mem_block_list; + +os_fast_mutex_t ut_list_mutex; /* this protects the list */ + +ibool ut_mem_block_list_inited = FALSE; + +/************************************************************************** +Initializes the mem block list at database startup. */ +static +void +ut_mem_block_list_init(void) +/*========================*/ +{ + os_fast_mutex_init(&ut_list_mutex); + UT_LIST_INIT(ut_mem_block_list); + ut_mem_block_list_inited = TRUE; +} + +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined and set_to_zero is TRUE. */ + void* -ut_malloc(ulint n) +ut_malloc_low( +/*==========*/ + /* out, own: allocated memory */ + ulint n, /* in: number of bytes to allocate */ + ibool set_to_zero) /* in: TRUE if allocated memory should be set + to zero if UNIV_SET_MEM_TO_ZERO is defined */ { void* ret; - /* - ret = VirtualAlloc(NULL, n, MEM_COMMIT, PAGE_READWRITE); - */ - ret = malloc(n); + ut_ad((sizeof(ut_mem_block_t) % 8) == 0); /* check alignment ok */ + + if (!ut_mem_block_list_inited) { + ut_mem_block_list_init(); + } + + os_fast_mutex_lock(&ut_list_mutex); + + ret = malloc(n + sizeof(ut_mem_block_t)); if (ret == NULL) { fprintf(stderr, - "Innobase: Fatal error: cannot allocate memory!\n"); - fprintf(stderr, - "Innobase: Cannot continue operation!\n"); - fprintf(stderr, - "Innobase: Check if you can increase the swap file of your\n"); - fprintf(stderr, - "Innobase: operating system.\n"); + "InnoDB: Fatal error: cannot allocate %lu bytes of\n" + "InnoDB: memory with malloc!\n" + "InnoDB: Operating system errno: %lu\n" + "InnoDB: Cannot continue operation!\n" + "InnoDB: Check if you should increase the swap file or\n" + "InnoDB: ulimits of your operating system.\n", n, errno); + + os_fast_mutex_unlock(&ut_list_mutex); exit(1); } - return(ret); + if (set_to_zero) { +#ifdef UNIV_SET_MEM_TO_ZERO + memset(ret, '\0', n + sizeof(ut_mem_block_t)); +#endif + } + + UT_LIST_ADD_FIRST(mem_block_list, ut_mem_block_list, + ((ut_mem_block_t*)ret)); + os_fast_mutex_unlock(&ut_list_mutex); + + return((void*)((byte*)ret + sizeof(ut_mem_block_t))); +} + +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined. */ + +void* +ut_malloc( +/*======*/ + /* out, own: allocated memory */ + ulint n) /* in: number of bytes to allocate */ +{ + return(ut_malloc_low(n, TRUE)); +} +/************************************************************************** +Frees a memory bloock allocated with ut_malloc. */ + +void +ut_free( +/*====*/ + void* ptr) /* in, own: memory block */ +{ + ut_mem_block_t* block; + + block = (ut_mem_block_t*)((byte*)ptr - sizeof(ut_mem_block_t)); + + os_fast_mutex_lock(&ut_list_mutex); + + UT_LIST_REMOVE(mem_block_list, ut_mem_block_list, block); + free(block); + + os_fast_mutex_unlock(&ut_list_mutex); +} + +/************************************************************************** +Frees all allocated memory not freed yet. */ + +void +ut_free_all_mem(void) +/*=================*/ +{ + ut_mem_block_t* block; + + os_fast_mutex_lock(&ut_list_mutex); + + while (block = UT_LIST_GET_FIRST(ut_mem_block_list)) { + + UT_LIST_REMOVE(mem_block_list, ut_mem_block_list, block); + free(block); + } + + os_fast_mutex_unlock(&ut_list_mutex); } /************************************************************************** From 0b064c3b0903ced19a97e4526e344226a42cb27f Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:14:49 +0300 Subject: [PATCH 2/4] univ.i Changes to eliminate unnecessary Purify warnings (documentation of flag UNIV_SET_MEM_TO_ZERO) --- innobase/include/univ.i | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/innobase/include/univ.i b/innobase/include/univ.i index f3e3b22bb3d..9fc9f85f633 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -61,8 +61,12 @@ subdirectory of 'mysql'. */ /* DEBUG VERSION CONTROL ===================== */ +/* The following flag will make InnoDB to initialize +all memory it allocates to zero. It hides Purify +warnings about reading unallocated memory unless +memory is read outside the allocated blocks. */ /* -#define UNIV_SYNC_DEBUG +#define UNIV_INIT_MEM_TO_ZERO */ /* Make a non-inline debug version */ @@ -72,7 +76,7 @@ subdirectory of 'mysql'. */ #define UNIV_SEARCH_DEBUG #define UNIV_IBUF_DEBUG - +#define UNIV_SYNC_DEBUG #define UNIV_SYNC_PERF_STAT #define UNIV_SEARCH_PERF_STAT */ From e2389946dd46fb5cf0fa92532c757d683d83c61b Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:38:46 +0300 Subject: [PATCH 3/4] os0sync.h Define os_fast_mutex functions also in Windows os0sync.ic Define os_fast_mutex functions also in Windows --- innobase/include/os0sync.h | 2 +- innobase/include/os0sync.ic | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index 89e3f953b50..78374cf8ede 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -160,6 +160,7 @@ os_fast_mutex_trylock( was reserved by another thread */ os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */ +#endif /************************************************************** Releases ownership of a fast mutex. */ UNIV_INLINE @@ -188,7 +189,6 @@ void os_fast_mutex_free( /*===============*/ os_fast_mutex_t* fast_mutex); /* in: mutex to free */ -#endif #ifndef UNIV_NONINL #include "os0sync.ic" diff --git a/innobase/include/os0sync.ic b/innobase/include/os0sync.ic index 8be9a783593..057ad424dee 100644 --- a/innobase/include/os0sync.ic +++ b/innobase/include/os0sync.ic @@ -38,6 +38,7 @@ os_fast_mutex_trylock( return((ulint) pthread_mutex_trylock(fast_mutex)); #endif } +#endif /************************************************************** Releases ownership of a fast mutex. */ @@ -53,4 +54,3 @@ os_fast_mutex_unlock( pthread_mutex_unlock(fast_mutex); #endif } -#endif From df1045ee3c5c25eb62fb1cb8a065fa1bf0d8b902 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:43:58 +0300 Subject: [PATCH 4/4] os0sync.c Define os_fast_mutex functions also in Windows --- innobase/os/os0sync.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index c5dd603100d..8da142cd4a6 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -422,7 +422,6 @@ os_mutex_free( #endif } -#ifndef _WIN32 /************************************************************* Initializes an operating system fast mutex semaphore. */ @@ -472,4 +471,3 @@ os_fast_mutex_free( #endif } -#endif