mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-06 13:29:56 -05:00
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
This commit is contained in:
parent
3d122d0fee
commit
9b0ab39b1c
7 changed files with 59 additions and 32 deletions
12
configure.ac
12
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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,9 +124,7 @@ 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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue