diff options
| author | Daniel Eischen <deischen@FreeBSD.org> | 2001-11-17 14:28:39 +0000 |
|---|---|---|
| committer | Daniel Eischen <deischen@FreeBSD.org> | 2001-11-17 14:28:39 +0000 |
| commit | ccc7b69205d48bc890a1565811ef265a7904977c (patch) | |
| tree | d9b490926b6ae401659e2052a1b89c5bea09c6d4 | |
| parent | 608f31f640fa809e3d3f91a58b0bcbe10e125267 (diff) | |
Notes
| -rw-r--r-- | lib/libc_r/uthread/pthread_private.h | 13 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_exit.c | 5 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_join.c | 12 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_sig.c | 12 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_exit.c | 5 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_join.c | 12 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_private.h | 13 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_sig.c | 12 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_exit.c | 5 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_join.c | 12 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_private.h | 13 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_sig.c | 12 |
12 files changed, 96 insertions, 30 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index 151fd0379ebd..b60d8b7aed96 100644 --- a/lib/libc_r/uthread/pthread_private.h +++ b/lib/libc_r/uthread/pthread_private.h @@ -601,6 +601,11 @@ struct pthread_state_data { /* XXX - What about thread->timeout and/or thread->error? */ }; +struct join_status { + struct pthread *thread; + int ret; + int error; +}; /* * Normally thread contexts are stored as jmp_bufs via _setjmp()/_longjmp(), @@ -757,8 +762,12 @@ struct pthread { */ int error; - /* Pointer to a thread that is waiting to join (NULL if no joiner). */ - struct pthread *joiner; + /* + * 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; + struct join_status join_status; /* * The current thread can belong to only one scheduling queue at diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c index 937635058de1..d916f5c3e232 100644 --- a/lib/libc_r/uthread/uthread_exit.c +++ b/lib/libc_r/uthread/uthread_exit.c @@ -220,8 +220,9 @@ _pthread_exit(void *status) } /* Set the return value for the joining thread: */ - pthread->ret = curthread->ret; - pthread->error = 0; + pthread->join_status.ret = curthread->ret; + pthread->join_status.error = 0; + pthread->join_status.thread = NULL; /* Make this thread collectable by the garbage collector. */ PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) == diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c index 454c79a924f9..0f5e8fc5c1ed 100644 --- a/lib/libc_r/uthread/uthread_join.c +++ b/lib/libc_r/uthread/uthread_join.c @@ -122,18 +122,20 @@ _pthread_join(pthread_t pthread, void **thread_return) pthread->joiner = curthread; /* Keep track of which thread we're joining to: */ - curthread->data.thread = pthread; + curthread->join_status.thread = pthread; - /* Schedule the next thread: */ - _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); + while (curthread->join_status.thread == pthread) { + /* Schedule the next thread: */ + _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); + } /* * The thread return value and error are set by the thread we're * joining to when it exits or detaches: */ - ret = curthread->error; + ret = curthread->join_status.error; if ((ret == 0) && (thread_return != NULL)) - *thread_return = curthread->ret; + *thread_return = curthread->join_status.ret; } else { /* * The thread exited (is dead) without being detached, and no diff --git a/lib/libc_r/uthread/uthread_sig.c b/lib/libc_r/uthread/uthread_sig.c index 9ca197efdbec..a05f9145b8df 100644 --- a/lib/libc_r/uthread/uthread_sig.c +++ b/lib/libc_r/uthread/uthread_sig.c @@ -671,7 +671,6 @@ thread_sig_add(pthread_t pthread, int sig, int has_args) * signal handler to run: */ case PS_COND_WAIT: - case PS_JOIN: case PS_MUTEX_WAIT: /* * Remove the thread from the wait queue. It will @@ -681,6 +680,17 @@ thread_sig_add(pthread_t pthread, int sig, int has_args) PTHREAD_WAITQ_REMOVE(pthread); break; + case PS_JOIN: + /* + * Remove the thread from the wait queue. It will + * be added back to the wait queue once all signal + * handlers have been invoked. + */ + PTHREAD_WAITQ_REMOVE(pthread); + /* Make the thread runnable: */ + PTHREAD_SET_STATE(pthread, PS_RUNNING); + break; + /* * States which are interruptible but may need to be removed * from queues before any signal handler is called. diff --git a/lib/libkse/thread/thr_exit.c b/lib/libkse/thread/thr_exit.c index 937635058de1..d916f5c3e232 100644 --- a/lib/libkse/thread/thr_exit.c +++ b/lib/libkse/thread/thr_exit.c @@ -220,8 +220,9 @@ _pthread_exit(void *status) } /* Set the return value for the joining thread: */ - pthread->ret = curthread->ret; - pthread->error = 0; + pthread->join_status.ret = curthread->ret; + pthread->join_status.error = 0; + pthread->join_status.thread = NULL; /* Make this thread collectable by the garbage collector. */ PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) == diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c index 454c79a924f9..0f5e8fc5c1ed 100644 --- a/lib/libkse/thread/thr_join.c +++ b/lib/libkse/thread/thr_join.c @@ -122,18 +122,20 @@ _pthread_join(pthread_t pthread, void **thread_return) pthread->joiner = curthread; /* Keep track of which thread we're joining to: */ - curthread->data.thread = pthread; + curthread->join_status.thread = pthread; - /* Schedule the next thread: */ - _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); + while (curthread->join_status.thread == pthread) { + /* Schedule the next thread: */ + _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); + } /* * The thread return value and error are set by the thread we're * joining to when it exits or detaches: */ - ret = curthread->error; + ret = curthread->join_status.error; if ((ret == 0) && (thread_return != NULL)) - *thread_return = curthread->ret; + *thread_return = curthread->join_status.ret; } else { /* * The thread exited (is dead) without being detached, and no diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h index 151fd0379ebd..b60d8b7aed96 100644 --- a/lib/libkse/thread/thr_private.h +++ b/lib/libkse/thread/thr_private.h @@ -601,6 +601,11 @@ struct pthread_state_data { /* XXX - What about thread->timeout and/or thread->error? */ }; +struct join_status { + struct pthread *thread; + int ret; + int error; +}; /* * Normally thread contexts are stored as jmp_bufs via _setjmp()/_longjmp(), @@ -757,8 +762,12 @@ struct pthread { */ int error; - /* Pointer to a thread that is waiting to join (NULL if no joiner). */ - struct pthread *joiner; + /* + * 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; + struct join_status join_status; /* * The current thread can belong to only one scheduling queue at diff --git a/lib/libkse/thread/thr_sig.c b/lib/libkse/thread/thr_sig.c index 9ca197efdbec..a05f9145b8df 100644 --- a/lib/libkse/thread/thr_sig.c +++ b/lib/libkse/thread/thr_sig.c @@ -671,7 +671,6 @@ thread_sig_add(pthread_t pthread, int sig, int has_args) * signal handler to run: */ case PS_COND_WAIT: - case PS_JOIN: case PS_MUTEX_WAIT: /* * Remove the thread from the wait queue. It will @@ -681,6 +680,17 @@ thread_sig_add(pthread_t pthread, int sig, int has_args) PTHREAD_WAITQ_REMOVE(pthread); break; + case PS_JOIN: + /* + * Remove the thread from the wait queue. It will + * be added back to the wait queue once all signal + * handlers have been invoked. + */ + PTHREAD_WAITQ_REMOVE(pthread); + /* Make the thread runnable: */ + PTHREAD_SET_STATE(pthread, PS_RUNNING); + break; + /* * States which are interruptible but may need to be removed * from queues before any signal handler is called. diff --git a/lib/libpthread/thread/thr_exit.c b/lib/libpthread/thread/thr_exit.c index 937635058de1..d916f5c3e232 100644 --- a/lib/libpthread/thread/thr_exit.c +++ b/lib/libpthread/thread/thr_exit.c @@ -220,8 +220,9 @@ _pthread_exit(void *status) } /* Set the return value for the joining thread: */ - pthread->ret = curthread->ret; - pthread->error = 0; + pthread->join_status.ret = curthread->ret; + pthread->join_status.error = 0; + pthread->join_status.thread = NULL; /* Make this thread collectable by the garbage collector. */ PTHREAD_ASSERT(((curthread->attr.flags & PTHREAD_DETACHED) == diff --git a/lib/libpthread/thread/thr_join.c b/lib/libpthread/thread/thr_join.c index 454c79a924f9..0f5e8fc5c1ed 100644 --- a/lib/libpthread/thread/thr_join.c +++ b/lib/libpthread/thread/thr_join.c @@ -122,18 +122,20 @@ _pthread_join(pthread_t pthread, void **thread_return) pthread->joiner = curthread; /* Keep track of which thread we're joining to: */ - curthread->data.thread = pthread; + curthread->join_status.thread = pthread; - /* Schedule the next thread: */ - _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); + while (curthread->join_status.thread == pthread) { + /* Schedule the next thread: */ + _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); + } /* * The thread return value and error are set by the thread we're * joining to when it exits or detaches: */ - ret = curthread->error; + ret = curthread->join_status.error; if ((ret == 0) && (thread_return != NULL)) - *thread_return = curthread->ret; + *thread_return = curthread->join_status.ret; } else { /* * The thread exited (is dead) without being detached, and no diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h index 151fd0379ebd..b60d8b7aed96 100644 --- a/lib/libpthread/thread/thr_private.h +++ b/lib/libpthread/thread/thr_private.h @@ -601,6 +601,11 @@ struct pthread_state_data { /* XXX - What about thread->timeout and/or thread->error? */ }; +struct join_status { + struct pthread *thread; + int ret; + int error; +}; /* * Normally thread contexts are stored as jmp_bufs via _setjmp()/_longjmp(), @@ -757,8 +762,12 @@ struct pthread { */ int error; - /* Pointer to a thread that is waiting to join (NULL if no joiner). */ - struct pthread *joiner; + /* + * 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; + struct join_status join_status; /* * The current thread can belong to only one scheduling queue at diff --git a/lib/libpthread/thread/thr_sig.c b/lib/libpthread/thread/thr_sig.c index 9ca197efdbec..a05f9145b8df 100644 --- a/lib/libpthread/thread/thr_sig.c +++ b/lib/libpthread/thread/thr_sig.c @@ -671,7 +671,6 @@ thread_sig_add(pthread_t pthread, int sig, int has_args) * signal handler to run: */ case PS_COND_WAIT: - case PS_JOIN: case PS_MUTEX_WAIT: /* * Remove the thread from the wait queue. It will @@ -681,6 +680,17 @@ thread_sig_add(pthread_t pthread, int sig, int has_args) PTHREAD_WAITQ_REMOVE(pthread); break; + case PS_JOIN: + /* + * Remove the thread from the wait queue. It will + * be added back to the wait queue once all signal + * handlers have been invoked. + */ + PTHREAD_WAITQ_REMOVE(pthread); + /* Make the thread runnable: */ + PTHREAD_SET_STATE(pthread, PS_RUNNING); + break; + /* * States which are interruptible but may need to be removed * from queues before any signal handler is called. |
