Skip to content

Instantly share code, notes, and snippets.

@kevgs
Created March 3, 2020 12:41
Show Gist options
  • Save kevgs/d34ba2edb21b8b44ba707fe7cb747f87 to your computer and use it in GitHub Desktop.
Save kevgs/d34ba2edb21b8b44ba707fe7cb747f87 to your computer and use it in GitHub Desktop.
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