diff options
Diffstat (limited to 'kern')
-rw-r--r-- | kern/sched_prim.h | 2 | ||||
-rw-r--r-- | kern/thread.c | 11 | ||||
-rw-r--r-- | kern/thread_swap.c | 17 | ||||
-rw-r--r-- | kern/thread_swap.h | 2 |
4 files changed, 22 insertions, 10 deletions
diff --git a/kern/sched_prim.h b/kern/sched_prim.h index fd989b6..62698dc 100644 --- a/kern/sched_prim.h +++ b/kern/sched_prim.h @@ -150,7 +150,7 @@ extern void stack_handoff( * or are defined directly by machine-dependent code. */ -extern void stack_alloc( +extern kern_return_t stack_alloc( thread_t thread, void (*resume)(thread_t)); extern boolean_t stack_alloc_try( diff --git a/kern/thread.c b/kern/thread.c index 009884c..f52c95b 100644 --- a/kern/thread.c +++ b/kern/thread.c @@ -171,7 +171,7 @@ boolean_t stack_alloc_try( * May block. */ -void stack_alloc( +kern_return_t stack_alloc( thread_t thread, void (*resume)(thread_t)) { @@ -195,15 +195,15 @@ void stack_alloc( (void) splx(s); if (stack == 0) { + kern_return_t kr; /* * Kernel stacks should be naturally aligned, * so that it is easy to find the starting/ending * addresses of a stack given an address in the middle. */ - - if (kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE) - != KERN_SUCCESS) - panic("stack_alloc"); + kr = kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE); + if (kr != KERN_SUCCESS) + return kr; #if MACH_DEBUG stack_init(stack); @@ -211,6 +211,7 @@ void stack_alloc( } stack_attach(thread, stack, resume); + return KERN_SUCCESS; } /* diff --git a/kern/thread_swap.c b/kern/thread_swap.c index dc2924a..20ad040 100644 --- a/kern/thread_swap.c +++ b/kern/thread_swap.c @@ -123,15 +123,18 @@ void thread_swapin(thread_t 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_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. @@ -144,6 +147,7 @@ void thread_doswapin(thread_t thread) thread_setrun(thread, TRUE); thread_unlock(thread); (void) splx(s); + return KERN_SUCCESS; } /* @@ -163,13 +167,20 @@ void __attribute__((noreturn)) 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); diff --git a/kern/thread_swap.h b/kern/thread_swap.h index 9d64537..d032acc 100644 --- a/kern/thread_swap.h +++ b/kern/thread_swap.h @@ -37,7 +37,7 @@ */ extern void swapper_init(void); extern void thread_swapin(thread_t thread); -extern void thread_doswapin(thread_t thread); +extern kern_return_t thread_doswapin(thread_t thread); extern void swapin_thread(void) __attribute__((noreturn)); #endif /* _KERN_THREAD_SWAP_H_ */ |