diff --git a/configure.cmake b/configure.cmake index 85cf352eba6..5a7809baa4f 100644 --- a/configure.cmake +++ b/configure.cmake @@ -379,7 +379,6 @@ CHECK_FUNCTION_EXISTS (pthread_attr_getguardsize HAVE_PTHREAD_ATTR_GETGUARDSIZE) CHECK_FUNCTION_EXISTS (pthread_attr_setstacksize HAVE_PTHREAD_ATTR_SETSTACKSIZE) CHECK_FUNCTION_EXISTS (pthread_condattr_create HAVE_PTHREAD_CONDATTR_CREATE) CHECK_FUNCTION_EXISTS (pthread_getaffinity_np HAVE_PTHREAD_GETAFFINITY_NP) -CHECK_FUNCTION_EXISTS (pthread_key_delete HAVE_PTHREAD_KEY_DELETE) CHECK_FUNCTION_EXISTS (pthread_rwlock_rdlock HAVE_PTHREAD_RWLOCK_RDLOCK) CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK) CHECK_FUNCTION_EXISTS (pthread_yield_np HAVE_PTHREAD_YIELD_NP) diff --git a/include/my_compiler.h b/include/my_compiler.h index 43b0e48f72c..4b596595434 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -183,4 +183,16 @@ rarely invoked function for size instead for speed. */ #include +/* + C++11 thread_local incurs a performance penalty on some platforms + accessing "extern thread_local" variable (not static). + To workaround, we use the platform specific thread local + storage mechanism, which also available in plain C. +*/ +#if defined (_MSC_VER) +# define MY_THREAD_LOCAL __declspec(thread) +#else +# define MY_THREAD_LOCAL __thread +#endif + #endif /* MY_COMPILER_INCLUDED */ diff --git a/include/my_pthread.h b/include/my_pthread.h index 8f3b04a2636..8f0b3ec30e3 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -109,14 +109,6 @@ int pthread_cancel(pthread_t thread); #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 #undef SAFE_MUTEX /* This will cause conflicts */ -#define pthread_key(T,V) DWORD V -#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) -#define pthread_key_delete(A) TlsFree(A) -#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V))) -#define pthread_setspecific(A,B) (!TlsSetValue((A),(LPVOID)(B))) -#define pthread_getspecific(A) (TlsGetValue(A)) -#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) -#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V)) #define pthread_equal(A,B) ((A) == (B)) #define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0) @@ -154,9 +146,6 @@ int pthread_cancel(pthread_t thread); #include #endif -#define pthread_key(T,V) pthread_key_t V -#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V)) -#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V)) #define pthread_detach_this_thread() #define pthread_handler_t EXTERNC void * typedef void *(* pthread_handler)(void *); @@ -232,8 +221,6 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implementation */ #undef HAVE_GETHOSTBYADDR_R /* No definition */ #endif -#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) - #ifndef HAVE_LOCALTIME_R struct tm *localtime_r(const time_t *clock, struct tm *res); #endif @@ -248,17 +235,7 @@ struct tm *gmtime_r(const time_t *clock, struct tm *res); #define pthread_condattr_destroy pthread_condattr_delete #endif -/* FSU THREADS */ -#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete) -#define pthread_key_delete(A) pthread_dummy(0) -#endif - #if defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT) -/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ -#define pthread_key_create(A,B) \ - pthread_keycreate(A,(B) ?\ - (pthread_destructor_t) (B) :\ - (pthread_destructor_t) pthread_dummy) #define pthread_attr_init(A) pthread_attr_create(A) #define pthread_attr_destroy(A) pthread_attr_delete(A) #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) @@ -723,7 +700,7 @@ extern uint my_thread_end_wait_time; extern my_bool safe_mutex_deadlock_detector; #define my_thread_var (_my_thread_var()) #define my_errno my_thread_var->thr_errno -int set_mysys_var(struct st_my_thread_var *mysys_var); +void set_mysys_var(struct st_my_thread_var *mysys_var); /* diff --git a/include/my_sys.h b/include/my_sys.h index 9a57fc32b4b..fa0b8935e68 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -260,7 +260,7 @@ extern ulong my_file_total_opened; extern ulong my_sync_count; extern uint mysys_usage_id; extern int32 my_file_opened; -extern my_bool my_init_done, my_thr_key_mysys_exists; +extern my_bool my_init_done; extern my_bool my_assert; extern my_bool my_assert_on_error; extern myf my_global_flags; /* Set to MY_WME for more error messages */ diff --git a/include/mysql/psi/psi.h b/include/mysql/psi/psi.h index 702d31fa01e..fefc3391b37 100644 --- a/include/mysql/psi/psi.h +++ b/include/mysql/psi/psi.h @@ -54,7 +54,6 @@ #ifdef _WIN32 typedef struct thread_attr pthread_attr_t; typedef DWORD pthread_t; -typedef DWORD pthread_key_t; #endif /* diff --git a/mysys/my_init.c b/mysys/my_init.c index 485ce163765..1596952745a 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -50,7 +50,6 @@ static void setup_codepages(); #define EXE_LINKPATH "/proc/curproc/file" #endif -extern pthread_key(struct st_my_thread_var*, THR_KEY_mysys); #define SCALE_SEC 100 #define SCALE_USEC 10000 @@ -350,8 +349,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", #endif /* At very last, delete mysys key, it is used everywhere including DBUG */ - pthread_key_delete(THR_KEY_mysys); - my_init_done= my_thr_key_mysys_exists= 0; + my_init_done= 0; } /* my_end */ #ifdef DBUG_ASSERT_EXISTS diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index b2436d2be27..f40dab43fa8 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -23,7 +23,6 @@ #include #include -pthread_key(struct st_my_thread_var*, THR_KEY_mysys=-1); mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_lock, THR_LOCK_myisam, THR_LOCK_heap, THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, @@ -41,8 +40,6 @@ static void install_sigabrt_handler(); /** True if @c my_thread_global_init() has been called. */ static my_bool my_thread_global_init_done= 0; -/* True if THR_KEY_mysys is created */ -my_bool my_thr_key_mysys_exists= 0; /* @@ -152,12 +149,10 @@ void my_thread_global_reinit(void) RETURN 0 ok - 1 error (Couldn't create THR_KEY_mysys) */ my_bool my_thread_global_init(void) { - int pth_ret; /* Normally this should never be called twice */ DBUG_ASSERT(my_thread_global_init_done == 0); @@ -165,21 +160,6 @@ my_bool my_thread_global_init(void) return 0; my_thread_global_init_done= 1; - /* - THR_KEY_mysys is deleted in my_end() as DBUG libraries are using it even - after my_thread_global_end() is called. - my_thr_key_mysys_exist is used to protect against application like QT - that calls my_thread_global_init() + my_thread_global_end() multiple times - without calling my_init() + my_end(). - */ - if (!my_thr_key_mysys_exists && - (pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0) - { - fprintf(stderr, "Can't initialize threads: error %d\n", pth_ret); - return 1; - } - my_thr_key_mysys_exists= 1; - /* Mutex used by my_thread_init() and after my_thread_destroy_mutex() */ my_thread_init_internal_mutex(); @@ -384,16 +364,18 @@ void my_thread_end(void) } } +static MY_THREAD_LOCAL struct st_my_thread_var *my_thread_var_; struct st_my_thread_var *_my_thread_var(void) { - return my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys); + return my_thread_var_; } -int set_mysys_var(struct st_my_thread_var *mysys_var) +void set_mysys_var(struct st_my_thread_var *mysys_var) { - return my_pthread_setspecific_ptr(THR_KEY_mysys, mysys_var); + my_thread_var_= mysys_var; } + /**************************************************************************** Get name of current thread. ****************************************************************************/ diff --git a/sql/slave.cc b/sql/slave.cc index 8f688378479..25cf0c30ab6 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -101,7 +101,6 @@ LEX_CSTRING default_master_connection_name= { (char*) "", 0 }; int disconnect_slave_event_count = 0, abort_slave_event_count = 0; -static pthread_key(Master_info*, RPL_MASTER_INFO); enum enum_slave_reconnect_actions { @@ -582,9 +581,6 @@ int init_slave() So it's safer to take the lock. */ - if (pthread_key_create(&RPL_MASTER_INFO, NULL)) - goto err; - master_info_index= new Master_info_index; if (!master_info_index || master_info_index->init_all_master_info()) { @@ -4831,9 +4827,6 @@ pthread_handler_t handle_slave_io(void *arg) DBUG_PRINT("master_info",("log_file_name: '%s' position: %llu", mi->master_log_name, mi->master_log_pos)); - /* This must be called before run any binlog_relay_io hooks */ - my_pthread_setspecific_ptr(RPL_MASTER_INFO, mi); - /* Load the set of seen GTIDs, if we did not already. */ if (rpl_load_gtid_slave_state(thd)) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9441e8066c5..8ceefcd1894 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5151,23 +5151,22 @@ void destroy_thd(MYSQL_THD thd) like for example, evaluation of virtual function in innodb purge. */ -extern "C" pthread_key(struct st_my_thread_var *, THR_KEY_mysys); MYSQL_THD create_background_thd() { auto save_thd = current_thd; set_current_thd(nullptr); - auto save_mysysvar= pthread_getspecific(THR_KEY_mysys); + auto save_mysysvar= my_thread_var; /* Allocate new mysys_var specifically new THD, so that e.g safemalloc, DBUG etc are happy. */ - pthread_setspecific(THR_KEY_mysys, 0); + set_mysys_var(nullptr); my_thread_init(); - auto thd_mysysvar= pthread_getspecific(THR_KEY_mysys); + auto thd_mysysvar= my_thread_var; auto thd= new THD(0); - pthread_setspecific(THR_KEY_mysys, save_mysysvar); + set_mysys_var(save_mysysvar); thd->set_psi(nullptr); set_current_thd(save_thd); @@ -5200,8 +5199,8 @@ void *thd_attach_thd(MYSQL_THD thd) DBUG_ASSERT(!current_thd); DBUG_ASSERT(thd && thd->mysys_var); - auto save_mysysvar= pthread_getspecific(THR_KEY_mysys); - pthread_setspecific(THR_KEY_mysys, thd->mysys_var); + auto save_mysysvar= my_thread_var; + set_mysys_var(thd->mysys_var); thd->thread_stack= (char *) &thd; thd->store_globals(); return save_mysysvar; @@ -5214,7 +5213,7 @@ void *thd_attach_thd(MYSQL_THD thd) void thd_detach_thd(void *mysysvar) { /* Restore mysys_var that is changed when THD was attached.*/ - pthread_setspecific(THR_KEY_mysys, mysysvar); + set_mysys_var((st_my_thread_var *)mysysvar); /* Restore the THD (we assume it was NULL during attach).*/ set_current_thd(0); } @@ -5227,7 +5226,7 @@ void destroy_background_thd(MYSQL_THD thd) { DBUG_ASSERT(!current_thd); auto thd_mysys_var= thd->mysys_var; - auto save_mysys_var= thd_attach_thd(thd); + auto save_mysys_var= (st_my_thread_var *)thd_attach_thd(thd); DBUG_ASSERT(thd_mysys_var != save_mysys_var); /* Workaround the adverse effect decrementing thread_count on THD() @@ -5249,9 +5248,9 @@ void destroy_background_thd(MYSQL_THD thd) auto save_psi_thread= PSI_CALL_get_thread(); #endif PSI_CALL_set_thread(0); - pthread_setspecific(THR_KEY_mysys, thd_mysys_var); + set_mysys_var(thd_mysys_var); my_thread_end(); - pthread_setspecific(THR_KEY_mysys, save_mysys_var); + set_mysys_var(save_mysys_var); PSI_CALL_set_thread(save_psi_thread); } diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index ede2c906d5a..831ed1b7f37 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -30,7 +30,6 @@ #include "rpl_rli.h" #include "rpl_mi.h" -extern "C" pthread_key(struct st_my_thread_var*, THR_KEY_mysys); static Wsrep_thd_queue* wsrep_rollback_queue= 0; static Atomic_counter wsrep_bf_aborts_counter; @@ -513,8 +512,8 @@ int wsrep_create_threadvars() { /* Caller should have called wsrep_reset_threadvars() before this method. */ - DBUG_ASSERT(!pthread_getspecific(THR_KEY_mysys)); - pthread_setspecific(THR_KEY_mysys, 0); + DBUG_ASSERT(!my_thread_var); + set_mysys_var(0); ret= my_thread_init(); } return ret; @@ -526,7 +525,7 @@ void wsrep_delete_threadvars() { /* The caller should have called wsrep_store_threadvars() before this method. */ - DBUG_ASSERT(pthread_getspecific(THR_KEY_mysys)); + DBUG_ASSERT(my_thread_var); /* Reset psi state to avoid deallocating applier thread psi_thread. */ #ifdef HAVE_PSI_INTERFACE @@ -538,7 +537,7 @@ void wsrep_delete_threadvars() #endif /* HAVE_PSI_INTERFACE */ my_thread_end(); PSI_CALL_set_thread(psi_thread); - pthread_setspecific(THR_KEY_mysys, 0); + set_mysys_var(0); } } @@ -546,9 +545,7 @@ void wsrep_assign_from_threadvars(THD *thd) { if (thread_handling == SCHEDULER_TYPES_COUNT) { - st_my_thread_var *mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); - DBUG_ASSERT(mysys_var); - thd->set_mysys_var(mysys_var); + thd->set_mysys_var(my_thread_var); } } @@ -556,21 +553,21 @@ Wsrep_threadvars wsrep_save_threadvars() { return Wsrep_threadvars{ current_thd, - (st_my_thread_var*) pthread_getspecific(THR_KEY_mysys) + my_thread_var }; } void wsrep_restore_threadvars(const Wsrep_threadvars& globals) { set_current_thd(globals.cur_thd); - pthread_setspecific(THR_KEY_mysys, globals.mysys_var); + set_mysys_var(globals.mysys_var); } void wsrep_store_threadvars(THD *thd) { if (thread_handling == SCHEDULER_TYPES_COUNT) { - pthread_setspecific(THR_KEY_mysys, thd->mysys_var); + set_mysys_var(thd->mysys_var); } thd->store_globals(); } @@ -579,7 +576,7 @@ void wsrep_reset_threadvars(THD *thd) { if (thread_handling == SCHEDULER_TYPES_COUNT) { - pthread_setspecific(THR_KEY_mysys, 0); + set_mysys_var(0); } else { diff --git a/storage/perfschema/my_thread.h b/storage/perfschema/my_thread.h index c1a079ce34d..78096b26dc5 100644 --- a/storage/perfschema/my_thread.h +++ b/storage/perfschema/my_thread.h @@ -18,7 +18,6 @@ #include #endif -typedef pthread_key_t thread_local_key_t; typedef pthread_t my_thread_handle; typedef pthread_attr_t my_thread_attr_t; #if defined(HAVE_PTHREAD_THREADID_NP) || defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID) || defined(HAVE_GETTHRID) @@ -34,19 +33,6 @@ typedef unsigned long long my_thread_os_id_t; #endif #define LOCK_plugin_delete LOCK_plugin - -static inline int my_create_thread_local_key(thread_local_key_t *key, void (*destructor)(void*)) -{ return pthread_key_create(key, destructor); } - -static inline int my_delete_thread_local_key(thread_local_key_t key) -{ return pthread_key_delete(key); } - -static inline void *my_get_thread_local(thread_local_key_t key) -{ return pthread_getspecific(key); } - -static inline int my_set_thread_local(thread_local_key_t key, const void *ptr) -{ return pthread_setspecific(key, ptr); } - static inline int my_thread_create(my_thread_handle *thread, const my_thread_attr_t *attr, void *(*start_routine)(void *), void *arg) { return pthread_create(thread, attr, start_routine, arg); } diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 1373f9dd43d..1a861b2a1a3 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -1351,24 +1351,22 @@ static inline int mysql_mutex_lock(...) @ingroup Performance_schema_implementation */ -thread_local_key_t THR_PFS; -thread_local_key_t THR_PFS_VG; // global_variables -thread_local_key_t THR_PFS_SV; // session_variables -thread_local_key_t THR_PFS_VBT; // variables_by_thread -thread_local_key_t THR_PFS_SG; // global_status -thread_local_key_t THR_PFS_SS; // session_status -thread_local_key_t THR_PFS_SBT; // status_by_thread -thread_local_key_t THR_PFS_SBU; // status_by_user -thread_local_key_t THR_PFS_SBH; // status_by_host -thread_local_key_t THR_PFS_SBA; // status_by_account +MY_THREAD_LOCAL void* THR_PFS_VG; // global_variables +MY_THREAD_LOCAL void* THR_PFS_SV; // session_variables +MY_THREAD_LOCAL void* THR_PFS_VBT; // variables_by_thread +MY_THREAD_LOCAL void* THR_PFS_SG; // global_status +MY_THREAD_LOCAL void* THR_PFS_SS; // session_status +MY_THREAD_LOCAL void* THR_PFS_SBT; // status_by_thread +MY_THREAD_LOCAL void* THR_PFS_SBU; // status_by_user +MY_THREAD_LOCAL void* THR_PFS_SBH; // status_by_host +MY_THREAD_LOCAL void* THR_PFS_SBA; // status_by_account -bool THR_PFS_initialized= false; +MY_THREAD_LOCAL PFS_thread* THR_PFS; static inline PFS_thread* my_thread_get_THR_PFS() { - assert(THR_PFS_initialized); - PFS_thread *thread= static_cast(my_get_thread_local(THR_PFS)); + PFS_thread *thread= THR_PFS; assert(thread == NULL || sanitize_thread(thread) != NULL); return thread; } @@ -1376,8 +1374,7 @@ my_thread_get_THR_PFS() static inline void my_thread_set_THR_PFS(PFS_thread *pfs) { - assert(THR_PFS_initialized); - my_set_thread_local(THR_PFS, pfs); + THR_PFS= pfs; } /** diff --git a/storage/perfschema/pfs.h b/storage/perfschema/pfs.h index 6e0cf258c91..f41299fc4e8 100644 --- a/storage/perfschema/pfs.h +++ b/storage/perfschema/pfs.h @@ -40,19 +40,18 @@ */ extern struct PSI_bootstrap PFS_bootstrap; /** Performance schema Thread Local Storage key. */ -extern pthread_key_t THR_PFS; -extern pthread_key_t THR_PFS_VG; // global_variables -extern pthread_key_t THR_PFS_SV; // session_variables -extern pthread_key_t THR_PFS_VBT; // variables_by_thread -extern pthread_key_t THR_PFS_SG; // global_status -extern pthread_key_t THR_PFS_SS; // session_status -extern pthread_key_t THR_PFS_SBT; // status_by_thread -extern pthread_key_t THR_PFS_SBU; // status_by_user -extern pthread_key_t THR_PFS_SBA; // status_by_host -extern pthread_key_t THR_PFS_SBH; // status_by_account +struct PFS_thread; -/** True when @c THR_PFS and all other Performance Schema TLS keys are initialized. */ -extern bool THR_PFS_initialized; +extern MY_THREAD_LOCAL PFS_thread* THR_PFS; +extern MY_THREAD_LOCAL void* THR_PFS_VG; // global_variables +extern MY_THREAD_LOCAL void* THR_PFS_SV; // session_variables +extern MY_THREAD_LOCAL void* THR_PFS_VBT; // variables_by_thread +extern MY_THREAD_LOCAL void* THR_PFS_SG; // global_status +extern MY_THREAD_LOCAL void* THR_PFS_SS; // session_status +extern MY_THREAD_LOCAL void* THR_PFS_SBT; // status_by_thread +extern MY_THREAD_LOCAL void* THR_PFS_SBU; // status_by_user +extern MY_THREAD_LOCAL void* THR_PFS_SBA; // status_by_host +extern MY_THREAD_LOCAL void* THR_PFS_SBH; // status_by_account #define PSI_VOLATILITY_UNKNOWN 0 #define PSI_VOLATILITY_SESSION 1 diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index 6a73f75f582..fbb5875f359 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -146,7 +146,7 @@ bool PFS_table_context::initialize(void) if (m_restore) { /* Restore context from TLS. */ - PFS_table_context *context= static_cast(my_get_thread_local(m_thr_key)); + PFS_table_context *context= static_cast(*m_thr_varptr); assert(context != NULL); if(context) @@ -160,7 +160,7 @@ bool PFS_table_context::initialize(void) else { /* Check that TLS is not in use. */ - PFS_table_context *context= static_cast(my_get_thread_local(m_thr_key)); + PFS_table_context *context= static_cast(*m_thr_varptr); //assert(context == NULL); context= this; @@ -178,7 +178,7 @@ bool PFS_table_context::initialize(void) } /* Write to TLS. */ - my_set_thread_local(m_thr_key, static_cast(context)); + *m_thr_varptr=static_cast(context); } m_initialized= (m_map_size > 0) ? (m_map != NULL) : true; @@ -187,8 +187,8 @@ bool PFS_table_context::initialize(void) } /* Constructor for global or single thread tables, map size = 0. */ -PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, thread_local_key_t key) : - m_thr_key(key), m_current_version(current_version), m_last_version(0), +PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, void** thr_var_ptr) : + m_thr_varptr(thr_var_ptr), m_current_version(current_version), m_last_version(0), m_map(NULL), m_map_size(0), m_restore(restore), m_initialized(false), m_last_item(0) { @@ -196,8 +196,8 @@ PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, th } /* Constructor for by-thread or aggregate tables, map size = max thread/user/host/account. */ -PFS_table_context::PFS_table_context(ulonglong current_version, ulong map_size, bool restore, thread_local_key_t key) : - m_thr_key(key), m_current_version(current_version), m_last_version(0), +PFS_table_context::PFS_table_context(ulonglong current_version, ulong map_size, bool restore, void** thr_var_ptr) : + m_thr_varptr(thr_var_ptr), m_current_version(current_version), m_last_version(0), m_map(NULL), m_map_size(map_size), m_restore(restore), m_initialized(false), m_last_item(0) { diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h index 389d9a56480..a2cc0ea0463 100644 --- a/storage/perfschema/pfs_engine_table.h +++ b/storage/perfschema/pfs_engine_table.h @@ -47,15 +47,7 @@ using PFS_ident_table = Lex_ident_i_s_table; */ #include "pfs_instr_class.h" -extern pthread_key_t THR_PFS_VG; // global_variables -extern pthread_key_t THR_PFS_SV; // session_variables -extern pthread_key_t THR_PFS_VBT; // variables_by_thread -extern pthread_key_t THR_PFS_SG; // global_status -extern pthread_key_t THR_PFS_SS; // session_status -extern pthread_key_t THR_PFS_SBT; // status_by_thread -extern pthread_key_t THR_PFS_SBU; // status_by_user -extern pthread_key_t THR_PFS_SBH; // status_by_host -extern pthread_key_t THR_PFS_SBA; // status_by_account +#include "pfs.h" class Field; struct PFS_engine_table_share; @@ -72,8 +64,8 @@ struct time_normalizer; class PFS_table_context { public: - PFS_table_context(ulonglong current_version, bool restore, pthread_key_t key); - PFS_table_context(ulonglong current_version, ulong map_size, bool restore, pthread_key_t key); + PFS_table_context(ulonglong current_version, bool restore, void** thr_var_ptr); + PFS_table_context(ulonglong current_version, ulong map_size, bool restore, void** thr_var_ptr); ~PFS_table_context(void); bool initialize(void); @@ -83,7 +75,7 @@ public: bool versions_match(void) { return m_last_version == m_current_version; } void set_item(ulong n); bool is_item_set(ulong n); - pthread_key_t m_thr_key; + void** m_thr_varptr; private: ulonglong m_current_version; diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index f08d1a25174..07457b7f427 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -434,7 +434,7 @@ void destroy_cond(PFS_cond *pfs) PFS_thread* PFS_thread::get_current_thread() { - return static_cast(my_get_thread_local(THR_PFS)); + return THR_PFS; } void PFS_thread::reset_session_connect_attrs() diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc index d5402547148..2a691a8f3bb 100644 --- a/storage/perfschema/pfs_server.cc +++ b/storage/perfschema/pfs_server.cc @@ -54,10 +54,6 @@ PFS_global_param pfs_param; PFS_table_stat PFS_table_stat::g_reset_template; -C_MODE_START -static void destroy_pfs_thread(void *key); -C_MODE_END - static void cleanup_performance_schema(void); void cleanup_instrument_config(void); @@ -71,40 +67,11 @@ void pre_initialize_performance_schema() global_idle_stat.reset(); global_table_io_stat.reset(); global_table_lock_stat.reset(); - - if (my_create_thread_local_key(&THR_PFS, destroy_pfs_thread)) - return; - if (my_create_thread_local_key(&THR_PFS_VG, NULL)) // global_variables - return; - if (my_create_thread_local_key(&THR_PFS_SV, NULL)) // session_variables - return; - if (my_create_thread_local_key(&THR_PFS_VBT, NULL)) // variables_by_thread - return; - if (my_create_thread_local_key(&THR_PFS_SG, NULL)) // global_status - return; - if (my_create_thread_local_key(&THR_PFS_SS, NULL)) // session_status - return; - if (my_create_thread_local_key(&THR_PFS_SBT, NULL)) // status_by_thread - return; - if (my_create_thread_local_key(&THR_PFS_SBU, NULL)) // status_by_user - return; - if (my_create_thread_local_key(&THR_PFS_SBH, NULL)) // status_by_host - return; - if (my_create_thread_local_key(&THR_PFS_SBA, NULL)) // status_by_account - return; - - THR_PFS_initialized= true; } struct PSI_bootstrap* initialize_performance_schema(PFS_global_param *param) { - if (!THR_PFS_initialized) - { - /* Pre-initialization failed. */ - return NULL; - } - pfs_enabled= param->m_enabled; pfs_automated_sizing(param); @@ -208,24 +175,6 @@ initialize_performance_schema(PFS_global_param *param) return NULL; } -static void destroy_pfs_thread(void *key) -{ - PFS_thread* pfs= reinterpret_cast (key); - assert(pfs); - /* - This automatic cleanup is a last resort and best effort to avoid leaks, - and may not work on windows due to the implementation of pthread_key_create(). - Please either use: - - my_thread_end() - - or PSI_server->delete_current_thread() - in the instrumented code, to explicitly cleanup the instrumentation. - - Avoid invalid writes when the main() thread completes after shutdown: - the memory pointed by pfs is already released. - */ - if (pfs_initialized) - destroy_thread(pfs); -} static void cleanup_performance_schema(void) { @@ -324,36 +273,16 @@ void shutdown_performance_schema(void) global_transaction_class.m_enabled= false; cleanup_performance_schema(); - /* - Be careful to not delete un-initialized keys, - this would affect key 0, which is THR_KEY_mysys, - */ - if (THR_PFS_initialized) - { - my_set_thread_local(THR_PFS, NULL); - my_set_thread_local(THR_PFS_VG, NULL); // global_variables - my_set_thread_local(THR_PFS_SV, NULL); // session_variables - my_set_thread_local(THR_PFS_VBT, NULL); // variables_by_thread - my_set_thread_local(THR_PFS_SG, NULL); // global_status - my_set_thread_local(THR_PFS_SS, NULL); // session_status - my_set_thread_local(THR_PFS_SBT, NULL); // status_by_thread - my_set_thread_local(THR_PFS_SBU, NULL); // status_by_user - my_set_thread_local(THR_PFS_SBH, NULL); // status_by_host - my_set_thread_local(THR_PFS_SBA, NULL); // status_by_account - - my_delete_thread_local_key(THR_PFS); - my_delete_thread_local_key(THR_PFS_VG); - my_delete_thread_local_key(THR_PFS_SV); - my_delete_thread_local_key(THR_PFS_VBT); - my_delete_thread_local_key(THR_PFS_SG); - my_delete_thread_local_key(THR_PFS_SS); - my_delete_thread_local_key(THR_PFS_SBT); - my_delete_thread_local_key(THR_PFS_SBU); - my_delete_thread_local_key(THR_PFS_SBH); - my_delete_thread_local_key(THR_PFS_SBA); - - THR_PFS_initialized= false; - } + THR_PFS= NULL; + THR_PFS_VG= NULL; // global_variables + THR_PFS_SV= NULL; // session_variables + THR_PFS_VBT= NULL; // variables_by_thread + THR_PFS_SG= NULL; // global_status + THR_PFS_SS= NULL; // session_status + THR_PFS_SBT= NULL; // status_by_thread + THR_PFS_SBU= NULL; // status_by_user + THR_PFS_SBH= NULL; // status_by_host + THR_PFS_SBA= NULL; // status_by_account } /** diff --git a/storage/perfschema/table_global_status.h b/storage/perfschema/table_global_status.h index 5b5f6e60c37..b0d5e53b9da 100644 --- a/storage/perfschema/table_global_status.h +++ b/storage/perfschema/table_global_status.h @@ -59,7 +59,7 @@ class table_global_status_context : public PFS_table_context { public: table_global_status_context(ulonglong current_version, bool restore) : - PFS_table_context(current_version, restore, THR_PFS_SG) { } + PFS_table_context(current_version, restore, &THR_PFS_SG) { } }; /** Table PERFORMANCE_SCHEMA.GLOBAL_STATUS. */ diff --git a/storage/perfschema/table_global_variables.h b/storage/perfschema/table_global_variables.h index 49083e63292..44c12637a2f 100644 --- a/storage/perfschema/table_global_variables.h +++ b/storage/perfschema/table_global_variables.h @@ -47,7 +47,7 @@ class table_global_variables_context : public PFS_table_context { public: table_global_variables_context(ulonglong hash_version, bool restore) : - PFS_table_context(hash_version, restore, THR_PFS_VG) {} + PFS_table_context(hash_version, restore, &THR_PFS_VG) {} }; /** diff --git a/storage/perfschema/table_session_status.h b/storage/perfschema/table_session_status.h index 0b3e16c6011..1eed6812a40 100644 --- a/storage/perfschema/table_session_status.h +++ b/storage/perfschema/table_session_status.h @@ -61,7 +61,7 @@ class table_session_status_context : public PFS_table_context { public: table_session_status_context(ulonglong current_version, bool restore) : - PFS_table_context(current_version, restore, THR_PFS_SS) { } + PFS_table_context(current_version, restore, &THR_PFS_SS) { } }; /** Table PERFORMANCE_SCHEMA.SESSION_STATUS. */ diff --git a/storage/perfschema/table_session_variables.h b/storage/perfschema/table_session_variables.h index f46d9967e5c..c6679b36fd4 100644 --- a/storage/perfschema/table_session_variables.h +++ b/storage/perfschema/table_session_variables.h @@ -47,7 +47,7 @@ class table_session_variables_context : public PFS_table_context { public: table_session_variables_context(ulonglong hash_version, bool restore) : - PFS_table_context(hash_version, restore, THR_PFS_SV) {} + PFS_table_context(hash_version, restore, &THR_PFS_SV) {} }; /** diff --git a/storage/perfschema/table_status_by_account.h b/storage/perfschema/table_status_by_account.h index c8d270c5926..a9e26228365 100644 --- a/storage/perfschema/table_status_by_account.h +++ b/storage/perfschema/table_status_by_account.h @@ -95,7 +95,7 @@ class table_status_by_account_context : public PFS_table_context { public: table_status_by_account_context(ulonglong current_version, bool restore) : - PFS_table_context(current_version, global_account_container.get_row_count(), restore, THR_PFS_SBH) { } + PFS_table_context(current_version, global_account_container.get_row_count(), restore, &THR_PFS_SBH) { } }; /** Table PERFORMANCE_SCHEMA.STATUS_BY_ACCOUNT. */ diff --git a/storage/perfschema/table_status_by_host.h b/storage/perfschema/table_status_by_host.h index 4e28966c016..5c9955fd85d 100644 --- a/storage/perfschema/table_status_by_host.h +++ b/storage/perfschema/table_status_by_host.h @@ -93,7 +93,7 @@ class table_status_by_host_context : public PFS_table_context { public: table_status_by_host_context(ulonglong current_version, bool restore) : - PFS_table_context(current_version, global_host_container.get_row_count(), restore, THR_PFS_SBH) { } + PFS_table_context(current_version, global_host_container.get_row_count(), restore, &THR_PFS_SBH) { } }; /** Table PERFORMANCE_SCHEMA.STATUS_BY_HOST. */ diff --git a/storage/perfschema/table_status_by_thread.h b/storage/perfschema/table_status_by_thread.h index 770490438f1..abd555e859f 100644 --- a/storage/perfschema/table_status_by_thread.h +++ b/storage/perfschema/table_status_by_thread.h @@ -91,7 +91,7 @@ class table_status_by_thread_context : public PFS_table_context { public: table_status_by_thread_context(ulonglong current_version, bool restore) : - PFS_table_context(current_version, global_thread_container.get_row_count(), restore, THR_PFS_SBT) { } + PFS_table_context(current_version, global_thread_container.get_row_count(), restore, &THR_PFS_SBT) { } }; /** Table PERFORMANCE_SCHEMA.STATUS_BY_THREAD. */ diff --git a/storage/perfschema/table_status_by_user.h b/storage/perfschema/table_status_by_user.h index 1954b15d820..f0798cecc7f 100644 --- a/storage/perfschema/table_status_by_user.h +++ b/storage/perfschema/table_status_by_user.h @@ -93,7 +93,7 @@ class table_status_by_user_context : public PFS_table_context { public: table_status_by_user_context(ulonglong current_version, bool restore) : - PFS_table_context(current_version, global_user_container.get_row_count(), restore, THR_PFS_SBU) { } + PFS_table_context(current_version, global_user_container.get_row_count(), restore, &THR_PFS_SBU) { } }; /** Table PERFORMANCE_SCHEMA.STATUS_BY_USER. */ diff --git a/storage/perfschema/table_variables_by_thread.h b/storage/perfschema/table_variables_by_thread.h index 99adcda4e98..c58baeaa139 100644 --- a/storage/perfschema/table_variables_by_thread.h +++ b/storage/perfschema/table_variables_by_thread.h @@ -92,7 +92,7 @@ class table_variables_by_thread_context : public PFS_table_context { public: table_variables_by_thread_context(ulonglong hash_version, bool restore) : - PFS_table_context(hash_version, global_thread_container.get_row_count(), restore, THR_PFS_VBT) { } + PFS_table_context(hash_version, global_thread_container.get_row_count(), restore, &THR_PFS_VBT) { } }; /** Table PERFORMANCE_SCHEMA.VARIABLES_BY_THREAD. */