diff options
author | Lennart Poettering <lennart@poettering.net> | 2007-09-10 23:57:10 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2007-09-10 23:57:10 +0000 |
commit | 9b0ab39b1c443744bb7b09b03e62e51d78aab527 (patch) | |
tree | 8effaaa2c5359af33e64d0e764739904a46c358f | |
parent | 3d122d0fee2e3d853ea1a1de297b249f2c125f73 (diff) |
unify static TLS support, make use of gcc __thread attribute if available
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1797 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | src/daemon/main.c | 6 | ||||
-rw-r--r-- | src/pulsecore/atomic.h | 2 | ||||
-rw-r--r-- | src/pulsecore/rtsig.c | 4 | ||||
-rw-r--r-- | src/pulsecore/thread-mq.c | 14 | ||||
-rw-r--r-- | src/pulsecore/thread-posix.c | 18 | ||||
-rw-r--r-- | src/pulsecore/thread.h | 35 |
7 files changed, 59 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac index c4f26c4e..7c8f3888 100644 --- a/configure.ac +++ b/configure.ac @@ -118,6 +118,18 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([whether $CC knows __thread]) +AC_LANG_CONFTEST([static __thread int a = 6; int main() { a = 5; }]) +$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null +ret=$? +rm -f conftest.o conftest +if test $ret -eq 0 ; then + AC_DEFINE([HAVE_TLS_BUILTIN], 1, [Have __thread().]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + #### libtool stuff #### AC_LTDL_ENABLE_INSTALL diff --git a/src/daemon/main.c b/src/daemon/main.c index 135a9ab6..ed5aa440 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -324,14 +324,14 @@ static void libtool_unlock(void) { pa_mutex_unlock(libtool_mutex); } -PA_STATIC_TLS_DECLARE(libtool_tls, NULL); +PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls); static void libtool_set_error(const char * error) { - pa_tls_set(PA_STATIC_TLS_GET(libtool_tls), (char*) error); + PA_STATIC_TLS_SET(libtool_tls, (char*) error); } static const char *libtool_get_error(void) { - return pa_tls_get(PA_STATIC_TLS_GET(libtool_tls)); + return PA_STATIC_TLS_GET(libtool_tls); } static void libtool_init(void) { diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 6fb85f09..0e3bfb9a 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -37,7 +37,7 @@ * libatomic_ops */ -/* We have to include config.h here, which sucks */ +/* We have to include config.h here (for the __sync stuff), which sucks */ #ifdef HAVE_CONFIG_H #include <config.h> #endif diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index a3226a0e..3513bedf 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -71,13 +71,13 @@ int pa_rtsig_get_for_thread(void) { int sig; void *p; - if ((p = pa_tls_get(PA_STATIC_TLS_GET(rtsig_tls)))) + if ((p = PA_STATIC_TLS_GET(rtsig_tls))) return PA_PTR_TO_INT(p); if ((sig = pa_rtsig_get()) < 0) return -1; - pa_tls_set(PA_STATIC_TLS_GET(rtsig_tls), PA_INT_TO_PTR(sig)); + PA_STATIC_TLS_SET(rtsig_tls, PA_INT_TO_PTR(sig)); return sig; } diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c index 3c466ceb..3000246a 100644 --- a/src/pulsecore/thread-mq.c +++ b/src/pulsecore/thread-mq.c @@ -41,8 +41,7 @@ #include "thread-mq.h" -static pa_once once = PA_ONCE_INIT; -static pa_tls *tls; +PA_STATIC_TLS_DECLARE_NO_FREE(thread_mq); static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { pa_thread_mq *q = userdata; @@ -101,20 +100,15 @@ void pa_thread_mq_done(pa_thread_mq *q) { q->mainloop = NULL; } -static void init_tls(void) { - tls = pa_tls_new(NULL); -} - void pa_thread_mq_install(pa_thread_mq *q) { pa_assert(q); - pa_run_once(&once, init_tls); - pa_tls_set(tls, q); + pa_assert(!(PA_STATIC_TLS_GET(thread_mq))); + PA_STATIC_TLS_SET(thread_mq, q); } pa_thread_mq *pa_thread_mq_get(void) { - pa_run_once(&once, init_tls); - return pa_tls_get(tls); + return PA_STATIC_TLS_GET(thread_mq); } int pa_thread_mq_process(pa_thread_mq *q) { diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 6ad5ac4a..3c69adfb 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -49,9 +49,6 @@ struct pa_tls { pthread_key_t key; }; -static pthread_key_t thread_key; -static pthread_once_t thread_once = PTHREAD_ONCE_INIT; - static void thread_free_cb(void *p) { pa_thread *t = p; @@ -62,9 +59,7 @@ static void thread_free_cb(void *p) { pa_xfree(t); } -static void thread_once_func(void) { - pa_assert_se(pthread_key_create(&thread_key, thread_free_cb) == 0); -} +PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb); static void* internal_thread_func(void *userdata) { pa_thread *t = userdata; @@ -72,8 +67,7 @@ static void* internal_thread_func(void *userdata) { t->id = pthread_self(); - pthread_once(&thread_once, thread_once_func); - pthread_setspecific(thread_key, t); + PA_STATIC_TLS_SET(current_thread, t); pa_atomic_inc(&t->running); t->thread_func(t->userdata); @@ -130,11 +124,9 @@ int pa_thread_join(pa_thread *t) { pa_thread* pa_thread_self(void) { pa_thread *t; - pthread_once(&thread_once, thread_once_func); - - if ((t = pthread_getspecific(thread_key))) + if ((t = PA_STATIC_TLS_GET(current_thread))) return t; - + /* This is a foreign thread, let's create a pthread structure to * make sure that we can always return a sensible pointer */ @@ -144,7 +136,7 @@ pa_thread* pa_thread_self(void) { t->userdata = NULL; pa_atomic_store(&t->running, 2); - pthread_setspecific(thread_key, t); + PA_STATIC_TLS_SET(current_thread, t); return t; } diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index 44b80a06..a0e331be 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -26,6 +26,12 @@ ***/ #include <pulse/def.h> +#include <pulsecore/once.h> + +/* We have to include config.h here (for the __tls stuff), which sucks */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif typedef struct pa_thread pa_thread; @@ -48,8 +54,6 @@ void pa_tls_free(pa_tls *t); void * pa_tls_get(pa_tls *t); void *pa_tls_set(pa_tls *t, void *userdata); -/* To make use of the static TLS stuff you have to include once.h, as well */ - #define PA_STATIC_TLS_DECLARE(name, free_cb) \ static struct { \ pa_once once; \ @@ -61,7 +65,7 @@ void *pa_tls_set(pa_tls *t, void *userdata); static void name##_tls_init(void) { \ name##_tls.tls = pa_tls_new(free_cb); \ } \ - static inline pa_tls* name##_tls_get(void) { \ + static inline pa_tls* name##_tls_obj(void) { \ pa_run_once(&name##_tls.once, name##_tls_init); \ return name##_tls.tls; \ } \ @@ -70,8 +74,33 @@ void *pa_tls_set(pa_tls *t, void *userdata); if (name##_tls.tls) \ pa_tls_free(name##_tls.tls); \ } \ + static inline void* name##_tls_get(void) { \ + return pa_tls_get(name##_tls_obj()); \ + } \ + static inline void* name##_tls_set(void *p) { \ + return pa_tls_set(name##_tls_obj(), p); \ + } \ struct __stupid_useless_struct_to_allow_trailing_semicolon +#ifdef HAVE_TLS_BUILTIN +/* An optimized version of the above that requires no dynamic + * allocation if the compiler supports __thread */ +#define PA_STATIC_TLS_DECLARE_NO_FREE(name) \ + static __thread void *name##_tls; \ + static inline void* name##_tls_get(void) { \ + return name##_tls; \ + } \ + static inline void* name##_tls_set(void *p) { \ + void *r = name##_tls; \ + name##_tls = p; \ + return r; \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon +#else +#define PA_STATIC_TLS_DECLARE_NO_FREE(name) PA_STATIC_TLS_DECLARE(name, NULL) +#endif + #define PA_STATIC_TLS_GET(name) (name##_tls_get()) +#define PA_STATIC_TLS_SET(name, p) (name##_tls_set(p)) #endif |