diff options
author | Michael Widenius <monty@askmonty.org> | 2013-01-23 16:16:14 +0100 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2013-01-23 16:16:14 +0100 |
commit | a260b155542179bec75a6bbe1e430bea57b70ad6 (patch) | |
tree | 761fdd82f49c9fc557398218a11d089961263ead /mysys | |
parent | 09665bfd0e83efbc6c67f14852800fb4a0fe1e13 (diff) | |
download | mariadb-git-a260b155542179bec75a6bbe1e430bea57b70ad6.tar.gz |
MDEV-4011 Added per thread memory counting and usage
Base code and idea from a patch from by plinux at Taobao.
The idea is that we mark all memory that are thread specific with MY_THREAD_SPECIFIC.
Memory counting is done per thread in the my_malloc_size_cb_func callback function from my_malloc().
There are plenty of new asserts to ensure that for a debug server the counting is correct.
Information_schema.processlist gets two new columns: MEMORY_USED and EXAMINED_ROWS.
- The later is there mainly to show how query is progressing.
The following changes in interfaces was needed to get this to work:
- init_alloc_root() amd init_sql_alloc() has extra option so that one can mark memory with MY_THREAD_SPECIFIC
- One now have to use alloc_root_set_min_malloc() to set min memory to be allocated by alloc_root()
- my_init_dynamic_array() has extra option so that one can mark memory with MY_THREAD_SPECIFIC
- my_net_init() has extra option so that one can mark memory with MY_THREAD_SPECIFIC
- Added flag for hash_init() so that one can mark hash table to be thread specific.
- Added flags to init_tree() so that one can mark tree to be thread specific.
- Removed with_delete option to init_tree(). Now one should instead use MY_TREE_WITH_DELETE_FLAG.
- Added flag to Warning_info::Warning_info() if the structure should be fully initialized.
- String elements can now be marked as thread specific.
- Internal HEAP tables are now marking it's memory as MY_THREAD_SPECIFIC.
- Changed type of myf from int to ulong, as this is always a set of bit flags.
Other things:
- Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
- We now also show EXAMINED_ROWS in SHOW PROCESSLIST
- Added new variable 'memory_used'
- Fixed bug where kill_threads_for_user() was using the wrong mem_root to allocate memory.
- Removed calls to the obsoleted function init_dynamic_array()
- Use set_current_thd() instead of my_pthread_setspecific_ptr(THR_THD,...)
client/completion_hash.cc:
Updated call to init_alloc_root()
client/mysql.cc:
Updated call to init_alloc_root()
client/mysqlbinlog.cc:
init_dynamic_array() -> my_init_dynamic_array()
Updated call to init_alloc_root()
client/mysqlcheck.c:
Updated call to my_init_dynamic_array()
client/mysqldump.c:
Updated call to init_alloc_root()
client/mysqltest.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Fixed compiler warnings
extra/comp_err.c:
Updated call to my_init_dynamic_array()
extra/resolve_stack_dump.c:
Updated call to my_init_dynamic_array()
include/hash.h:
Added HASH_THREAD_SPECIFIC
include/heap.h:
Added flag is internal temporary table.
include/my_dir.h:
Safety fix: Ensure that MY_DONT_SORT and MY_WANT_STAT don't interfer with other mysys flags
include/my_global.h:
Changed type of myf from int to ulong, as this is always a set of bit flags.
include/my_sys.h:
Added MY_THREAD_SPECIFIC and MY_THREAD_MOVE
Added malloc_flags to DYNAMIC_ARRAY
Added extra mysys flag argument to my_init_dynamic_array()
Removed deprecated functions init_dynamic_array() and my_init_dynamic_array.._ci
Updated paramaters for init_alloc_root()
include/my_tree.h:
Added my_flags to allow one to use MY_THREAD_SPECIFIC with hash tables.
Removed with_delete. One should now instead use MY_TREE_WITH_DELETE_FLAG
Updated parameters to init_tree()
include/myisamchk.h:
Added malloc_flags to allow one to use MY_THREAD_SPECIFIC for checks.
include/mysql.h:
Added MYSQL_THREAD_SPECIFIC_MALLOC
Used 'unused1' to mark memory as thread specific.
include/mysql.h.pp:
Updated file
include/mysql_com.h:
Used 'unused1' to mark memory as thread specific.
Updated parameters for my_net_init()
libmysql/libmysql.c:
Updated call to init_alloc_root() to mark memory thread specific.
libmysqld/emb_qcache.cc:
Updated call to init_alloc_root()
libmysqld/lib_sql.cc:
Updated call to init_alloc_root()
mysql-test/r/create.result:
Updated results
mysql-test/r/user_var.result:
Updated results
mysql-test/suite/funcs_1/datadict/processlist_priv.inc:
Update to handle new format of SHOW PROCESSLIST
mysql-test/suite/funcs_1/datadict/processlist_val.inc:
Update to handle new format of SHOW PROCESSLIST
mysql-test/suite/funcs_1/r/is_columns_is.result:
Update to handle new format of SHOW PROCESSLIST
mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result:
Updated results
mysql-test/suite/funcs_1/r/processlist_val_no_prot.result:
Updated results
mysql-test/t/show_explain.test:
Fixed usage of debug variable so that one can run test with --debug
mysql-test/t/user_var.test:
Added test of memory_usage variable.
mysys/array.c:
Added extra my_flags option to init_dynamic_array() and init_dynamic_array2() so that one can mark memory with MY_THREAD_SPECIFIC
All allocated memory is marked with the given my_flags.
Removed obsolete function init_dynamic_array()
mysys/default.c:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
mysys/hash.c:
Updated call to my_init_dynamic_array_ci().
Allocated memory is marked with MY_THREAD_SPECIFIC if HASH_THREAD_SPECIFIC is used.
mysys/ma_dyncol.c:
init_dynamic_array() -> my_init_dynamic_array()
Added #if to get rid of compiler warnings
mysys/mf_tempdir.c:
Updated call to my_init_dynamic_array()
mysys/my_alloc.c:
Added extra parameter to init_alloc_root() so that one can mark memory with MY_THREAD_SPECIFIC
Extend MEM_ROOT with a flag if memory is thread specific.
This is stored in block_size, to keep the size of the MEM_ROOT object identical as before.
Allocated memory is marked with MY_THREAD_SPECIFIC if used with init_alloc_root()
mysys/my_chmod.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_chsize.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_copy.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_create.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_delete.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_error.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_fopen.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_fstream.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_getwd.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_lib.c:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Updated DBUG_PRINT because of change of myf type
mysys/my_lock.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_malloc.c:
Store at start of each allocated memory block the size of the block and if the block is thread specific.
Call malloc_size_cb_func, if set, with the memory allocated/freed.
Updated DBUG_PRINT because of change of myf type
mysys/my_open.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_pread.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_read.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_redel.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_rename.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_seek.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_sync.c:
Updated DBUG_PRINT because of change of myf type
mysys/my_thr_init.c:
Ensure that one can call my_thread_dbug_id() even if thread is not properly initialized.
mysys/my_write.c:
Updated DBUG_PRINT because of change of myf type
mysys/mysys_priv.h:
Updated parameters to sf_malloc and sf_realloc()
mysys/safemalloc.c:
Added checking that for memory marked with MY_THREAD_SPECIFIC that it's the same thread that is allocation and freeing the memory.
Added sf_malloc_dbug_id() to allow MariaDB to specify which THD is handling the memory.
Added my_flags arguments to sf_malloc() and sf_realloc() to be able to mark memory with MY_THREAD_SPECIFIC.
Added sf_report_leaked_memory() to get list of memory not freed by a thread.
mysys/tree.c:
Added flags to init_tree() so that one can mark tree to be thread specific.
Removed with_delete option to init_tree(). Now one should instead use MY_TREE_WITH_DELETE_FLAG.
Updated call to init_alloc_root()
All allocated memory is marked with the given malloc flags
mysys/waiting_threads.c:
Updated call to my_init_dynamic_array()
sql-common/client.c:
Updated call to init_alloc_root() and my_net_init() to mark memory thread specific.
Updated call to my_init_dynamic_array().
Added MYSQL_THREAD_SPECIFIC_MALLOC so that client can mark memory as MY_THREAD_SPECIFIC.
sql-common/client_plugin.c:
Updated call to init_alloc_root()
sql/debug_sync.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/event_scheduler.cc:
Removed calls to net_end() as this is now done in ~THD()
Call set_current_thd() to ensure that memory is assigned to right thread.
sql/events.cc:
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/filesort.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/filesort_utils.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/ha_ndbcluster.cc:
Updated call to init_alloc_root()
Updated call to my_net_init()
Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
sql/ha_ndbcluster_binlog.cc:
Updated call to my_net_init()
Updated call to init_sql_alloc()
Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
sql/ha_partition.cc:
Updated call to init_alloc_root()
sql/handler.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
Added missing call to my_dir_end()
sql/item_func.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/item_subselect.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/item_sum.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/log.cc:
More DBUG
Updated call to init_alloc_root()
sql/mdl.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/mysqld.cc:
Added total_memory_used
Updated call to init_alloc_root()
Move mysql_cond_broadcast() before my_thread_end()
Added mariadb_dbug_id() to count memory per THD instead of per thread.
Added my_malloc_size_cb_func() callback function for my_malloc() to count memory.
Move initialization of mysqld_server_started and mysqld_server_initialized earlier.
Updated call to my_init_dynamic_array().
Updated call to my_net_init().
Call my_pthread_setspecific_ptr(THR_THD,...) to ensure that memory is assigned to right thread.
Added status variable 'memory_used'.
Updated call to init_alloc_root()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/mysqld.h:
Added set_current_thd()
sql/net_serv.cc:
Added new parameter to my_net_init() so that one can mark memory with MY_THREAD_SPECIFIC.
Store in net->thread_specific_malloc if memory is thread specific.
Mark memory to be thread specific if requested.
sql/opt_range.cc:
Updated call to my_init_dynamic_array()
Updated call to init_sql_alloc()
Added MY_THREAD_SPECIFIC to allocated memory.
sql/opt_subselect.cc:
Updated call to init_sql_alloc() to mark memory thread specific.
sql/protocol.cc:
Fixed compiler warning
sql/records.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/rpl_filter.cc:
Updated call to my_init_dynamic_array()
sql/rpl_handler.cc:
Updated call to my_init_dynamic_array2()
sql/rpl_handler.h:
Updated call to init_sql_alloc()
sql/rpl_mi.cc:
Updated call to my_init_dynamic_array()
sql/rpl_tblmap.cc:
Updated call to init_alloc_root()
sql/rpl_utility.cc:
Updated call to my_init_dynamic_array()
sql/slave.cc:
Initialize things properly before calling functions that allocate memory.
Removed calls to net_end() as this is now done in ~THD()
sql/sp_head.cc:
Updated call to init_sql_alloc()
Updated call to my_init_dynamic_array()
Added parameter to warning_info() that it should be fully initialized.
sql/sp_pcontext.cc:
Updated call to my_init_dynamic_array()
sql/sql_acl.cc:
Updated call to init_sql_alloc()
Updated call to my_init_dynamic_array()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_admin.cc:
Added parameter to warning_info() that it should be fully initialized.
sql/sql_analyse.h:
Updated call to init_tree() to mark memory thread specific.
sql/sql_array.h:
Updated call to my_init_dynamic_array() to mark memory thread specific.
sql/sql_audit.cc:
Updated call to my_init_dynamic_array()
sql/sql_base.cc:
Updated call to init_sql_alloc()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_cache.cc:
Updated comment
sql/sql_class.cc:
Added parameter to warning_info() that not initialize it until THD is fully created.
Updated call to init_sql_alloc()
Mark THD::user_vars has to be thread specific.
Updated call to my_init_dynamic_array()
Ensure that memory allocated by THD is assigned to the THD.
More DBUG
Always acll net_end() in ~THD()
Assert that all memory signed to this THD is really deleted at ~THD.
Fixed set_status_var_init() to not reset memory_used.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_class.h:
Added MY_THREAD_SPECIFIC to allocated memory.
Added malloc_size to THD to record allocated memory per THD.
sql/sql_delete.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/sql_error.cc:
Added 'initialize' parameter to Warning_info() to say if should allocate memory for it's structures.
This is used by THD::THD() to not allocate memory until THD is ready.
Added Warning_info::free_memory()
sql/sql_error.h:
Updated Warning_info() class.
sql/sql_handler.cc:
Updated call to init_alloc_root() to mark memory thread specific.
sql/sql_insert.cc:
More DBUG
sql/sql_join_cache.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/sql_lex.cc:
Updated call to my_init_dynamic_array()
sql/sql_lex.h:
Updated call to my_init_dynamic_array()
sql/sql_load.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/sql_parse.cc:
Removed calls to net_end() and thd->cleanup() as these are now done in ~THD()
Ensure that examined_row_count() is reset before query.
Fixed bug where kill_threads_for_user() was using the wrong mem_root to allocate memory.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
Don't restore thd->status_var.memory_used when restoring thd->status_var
sql/sql_plugin.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Don't allocate THD on the stack, as this causes problems with valgrind when doing thd memory counting.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_prepare.cc:
Added parameter to warning_info() that it should be fully initialized.
Updated call to init_sql_alloc() to mark memory thread specific.
sql/sql_reload.cc:
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_select.cc:
Updated call to my_init_dynamic_array() and init_sql_alloc() to mark memory thread specific.
Added MY_THREAD_SPECIFIC to allocated memory.
More DBUG
sql/sql_servers.cc:
Updated call to init_sql_alloc() to mark memory some memory thread specific.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_show.cc:
Updated call to my_init_dynamic_array()
Mark my_dir() memory thread specific.
Use my_pthread_setspecific_ptr(THR_THD,...) to mark that allocated memory should be allocated to calling thread.
More DBUG.
Added malloc_size and examined_row_count to SHOW PROCESSLIST.
Added MY_THREAD_SPECIFIC to allocated memory.
Updated call to init_sql_alloc()
Added parameter to warning_info() that it should be fully initialized.
sql/sql_statistics.cc:
Fixed compiler warning
sql/sql_string.cc:
String elements can now be marked as thread specific.
sql/sql_string.h:
String elements can now be marked as thread specific.
sql/sql_table.cc:
Updated call to init_sql_alloc() and my_malloc() to mark memory thread specific
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
Fixed compiler warning
sql/sql_test.cc:
Updated call to my_init_dynamic_array() to mark memory thread specific.
sql/sql_trigger.cc:
Updated call to init_sql_alloc()
sql/sql_udf.cc:
Updated call to init_sql_alloc()
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/sql_update.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
sql/table.cc:
Updated call to init_sql_alloc().
Mark memory used by temporary tables, that are not for slave threads, as MY_THREAD_SPECIFIC
Updated call to init_sql_alloc()
sql/thr_malloc.cc:
Added my_flags argument to init_sql_alloc() to be able to mark memory as MY_THREAD_SPECIFIC.
sql/thr_malloc.h:
Updated prototype for init_sql_alloc()
sql/tztime.cc:
Updated call to init_sql_alloc()
Updated call to init_alloc_root() to mark memory thread specific.
my_pthread_setspecific_ptr(THR_THD,...) -> set_current_thd()
sql/uniques.cc:
Updated calls to init_tree(), my_init_dynamic_array() and my_malloc() to mark memory thread specific.
sql/unireg.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
storage/csv/ha_tina.cc:
Updated call to init_alloc_root()
storage/federated/ha_federated.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
Ensure that memory allocated by fedarated is registered for the system, not for the thread.
storage/federatedx/federatedx_io_mysql.cc:
Updated call to my_init_dynamic_array()
storage/federatedx/ha_federatedx.cc:
Updated call to init_alloc_root()
Updated call to my_init_dynamic_array()
storage/heap/ha_heap.cc:
Added MY_THREAD_SPECIFIC to allocated memory.
storage/heap/heapdef.h:
Added parameter to hp_get_new_block() to be able to do thread specific memory tagging.
storage/heap/hp_block.c:
Added parameter to hp_get_new_block() to be able to do thread specific memory tagging.
storage/heap/hp_create.c:
- Internal HEAP tables are now marking it's memory as MY_THREAD_SPECIFIC.
- Use MY_TREE_WITH_DELETE instead of removed option 'with_delete'.
storage/heap/hp_open.c:
Internal HEAP tables are now marking it's memory as MY_THREAD_SPECIFIC.
storage/heap/hp_write.c:
Added new parameter to hp_get_new_block()
storage/maria/ma_bitmap.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_blockrec.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_check.c:
Updated call to init_alloc_root()
storage/maria/ma_ft_boolean_search.c:
Updated calls to init_tree() and init_alloc_root()
storage/maria/ma_ft_nlq_search.c:
Updated call to init_tree()
storage/maria/ma_ft_parser.c:
Updated call to init_tree()
Updated call to init_alloc_root()
storage/maria/ma_loghandler.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_open.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_sort.c:
Updated call to my_init_dynamic_array()
storage/maria/ma_write.c:
Updated calls to my_init_dynamic_array() and init_tree()
storage/maria/maria_pack.c:
Updated call to init_tree()
storage/maria/unittest/sequence_storage.c:
Updated call to my_init_dynamic_array()
storage/myisam/ft_boolean_search.c:
Updated call to init_tree()
Updated call to init_alloc_root()
storage/myisam/ft_nlq_search.c:
Updated call to init_tree()
storage/myisam/ft_parser.c:
Updated call to init_tree()
Updated call to init_alloc_root()
storage/myisam/ft_stopwords.c:
Updated call to init_tree()
storage/myisam/mi_check.c:
Updated call to init_alloc_root()
storage/myisam/mi_write.c:
Updated call to my_init_dynamic_array()
Updated call to init_tree()
storage/myisam/myisamlog.c:
Updated call to init_tree()
storage/myisam/myisampack.c:
Updated call to init_tree()
storage/myisam/sort.c:
Updated call to my_init_dynamic_array()
storage/myisammrg/ha_myisammrg.cc:
Updated call to init_sql_alloc()
storage/perfschema/pfs_check.cc:
Rest current_thd
storage/perfschema/pfs_instr.cc:
Removed DBUG_ENTER/DBUG_VOID_RETURN as at this point my_thread_var is not allocated anymore, which can cause problems.
support-files/compiler_warnings.supp:
Disable compiler warning from offsetof macro.
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/array.c | 26 | ||||
-rw-r--r-- | mysys/default.c | 6 | ||||
-rw-r--r-- | mysys/hash.c | 6 | ||||
-rw-r--r-- | mysys/ma_dyncol.c | 9 | ||||
-rw-r--r-- | mysys/mf_tempdir.c | 2 | ||||
-rw-r--r-- | mysys/my_alloc.c | 37 | ||||
-rw-r--r-- | mysys/my_chmod.c | 2 | ||||
-rw-r--r-- | mysys/my_chsize.c | 2 | ||||
-rw-r--r-- | mysys/my_copy.c | 2 | ||||
-rw-r--r-- | mysys/my_create.c | 2 | ||||
-rw-r--r-- | mysys/my_delete.c | 2 | ||||
-rw-r--r-- | mysys/my_error.c | 6 | ||||
-rw-r--r-- | mysys/my_fopen.c | 6 | ||||
-rw-r--r-- | mysys/my_fstream.c | 8 | ||||
-rw-r--r-- | mysys/my_getwd.c | 4 | ||||
-rw-r--r-- | mysys/my_lib.c | 17 | ||||
-rw-r--r-- | mysys/my_lock.c | 2 | ||||
-rw-r--r-- | mysys/my_malloc.c | 126 | ||||
-rw-r--r-- | mysys/my_open.c | 4 | ||||
-rw-r--r-- | mysys/my_pread.c | 4 | ||||
-rw-r--r-- | mysys/my_read.c | 2 | ||||
-rw-r--r-- | mysys/my_redel.c | 2 | ||||
-rw-r--r-- | mysys/my_rename.c | 2 | ||||
-rw-r--r-- | mysys/my_seek.c | 4 | ||||
-rw-r--r-- | mysys/my_sync.c | 7 | ||||
-rw-r--r-- | mysys/my_thr_init.c | 7 | ||||
-rw-r--r-- | mysys/my_write.c | 2 | ||||
-rw-r--r-- | mysys/mysys_priv.h | 9 | ||||
-rw-r--r-- | mysys/safemalloc.c | 70 | ||||
-rw-r--r-- | mysys/tree.c | 16 | ||||
-rw-r--r-- | mysys/waiting_threads.c | 4 |
31 files changed, 294 insertions, 104 deletions
diff --git a/mysys/array.c b/mysys/array.c index c969da83586..5aa1b1abb88 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -28,6 +28,7 @@ init_buffer Initial buffer pointer init_alloc Number of initial elements alloc_increment Increment for adding new elements + my_flags Flags to my_malloc DESCRIPTION init_dynamic_array() initiates array and allocate space for @@ -42,7 +43,7 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, void *init_buffer, uint init_alloc, - uint alloc_increment) + uint alloc_increment, myf my_flags) { DBUG_ENTER("init_dynamic_array2"); if (!alloc_increment) @@ -55,6 +56,7 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, array->max_element=init_alloc; array->alloc_increment=alloc_increment; array->size_of_element=element_size; + array->malloc_flags= my_flags; if ((array->buffer= init_buffer)) DBUG_RETURN(FALSE); /* @@ -62,18 +64,12 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, should not throw an error */ if (init_alloc && - !(array->buffer= (uchar*) my_malloc(element_size*init_alloc, MYF(0)))) + !(array->buffer= (uchar*) my_malloc(element_size*init_alloc, + MYF(my_flags)))) array->max_element=0; DBUG_RETURN(FALSE); } -my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, uint alloc_increment) -{ - /* placeholder to preserve ABI */ - return my_init_dynamic_array_ci(array, element_size, init_alloc, - alloc_increment); -} /* Insert element at the end of array. Allocate memory if needed. @@ -137,7 +133,7 @@ uchar *alloc_dynamic(DYNAMIC_ARRAY *array) if (!(new_ptr= (char *) my_malloc((array->max_element+ array->alloc_increment) * array->size_of_element, - MYF(MY_WME)))) + MYF(array->malloc_flags | MY_WME)))) DBUG_RETURN(0); memcpy(new_ptr, array->buffer, array->elements * array->size_of_element); @@ -146,7 +142,8 @@ uchar *alloc_dynamic(DYNAMIC_ARRAY *array) my_realloc(array->buffer,(array->max_element+ array->alloc_increment)* array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + MYF(MY_WME | MY_ALLOW_ZERO_PTR | + array->malloc_flags)))) DBUG_RETURN(0); array->buffer= (uchar*) new_ptr; array->max_element+=array->alloc_increment; @@ -242,14 +239,15 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) */ if (!(new_ptr= (uchar *) my_malloc(size * array->size_of_element, - MYF(MY_WME)))) + MYF(array->malloc_flags | MY_WME)))) DBUG_RETURN(0); memcpy(new_ptr, array->buffer, array->elements * array->size_of_element); } else if (!(new_ptr= (uchar*) my_realloc(array->buffer,size* array->size_of_element, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) + MYF(MY_WME | MY_ALLOW_ZERO_PTR | + array->malloc_flags)))) DBUG_RETURN(TRUE); array->buffer= new_ptr; array->max_element= size; @@ -347,7 +345,7 @@ void freeze_size(DYNAMIC_ARRAY *array) { array->buffer=(uchar*) my_realloc(array->buffer, elements*array->size_of_element, - MYF(MY_WME)); + MYF(MY_WME | array->malloc_flags)); array->max_element=elements; } } diff --git a/mysys/default.c b/mysys/default.c index c7ac0d89462..94609ba4539 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -520,7 +520,7 @@ int my_load_defaults(const char *conf_file, const char **groups, uint args_sep= my_getopt_use_args_separator ? 1 : 0; DBUG_ENTER("load_defaults"); - init_alloc_root(&alloc,512,0); + init_alloc_root(&alloc, 512, 0, 0); if ((dirs= init_default_directories(&alloc)) == NULL) goto err; /* @@ -566,7 +566,7 @@ int my_load_defaults(const char *conf_file, const char **groups, for (; *groups ; groups++) group.count++; - if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32)) + if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32, 0)) goto err; ctx.alloc= &alloc; @@ -1043,7 +1043,7 @@ void my_print_default_files(const char *conf_file) { const char **dirs; MEM_ROOT alloc; - init_alloc_root(&alloc,512,0); + init_alloc_root(&alloc, 512, 0, 0); if ((dirs= init_default_directories(&alloc)) == NULL) { diff --git a/mysys/hash.c b/mysys/hash.c index b93f6b666d6..0a830d8e3f4 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -89,8 +89,10 @@ _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, hash->free=free_element; hash->flags=flags; hash->charset=charset; - res= my_init_dynamic_array_ci(&hash->array, - sizeof(HASH_LINK), size, growth_size); + res= my_init_dynamic_array2(&hash->array, + sizeof(HASH_LINK), NULL, size, growth_size, + MYF((flags & HASH_THREAD_SPECIFIC ? + MY_THREAD_SPECIFIC : 0))); DBUG_RETURN(res); } diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index f45f73fbd8e..2441243c132 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -342,8 +342,10 @@ static my_bool type_and_offset_store_num(uchar *place, size_t offset_size, int3store(place, val); break; case 4: +#if SIZEOF_SIZE_T > 4 if (offset >= 0x1fffffff) /* all 1 value is reserved */ return TRUE; +#endif int4store(place, val); break; default: @@ -381,8 +383,10 @@ static my_bool type_and_offset_store_named(uchar *place, size_t offset_size, int4store(place, val); break; case 5: +#if SIZEOF_SIZE_T > 4 if (offset >= 0xfffffffffull) /* all 1 value is reserved */ return TRUE; +#endif int5store(place, val); break; case 1: @@ -482,8 +486,10 @@ static size_t dynamic_column_offset_bytes_named(size_t data_length) return 3; if (data_length < 0xfffffff) /* all 1 value is reserved */ return 4; +#if SIZEOF_SIZE_T > 4 if (data_length < 0xfffffffffull) /* all 1 value is reserved */ return 5; +#endif return MAX_OFFSET_LENGTH_NM + 1; /* For an error generation */ } @@ -2403,7 +2409,8 @@ dynamic_column_list(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_uint) str->length) return ER_DYNCOL_FORMAT; - if (init_dynamic_array(array_of_uint, sizeof(uint), header.column_count, 0)) + if (my_init_dynamic_array(array_of_uint, sizeof(uint), header.column_count, + 0, 0)) return ER_DYNCOL_RESOURCE; for (i= 0, read= header.header; diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c index eceb90bb619..bd42002ae86 100644 --- a/mysys/mf_tempdir.c +++ b/mysys/mf_tempdir.c @@ -30,7 +30,7 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist) DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL")); mysql_mutex_init(key_TMPDIR_mutex, &tmpdir->mutex, MY_MUTEX_INIT_FAST); - if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5)) + if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5, 0)) goto err; if (!pathlist || !pathlist[0]) { diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 1054db6cee4..6c8a73df4a7 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -22,6 +22,10 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG +/* data packed in MEM_ROOT -> min_malloc */ + +#define MALLOC_FLAG(A) ((A & 1) ? MY_THREAD_SPECIFIC : 0) + /* Initialize memory root @@ -34,6 +38,7 @@ should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE) pre_alloc_size - if non-0, then size of block that should be pre-allocated during memory root initialization. + my_flags MY_THREAD_SPECIFIC flag for my_malloc DESCRIPTION This function prepares memory root for further use, sets initial size of @@ -41,17 +46,24 @@ Altough error can happen during execution of this function if pre_alloc_size is non-0 it won't be reported. Instead it will be reported as error in first alloc_root() on this memory root. + + We don't want to change the structure size for MEM_ROOT. + Because of this, we store in MY_THREAD_SPECIFIC as bit 1 in block_size */ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, - size_t pre_alloc_size __attribute__((unused))) + size_t pre_alloc_size __attribute__((unused)), + myf my_flags) { DBUG_ENTER("init_alloc_root"); DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root)); mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; - mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; + mem_root->block_size= (block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1; + if (test(my_flags & MY_THREAD_SPECIFIC)) + mem_root->block_size|= 1; + mem_root->error_handler= 0; mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; @@ -61,7 +73,7 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, { if ((mem_root->free= mem_root->pre_alloc= (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)), - MYF(0)))) + MYF(my_flags)))) { mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); mem_root->free->left= pre_alloc_size; @@ -72,7 +84,6 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, DBUG_VOID_RETURN; } - /* SYNOPSIS reset_root_defaults() @@ -95,7 +106,8 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, { DBUG_ASSERT(alloc_root_inited(mem_root)); - mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE; + mem_root->block_size= (((block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1) | + (mem_root->block_size & 1)); #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size) { @@ -126,7 +138,9 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, prev= &mem->next; } /* Allocate new prealloc block and add it to the end of free list */ - if ((mem= (USED_MEM *) my_malloc(size, MYF(0)))) + if ((mem= (USED_MEM *) my_malloc(size, + MYF(MALLOC_FLAG(mem_root-> + block_size))))) { mem->size= size; mem->left= pre_alloc_size; @@ -163,7 +177,9 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) }); length+=ALIGN_SIZE(sizeof(USED_MEM)); - if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR)))) + if (!(next = (USED_MEM*) my_malloc(length, + MYF(MY_WME | ME_FATALERROR | + MALLOC_FLAG(mem_root->block_size))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); @@ -210,11 +226,14 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) } if (! next) { /* Time to alloc new block */ - block_size= mem_root->block_size * (mem_root->block_num >> 2); + block_size= (mem_root->block_size & ~1) * (mem_root->block_num >> 2); get_size= length+ALIGN_SIZE(sizeof(USED_MEM)); get_size= max(get_size, block_size); - if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR)))) + if (!(next = (USED_MEM*) my_malloc(get_size, + MYF(MY_WME | ME_FATALERROR | + MALLOC_FLAG(mem_root-> + block_size))))) { if (mem_root->error_handler) (*mem_root->error_handler)(); diff --git a/mysys/my_chmod.c b/mysys/my_chmod.c index afdea758833..91fd51b47d2 100644 --- a/mysys/my_chmod.c +++ b/mysys/my_chmod.c @@ -34,7 +34,7 @@ int my_chmod(const char *name, mode_t mode, myf my_flags) { DBUG_ENTER("my_chmod"); - DBUG_PRINT("my",("name: %s mode: %lu flags: %d", name, (ulong) mode, + DBUG_PRINT("my",("name: %s mode: %lu flags: %lu", name, (ulong) mode, my_flags)); if (chmod(name, mode)) diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index 63964916d6f..51da6be7935 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -43,7 +43,7 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) my_off_t oldsize; uchar buff[IO_SIZE]; DBUG_ENTER("my_chsize"); - DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength, + DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %lu",fd,(ulong) newlength, MyFlags)); if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength) diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 21de1e953a2..58cacb9639d 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -61,7 +61,7 @@ int my_copy(const char *from, const char *to, myf MyFlags) MY_STAT stat_buff,new_stat_buff; my_bool file_created= 0; DBUG_ENTER("my_copy"); - DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); + DBUG_PRINT("my",("from %s to %s MyFlags %lu", from, to, MyFlags)); from_file=to_file= -1; DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */ diff --git a/mysys/my_create.c b/mysys/my_create.c index 2e4e8eb1af2..51de343d4a1 100644 --- a/mysys/my_create.c +++ b/mysys/my_create.c @@ -38,7 +38,7 @@ File my_create(const char *FileName, int CreateFlags, int access_flags, { int fd, rc; DBUG_ENTER("my_create"); - DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d", + DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %lu", FileName, CreateFlags, access_flags, MyFlags)); #if defined(_WIN32) fd= my_win_open(FileName, access_flags | O_CREAT); diff --git a/mysys/my_delete.c b/mysys/my_delete.c index cf9573f592b..0655501aa16 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -21,7 +21,7 @@ int my_delete(const char *name, myf MyFlags) { int err; DBUG_ENTER("my_delete"); - DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags)); + DBUG_PRINT("my",("name %s MyFlags %lu", name, MyFlags)); if ((err = unlink(name)) == -1) { diff --git a/mysys/my_error.c b/mysys/my_error.c index 3302add688b..08c67412fe1 100644 --- a/mysys/my_error.c +++ b/mysys/my_error.c @@ -75,7 +75,7 @@ void my_error(int nr, myf MyFlags, ...) va_list args; char ebuff[ERRMSGSIZE]; DBUG_ENTER("my_error"); - DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno)); + DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d", nr, MyFlags, errno)); /* Search for the error messages array, which could contain the message. */ for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next) @@ -114,7 +114,7 @@ void my_printf_error(uint error, const char *format, myf MyFlags, ...) va_list args; char ebuff[ERRMSGSIZE]; DBUG_ENTER("my_printf_error"); - DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s", + DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d format: %s", error, MyFlags, errno, format)); va_start(args,MyFlags); @@ -140,7 +140,7 @@ void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap) { char ebuff[ERRMSGSIZE]; DBUG_ENTER("my_printv_error"); - DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s", + DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d format: %s", error, MyFlags, errno, format)); (void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap); diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 54469d2c05a..8a30dd6c10b 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -44,7 +44,7 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) FILE *fd; char type[5]; DBUG_ENTER("my_fopen"); - DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d", + DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %lu", filename, flags, MyFlags)); make_ftype(type,flags); @@ -229,7 +229,7 @@ int my_fclose(FILE *fd, myf MyFlags) { int err,file; DBUG_ENTER("my_fclose"); - DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags)); + DBUG_PRINT("my",("stream: 0x%lx MyFlags: %lu", (long) fd, MyFlags)); mysql_mutex_lock(&THR_LOCK_open); file= my_fileno(fd); @@ -265,7 +265,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) FILE *fd; char type[5]; DBUG_ENTER("my_fdopen"); - DBUG_PRINT("my",("fd: %d Flags: %d MyFlags: %d", + DBUG_PRINT("my",("fd: %d Flags: %d MyFlags: %lu", Filedes, Flags, MyFlags)); make_ftype(type,Flags); diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c index e758609741b..de752fa149f 100644 --- a/mysys/my_fstream.c +++ b/mysys/my_fstream.c @@ -46,7 +46,7 @@ size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags) { size_t readbytes; DBUG_ENTER("my_fread"); - DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", + DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %lu", (long) stream, (long) Buffer, (uint) Count, MyFlags)); if ((readbytes= fread(Buffer, sizeof(char), Count, stream)) != Count) @@ -94,7 +94,7 @@ size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags) uint errors; #endif DBUG_ENTER("my_fwrite"); - DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", + DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %lu", (long) stream, (long) Buffer, (uint) Count, MyFlags)); #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) @@ -163,7 +163,7 @@ my_off_t my_fseek(FILE *stream, my_off_t pos, int whence, myf MyFlags __attribute__((unused))) { DBUG_ENTER("my_fseek"); - DBUG_PRINT("my",("stream: 0x%lx pos: %lu whence: %d MyFlags: %d", + DBUG_PRINT("my",("stream: 0x%lx pos: %lu whence: %d MyFlags: %lu", (long) stream, (long) pos, whence, MyFlags)); DBUG_RETURN(fseek(stream, (off_t) pos, whence) ? MY_FILEPOS_ERROR : (my_off_t) ftell(stream)); @@ -176,7 +176,7 @@ my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused))) { off_t pos; DBUG_ENTER("my_ftell"); - DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) stream, MyFlags)); + DBUG_PRINT("my",("stream: 0x%lx MyFlags: %lu", (long) stream, MyFlags)); pos=ftell(stream); DBUG_PRINT("exit",("ftell: %lu",(ulong) pos)); DBUG_RETURN((my_off_t) pos); diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c index 444ed4273b5..79ec58d3c5c 100644 --- a/mysys/my_getwd.c +++ b/mysys/my_getwd.c @@ -48,7 +48,7 @@ int my_getwd(char * buf, size_t size, myf MyFlags) { char * pos; DBUG_ENTER("my_getwd"); - DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d", + DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %lu", (long) buf, (uint) size, MyFlags)); if (size < 1) @@ -95,7 +95,7 @@ int my_setwd(const char *dir, myf MyFlags) size_t length; char *start, *pos; DBUG_ENTER("my_setwd"); - DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags)); + DBUG_PRINT("my",("dir: '%s' MyFlags %lu", dir, MyFlags)); start=(char *) dir; if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) diff --git a/mysys/my_lib.c b/mysys/my_lib.c index b42a3d55d93..543d96455ff 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -100,7 +100,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; DBUG_ENTER("my_dir"); - DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); + DBUG_PRINT("my",("path: '%s' MyFlags: %lu",path,MyFlags)); #if !defined(HAVE_READDIR_R) mysql_mutex_lock(&THR_LOCK_open); @@ -122,12 +122,14 @@ MY_DIR *my_dir(const char *path, myf MyFlags) ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), - ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + ENTRIES_START_SIZE, ENTRIES_INCREMENT, + MyFlags)) { my_free(buffer); goto error; } - init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE, + MyFlags); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; @@ -263,12 +265,13 @@ MY_DIR *my_dir(const char *path, myf MyFlags) ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), - ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + ENTRIES_START_SIZE, ENTRIES_INCREMENT, + MyFlags)) { my_free(buffer); goto error; } - init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE, MyFlags); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; @@ -383,7 +386,7 @@ int my_fstat(File Filedes, MY_STAT *stat_area, myf MyFlags __attribute__((unused))) { DBUG_ENTER("my_fstat"); - DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %lu", Filedes, MyFlags)); #ifdef _WIN32 DBUG_RETURN(my_win_fstat(Filedes, stat_area)); #else @@ -396,7 +399,7 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags) { int m_used; DBUG_ENTER("my_stat"); - DBUG_PRINT("my", ("path: '%s' stat_area: 0x%lx MyFlags: %d", path, + DBUG_PRINT("my", ("path: '%s' stat_area: 0x%lx MyFlags: %lu", path, (long) stat_area, my_flags)); if ((m_used= (stat_area == NULL))) diff --git a/mysys/my_lock.c b/mysys/my_lock.c index 54ec3838b58..0abbc6c3084 100644 --- a/mysys/my_lock.c +++ b/mysys/my_lock.c @@ -144,7 +144,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, #endif DBUG_ENTER("my_lock"); - DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d", + DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %lu", fd,locktype,(long) start,(long) length,MyFlags)); if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK)) DBUG_RETURN(0); diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 1a9caf71380..88f3f412faf 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -18,6 +18,60 @@ #include "mysys_err.h" #include <m_string.h> +/* If we have our own safemalloc (for debugging) */ +#if defined(SAFEMALLOC) +#define MALLOC_SIZE_AND_FLAG(p,b) sf_malloc_usable_size(p,b) +#define MALLOC_PREFIX_SIZE 0 +#define MALLOC_STORE_SIZE(a,b,c,d) +#define MALLOC_FIX_POINTER_FOR_FREE(a) a +#else +/* + * We use double as prefix size as this guarantees the correct + * alignment on all platforms and will optimize things for + * memcpy(), memcmp() etc. + */ +#define MALLOC_PREFIX_SIZE (sizeof(double)) +#define MALLOC_SIZE(p) (*(size_t*) ((char*)(p) - MALLOC_PREFIX_SIZE)) +#define MALLOC_STORE_SIZE(p, type_of_p, size, flag) \ +{\ + *(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) +{ + size_t size= MALLOC_SIZE(p); + *flags= (size & 1); + return size & ~ (ulonglong) 1; +} +#define MALLOC_SIZE_AND_FLAG(p,b) malloc_size_and_flag(p, b); +#define MALLOC_FIX_POINTER_FOR_FREE(p) (((char*) (p)) - MALLOC_PREFIX_SIZE) +#endif /* SAFEMALLOC */ + +static MALLOC_SIZE_CB malloc_size_cb_func= NULL; + +/** + Inform application that memory usage has changed + + @param size Size of memory segment allocated or freed + @param flag 1 if thread specific (allocated by MY_THREAD_SPECIFIC), + 0 if system specific. + + The type os size is long long, to be able to handle negative numbers to + decrement the memory usage +*/ + +static void update_malloc_size(long long size, myf my_flags) +{ + if (malloc_size_cb_func) + malloc_size_cb_func(size, my_flags); +} + +void set_malloc_size_cb(MALLOC_SIZE_CB func) +{ + malloc_size_cb_func= func; +} + + /** Allocate a sized block of memory. @@ -30,7 +84,9 @@ void *my_malloc(size_t size, myf my_flags) { void* point; DBUG_ENTER("my_malloc"); - DBUG_PRINT("my",("size: %lu my_flags: %d", (ulong) size, my_flags)); + DBUG_PRINT("my",("size: %lu my_flags: %lu", (ulong) size, my_flags)); + compile_time_assert(sizeof(size_t) <= sizeof(double)); + if (!(my_flags & (MY_WME | MY_FAE))) my_flags|= my_global_flags; @@ -38,12 +94,9 @@ void *my_malloc(size_t size, myf my_flags) if (!size) size=1; - point= sf_malloc(size); - DBUG_EXECUTE_IF("simulate_out_of_memory", - { - my_free(point); - point= NULL; - }); + /* We have to align size to be able to store markers in it */ + size= ALIGN_SIZE(size); + point= sf_malloc(size + MALLOC_PREFIX_SIZE, my_flags); if (point == NULL) { @@ -59,8 +112,20 @@ void *my_malloc(size_t size, myf my_flags) if (my_flags & MY_FAE) exit(1); } - else if (my_flags & MY_ZEROFILL) - bzero(point, size); + else + { + MALLOC_STORE_SIZE(point, void*, size, test(my_flags & MY_THREAD_SPECIFIC)); + update_malloc_size(size + MALLOC_PREFIX_SIZE, + test(my_flags & MY_THREAD_SPECIFIC)); + DBUG_EXECUTE_IF("simulate_out_of_memory", + { + /* my_free() handles memory accounting */ + my_free(point); + point= NULL; + }); + if (my_flags & MY_ZEROFILL) + bzero(point, size); + } DBUG_PRINT("exit",("ptr: %p", point)); DBUG_RETURN(point); } @@ -79,23 +144,53 @@ void *my_malloc(size_t size, myf my_flags) void *my_realloc(void *oldpoint, size_t size, myf my_flags) { void *point; + size_t old_size; + myf old_flags; DBUG_ENTER("my_realloc"); - DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %d", oldpoint, + DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %lu", oldpoint, (ulong) size, my_flags)); DBUG_ASSERT(size > 0); if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR)) DBUG_RETURN(my_malloc(size, my_flags)); - if ((point= sf_realloc(oldpoint, size)) == NULL) + + size= ALIGN_SIZE(size); + old_size= MALLOC_SIZE_AND_FLAG(oldpoint, &old_flags); + /* + Test that the new and old area are the same, if not MY_THREAD_MOVE is + given + */ + DBUG_ASSERT((test(my_flags & MY_THREAD_SPECIFIC) == old_flags) || + (my_flags & MY_THREAD_MOVE)); + if ((point= sf_realloc(MALLOC_FIX_POINTER_FOR_FREE(oldpoint), + size + MALLOC_PREFIX_SIZE, my_flags)) == NULL) { if (my_flags & MY_FREE_ON_ERROR) + { + /* my_free will take care of size accounting */ my_free(oldpoint); + oldpoint= 0; + } if (my_flags & MY_HOLD_ON_ERROR) DBUG_RETURN(oldpoint); my_errno=errno; if (my_flags & (MY_FAE+MY_WME)) my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size); } + else + { + MALLOC_STORE_SIZE(point, void*, size, test(my_flags & MY_THREAD_SPECIFIC)); + if (test(my_flags & MY_THREAD_SPECIFIC) != old_flags) + { + /* memory moved between system and thread specific */ + update_malloc_size(-(longlong) old_size - MALLOC_PREFIX_SIZE, old_flags); + update_malloc_size((longlong) size + MALLOC_PREFIX_SIZE, + my_flags & MY_THREAD_SPECIFIC); + } + else + update_malloc_size((longlong) (size - old_size), old_flags); + } + DBUG_PRINT("exit",("ptr: %p", point)); DBUG_RETURN(point); } @@ -112,7 +207,14 @@ void my_free(void *ptr) { DBUG_ENTER("my_free"); DBUG_PRINT("my",("ptr: %p", ptr)); - sf_free(ptr); + if (ptr) + { + size_t old_size; + myf 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)); + } DBUG_VOID_RETURN; } diff --git a/mysys/my_open.c b/mysys/my_open.c index 645d6709358..5263ba4b5c8 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -39,7 +39,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags) { File fd; DBUG_ENTER("my_open"); - DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d", + DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %lu", FileName, Flags, MyFlags)); if (!(MyFlags & (MY_WME | MY_FAE | MY_FFNF))) MyFlags|= my_global_flags; @@ -71,7 +71,7 @@ int my_close(File fd, myf MyFlags) { int err; DBUG_ENTER("my_close"); - DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %lu",fd, MyFlags)); if (!(MyFlags & (MY_WME | MY_FAE))) MyFlags|= my_global_flags; diff --git a/mysys/my_pread.c b/mysys/my_pread.c index 51b4c5f5599..745cde9ec41 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -52,7 +52,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, DBUG_ENTER("my_pread"); - DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %lu", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) @@ -130,7 +130,7 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count, size_t writtenbytes, written; uint errors; DBUG_ENTER("my_pwrite"); - DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %lu", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); errors= 0; written= 0; diff --git a/mysys/my_read.c b/mysys/my_read.c index 0afbf3773f3..66b7f6d353d 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -37,7 +37,7 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags) { size_t readbytes, save_count; DBUG_ENTER("my_read"); - DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %lu", Filedes, Buffer, (ulong) Count, MyFlags)); save_count= Count; if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) diff --git a/mysys/my_redel.c b/mysys/my_redel.c index d15dd87001a..e4d88b70f38 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -46,7 +46,7 @@ int my_redel(const char *org_name, const char *tmp_name, { int error=1; DBUG_ENTER("my_redel"); - DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", + DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %lu", org_name,tmp_name,MyFlags)); if (my_copystat(org_name,tmp_name,MyFlags) < 0) diff --git a/mysys/my_rename.c b/mysys/my_rename.c index b89bc4c8fbd..8a9e6eb3dfd 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -25,7 +25,7 @@ int my_rename(const char *from, const char *to, myf MyFlags) { int error = 0; DBUG_ENTER("my_rename"); - DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); + DBUG_PRINT("my",("from %s to %s MyFlags %lu", from, to, MyFlags)); #if defined(HAVE_RENAME) #if defined(__WIN__) diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 1033d7ac806..e15179a408f 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -48,7 +48,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) { os_off_t newpos= -1; DBUG_ENTER("my_seek"); - DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %d", + DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %lu", fd, (ulonglong) pos, whence, MyFlags)); DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ @@ -84,7 +84,7 @@ my_off_t my_tell(File fd, myf MyFlags) { os_off_t pos; DBUG_ENTER("my_tell"); - DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); + DBUG_PRINT("my",("fd: %d MyFlags: %lu",fd, MyFlags)); DBUG_ASSERT(fd >= 0); #if defined (HAVE_TELL) && !defined (_WIN32) pos= tell(fd); diff --git a/mysys/my_sync.c b/mysys/my_sync.c index 88bcb685271..c0afd587ada 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -65,16 +65,13 @@ int my_sync(File fd, myf my_flags) { int res; DBUG_ENTER("my_sync"); - - DBUG_PRINT("my",("fd: %d my_flags: %d", fd, my_flags)); + DBUG_PRINT("my",("fd: %d my_flags: %lu", fd, my_flags)); if (my_disable_sync) DBUG_RETURN(0); statistic_increment(my_sync_count,&THR_LOCK_open); - DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags)); - if (before_sync_wait) (*before_sync_wait)(); @@ -158,7 +155,7 @@ int my_sync_dir(const char *dir_name __attribute__((unused)), int res= 0; const char *correct_dir_name; DBUG_ENTER("my_sync_dir"); - DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags)); + DBUG_PRINT("my",("Dir: '%s' my_flags: %lu", dir_name, my_flags)); /* Sometimes the path does not contain an explicit directory */ correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name; /* diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index ac16189f3a7..56f7ca8b31a 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -427,7 +427,12 @@ struct st_my_thread_var *_my_thread_var(void) my_thread_id my_thread_dbug_id() { - return my_thread_var->id; + /* + We need to do this test as some system thread may not yet have called + my_thread_init(). + */ + struct st_my_thread_var *tmp= my_thread_var; + return tmp ? tmp->id : 0; } #ifdef DBUG_OFF diff --git a/mysys/my_write.c b/mysys/my_write.c index c4cba7a927d..204e2e1488d 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -25,7 +25,7 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) size_t writtenbytes, written; uint errors; DBUG_ENTER("my_write"); - DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", + DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %lu", Filedes, Buffer, (ulong) Count, MyFlags)); errors= 0; written= 0; if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP))) diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index f5d2f301837..aa4af92202a 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -70,12 +70,13 @@ extern PSI_file_key key_file_charset, key_file_cnf; #endif /* HAVE_PSI_INTERFACE */ #ifdef SAFEMALLOC -void *sf_malloc(size_t size); -void *sf_realloc(void *ptr, size_t size); +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); #else -#define sf_malloc(X) malloc(X) -#define sf_realloc(X,Y) realloc(X,Y) +#define sf_malloc(X,Y) malloc(X) +#define sf_realloc(X,Y,Z) realloc(X,Y) #define sf_free(X) free(X) #endif diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 31f0333725f..d9a04d9e8d1 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -58,6 +58,8 @@ struct st_irem #ifdef HAVE_BACKTRACE void *frame[SF_REMEMBER_FRAMES]; /* call stack */ #endif + uint32 flags; /* Flags passed to malloc */ + my_thread_id thread_id; /* Which thread did the allocation */ uint32 marker; /* Underrun marker value */ }; @@ -79,11 +81,21 @@ static int bad_ptr(const char *where, void *ptr); static void free_memory(void *ptr); static void sf_terminate(); +/* Setup default call to get a thread id for the memory */ + +my_thread_id default_sf_malloc_dbug_id(void) +{ + return my_thread_dbug_id(); +} + +my_thread_id (*sf_malloc_dbug_id)(void)= default_sf_malloc_dbug_id; + + /** allocates memory */ -void *sf_malloc(size_t size) +void *sf_malloc(size_t size, myf my_flags) { struct st_irem *irem; uchar *data; @@ -114,7 +126,9 @@ void *sf_malloc(size_t size) data= (uchar*) (irem + 1); irem->datasize= size; irem->prev= 0; + irem->flags= my_flags; irem->marker= MAGICSTART; + irem->thread_id= sf_malloc_dbug_id(); data[size + 0]= MAGICEND0; data[size + 1]= MAGICEND1; data[size + 2]= MAGICEND2; @@ -154,17 +168,17 @@ void *sf_malloc(size_t size) return data; } -void *sf_realloc(void *ptr, size_t size) +void *sf_realloc(void *ptr, size_t size, myf my_flags) { char *data; if (!ptr) - return sf_malloc(size); + return sf_malloc(size, my_flags); if (bad_ptr("Reallocating", ptr)) return 0; - if ((data= sf_malloc(size))) + if ((data= sf_malloc(size, my_flags))) { struct st_irem *irem= (struct st_irem *)ptr - 1; set_if_smaller(size, irem->datasize); @@ -182,10 +196,38 @@ void sf_free(void *ptr) free_memory(ptr); } +/** + Return size of memory block and if block is thread specific + + sf_malloc_usable_size() + @param ptr Pointer to malloced block + @param flags We will store 1 here if block is marked as MY_THREAD_SPECIFIC + otherwise 0 + + @return Size of block +*/ + +size_t sf_malloc_usable_size(void *ptr, myf *flags) +{ + struct st_irem *irem= (struct st_irem *)ptr - 1; + DBUG_ENTER("sf_malloc_usable_size"); + *flags= test(irem->flags & MY_THREAD_SPECIFIC); + DBUG_PRINT("exit", ("size: %lu flags: %lu", (ulong) irem->datasize, + *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) @@ -312,9 +354,11 @@ static int sf_sanity() /** report on all the memory pieces that have not been free'd + + @param id Id of thread to report. 0 if all */ -static void sf_terminate() +void sf_report_leaked_memory(my_thread_id id) { size_t total= 0; struct st_irem *irem; @@ -322,21 +366,29 @@ static void sf_terminate() sf_sanity(); /* Report on all the memory that was allocated but not free'd */ - if (!sf_leaking_memory && sf_malloc_root) + + for (irem= sf_malloc_root; irem; irem= irem->next) { - for (irem= sf_malloc_root; irem; irem= irem->next) + if (!id || (irem->thread_id == id && irem->flags & MY_THREAD_SPECIFIC)) { fprintf(stderr, "Warning: %4lu bytes lost, allocated at ", (ulong) irem->datasize); print_stack(irem->frame); total+= irem->datasize; } + } + if (total) fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n", (ulong) total, sf_malloc_count); - } + return; +} + +static void sf_terminate() +{ + if (!sf_leaking_memory) + sf_report_leaked_memory(0); pthread_mutex_destroy(&sf_mutex); - return; } #endif diff --git a/mysys/tree.c b/mysys/tree.c index 85770194f25..b8c951df4cf 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -84,8 +84,9 @@ static int test_rb_tree(TREE_ELEMENT *element); #endif void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, - int size, qsort_cmp2 compare, my_bool with_delete, - tree_element_free free_element, void *custom_arg) + int size, qsort_cmp2 compare, + tree_element_free free_element, void *custom_arg, + myf my_flags) { DBUG_ENTER("init_tree"); DBUG_PRINT("enter",("tree: 0x%lx size: %d", (long) tree, size)); @@ -104,6 +105,7 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, tree->custom_arg = custom_arg; tree->null_element.colour=BLACK; tree->null_element.left=tree->null_element.right=0; + tree->my_flags= my_flags; tree->flag= 0; if (!free_element && size >= 0 && ((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1)))) @@ -125,10 +127,11 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, tree->offset_to_key=0; /* use key through pointer */ tree->size_of_element+=sizeof(void*); } - if (!(tree->with_delete=with_delete)) + if (!(tree->with_delete= test(my_flags & MY_TREE_WITH_DELETE))) { - init_alloc_root(&tree->mem_root, default_alloc_size, 0); - tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element); + init_alloc_root(&tree->mem_root, default_alloc_size, 0, + my_flags); + tree->mem_root.min_malloc= sizeof(TREE_ELEMENT)+tree->size_of_element; } DBUG_VOID_RETURN; } @@ -236,7 +239,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, key_size+=tree->size_of_element; if (tree->with_delete) - element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME)); + element=(TREE_ELEMENT *) my_malloc(alloc_size, + MYF(tree->my_flags | MY_WME)); else element=(TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size); if (!element) diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index 0a9474e68b4..7d7fcb69da0 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -403,7 +403,7 @@ static void wt_resource_init(uchar *arg) bzero(rc, sizeof(*rc)); rc_rwlock_init(rc); mysql_cond_init(key_WT_RESOURCE_cond, &rc->cond, 0); - my_init_dynamic_array(&rc->owners, sizeof(WT_THD *), 0, 5); + my_init_dynamic_array(&rc->owners, sizeof(WT_THD *), 0, 5, 0); DBUG_VOID_RETURN; } @@ -509,7 +509,7 @@ void wt_thd_lazy_init(WT_THD *thd, const ulong *ds, const ulong *ts, thd->deadlock_search_depth_long= dl; thd->timeout_long= tl; /* dynamic array is also initialized lazily - without memory allocations */ - my_init_dynamic_array(&thd->my_resources, sizeof(WT_RESOURCE *), 0, 5); + my_init_dynamic_array(&thd->my_resources, sizeof(WT_RESOURCE *), 0, 5, 0); #ifndef DBUG_OFF thd->name= my_thread_name(); #endif |