diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-01-23 16:20:39 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-01-23 16:20:39 +0100 |
commit | c71fad9983b4a3c6e0d9e9eca02dadfd923ddbbb (patch) | |
tree | 76dbef3d7d96a3692039779f20f48938c260a5f1 | |
parent | 52051882002c1b88a427d50fb343a9ed3614ffe0 (diff) | |
download | mariadb-git-c71fad9983b4a3c6e0d9e9eca02dadfd923ddbbb.tar.gz |
cleanup:
* don't use 'myf flags', when 'my_bool is_thread_specific' is meant
* call set_malloc_size_cb() for embedded too
* warn in safemalloc if the memory is freed by a wrong thread
sql/mysqld.cc:
move set_malloc_size_cb() to a function that is also called for embedded
sql/mysqld.h:
gdb-friendly, one can put breakpoint on a function, but not on a macro
sql/sql_class.cc:
initialize thread_id earlier
-rw-r--r-- | include/my_sys.h | 2 | ||||
-rw-r--r-- | mysys/my_malloc.c | 12 | ||||
-rw-r--r-- | mysys/mysys_priv.h | 2 | ||||
-rw-r--r-- | mysys/safemalloc.c | 76 | ||||
-rw-r--r-- | sql/mysqld.cc | 64 | ||||
-rw-r--r-- | sql/mysqld.h | 5 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 |
7 files changed, 85 insertions, 78 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index 62e194157eb..13e4d463515 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -161,7 +161,7 @@ extern my_thread_id (*sf_malloc_dbug_id)(void); #define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0) #endif -typedef void (*MALLOC_SIZE_CB) (long long size, myf my_flags); +typedef void (*MALLOC_SIZE_CB) (long long size, my_bool is_thread_specific); extern void set_malloc_size_cb(MALLOC_SIZE_CB func); /* defines when allocating data */ diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 88f3f412faf..e9956263ce1 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -37,10 +37,10 @@ *(size_t*) p= (size) | (flag); \ (p)= (type_of_p) (((char*) (p)) + MALLOC_PREFIX_SIZE); \ } -static inline size_t malloc_size_and_flag(void *p, myf *flags) +static inline size_t malloc_size_and_flag(void *p, my_bool *is_thread_specific) { size_t size= MALLOC_SIZE(p); - *flags= (size & 1); + *is_thread_specific= (size & 1); return size & ~ (ulonglong) 1; } #define MALLOC_SIZE_AND_FLAG(p,b) malloc_size_and_flag(p, b); @@ -60,10 +60,10 @@ static MALLOC_SIZE_CB malloc_size_cb_func= NULL; decrement the memory usage */ -static void update_malloc_size(long long size, myf my_flags) +static void update_malloc_size(long long size, my_bool is_thread_specific) { if (malloc_size_cb_func) - malloc_size_cb_func(size, my_flags); + malloc_size_cb_func(size, is_thread_specific); } void set_malloc_size_cb(MALLOC_SIZE_CB func) @@ -145,7 +145,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags) { void *point; size_t old_size; - myf old_flags; + my_bool old_flags; DBUG_ENTER("my_realloc"); DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %lu", oldpoint, (ulong) size, my_flags)); @@ -210,7 +210,7 @@ void my_free(void *ptr) if (ptr) { size_t old_size; - myf old_flags; + my_bool old_flags; old_size= MALLOC_SIZE_AND_FLAG(ptr, &old_flags); update_malloc_size(- (longlong) old_size - MALLOC_PREFIX_SIZE, old_flags); sf_free(MALLOC_FIX_POINTER_FOR_FREE(ptr)); diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index aa4af92202a..61b7f2897d4 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -73,7 +73,7 @@ extern PSI_file_key key_file_charset, key_file_cnf; void *sf_malloc(size_t size, myf my_flags); void *sf_realloc(void *ptr, size_t size, myf my_flags); void sf_free(void *ptr); -size_t sf_malloc_usable_size(void *ptr, myf *my_flags); +size_t sf_malloc_usable_size(void *ptr, my_bool *is_thread_specific); #else #define sf_malloc(X,Y) malloc(X) #define sf_realloc(X,Y,Z) realloc(X,Y) diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index d9a04d9e8d1..6283ed20cca 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -207,47 +207,16 @@ void sf_free(void *ptr) @return Size of block */ -size_t sf_malloc_usable_size(void *ptr, myf *flags) +size_t sf_malloc_usable_size(void *ptr, my_bool *is_thread_specific) { struct st_irem *irem= (struct st_irem *)ptr - 1; DBUG_ENTER("sf_malloc_usable_size"); - *flags= test(irem->flags & MY_THREAD_SPECIFIC); + *is_thread_specific= test(irem->flags & MY_THREAD_SPECIFIC); DBUG_PRINT("exit", ("size: %lu flags: %lu", (ulong) irem->datasize, - *flags)); + (ulong)irem->flags)); DBUG_RETURN(irem->datasize); } -static void free_memory(void *ptr) -{ - struct st_irem *irem= (struct st_irem *)ptr - 1; - - if ((irem->flags & MY_THREAD_SPECIFIC) && - irem->thread_id != sf_malloc_dbug_id()) - { - DBUG_PRINT("warning", - ("Memory: %p was allocated by thread %lu and freed by thread %lu", ptr, (ulong) irem->thread_id, (ulong) sf_malloc_dbug_id())); - } - - pthread_mutex_lock(&sf_mutex); - /* Remove this structure from the linked list */ - if (irem->prev) - irem->prev->next= irem->next; - else - sf_malloc_root= irem->next; - - if (irem->next) - irem->next->prev= irem->prev; - - /* Handle the statistics */ - sf_malloc_count--; - pthread_mutex_unlock(&sf_mutex); - - /* only trash the data and magic values, but keep the stack trace */ - TRASH_FREE((uchar*)(irem + 1) - 4, irem->datasize + 8); - free(irem); - return; -} - #ifdef HAVE_BACKTRACE static void print_stack(void **frame) { @@ -277,6 +246,39 @@ static void print_stack(void **frame) #define print_stack(X) fprintf(stderr, "???\n") #endif +static void free_memory(void *ptr) +{ + struct st_irem *irem= (struct st_irem *)ptr - 1; + + if ((irem->flags & MY_THREAD_SPECIFIC) && irem->thread_id && + irem->thread_id != sf_malloc_dbug_id()) + { + fprintf(stderr, "Warning: %4lu bytes freed by T@%lu, allocated by T@%lu at ", + (ulong) irem->datasize, + (ulong) sf_malloc_dbug_id(), (ulong) irem->thread_id); + print_stack(irem->frame); + } + + pthread_mutex_lock(&sf_mutex); + /* Remove this structure from the linked list */ + if (irem->prev) + irem->prev->next= irem->next; + else + sf_malloc_root= irem->next; + + if (irem->next) + irem->next->prev= irem->prev; + + /* Handle the statistics */ + sf_malloc_count--; + pthread_mutex_unlock(&sf_mutex); + + /* only trash the data and magic values, but keep the stack trace */ + TRASH_FREE((uchar*)(irem + 1) - 4, irem->datasize + 8); + free(irem); + return; +} + static void warn(const char *format,...) { va_list args; @@ -371,8 +373,10 @@ void sf_report_leaked_memory(my_thread_id id) { if (!id || (irem->thread_id == id && irem->flags & MY_THREAD_SPECIFIC)) { - fprintf(stderr, "Warning: %4lu bytes lost, allocated at ", - (ulong) irem->datasize); + my_thread_id tid = irem->thread_id && irem->flags & MY_THREAD_SPECIFIC ? + irem->thread_id : 0; + fprintf(stderr, "Warning: %4lu bytes lost, allocated by T@%lu at ", + (ulong) irem->datasize,tid); print_stack(irem->frame); total+= irem->datasize; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b2c8a842283..93e5fc5864b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3454,6 +3454,36 @@ extern "C" my_thread_id mariadb_dbug_id() } #endif /* SAFEMALLOC */ +/* Thread Mem Usage By P.Linux */ +extern "C" { +static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) +{ + /* If thread specific memory */ + if (is_thread_specific) + { + THD *thd= current_thd; + if (mysqld_server_initialized || thd) + { + /* + THD may not be set if we are called from my_net_init() before THD + thread has started. + However, this should never happen, so better to assert and + fix this. + */ + DBUG_ASSERT(thd); + if (thd) + { + DBUG_PRINT("info", ("memory_used: %lld size: %lld", + (longlong) thd->status_var.memory_used, size)); + thd->status_var.memory_used+= size; + DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0); + } + } + } + my_atomic_add64(&global_status_var.memory_used, size); +} +} + /* Init common variables @@ -3464,6 +3494,8 @@ static int init_common_variables() umask(((~my_umask) & 0666)); my_decimal_set_zero(&decimal_zero); // set decimal_zero constant; + set_malloc_size_cb(my_malloc_size_cb_func); + tzset(); // Set tzname sf_leaking_memory= 0; // no memory leaks from now on @@ -4675,36 +4707,6 @@ static void test_lc_time_sz() #endif//DBUG_OFF -/* Thread Mem Usage By P.Linux */ -extern "C" -void my_malloc_size_cb_func(long long size, myf my_flags) -{ - /* If thread specific memory */ - if (my_flags) - { - THD *thd= current_thd; - if (mysqld_server_initialized || thd) - { - /* - THD may not be set if we are called from my_net_init() before THD - thread has started. - However, this should never happen, so better to assert and - fix this. - */ - DBUG_ASSERT(thd); - if (thd) - { - DBUG_PRINT("info", ("memory_used: %lld size: %lld", - (longlong) thd->status_var.memory_used, size)); - thd->status_var.memory_used+= size; - DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0); - } - } - } - my_atomic_add64(&global_status_var.memory_used, size); -} - - #ifdef __WIN__ int win_main(int argc, char **argv) #else @@ -4717,7 +4719,6 @@ int mysqld_main(int argc, char **argv) */ my_progname= argv[0]; sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early - set_malloc_size_cb(my_malloc_size_cb_func); mysqld_server_started= mysqld_server_initialized= 0; #ifdef HAVE_NPTL @@ -5246,7 +5247,6 @@ int mysqld_main(int argc, char **argv) /* Must be initialized early for comparison of service name */ system_charset_info= &my_charset_utf8_general_ci; - set_malloc_size_cb(my_malloc_size_cb_func); if (my_init()) { diff --git a/sql/mysqld.h b/sql/mysqld.h index e9c4f713182..520fa03bdbf 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -534,7 +534,10 @@ inline THD *_current_thd(void) } #endif #define current_thd _current_thd() -#define set_current_thd(X) my_pthread_setspecific_ptr(THR_THD, (X)) +inline int set_current_thd(THD *thd) +{ + return my_pthread_setspecific_ptr(THR_THD, thd); +} /* @todo remove, make it static in ha_maria.cc diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 44102aaf3bc..47c104c2a65 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -793,6 +793,7 @@ THD::THD() accessed_rows_and_keys(0), warning_info(&main_warning_info), stmt_da(&main_da), + thread_id(0), global_disable_checkpoint(0), is_fatal_error(0), transaction_rollback_request(0), @@ -867,7 +868,6 @@ THD::THD() connection_name.length= 0; bzero(&variables, sizeof(variables)); - thread_id= 0; one_shot_set= 0; file_id = 0; query_id= 0; |