diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-04-05 05:21:15 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-04-05 05:21:15 +0000 |
commit | b22d701bb72b928526efff83c019b912f469af72 (patch) | |
tree | 4474c99dbe6f90a380c378817307646f6f8eff5c /nptl/sysdeps | |
parent | 3242201746d74bfbccb8267f8b2e81a9478bf78b (diff) | |
download | glibc-b22d701bb72b928526efff83c019b912f469af72.zip glibc-b22d701bb72b928526efff83c019b912f469af72.tar.gz glibc-b22d701bb72b928526efff83c019b912f469af72.tar.bz2 |
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.h | 34 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/createthread.c | 12 | ||||
-rw-r--r-- | nptl/sysdeps/x86_64/tls.h | 26 |
3 files changed, 67 insertions, 5 deletions
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h index 7fe2222..4f2e818 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 fae744f..9d00e4e 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 f382db2..dec1b5d 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" \ |