aboutsummaryrefslogtreecommitdiff
path: root/nptl/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-05 05:21:15 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-05 05:21:15 +0000
commitb22d701bb72b928526efff83c019b912f469af72 (patch)
tree4474c99dbe6f90a380c378817307646f6f8eff5c /nptl/sysdeps
parent3242201746d74bfbccb8267f8b2e81a9478bf78b (diff)
downloadglibc-b22d701bb72b928526efff83c019b912f469af72.tar
glibc-b22d701bb72b928526efff83c019b912f469af72.tar.gz
glibc-b22d701bb72b928526efff83c019b912f469af72.tar.bz2
glibc-b22d701bb72b928526efff83c019b912f469af72.zip
Update.
2003-04-04 Ulrich Drepper <drepper@redhat.com> * sysdeps/pthread/createthread.c (create_thread): Add some more comments explaining when to set multiple_threads and when not. * pthreadP.h: Define THREAD_ATOMIC_CMPXCHG_VAL and THREAD_ATOMIC_BIT_SET if not already defined. * sysdeps/i386/tls.h: Define THREAD_ATOMIC_CMPXCHG_VAL and THREAD_ATOMIC_BIT_SET: * sysdeps/x86_64/tls.h: Likewise. * cleanup_defer.c (_pthread_cleanup_push_defer): Rewrite to use THREAD_ATOMIC_CMPXCHG_VAL. (_pthread_cleanup_pop_restore): Likewise. * cancellation.c (__pthread_enable_asynccancel): Likewise. (__pthread_enable_asynccancel_2): Likewise. (__pthread_disable_asynccancel): Likewise. * libc-cancellation.c (__libc_enable_asynccancel): Likewise. (__libc_disable_asynccancel): Likewise. * init.c (sigcancel_handler): Likewise. * pthread_setcancelstate.c (__pthread_setcancelstate): Likewise. * pthread_setcanceltype.c (__pthread_setcanceltype): Likewise.
Diffstat (limited to 'nptl/sysdeps')
-rw-r--r--nptl/sysdeps/i386/tls.h34
-rw-r--r--nptl/sysdeps/pthread/createthread.c12
-rw-r--r--nptl/sysdeps/x86_64/tls.h26
3 files changed, 67 insertions, 5 deletions
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index 7fe2222c68..4f2e8180d3 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -169,6 +169,14 @@ union user_desc_init
# define INIT_SYSINFO
#endif
+#ifndef LOCK
+# ifdef UP
+# define LOCK /* nothing */
+# else
+# define LOCK "lock;"
+# endif
+#endif
+
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
@@ -352,6 +360,32 @@ union user_desc_init
}})
+/* Atomic compare and exchange on TLS, returning old value. */
+#define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
+ ({ __typeof (descr->member) __ret; \
+ __typeof (oldval) __old = (oldval); \
+ if (sizeof (descr->member) == 4) \
+ asm volatile (LOCK "cmpxchgl %2, %%gs:%P3" \
+ : "=a" (__ret) \
+ : "0" (__old), "r" (newval), \
+ "i" (offsetof (struct pthread, member))); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); \
+ __ret; })
+
+
+/* Atomic set bit. */
+#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+ (void) ({ if (sizeof ((descr)->member) == 4) \
+ asm volatile (LOCK "orl %1, %%gs:%P0" \
+ :: "i" (offsetof (struct pthread, member)), \
+ "ir" (1 << (bit))); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); })
+
+
/* Call the user-provided thread function. */
#define CALL_THREAD_FCT(descr) \
({ void *__res; \
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index fae744f298..9d00e4e135 100644
--- a/nptl/sysdeps/pthread/createthread.c
+++ b/nptl/sysdeps/pthread/createthread.c
@@ -83,11 +83,11 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Failed. */
return errno;
+ /* We now have for sure more than one thread. The main
+ thread might not yet have the flag set. No need to set
+ the global variable again if this is what we use. */
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
- /* We now have for sure more than one thread. */
- pd->header.multiple_threads = 1;
-#else
- __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
+ THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
#endif
/* Now fill in the information about the new thread in
@@ -155,8 +155,10 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Failed. */
return errno;
+ /* We now have for sure more than one thread. The main thread might
+ not yet have the flag set. No need to set the global variable
+ again if this is what we use. */
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
- /* We now have for sure more than one thread. */
THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
#endif
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index f382db2861..dec1b5d1b7 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -253,6 +253,32 @@ typedef struct
}})
+/* Atomic compare and exchange on TLS, returning old value. */
+#define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
+ ({ __typeof (descr->member) __ret; \
+ __typeof (oldval) __old = (oldval); \
+ if (sizeof (descr->member) == 4) \
+ asm volatile (LOCK "cmpxchgl %2, %%fs:%P3" \
+ : "=a" (__ret) \
+ : "0" (__old), "r" (newval), \
+ "i" (offsetof (struct pthread, member))); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); \
+ __ret; })
+
+
+/* Atomic set bit. */
+#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+ (void) ({ if (sizeof ((descr)->member) == 4) \
+ asm volatile (LOCK "orl %1, %%fs:%P0" \
+ :: "i" (offsetof (struct pthread, member)), \
+ "ir" (1 << (bit))); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); })
+
+
#define CALL_THREAD_FCT(descr) \
({ void *__res; \
asm volatile ("movq %%fs:%P2, %%rdi\n\t" \