diff options
Diffstat (limited to 'kern/thread_swap.c')
-rw-r--r-- | kern/thread_swap.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/kern/thread_swap.c b/kern/thread_swap.c index f29bd5b7..20ad0409 100644 --- a/kern/thread_swap.c +++ b/kern/thread_swap.c @@ -86,8 +86,7 @@ void swapper_init(void) * our callers have already tried that route. */ -void thread_swapin(thread) - thread_t thread; +void thread_swapin(thread_t thread) { switch (thread->state & TH_SWAP_STATE) { case TH_SWAPPED: @@ -97,7 +96,7 @@ void thread_swapin(thread) thread->state = (thread->state & ~TH_SWAP_STATE) | TH_SW_COMING_IN; swapper_lock(); - enqueue_tail(&swapin_queue, (queue_entry_t) thread); + enqueue_tail(&swapin_queue, &(thread->links)); swapper_unlock(); thread_wakeup((event_t) &swapin_queue); break; @@ -124,16 +123,18 @@ void thread_swapin(thread) * it on a run queue. No locks should be held on entry, as it is * likely that this routine will sleep (waiting for stack allocation). */ -void thread_doswapin(thread) - register thread_t thread; +kern_return_t thread_doswapin(thread_t thread) { + kern_return_t kr; spl_t s; /* * Allocate the kernel stack. */ - stack_alloc(thread, thread_continue); + kr = stack_alloc(thread, thread_continue); + if (kr != KERN_SUCCESS) + return kr; /* * Place on run queue. @@ -146,6 +147,7 @@ void thread_doswapin(thread) thread_setrun(thread, TRUE); thread_unlock(thread); (void) splx(s); + return KERN_SUCCESS; } /* @@ -154,10 +156,10 @@ void thread_doswapin(thread) * This procedure executes as a kernel thread. Threads that need to * be swapped in are swapped in by this thread. */ -void swapin_thread_continue(void) +void __attribute__((noreturn)) swapin_thread_continue(void) { for (;;) { - register thread_t thread; + thread_t thread; spl_t s; s = splsched(); @@ -165,13 +167,20 @@ void swapin_thread_continue(void) while ((thread = (thread_t) dequeue_head(&swapin_queue)) != THREAD_NULL) { + kern_return_t kr; swapper_unlock(); (void) splx(s); - thread_doswapin(thread); /* may block */ + kr = thread_doswapin(thread); /* may block */ s = splsched(); swapper_lock(); + + if (kr != KERN_SUCCESS) { + enqueue_head(&swapin_queue, + (queue_entry_t) thread); + break; + } } assert_wait((event_t) &swapin_queue, FALSE); |