X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..43866e378188c25dd1e2208016ab3cbeb086ae6c:/osfmk/kern/thread_swap.c diff --git a/osfmk/kern/thread_swap.c b/osfmk/kern/thread_swap.c index 46bb6cc9e..60655208a 100644 --- a/osfmk/kern/thread_swap.c +++ b/osfmk/kern/thread_swap.c @@ -3,19 +3,22 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -49,23 +52,6 @@ */ /* */ -/* - * - * File: kern/thread_swap.c - * Author: Avadis Tevanian, Jr. - * Date: 1987 - * - * Mach thread swapper: - * Swap in threads that need to be run. This is done here - * by the swapper thread since it cannot be done (in general) - * when the kernel tries to place a thread on a run queue. - * - * Note: The act of swapping a thread in Mach does not mean that - * its memory gets forcibly swapped to secondary storage. The memory - * for the task corresponding to a swapped thread is paged out - * through the normal paging mechanism. - * - */ #include #include @@ -73,7 +59,6 @@ #include #include #include -#include #include #include #include /* for splsched */ @@ -82,58 +67,60 @@ #include queue_head_t swapin_queue; -decl_simple_lock_data(, swapper_lock_data) - -#define swapper_lock() simple_lock(&swapper_lock_data) -#define swapper_unlock() simple_unlock(&swapper_lock_data) +decl_simple_lock_data(,swapin_lock) mach_counter_t c_swapin_thread_block; +void swapin_thread(void); + /* - * swapper_init: [exported] + * swapin_init: [exported] * * Initialize the swapper module. */ -void swapper_init() +void +swapin_init(void) { queue_init(&swapin_queue); - simple_lock_init(&swapper_lock_data, ETAP_THREAD_SWAPPER); + simple_lock_init(&swapin_lock, ETAP_THREAD_SWAPPER); + kernel_thread_with_priority( + kernel_task, BASEPRI_PREEMPT - 2, + swapin_thread, TRUE, TRUE); } /* * thread_swapin: [exported] * - * Place the specified thread in the list of threads to swapin. It - * is assumed that the thread is locked, therefore we are at splsched. - * - * We don't bother with stack_alloc_try to optimize swapin; - * our callers have already tried that route. + * Place the specified thread in the list of threads to swapin. + * Called with thread locked, returned unlocked. */ -void thread_swapin(thread) - thread_t thread; +void +thread_swapin( + register thread_t thread) { switch (thread->state & TH_STACK_STATE) { + case TH_STACK_HANDOFF: /* - * Swapped out - queue for swapin thread. + * Swapped out. */ - thread->state = (thread->state & ~TH_STACK_STATE) - | TH_STACK_COMING_IN; - swapper_lock(); + thread->state = (thread->state & ~TH_STACK_STATE) | TH_STACK_ALLOC; + thread_unlock(thread); + simple_lock(&swapin_lock); enqueue_tail(&swapin_queue, (queue_entry_t) thread); - swapper_unlock(); - thread_wakeup((event_t) &swapin_queue); + simple_unlock(&swapin_lock); + thread_wakeup((event_t)&swapin_queue); break; - case TH_STACK_COMING_IN: + case TH_STACK_ALLOC: /* - * Already queued for swapin thread, or being - * swapped in. + * Already queued. */ + thread_unlock(thread); break; - default: + default: /* * Already swapped in. */ @@ -145,18 +132,14 @@ void thread_swapin(thread) * thread_doswapin: * * Swapin the specified thread, if it should be runnable, then put - * 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). + * it on a run queue. */ -void thread_doswapin(thread) - register thread_t thread; +void +thread_doswapin( + register thread_t thread) { - spl_t s; - vm_offset_t stack; - - /* - * do machdep allocation - */ + vm_offset_t stack; + spl_t s; /* * Allocate the kernel stack. @@ -167,12 +150,11 @@ void thread_doswapin(thread) /* * Place on run queue. */ - s = splsched(); thread_lock(thread); - thread->state &= ~(TH_STACK_HANDOFF | TH_STACK_COMING_IN); + thread->state &= ~(TH_STACK_HANDOFF | TH_STACK_ALLOC); if (thread->state & TH_RUN) - thread_setrun(thread, TRUE, FALSE); + thread_setrun(thread, HEAD_Q); thread_unlock(thread); (void) splx(s); } @@ -183,42 +165,39 @@ 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 +swapin_thread_continue(void) { - for (;;) { - register thread_t thread; - spl_t s; - - s = splsched(); - swapper_lock(); - - while ((thread = (thread_t) dequeue_head(&swapin_queue)) - != THREAD_NULL) { - swapper_unlock(); - (void) splx(s); - - thread_doswapin(thread); /* may block */ - - s = splsched(); - swapper_lock(); - } - - assert_wait((event_t) &swapin_queue, THREAD_UNINT); - swapper_unlock(); - (void) splx(s); - counter(c_swapin_thread_block++); -#if defined (__i386__) - thread_block((void (*)(void)) 0); -#else - thread_block(swapin_thread_continue); -#endif + register thread_t thread; + + (void)splsched(); + simple_lock(&swapin_lock); + + while ((thread = (thread_t)dequeue_head(&swapin_queue)) != THREAD_NULL) { + simple_unlock(&swapin_lock); + (void)spllo(); + + thread_doswapin(thread); + + (void)splsched(); + simple_lock(&swapin_lock); } + + assert_wait((event_t)&swapin_queue, THREAD_UNINT); + simple_unlock(&swapin_lock); + (void)spllo(); + + counter(c_swapin_thread_block++); + thread_block(swapin_thread_continue); + /*NOTREACHED*/ } -void swapin_thread() +void +swapin_thread(void) { - stack_privilege(current_thread()); - current_thread()->vm_privilege = TRUE; + thread_t self = current_thread(); + + stack_privilege(self); swapin_thread_continue(); /*NOTREACHED*/