summaryrefslogtreecommitdiff
path: root/kern/thread.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-07-02 16:20:44 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-28 15:48:04 +0200
commit66fa48d924d6898c97eb29a1165bbbc0f08c6ab4 (patch)
tree6b4798c6fd55f97fad06f7b4d854fa23a4f84d27 /kern/thread.c
parentff7a6dae1e8a6a4d5ce4591b682116e22e76dc18 (diff)
kern: allocate kernel stacks using the slab allocator
* kern/slab.c (kmem_cache_init): Relax alignment restriction. * kern/thread.c (stack_cache): New variable. (stack_alloc): Use the slab allocator. (stack_collect): Adjust accordingly. (thread_init): Initialize `stack_cache'.
Diffstat (limited to 'kern/thread.c')
-rw-r--r--kern/thread.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/kern/thread.c b/kern/thread.c
index b996559..3586e34 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -165,6 +165,11 @@ boolean_t stack_alloc_try(
}
/*
+ * We allocate kernel stacks using the slab allocator.
+ */
+static struct kmem_cache stack_cache;
+
+/*
* stack_alloc:
*
* Allocate a kernel stack for a thread.
@@ -195,15 +200,10 @@ kern_return_t 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.
- */
- kr = kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE);
- if (kr != KERN_SUCCESS)
- return kr;
+ stack = kmem_cache_alloc(&stack_cache);
+ assert ((stack & (KERNEL_STACK_SIZE-1)) == 0);
+ if (stack == 0)
+ return KERN_RESOURCE_SHORTAGE;
#if MACH_DEBUG
stack_init(stack);
@@ -265,7 +265,7 @@ void stack_collect(void)
#if MACH_DEBUG
stack_finalize(stack);
#endif /* MACH_DEBUG */
- kmem_free(kmem_map, stack, KERNEL_STACK_SIZE);
+ kmem_cache_free(&stack_cache, stack);
s = splsched();
stack_lock();
@@ -301,6 +301,15 @@ void thread_init(void)
NULL, NULL, NULL, 0);
/*
+ * 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.
+ */
+ kmem_cache_init(&stack_cache, "stack",
+ KERNEL_STACK_SIZE, KERNEL_STACK_SIZE,
+ NULL, NULL, NULL, 0);
+
+ /*
* Fill in a template thread for fast initialization.
* [Fields that must be (or are typically) reset at
* time of creation are so noted.]