summaryrefslogtreecommitdiff
path: root/kern/thread_swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kern/thread_swap.c')
-rw-r--r--kern/thread_swap.c27
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);