|
|
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.