mirror of
https://github.com/MariaDB/server.git
synced 2026-05-17 12:27:33 +02:00
MDEV-33748 get rid of pthread_(get_/set_)specific, use thread_local
Apart from better performance when accessing thread local variables, we'll get rid of things that depend on initialization/cleanup of pthread_key_t variables. Where appropriate, use compiler-dependent pre-C++11 thread-local equivalents, where it makes sense, to avoid initialization check overhead that non-static thread_local can suffer from.
This commit is contained in:
parent
68fed7e785
commit
7c5fdc9b6a
26 changed files with 95 additions and 236 deletions
|
|
@ -18,7 +18,6 @@
|
|||
#include <cstdint>
|
||||
#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); }
|
||||
|
|
|
|||
|
|
@ -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<PFS_thread*>(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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ bool PFS_table_context::initialize(void)
|
|||
if (m_restore)
|
||||
{
|
||||
/* Restore context from TLS. */
|
||||
PFS_table_context *context= static_cast<PFS_table_context *>(my_get_thread_local(m_thr_key));
|
||||
PFS_table_context *context= static_cast<PFS_table_context *>(*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<PFS_table_context *>(my_get_thread_local(m_thr_key));
|
||||
PFS_table_context *context= static_cast<PFS_table_context *>(*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<void *>(context));
|
||||
*m_thr_varptr=static_cast<void *>(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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ void destroy_cond(PFS_cond *pfs)
|
|||
|
||||
PFS_thread* PFS_thread::get_current_thread()
|
||||
{
|
||||
return static_cast<PFS_thread*>(my_get_thread_local(THR_PFS));
|
||||
return THR_PFS;
|
||||
}
|
||||
|
||||
void PFS_thread::reset_session_connect_attrs()
|
||||
|
|
|
|||
|
|
@ -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<PFS_thread*> (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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue