summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kern/sched_prim.h2
-rw-r--r--kern/thread.c11
-rw-r--r--kern/thread_swap.c17
-rw-r--r--kern/thread_swap.h2
4 files changed, 22 insertions, 10 deletions
diff --git a/kern/sched_prim.h b/kern/sched_prim.h
index fd989b6c..62698dc2 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 009884ce..f52c95b8 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 dc2924a9..20ad0409 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 9d645373..d032accf 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_ */