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