summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2012-12-23 14:59:54 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-12-23 15:04:02 +0100
commit4133b7f7992a38b19d5bfe47591e932e92d958e8 (patch)
tree883ee7f02a0087712c76ec6697453f5b523e69d7
parent7aa475db4ce168401167dc2ffed6221493ae2db4 (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.c3
-rw-r--r--kern/thread.c8
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;