diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-12 20:56:59 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-12 20:56:59 +0000 |
commit | 52c9ef85a65f4dc25a4d1ff79c0fba1ed53ef43a (patch) | |
tree | 4b034bbe45a4e21907dda9e0a2af6d9adc2b63d0 /libpthread/linuxthreads/pthread.c | |
parent | a8e76cbe147263a58d9e70e426d295858f9cd308 (diff) |
linuxthreads fixes from Will Newton (will.newton AT gmail.com):
* share Sys V semaphores in order to get appropriate SEM_UNDO semantics.
* correct guardaddr in pthread_free() for TLS case
* move spinlock unlocking before restart()
* When exit was called from a signal handler, the restart
from the manager processing the exit request instead restarted the thread
in pthread_cond_timedwait.
(see http://sources.redhat.com/ml/libc-ports/2006-05/msg00000.html)
Diffstat (limited to 'libpthread/linuxthreads/pthread.c')
-rw-r--r-- | libpthread/linuxthreads/pthread.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/libpthread/linuxthreads/pthread.c b/libpthread/linuxthreads/pthread.c index 91333f2d1..4d1d9062a 100644 --- a/libpthread/linuxthreads/pthread.c +++ b/libpthread/linuxthreads/pthread.c @@ -740,17 +740,17 @@ int __pthread_initialize_manager(void) pid = __clone2(__pthread_manager_event, (void **) __pthread_manager_thread_bos, THREAD_MANAGER_STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr); #elif _STACK_GROWS_UP pid = __clone(__pthread_manager_event, (void **) __pthread_manager_thread_bos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr); #else pid = __clone(__pthread_manager_event, (void **) __pthread_manager_thread_tos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr); #endif @@ -780,13 +780,13 @@ int __pthread_initialize_manager(void) #ifdef NEED_SEPARATE_REGISTER_STACK pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos, THREAD_MANAGER_STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr); + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr); #elif _STACK_GROWS_UP pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr); + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr); #else pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos, - CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr); + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_SYSVSEM, mgr); #endif } if (__builtin_expect (pid, 0) == -1) { @@ -972,6 +972,10 @@ static void pthread_onexit_process(int retcode, void *arg) struct pthread_request request; pthread_descr self = thread_self(); + /* Make sure we come back here after suspend(), in case we entered + from a signal handler. */ + THREAD_SETMEM(self, p_signal_jmp, NULL); + request.req_thread = self; request.req_kind = REQ_PROCESS_EXIT; request.req_args.exit.code = retcode; @@ -1201,13 +1205,13 @@ void __pthread_wait_for_restart_signal(pthread_descr self) void __pthread_restart_old(pthread_descr th) { - if (atomic_increment(&th->p_resume_count) == -1) + if (pthread_atomic_increment(&th->p_resume_count) == -1) kill(th->p_pid, __pthread_sig_restart); } void __pthread_suspend_old(pthread_descr self) { - if (atomic_decrement(&self->p_resume_count) <= 0) + if (pthread_atomic_decrement(&self->p_resume_count) <= 0) __pthread_wait_for_restart_signal(self); } @@ -1218,7 +1222,7 @@ __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime) int was_signalled = 0; sigjmp_buf jmpbuf; - if (atomic_decrement(&self->p_resume_count) == 0) { + if (pthread_atomic_decrement(&self->p_resume_count) == 0) { /* Set up a longjmp handler for the restart signal, unblock the signal and sleep. */ @@ -1275,9 +1279,9 @@ __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime) being delivered. */ if (!was_signalled) { - if (atomic_increment(&self->p_resume_count) != -1) { + if (pthread_atomic_increment(&self->p_resume_count) != -1) { __pthread_wait_for_restart_signal(self); - atomic_decrement(&self->p_resume_count); /* should be zero now! */ + pthread_atomic_decrement(&self->p_resume_count); /* should be zero now! */ /* woke spontaneously and consumed restart signal */ return 1; } |