diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-12-23 14:59:54 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-12-23 15:04:02 +0100 |
commit | 4133b7f7992a38b19d5bfe47591e932e92d958e8 (patch) | |
tree | 883ee7f02a0087712c76ec6697453f5b523e69d7 | |
parent | 7aa475db4ce168401167dc2ffed6221493ae2db4 (diff) |
Make thread_suspend wait for !TH_UNINT
0a55db5 made thread_suspend return KERN_FAILURE when the target thread is in
TH_UNINT state. That however is not currently handled by libc, and it's more
useful to just wait for the thread to get interruptible.
* kern/sched_prim.c (thread_invoke): Wake NEW_THREAD->STATE for thread_suspend.
* kern/thread.c (thread_suspend): Wait on NEW_THREAD->STATE as long as THREAD
has TH_UNINT.
-rw-r--r-- | kern/sched_prim.c | 3 | ||||
-rw-r--r-- | kern/thread.c | 8 |
2 files changed, 8 insertions, 3 deletions
diff --git a/kern/sched_prim.c b/kern/sched_prim.c index a7b7a4e..ba2dc8a 100644 --- a/kern/sched_prim.c +++ b/kern/sched_prim.c @@ -637,6 +637,7 @@ boolean_t thread_invoke( thread_lock(new_thread); new_thread->state &= ~TH_UNINT; thread_unlock(new_thread); + thread_wakeup(&new_thread->state); if (continuation != (void (*)()) 0) { (void) spl0(); @@ -658,6 +659,7 @@ boolean_t thread_invoke( new_thread->state &= ~(TH_SWAPPED | TH_UNINT); thread_unlock(new_thread); + thread_wakeup(&new_thread->state); #if NCPUS > 1 new_thread->last_processor = current_processor(); @@ -787,6 +789,7 @@ boolean_t thread_invoke( new_thread->state &= ~(TH_SWAPPED | TH_UNINT); thread_unlock(new_thread); + thread_wakeup(&new_thread->state); /* * Thread is now interruptible. diff --git a/kern/thread.c b/kern/thread.c index d279bc8..87be923 100644 --- a/kern/thread.c +++ b/kern/thread.c @@ -1326,10 +1326,12 @@ kern_return_t thread_suspend( hold = FALSE; spl = splsched(); thread_lock(thread); - if (thread->state & TH_UNINT) { + /* Wait for thread to get interruptible */ + while (thread->state & TH_UNINT) { + assert_wait(&thread->state, TRUE); thread_unlock(thread); - (void) splx(spl); - return KERN_FAILURE; + thread_block(NULL); + thread_lock(thread); } if (thread->user_stop_count++ == 0) { hold = TRUE; |