diff options
author | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2001-12-19 02:02:53 +0000 |
---|---|---|
committer | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2001-12-19 02:02:53 +0000 |
commit | eda62f0bd378e59f8f8834ff5aa82b6116d16f3c (patch) | |
tree | c86efedef1e44a31c0ca350e46c9ccbd266c7a84 | |
parent | a0b122637ad74506e34f0e1c7da4d51b152b73d9 (diff) |
More sync.
-rw-r--r-- | lib/libc_r/uthread/pthread_private.h | 72 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_cancel.c | 47 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_exit.c | 4 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_join.c | 3 | ||||
-rw-r--r-- | lib/libc_r/uthread/uthread_resume_np.c | 41 | ||||
-rw-r--r-- | lib/libpthread/uthread/pthread_private.h | 72 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_cancel.c | 47 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_exit.c | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_join.c | 3 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_resume_np.c | 41 |
10 files changed, 246 insertions, 88 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index b5556c44ffe..af234ac6c7d 100644 --- a/lib/libc_r/uthread/pthread_private.h +++ b/lib/libc_r/uthread/pthread_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pthread_private.h,v 1.31 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: pthread_private.h,v 1.32 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -120,6 +120,14 @@ * called with preemption deferred (see thread_kern_sched_[un]defer). */ #if defined(_PTHREADS_INVARIANTS) +#include <assert.h> +#define PTHREAD_ASSERT(cond, msg) do { \ + if (!(cond)) \ + PANIC(msg); \ +} while (0) +#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \ + PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \ + "Illegal call from signal handler"); #define PTHREAD_NEW_STATE(thrd, newstate) do { \ if (_thread_kern_new_state != 0) \ PANIC("Recursive PTHREAD_NEW_STATE"); \ @@ -137,6 +145,8 @@ PTHREAD_SET_STATE(thrd, newstate); \ } while (0) #else +#define PTHREAD_ASSERT(cond, msg) +#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) #define PTHREAD_NEW_STATE(thrd, newstate) do { \ if ((thrd)->state != newstate) { \ if ((thrd)->state == PS_RUNNING) { \ @@ -645,7 +655,7 @@ struct pthread { int error; /* - * The joiner is the thread that is joining this thraed. The + * The joiner is the thread that is joining to this thread. The * join status keeps track of a join operation to another thread. */ struct pthread *joiner; @@ -653,8 +663,7 @@ struct pthread { /* * The current thread can belong to only one scheduling queue at - * a time (ready or waiting queue). It can also belong to (only) - * one of: + * a time (ready or waiting queue). It can also belong to: * * o A queue of threads waiting for a mutex * o A queue of threads waiting for a condition variable @@ -662,18 +671,25 @@ struct pthread { * o A queue of threads needing work done by the kernel thread * (waiting for a spinlock or file I/O) * + * A thread can also be joining a thread (the joiner field above). + * + * It must not be possible for a thread to belong to any of the + * above queues while it is handling a signal. Signal handlers + * may longjmp back to previous stack frames circumventing normal + * control flow. This could corrupt queue integrity if the thread + * retains membership in the queue. Therefore, if a thread is a + * member of one of these queues when a signal handler is invoked, + * it must remove itself from the queue before calling the signal + * handler and reinsert itself after normal return of the handler. + * * Use pqe for the scheduling queue link (both ready and waiting), - * and qe for other links. + * sqe for synchronization (mutex and condition variable) queue + * links, and qe for all other links. */ - /* Priority queue entry for this thread: */ - pthread_entry_t pqe; - - /* Priority queue entry for this thread: */ - pthread_entry_t sqe; - - /* Queue entry for this thread: */ - pthread_entry_t qe; + pthread_entry_t pqe; /* priority queue link */ + pthread_entry_t sqe; /* synchronization queue link */ + pthread_entry_t qe; /* all other queues link */ /* Wait data. */ union pthread_wait_data data; @@ -704,19 +720,19 @@ struct pthread { */ int yield_on_sig_undefer; - /* Miscellaneous data. */ + /* Miscellaneous flags; only set with signals deferred. */ int flags; #define PTHREAD_FLAGS_PRIVATE 0x0001 #define PTHREAD_EXITING 0x0002 -#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link*/ -#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link*/ +#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link */ +#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */ #define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */ #define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */ #define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */ -#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ -#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link*/ +#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link */ +#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ #define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */ -#define PTHREAD_FLAGS_IN_SYNQ \ +#define PTHREAD_FLAGS_IN_SYNCQ \ (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ) /* @@ -992,6 +1008,21 @@ SCLASS volatile int _spinblock_count #endif ; +/* Used to maintain pending and active signals: */ +struct sigstatus { + int pending; /* Is this a pending signal? */ + int blocked; /* + * A handler is currently active for + * this signal; ignore subsequent + * signals until the handler is done. + */ + int signo; /* arg 1 to signal handler */ + siginfo_t siginfo; /* arg 2 to signal handler */ + struct sigcontext uc; /* arg 3 to signal handler */ +}; + +SCLASS struct sigstatus _thread_sigq[NSIG]; + /* Indicates that the signal queue needs to be checked. */ SCLASS volatile int _sigq_check_reqd #ifdef GLOBAL_PTHREAD_PRIVATE @@ -999,6 +1030,9 @@ SCLASS volatile int _sigq_check_reqd #endif ; +/* The signal stack. */ +SCLASS struct sigaltstack _thread_sigstack; + /* Thread switch hook. */ SCLASS pthread_switch_routine_t _sched_switch_hook #ifdef GLOBAL_PTHREAD_PRIVATE diff --git a/lib/libc_r/uthread/uthread_cancel.c b/lib/libc_r/uthread/uthread_cancel.c index 8c8515dbbc7..29f3a8edebf 100644 --- a/lib/libc_r/uthread/uthread_cancel.c +++ b/lib/libc_r/uthread/uthread_cancel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_cancel.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: uthread_cancel.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */ /* * David Leonard <d@openbsd.org>, 1999. Public domain. */ @@ -59,17 +59,6 @@ pthread_cancel(pthread) PTHREAD_NEW_STATE(pthread,PS_RUNNING); break; - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - case PS_FDLR_WAIT: - case PS_FDLW_WAIT: - case PS_FILE_WAIT: - pthread->interrupted = 1; - pthread->cancelflags |= PTHREAD_CANCEL_NEEDED; - PTHREAD_NEW_STATE(pthread,PS_RUNNING); - pthread->continuation = finish_cancellation; - break; - case PS_JOIN: /* * Disconnect the thread from the joinee and @@ -85,9 +74,39 @@ pthread_cancel(pthread) break; case PS_SUSPENDED: - /* Simply wake: */ - /* XXX may be incorrect */ + if (pthread->suspended == SUSP_NO || + pthread->suspended == SUSP_YES || + pthread->suspended == SUSP_JOIN || + pthread->suspended == SUSP_NOWAIT) { + /* + * This thread isn't in any scheduling + * queues; just change it's state: + */ + pthread->cancelflags |= + PTHREAD_CANCELLING; + PTHREAD_SET_STATE(pthread, PS_RUNNING); + break; + } + /* FALLTHROUGH */ + case PS_MUTEX_WAIT: + case PS_COND_WAIT: + case PS_FDLR_WAIT: + case PS_FDLW_WAIT: + case PS_FILE_WAIT: + /* + * Threads in these states may be in queues. + * In order to preserve queue integrity, the + * cancelled thread must remove itself from the + * queue. Mark the thread as interrupted and + * needing cancellation, and set the state to + * running. When the thread resumes, it will + * remove itself from the queue and call the + * cancellation completion routine. + */ + pthread->interrupted = 1; + pthread->cancelflags |= PTHREAD_CANCEL_NEEDED; PTHREAD_NEW_STATE(pthread,PS_RUNNING); + pthread->continuation = finish_cancellation; break; case PS_DEAD: diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c index 232b55e008e..a7a0c60a267 100644 --- a/lib/libc_r/uthread/uthread_exit.c +++ b/lib/libc_r/uthread/uthread_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_exit.c,v 1.14 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: uthread_exit.c,v 1.15 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -226,11 +226,9 @@ pthread_exit(void *status) pthread->join_status.error = 0; pthread->join_status.thread = NULL; -#ifdef notyet /* Make this thread collectable by the garbage collector. */ PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) == 0), "Cannot join a detached thread"); -#endif curthread->attr.flags |= PTHREAD_DETACHED; } diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c index 1cf1624a884..0167427b570 100644 --- a/lib/libc_r/uthread/uthread_join.c +++ b/lib/libc_r/uthread/uthread_join.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_join.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: uthread_join.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -134,7 +134,6 @@ pthread_join(pthread_t pthread, void **thread_return) * joining to when it exits or detaches: */ ret = curthread->join_status.error; - ret = curthread->join_status.error; if ((ret == 0) && (thread_return != NULL)) *thread_return = curthread->join_status.ret; } else { diff --git a/lib/libc_r/uthread/uthread_resume_np.c b/lib/libc_r/uthread/uthread_resume_np.c index 8816f76e4c8..ace16df8e45 100644 --- a/lib/libc_r/uthread/uthread_resume_np.c +++ b/lib/libc_r/uthread/uthread_resume_np.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_resume_np.c,v 1.4 1999/11/25 07:01:42 d Exp $ */ +/* $OpenBSD: uthread_resume_np.c,v 1.5 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -41,20 +41,49 @@ int pthread_resume_np(pthread_t thread) { - int ret; + int ret; + enum pthread_susp old_suspended; /* Find the thread in the list of active threads: */ if ((ret = _find_thread(thread)) == 0) { - /* The thread exists. Is it suspended? */ - if (thread->state != PS_SUSPENDED) { + /* Cancel any pending suspensions: */ + old_suspended = thread->suspended; + thread->suspended = SUSP_NO; + + /* Is it currently suspended? */ + if (thread->state == PS_SUSPENDED) { /* * Defer signals to protect the scheduling queues * from access by the signal handler: */ _thread_kern_sig_defer(); - /* Allow the thread to run. */ - PTHREAD_NEW_STATE(thread,PS_RUNNING); + switch (old_suspended) { + case SUSP_MUTEX_WAIT: + /* Set the thread's state back. */ + PTHREAD_SET_STATE(thread,PS_MUTEX_WAIT); + break; + case SUSP_COND_WAIT: + /* Set the thread's state back. */ + PTHREAD_SET_STATE(thread,PS_COND_WAIT); + break; + case SUSP_JOIN: + /* Set the thread's state back. */ + PTHREAD_SET_STATE(thread,PS_JOIN); + break; + case SUSP_NOWAIT: + /* Allow the thread to run. */ + PTHREAD_SET_STATE(thread,PS_RUNNING); + PTHREAD_WAITQ_REMOVE(thread); + PTHREAD_PRIOQ_INSERT_TAIL(thread); + break; + case SUSP_NO: + case SUSP_YES: + /* Allow the thread to run. */ + PTHREAD_SET_STATE(thread,PS_RUNNING); + PTHREAD_PRIOQ_INSERT_TAIL(thread); + break; + } /* * Undefer and handle pending signals, yielding if diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h index b5556c44ffe..af234ac6c7d 100644 --- a/lib/libpthread/uthread/pthread_private.h +++ b/lib/libpthread/uthread/pthread_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pthread_private.h,v 1.31 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: pthread_private.h,v 1.32 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -120,6 +120,14 @@ * called with preemption deferred (see thread_kern_sched_[un]defer). */ #if defined(_PTHREADS_INVARIANTS) +#include <assert.h> +#define PTHREAD_ASSERT(cond, msg) do { \ + if (!(cond)) \ + PANIC(msg); \ +} while (0) +#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \ + PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \ + "Illegal call from signal handler"); #define PTHREAD_NEW_STATE(thrd, newstate) do { \ if (_thread_kern_new_state != 0) \ PANIC("Recursive PTHREAD_NEW_STATE"); \ @@ -137,6 +145,8 @@ PTHREAD_SET_STATE(thrd, newstate); \ } while (0) #else +#define PTHREAD_ASSERT(cond, msg) +#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) #define PTHREAD_NEW_STATE(thrd, newstate) do { \ if ((thrd)->state != newstate) { \ if ((thrd)->state == PS_RUNNING) { \ @@ -645,7 +655,7 @@ struct pthread { int error; /* - * The joiner is the thread that is joining this thraed. The + * The joiner is the thread that is joining to this thread. The * join status keeps track of a join operation to another thread. */ struct pthread *joiner; @@ -653,8 +663,7 @@ struct pthread { /* * The current thread can belong to only one scheduling queue at - * a time (ready or waiting queue). It can also belong to (only) - * one of: + * a time (ready or waiting queue). It can also belong to: * * o A queue of threads waiting for a mutex * o A queue of threads waiting for a condition variable @@ -662,18 +671,25 @@ struct pthread { * o A queue of threads needing work done by the kernel thread * (waiting for a spinlock or file I/O) * + * A thread can also be joining a thread (the joiner field above). + * + * It must not be possible for a thread to belong to any of the + * above queues while it is handling a signal. Signal handlers + * may longjmp back to previous stack frames circumventing normal + * control flow. This could corrupt queue integrity if the thread + * retains membership in the queue. Therefore, if a thread is a + * member of one of these queues when a signal handler is invoked, + * it must remove itself from the queue before calling the signal + * handler and reinsert itself after normal return of the handler. + * * Use pqe for the scheduling queue link (both ready and waiting), - * and qe for other links. + * sqe for synchronization (mutex and condition variable) queue + * links, and qe for all other links. */ - /* Priority queue entry for this thread: */ - pthread_entry_t pqe; - - /* Priority queue entry for this thread: */ - pthread_entry_t sqe; - - /* Queue entry for this thread: */ - pthread_entry_t qe; + pthread_entry_t pqe; /* priority queue link */ + pthread_entry_t sqe; /* synchronization queue link */ + pthread_entry_t qe; /* all other queues link */ /* Wait data. */ union pthread_wait_data data; @@ -704,19 +720,19 @@ struct pthread { */ int yield_on_sig_undefer; - /* Miscellaneous data. */ + /* Miscellaneous flags; only set with signals deferred. */ int flags; #define PTHREAD_FLAGS_PRIVATE 0x0001 #define PTHREAD_EXITING 0x0002 -#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link*/ -#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link*/ +#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link */ +#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */ #define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */ #define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */ #define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */ -#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ -#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link*/ +#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link */ +#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ #define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */ -#define PTHREAD_FLAGS_IN_SYNQ \ +#define PTHREAD_FLAGS_IN_SYNCQ \ (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ) /* @@ -992,6 +1008,21 @@ SCLASS volatile int _spinblock_count #endif ; +/* Used to maintain pending and active signals: */ +struct sigstatus { + int pending; /* Is this a pending signal? */ + int blocked; /* + * A handler is currently active for + * this signal; ignore subsequent + * signals until the handler is done. + */ + int signo; /* arg 1 to signal handler */ + siginfo_t siginfo; /* arg 2 to signal handler */ + struct sigcontext uc; /* arg 3 to signal handler */ +}; + +SCLASS struct sigstatus _thread_sigq[NSIG]; + /* Indicates that the signal queue needs to be checked. */ SCLASS volatile int _sigq_check_reqd #ifdef GLOBAL_PTHREAD_PRIVATE @@ -999,6 +1030,9 @@ SCLASS volatile int _sigq_check_reqd #endif ; +/* The signal stack. */ +SCLASS struct sigaltstack _thread_sigstack; + /* Thread switch hook. */ SCLASS pthread_switch_routine_t _sched_switch_hook #ifdef GLOBAL_PTHREAD_PRIVATE diff --git a/lib/libpthread/uthread/uthread_cancel.c b/lib/libpthread/uthread/uthread_cancel.c index 8c8515dbbc7..29f3a8edebf 100644 --- a/lib/libpthread/uthread/uthread_cancel.c +++ b/lib/libpthread/uthread/uthread_cancel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_cancel.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: uthread_cancel.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */ /* * David Leonard <d@openbsd.org>, 1999. Public domain. */ @@ -59,17 +59,6 @@ pthread_cancel(pthread) PTHREAD_NEW_STATE(pthread,PS_RUNNING); break; - case PS_MUTEX_WAIT: - case PS_COND_WAIT: - case PS_FDLR_WAIT: - case PS_FDLW_WAIT: - case PS_FILE_WAIT: - pthread->interrupted = 1; - pthread->cancelflags |= PTHREAD_CANCEL_NEEDED; - PTHREAD_NEW_STATE(pthread,PS_RUNNING); - pthread->continuation = finish_cancellation; - break; - case PS_JOIN: /* * Disconnect the thread from the joinee and @@ -85,9 +74,39 @@ pthread_cancel(pthread) break; case PS_SUSPENDED: - /* Simply wake: */ - /* XXX may be incorrect */ + if (pthread->suspended == SUSP_NO || + pthread->suspended == SUSP_YES || + pthread->suspended == SUSP_JOIN || + pthread->suspended == SUSP_NOWAIT) { + /* + * This thread isn't in any scheduling + * queues; just change it's state: + */ + pthread->cancelflags |= + PTHREAD_CANCELLING; + PTHREAD_SET_STATE(pthread, PS_RUNNING); + break; + } + /* FALLTHROUGH */ + case PS_MUTEX_WAIT: + case PS_COND_WAIT: + case PS_FDLR_WAIT: + case PS_FDLW_WAIT: + case PS_FILE_WAIT: + /* + * Threads in these states may be in queues. + * In order to preserve queue integrity, the + * cancelled thread must remove itself from the + * queue. Mark the thread as interrupted and + * needing cancellation, and set the state to + * running. When the thread resumes, it will + * remove itself from the queue and call the + * cancellation completion routine. + */ + pthread->interrupted = 1; + pthread->cancelflags |= PTHREAD_CANCEL_NEEDED; PTHREAD_NEW_STATE(pthread,PS_RUNNING); + pthread->continuation = finish_cancellation; break; case PS_DEAD: diff --git a/lib/libpthread/uthread/uthread_exit.c b/lib/libpthread/uthread/uthread_exit.c index 232b55e008e..a7a0c60a267 100644 --- a/lib/libpthread/uthread/uthread_exit.c +++ b/lib/libpthread/uthread/uthread_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_exit.c,v 1.14 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: uthread_exit.c,v 1.15 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -226,11 +226,9 @@ pthread_exit(void *status) pthread->join_status.error = 0; pthread->join_status.thread = NULL; -#ifdef notyet /* Make this thread collectable by the garbage collector. */ PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) == 0), "Cannot join a detached thread"); -#endif curthread->attr.flags |= PTHREAD_DETACHED; } diff --git a/lib/libpthread/uthread/uthread_join.c b/lib/libpthread/uthread/uthread_join.c index 1cf1624a884..0167427b570 100644 --- a/lib/libpthread/uthread/uthread_join.c +++ b/lib/libpthread/uthread/uthread_join.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_join.c,v 1.8 2001/12/11 00:19:47 fgsch Exp $ */ +/* $OpenBSD: uthread_join.c,v 1.9 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -134,7 +134,6 @@ pthread_join(pthread_t pthread, void **thread_return) * joining to when it exits or detaches: */ ret = curthread->join_status.error; - ret = curthread->join_status.error; if ((ret == 0) && (thread_return != NULL)) *thread_return = curthread->join_status.ret; } else { diff --git a/lib/libpthread/uthread/uthread_resume_np.c b/lib/libpthread/uthread/uthread_resume_np.c index 8816f76e4c8..ace16df8e45 100644 --- a/lib/libpthread/uthread/uthread_resume_np.c +++ b/lib/libpthread/uthread/uthread_resume_np.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_resume_np.c,v 1.4 1999/11/25 07:01:42 d Exp $ */ +/* $OpenBSD: uthread_resume_np.c,v 1.5 2001/12/19 02:02:52 fgsch Exp $ */ /* * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -41,20 +41,49 @@ int pthread_resume_np(pthread_t thread) { - int ret; + int ret; + enum pthread_susp old_suspended; /* Find the thread in the list of active threads: */ if ((ret = _find_thread(thread)) == 0) { - /* The thread exists. Is it suspended? */ - if (thread->state != PS_SUSPENDED) { + /* Cancel any pending suspensions: */ + old_suspended = thread->suspended; + thread->suspended = SUSP_NO; + + /* Is it currently suspended? */ + if (thread->state == PS_SUSPENDED) { /* * Defer signals to protect the scheduling queues * from access by the signal handler: */ _thread_kern_sig_defer(); - /* Allow the thread to run. */ - PTHREAD_NEW_STATE(thread,PS_RUNNING); + switch (old_suspended) { + case SUSP_MUTEX_WAIT: + /* Set the thread's state back. */ + PTHREAD_SET_STATE(thread,PS_MUTEX_WAIT); + break; + case SUSP_COND_WAIT: + /* Set the thread's state back. */ + PTHREAD_SET_STATE(thread,PS_COND_WAIT); + break; + case SUSP_JOIN: + /* Set the thread's state back. */ + PTHREAD_SET_STATE(thread,PS_JOIN); + break; + case SUSP_NOWAIT: + /* Allow the thread to run. */ + PTHREAD_SET_STATE(thread,PS_RUNNING); + PTHREAD_WAITQ_REMOVE(thread); + PTHREAD_PRIOQ_INSERT_TAIL(thread); + break; + case SUSP_NO: + case SUSP_YES: + /* Allow the thread to run. */ + PTHREAD_SET_STATE(thread,PS_RUNNING); + PTHREAD_PRIOQ_INSERT_TAIL(thread); + break; + } /* * Undefer and handle pending signals, yielding if |