mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 22:12:30 +01:00
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.
This commit is contained in:
parent
b10078d34f
commit
732f9dd7fb
4 changed files with 51 additions and 9 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
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,11 +26,16 @@ 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 */
|
||||
extern ulint ut_total_allocated_memory;
|
||||
/* 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*
|
||||
|
|
23
os/os0proc.c
23
os/os0proc.c
|
@ -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
|
||||
}
|
||||
|
|
16
ut/ut0mem.c
16
ut/ut0mem.c
|
@ -29,15 +29,21 @@ 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 */
|
||||
UNIV_INTERN ulint ut_total_allocated_memory = 0;
|
||||
/* 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;
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue