Module: xenomai-forge
Branch: master
Commit: 714a2447c9c79d4cc27296d0ea0d590ae7f17454
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=714a2447c9c79d4cc27296d0ea0d590ae7f17454

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Dec  2 19:28:01 2011 +0100

copperplate/threadobj: use TLS for current thread control block

Enable TLS on powerpc builds by default (Yes, we do expect recent and
sane compilers to be used). Otherwise, user can still fallback to
--without-__thread at configuration time.

---

 configure                          |    1 +
 configure.in                       |    1 +
 include/copperplate/threadobj.h    |   38 +++++++++++++++++++++++++++++------
 lib/copperplate/threadobj.c        |   32 +++++++++++++++++++++++------
 lib/copperplate/timerobj-cobalt.c  |    2 +-
 lib/copperplate/timerobj-mercury.c |    2 +-
 6 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/configure b/configure
index 89ca174..36b61ed 100755
--- a/configure
+++ b/configure
@@ -5170,6 +5170,7 @@ case "$build_for" in
        CONFIG_XENO_DEFAULT_PERIOD=100000
        ;;
  ppc-*|powerpc-*|powerpc64-*|ppc64-*)
+       use__thread=yes
        XENO_TARGET_ARCH=powerpc
        CONFIG_XENO_DEFAULT_PERIOD=100000
        ;;
diff --git a/configure.in b/configure.in
index 2ba0e18..de7664e 100644
--- a/configure.in
+++ b/configure.in
@@ -97,6 +97,7 @@ case "$build_for" in
        CONFIG_XENO_DEFAULT_PERIOD=100000
        ;;
  ppc-*|powerpc-*|powerpc64-*|ppc64-*)
+       use__thread=yes
        XENO_TARGET_ARCH=powerpc
        CONFIG_XENO_DEFAULT_PERIOD=100000
        ;;
diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h
index c580a3f..f18f4e4 100644
--- a/include/copperplate/threadobj.h
+++ b/include/copperplate/threadobj.h
@@ -151,12 +151,41 @@ struct threadobj_init_data {
        void (*suspend_hook)(struct threadobj *thobj, int status);
 };
 
-extern pthread_key_t threadobj_tskey;
-
 extern int threadobj_high_prio;
 
 extern int threadobj_irq_prio;
 
+#ifdef HAVE___THREAD
+
+extern __thread __attribute__ ((tls_model ("initial-exec")))
+struct threadobj *__threadobj_current;
+
+static inline void threadobj_set_current(struct threadobj *thobj)
+{
+       __threadobj_current = thobj;
+}
+
+static inline struct threadobj *threadobj_current(void)
+{
+       return __threadobj_current;
+}
+
+#else /* !HAVE___THREAD */
+
+extern pthread_key_t threadobj_tskey;
+
+static inline void threadobj_set_current(struct threadobj *thobj)
+{
+       pthread_setspecific(threadobj_tskey, thobj);
+}
+
+static inline struct threadobj *threadobj_current(void)
+{
+       return pthread_getspecific(threadobj_tskey);
+}
+
+#endif /* !HAVE___THREAD */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -266,11 +295,6 @@ static inline int threadobj_unlock(struct threadobj *thobj)
        return write_unlock_safe(&thobj->lock, thobj->cancel_state);
 }
 
-static inline struct threadobj *threadobj_current(void)
-{
-       return pthread_getspecific(threadobj_tskey);
-}
-
 static inline int threadobj_irq_p(void)
 {
        struct threadobj *current = threadobj_current();
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index 75334ad..15e1c1b 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -57,8 +57,6 @@ static void threadobj_finalize(void *p);
  * returning from threadobj_cancel().
  */
 
-pthread_key_t threadobj_tskey;
-
 int threadobj_high_prio;
 
 int threadobj_irq_prio;
@@ -73,6 +71,27 @@ static struct timespec global_quantum;
 
 static void cancel_sync(struct threadobj *thobj);
 
+#ifdef HAVE___THREAD
+
+__thread __attribute__ ((tls_model ("initial-exec")))
+struct threadobj *__threadobj_current;
+
+static inline void threadobj_init_key(void)
+{
+}
+
+#else /* !HAVE____THREAD */
+
+pthread_key_t threadobj_tskey;
+
+static inline void threadobj_init_key(void)
+{
+       if (pthread_key_create(&threadobj_tskey, threadobj_finalize))
+               panic("failed to allocate TSD key");
+}
+
+#endif /* !HAVE____THREAD */
+
 #ifdef CONFIG_XENO_COBALT
 
 #include "cobalt/internal.h"
@@ -955,7 +974,7 @@ int threadobj_prologue(struct threadobj *thobj, const char 
*name)
        write_unlock(&list_lock);
 
        thobj->errno_pointer = &errno;
-       pthread_setspecific(threadobj_tskey, thobj);
+       threadobj_set_current(thobj);
 
        if (global_rr)
                threadobj_set_rr(thobj, &global_quantum);
@@ -997,7 +1016,7 @@ static void threadobj_finalize(void *p) /* thobj->lock 
free */
                return;
 
        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
-       pthread_setspecific(threadobj_tskey, p);
+       threadobj_set_current(p);
 
        if (thobj->wait_sobj)
                __syncobj_cleanup_wait(thobj->wait_sobj, thobj);
@@ -1015,7 +1034,7 @@ static void threadobj_finalize(void *p) /* thobj->lock 
free */
        if (thobj->finalizer)
                thobj->finalizer(thobj);
 
-       pthread_setspecific(threadobj_tskey, NULL);
+       threadobj_set_current(NULL);
 }
 
 void threadobj_destroy(struct threadobj *thobj) /* thobj->lock free */
@@ -1101,8 +1120,7 @@ void threadobj_pkg_init(void)
 
        __RT(pthread_mutex_init(&list_lock, NULL));
 
-       if (pthread_key_create(&threadobj_tskey, threadobj_finalize) != 0)
-               panic("failed to allocate TSD key");
+       threadobj_init_key();
 
        pkg_init_corespec();
 
diff --git a/lib/copperplate/timerobj-cobalt.c 
b/lib/copperplate/timerobj-cobalt.c
index 44401a5..8a79ad5 100644
--- a/lib/copperplate/timerobj-cobalt.c
+++ b/lib/copperplate/timerobj-cobalt.c
@@ -74,7 +74,7 @@ static void *timerobj_server(void *arg)
        int ret;
 
        pthread_set_name_np(pthread_self(), "timer-internal");
-       pthread_setspecific(threadobj_tskey, THREADOBJ_IRQCONTEXT);
+       threadobj_set_current(THREADOBJ_IRQCONTEXT);
 
        for (;;) {
                ret = __RT(sem_wait(&svsem));
diff --git a/lib/copperplate/timerobj-mercury.c 
b/lib/copperplate/timerobj-mercury.c
index d922a0f..98466ff 100644
--- a/lib/copperplate/timerobj-mercury.c
+++ b/lib/copperplate/timerobj-mercury.c
@@ -34,7 +34,7 @@
 static void timerobj_handler(union sigval sigval)
 {
        struct timerobj *tmobj = sigval.sival_ptr;
-       pthread_setspecific(threadobj_tskey, THREADOBJ_IRQCONTEXT);
+       threadobj_set_current(THREADOBJ_IRQCONTEXT);
        assert(tmobj->handler != NULL);
        tmobj->handler(tmobj);
 }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to