Commit 732f9dd7 authored by marko's avatar marko

branches/zip: Protect ut_total_allocated_memory with ut_list_mutex.

Unprotected updates to ut_total_allocated_memory in
os_mem_alloc_large() and os_mem_free_large(), called during
fast index creation, may corrupt the variable and cause assertion failures.

Also, add UNIV_MEM_ALLOC() and UNIV_MEM_FREE() instrumentation around
os_mem_alloc_large() and os_mem_free_large(), so that Valgrind can
detect more errors.

rb://90 approved by Heikki Tuuri.  This addresses Issue #177.
parent b10078d3
2009-02-18 The InnoDB Team
* os/os0proc.c, ut/ut0mem.c, include/ut0mem.h:
Protect ut_total_allocated_memory with ut_list_mutex in
os_mem_alloc_large() and os_mem_free_large(). The lack of this
mutex protection could cause an assertion failure during fast
index creation. Also, add UNIV_MEM_ALLOC and UNIV_MEM_FREE
instrumentation to os_mem_alloc_large() and os_mem_free_large(),
so that Valgrind can detect more errors.
2009-02-11 The InnoDB Team
* handler/ha_innodb.cc:
......
......@@ -26,12 +26,17 @@ Created 5/30/1994 Heikki Tuuri
#define ut0mem_h
#include "univ.i"
#include "os0sync.h"
#include <string.h>
#include <stdlib.h>
/* The total amount of memory currently allocated from the OS with malloc */
/* The total amount of memory currently allocated from the operating
system with os_mem_alloc_large() or malloc(). Does not count malloc()
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
extern ulint ut_total_allocated_memory;
/* Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
extern os_fast_mutex_t ut_list_mutex;
UNIV_INLINE
void*
ut_memcpy(void* dest, const void* sour, ulint n);
......
......@@ -127,10 +127,13 @@ os_mem_alloc_large(
if (ptr) {
*n = size;
os_fast_mutex_lock(&ut_list_mutex);
ut_total_allocated_memory += size;
os_fast_mutex_unlock(&ut_list_mutex);
# ifdef UNIV_SET_MEM_TO_ZERO
memset(ptr, '\0', size);
# endif
UNIV_MEM_ALLOC(ptr, size);
return(ptr);
}
......@@ -156,7 +159,10 @@ skip:
" Windows error %lu\n",
(ulong) size, (ulong) GetLastError());
} else {
os_fast_mutex_lock(&ut_list_mutex);
ut_total_allocated_memory += size;
os_fast_mutex_unlock(&ut_list_mutex);
UNIV_MEM_ALLOC(ptr, size);
}
#elif defined __NETWARE__ || !defined OS_MAP_ANON
size = *n;
......@@ -178,7 +184,10 @@ skip:
(ulong) size, (ulong) errno);
ptr = NULL;
} else {
os_fast_mutex_lock(&ut_list_mutex);
ut_total_allocated_memory += size;
os_fast_mutex_unlock(&ut_list_mutex);
UNIV_MEM_ALLOC(ptr, size);
}
#endif
return(ptr);
......@@ -195,11 +204,17 @@ os_mem_free_large(
ulint size) /* in: size returned by
os_mem_alloc_large() */
{
os_fast_mutex_lock(&ut_list_mutex);
ut_a(ut_total_allocated_memory >= size);
os_fast_mutex_unlock(&ut_list_mutex);
#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
os_fast_mutex_lock(&ut_list_mutex);
ut_a(ut_total_allocated_memory >= size);
ut_total_allocated_memory -= size;
os_fast_mutex_unlock(&ut_list_mutex);
UNIV_MEM_FREE(ptr, size);
return;
}
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
......@@ -211,7 +226,11 @@ os_mem_free_large(
" Windows error %lu\n",
ptr, (ulong) size, (ulong) GetLastError());
} else {
os_fast_mutex_lock(&ut_list_mutex);
ut_a(ut_total_allocated_memory >= size);
ut_total_allocated_memory -= size;
os_fast_mutex_unlock(&ut_list_mutex);
UNIV_MEM_FREE(ptr, size);
}
#elif defined __NETWARE__ || !defined OS_MAP_ANON
ut_free(ptr);
......@@ -221,7 +240,11 @@ os_mem_free_large(
" errno %lu\n",
ptr, (ulong) size, (ulong) errno);
} else {
os_fast_mutex_lock(&ut_list_mutex);
ut_a(ut_total_allocated_memory >= size);
ut_total_allocated_memory -= size;
os_fast_mutex_unlock(&ut_list_mutex);
UNIV_MEM_FREE(ptr, size);
}
#endif
}
......
......@@ -29,16 +29,22 @@ Created 5/11/1994 Heikki Tuuri
#endif
#include "mem0mem.h"
#include "os0sync.h"
#include "os0thread.h"
#include "srv0srv.h"
#include <stdlib.h>
/* This struct is placed first in every allocated memory block */
typedef struct ut_mem_block_struct ut_mem_block_t;
/* The total amount of memory currently allocated from the OS with malloc */
/* The total amount of memory currently allocated from the operating
system with os_mem_alloc_large() or malloc(). Does not count malloc()
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
UNIV_INTERN ulint ut_total_allocated_memory = 0;
/* Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
UNIV_INTERN os_fast_mutex_t ut_list_mutex;
struct ut_mem_block_struct{
UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;
/* mem block list node */
......@@ -49,11 +55,9 @@ struct ut_mem_block_struct{
#define UT_MEM_MAGIC_N 1601650166
/* List of all memory blocks allocated from the operating system
with malloc */
with malloc. Protected by ut_list_mutex. */
static UT_LIST_BASE_NODE_T(ut_mem_block_t) ut_mem_block_list;
static os_fast_mutex_t ut_list_mutex; /* this protects the list */
static ibool ut_mem_block_list_inited = FALSE;
static ulint* ut_mem_null_ptr = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment