From 52c9ef85a65f4dc25a4d1ff79c0fba1ed53ef43a Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Thu, 12 Mar 2009 20:56:59 +0000 Subject: 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) --- libpthread/linuxthreads/pthread.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'libpthread/linuxthreads/pthread.c') 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; } -- cgit v1.2.3