|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: * ! 52: * File: kern/thread_swap.c ! 53: * Author: Avadis Tevanian, Jr. ! 54: * Date: 1987 ! 55: * ! 56: * Mach thread swapper: ! 57: * Find idle threads to swap, freeing up kernel stack resources ! 58: * at the expense of allowing them to execute. ! 59: * ! 60: * Swap in threads that need to be run. This is done here ! 61: * by the swapper thread since it cannot be done (in general) ! 62: * when the kernel tries to place a thread on a run queue. ! 63: * ! 64: * Note: The act of swapping a thread in Mach does not mean that ! 65: * its memory gets forcibly swapped to secondary storage. The memory ! 66: * for the task corresponding to a swapped thread is paged out ! 67: * through the normal paging mechanism. ! 68: * ! 69: */ ! 70: ! 71: #include <ipc/ipc_kmsg.h> ! 72: #include <kern/counters.h> ! 73: #include <kern/thread.h> ! 74: #include <kern/lock.h> ! 75: #include <vm/vm_map.h> ! 76: #include <vm/vm_kern.h> ! 77: #include <mach/vm_param.h> ! 78: #include <kern/sched_prim.h> ! 79: #include <kern/processor.h> ! 80: #include <kern/thread_swap.h> ! 81: #include <machine/machspl.h> /* for splsched */ ! 82: ! 83: ! 84: ! 85: queue_head_t swapin_queue; ! 86: decl_simple_lock_data(, swapper_lock_data) ! 87: ! 88: #define swapper_lock() simple_lock(&swapper_lock_data) ! 89: #define swapper_unlock() simple_unlock(&swapper_lock_data) ! 90: ! 91: /* ! 92: * swapper_init: [exported] ! 93: * ! 94: * Initialize the swapper module. ! 95: */ ! 96: void swapper_init() ! 97: { ! 98: queue_init(&swapin_queue); ! 99: simple_lock_init(&swapper_lock_data); ! 100: } ! 101: ! 102: /* ! 103: * thread_swapin: [exported] ! 104: * ! 105: * Place the specified thread in the list of threads to swapin. It ! 106: * is assumed that the thread is locked, therefore we are at splsched. ! 107: * ! 108: * We don't bother with stack_alloc_try to optimize swapin; ! 109: * our callers have already tried that route. ! 110: */ ! 111: ! 112: void thread_swapin(thread) ! 113: thread_t thread; ! 114: { ! 115: switch (thread->state & TH_SWAP_STATE) { ! 116: case TH_SWAPPED: ! 117: /* ! 118: * Swapped out - queue for swapin thread. ! 119: */ ! 120: thread->state = (thread->state & ~TH_SWAP_STATE) ! 121: | TH_SW_COMING_IN; ! 122: swapper_lock(); ! 123: enqueue_tail(&swapin_queue, (queue_entry_t) thread); ! 124: swapper_unlock(); ! 125: thread_wakeup((event_t) &swapin_queue); ! 126: break; ! 127: ! 128: case TH_SW_COMING_IN: ! 129: /* ! 130: * Already queued for swapin thread, or being ! 131: * swapped in. ! 132: */ ! 133: break; ! 134: ! 135: default: ! 136: /* ! 137: * Already swapped in. ! 138: */ ! 139: panic("thread_swapin"); ! 140: } ! 141: } ! 142: ! 143: /* ! 144: * thread_doswapin: ! 145: * ! 146: * Swapin the specified thread, if it should be runnable, then put ! 147: * it on a run queue. No locks should be held on entry, as it is ! 148: * likely that this routine will sleep (waiting for stack allocation). ! 149: */ ! 150: void thread_doswapin(thread) ! 151: register thread_t thread; ! 152: { ! 153: spl_t s; ! 154: ! 155: /* ! 156: * Allocate the kernel stack. ! 157: */ ! 158: ! 159: stack_alloc(thread, thread_continue); ! 160: ! 161: /* ! 162: * Place on run queue. ! 163: */ ! 164: ! 165: s = splsched(); ! 166: thread_lock(thread); ! 167: thread->state &= ~(TH_SWAPPED | TH_SW_COMING_IN); ! 168: if (thread->state & TH_RUN) ! 169: thread_setrun(thread, TRUE); ! 170: thread_unlock(thread); ! 171: (void) splx(s); ! 172: } ! 173: ! 174: /* ! 175: * swapin_thread: [exported] ! 176: * ! 177: * This procedure executes as a kernel thread. Threads that need to ! 178: * be swapped in are swapped in by this thread. ! 179: */ ! 180: void swapin_thread_continue() ! 181: { ! 182: for (;;) { ! 183: register thread_t thread; ! 184: spl_t s; ! 185: ! 186: s = splsched(); ! 187: swapper_lock(); ! 188: ! 189: while ((thread = (thread_t) dequeue_head(&swapin_queue)) ! 190: != THREAD_NULL) { ! 191: swapper_unlock(); ! 192: (void) splx(s); ! 193: ! 194: thread_doswapin(thread); /* may block */ ! 195: ! 196: s = splsched(); ! 197: swapper_lock(); ! 198: } ! 199: ! 200: assert_wait((event_t) &swapin_queue, FALSE); ! 201: swapper_unlock(); ! 202: (void) splx(s); ! 203: counter(c_swapin_thread_block++); ! 204: thread_block_with_continuation(swapin_thread_continue); ! 205: } ! 206: } ! 207: ! 208: void swapin_thread() ! 209: { ! 210: stack_privilege(current_thread()); ! 211: current_thread()->vm_privilege = TRUE; ! 212: ! 213: swapin_thread_continue(); ! 214: /*NOTREACHED*/ ! 215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.