Created
March 3, 2020 12:41
-
-
Save kevgs/d34ba2edb21b8b44ba707fe7cb747f87 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 2f1a5232e4bb97412ca726ce70e104786eff7064 | |
Author: Eugene Kosov <[email protected]> | |
Date: Wed Jan 8 00:35:02 2020 +0700 | |
let newer compilers use native thread local storage | |
This should not affect old compilers at all. | |
But newer ones can use thread_local from C++11 and _Thread_local from C11. | |
Native TLS is faster than library pthreads implementation. | |
So, this is just a performance optimization, no functional changes are intended. | |
In my environment speed up looks like this: | |
main.select [ pass ] 1978 | |
main.select [ pass ] 1927 | |
main.select [ pass ] 1931 | |
main.select [ pass ] 1929 | |
main.select [ pass ] 1928 | |
main.select [ pass ] 1926 | |
main.select [ pass ] 1938 | |
main.select [ pass ] 1931 | |
main.select [ pass ] 1928 | |
main.select [ pass ] 1929 | |
main.select [ pass ] 1936 | |
main.select [ pass ] 1940 | |
main.select [ pass ] 1935 | |
main.select [ pass ] 1937 | |
main.select [ pass ] 1933 | |
main.select [ pass ] 1939 | |
main.select [ pass ] 1940 | |
main.select [ pass ] 1963 | |
main.select [ pass ] 1932 | |
main.select [ pass ] 1951 | |
-------------------------------------------------------------------------- | |
The servers were restarted 0 times | |
Spent 38.751 of 45 seconds executing testcases | |
Completed: All 20 tests were successful. | |
./mtr -mem main.select -repe=20 39.40s user 3.60s system 95% cpu 45.233 total | |
main.select [ pass ] 1828 | |
main.select [ pass ] 1766 | |
main.select [ pass ] 1837 | |
main.select [ pass ] 1810 | |
main.select [ pass ] 1795 | |
main.select [ pass ] 1780 | |
main.select [ pass ] 1779 | |
main.select [ pass ] 1784 | |
main.select [ pass ] 1763 | |
main.select [ pass ] 1777 | |
main.select [ pass ] 1762 | |
main.select [ pass ] 1781 | |
main.select [ pass ] 1772 | |
main.select [ pass ] 1768 | |
main.select [ pass ] 1774 | |
main.select [ pass ] 1762 | |
main.select [ pass ] 1755 | |
main.select [ pass ] 1772 | |
main.select [ pass ] 1747 | |
main.select [ pass ] 1746 | |
-------------------------------------------------------------------------- | |
The servers were restarted 0 times | |
Spent 35.558 of 41 seconds executing testcases | |
Completed: All 20 tests were successful. | |
./mtr -mem main.select -repe=20 35.45s user 3.78s system 94% cpu 41.336 total | |
diff --git a/include/my_pthread.h b/include/my_pthread.h | |
index 2b3f4f14ea3..5138891dd9e 100644 | |
--- a/include/my_pthread.h | |
+++ b/include/my_pthread.h | |
@@ -160,9 +160,48 @@ int pthread_cancel(pthread_t thread); | |
#include <synch.h> | |
#endif | |
+#if __STDC_VERSION__ >= 201112L | |
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ | |
+ ((__GNUC__ * 100) + __GNUC_MINOR__) >= 409 | |
+#define THREAD_LOCAL_SUPPORTED | |
+#endif | |
+ | |
+#if defined(__clang__) | |
+#define THREAD_LOCAL_SUPPORTED | |
+#endif | |
+#endif | |
+ | |
+#if __cplusplus >= 201103L | |
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ | |
+ ((__GNUC__ * 100) + __GNUC_MINOR__) >= 408 | |
+#define THREAD_LOCAL_SUPPORTED | |
+#endif | |
+ | |
+#if defined(__clang__) | |
+#define THREAD_LOCAL_SUPPORTED | |
+#endif | |
+#endif | |
+ | |
+ | |
+#ifdef THREAD_LOCAL_SUPPORTED | |
+#ifdef __cplusplus | |
+#define pthread_key(T, V) thread_local T V; | |
+#else | |
+#define pthread_key(T, V) _Thread_local T V; | |
+#endif | |
+#define my_pthread_getspecific_ptr(T,V) V | |
+#define my_pthread_setspecific_ptr(T, V) \ | |
+ T= V, 0 /* expression value is 0 due to comma hack */ | |
+#define pthread_getspecific(T) T | |
+#define pthread_setspecific(T,V) T = V | |
+#define pthread_key_create(A, B) 0 | |
+#define mypthread_key_create(A, B) 0 | |
+#define pthread_key_delete(A) 0 | |
+#else | |
#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)) | |
+#endif | |
#define pthread_detach_this_thread() | |
#define pthread_handler_t EXTERNC void * | |
typedef void *(* pthread_handler)(void *); | |
@@ -228,7 +267,11 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ | |
#undef HAVE_GETHOSTBYADDR_R /* No definition */ | |
#endif | |
+#ifdef THREAD_LOCAL_SUPPORTED | |
+#define my_pthread_getspecific(A,B) (B) | |
+#else | |
#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) | |
+#endif | |
#ifndef HAVE_LOCALTIME_R | |
struct tm *localtime_r(const time_t *clock, struct tm *res); | |
@@ -734,6 +777,7 @@ extern void **my_thread_var_dbug(void); | |
extern safe_mutex_t **my_thread_var_mutex_in_use(void); | |
extern uint my_thread_end_wait_time; | |
extern my_bool safe_mutex_deadlock_detector; | |
+extern int set_mysys_var(struct st_my_thread_var *mysys_var); | |
#define my_thread_var (_my_thread_var()) | |
#define my_errno my_thread_var->thr_errno | |
/* | |
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc | |
index 0a374147e07..b0438770aae 100644 | |
--- a/sql/threadpool_common.cc | |
+++ b/sql/threadpool_common.cc | |
@@ -45,7 +45,6 @@ static void threadpool_remove_connection(THD *thd); | |
static int threadpool_process_request(THD *thd); | |
static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data); | |
-extern "C" pthread_key(struct st_my_thread_var*, THR_KEY_mysys); | |
extern bool do_command(THD*); | |
static inline TP_connection *get_TP_connection(THD *thd) | |
@@ -87,7 +86,7 @@ struct Worker_thread_context | |
#ifdef HAVE_PSI_THREAD_INTERFACE | |
psi_thread = PSI_THREAD_CALL(get_thread)(); | |
#endif | |
- mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); | |
+ mysys_var= my_thread_var; | |
} | |
void restore() | |
@@ -95,7 +94,7 @@ struct Worker_thread_context | |
#ifdef HAVE_PSI_THREAD_INTERFACE | |
PSI_THREAD_CALL(set_thread)(psi_thread); | |
#endif | |
- pthread_setspecific(THR_KEY_mysys,mysys_var); | |
+ set_mysys_var(mysys_var); | |
pthread_setspecific(THR_THD, 0); | |
} | |
}; | |
@@ -141,7 +140,7 @@ static inline void set_thd_idle(THD *thd) | |
*/ | |
static void thread_attach(THD* thd) | |
{ | |
- pthread_setspecific(THR_KEY_mysys,thd->mysys_var); | |
+ set_mysys_var(thd->mysys_var); | |
thd->thread_stack=(char*)&thd; | |
thd->store_globals(); | |
#ifdef HAVE_PSI_THREAD_INTERFACE | |
@@ -228,9 +227,9 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data) | |
Store them in THD. | |
*/ | |
- pthread_setspecific(THR_KEY_mysys, 0); | |
+ set_mysys_var(NULL); | |
my_thread_init(); | |
- st_my_thread_var* mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); | |
+ st_my_thread_var* mysys_var= my_thread_var; | |
if (!mysys_var ||!(thd= connect->create_thd(NULL))) | |
{ | |
/* Out of memory? */ | |
diff --git a/storage/perfschema/pfs.h b/storage/perfschema/pfs.h | |
index 8e0d9b760ed..55e0b37eeef 100644 | |
--- a/storage/perfschema/pfs.h | |
+++ b/storage/perfschema/pfs.h | |
@@ -40,6 +40,7 @@ | |
*/ | |
extern struct PSI_bootstrap PFS_bootstrap; | |
/** Performance schema Thread Local Storage key. */ | |
+struct PFS_thread; | |
extern pthread_key(PFS_thread*, THR_PFS); | |
/** True when @c THR_PFS is initialized. */ | |
extern bool THR_PFS_initialized; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment