|
|
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>
1.1.1.2 ! root 49: #include <kern/debug.h>
1.1 root 50: #include <kern/thread.h>
51: #include <kern/lock.h>
52: #include <vm/vm_map.h>
53: #include <vm/vm_kern.h>
54: #include <mach/vm_param.h>
55: #include <kern/sched_prim.h>
56: #include <kern/processor.h>
57: #include <kern/thread_swap.h>
58: #include <machine/machspl.h> /* for splsched */
59:
60:
61:
62: queue_head_t swapin_queue;
63: decl_simple_lock_data(, swapper_lock_data)
64:
65: #define swapper_lock() simple_lock(&swapper_lock_data)
66: #define swapper_unlock() simple_unlock(&swapper_lock_data)
67:
68: /*
69: * swapper_init: [exported]
70: *
71: * Initialize the swapper module.
72: */
1.1.1.2 ! root 73: void swapper_init(void)
1.1 root 74: {
75: queue_init(&swapin_queue);
76: simple_lock_init(&swapper_lock_data);
77: }
78:
79: /*
80: * thread_swapin: [exported]
81: *
82: * Place the specified thread in the list of threads to swapin. It
83: * is assumed that the thread is locked, therefore we are at splsched.
84: *
85: * We don't bother with stack_alloc_try to optimize swapin;
86: * our callers have already tried that route.
87: */
88:
89: void thread_swapin(thread)
90: thread_t thread;
91: {
92: switch (thread->state & TH_SWAP_STATE) {
93: case TH_SWAPPED:
94: /*
95: * Swapped out - queue for swapin thread.
96: */
97: thread->state = (thread->state & ~TH_SWAP_STATE)
98: | TH_SW_COMING_IN;
99: swapper_lock();
100: enqueue_tail(&swapin_queue, (queue_entry_t) thread);
101: swapper_unlock();
102: thread_wakeup((event_t) &swapin_queue);
103: break;
104:
105: case TH_SW_COMING_IN:
106: /*
107: * Already queued for swapin thread, or being
108: * swapped in.
109: */
110: break;
111:
112: default:
113: /*
114: * Already swapped in.
115: */
116: panic("thread_swapin");
117: }
118: }
119:
120: /*
121: * thread_doswapin:
122: *
123: * Swapin the specified thread, if it should be runnable, then put
124: * it on a run queue. No locks should be held on entry, as it is
125: * likely that this routine will sleep (waiting for stack allocation).
126: */
127: void thread_doswapin(thread)
128: register thread_t thread;
129: {
130: spl_t s;
131:
132: /*
133: * Allocate the kernel stack.
134: */
135:
136: stack_alloc(thread, thread_continue);
137:
138: /*
139: * Place on run queue.
140: */
141:
142: s = splsched();
143: thread_lock(thread);
144: thread->state &= ~(TH_SWAPPED | TH_SW_COMING_IN);
145: if (thread->state & TH_RUN)
146: thread_setrun(thread, TRUE);
147: thread_unlock(thread);
148: (void) splx(s);
149: }
150:
151: /*
152: * swapin_thread: [exported]
153: *
154: * This procedure executes as a kernel thread. Threads that need to
155: * be swapped in are swapped in by this thread.
156: */
1.1.1.2 ! root 157: void swapin_thread_continue(void)
1.1 root 158: {
159: for (;;) {
160: register thread_t thread;
161: spl_t s;
162:
163: s = splsched();
164: swapper_lock();
165:
166: while ((thread = (thread_t) dequeue_head(&swapin_queue))
167: != THREAD_NULL) {
168: swapper_unlock();
169: (void) splx(s);
170:
171: thread_doswapin(thread); /* may block */
172:
173: s = splsched();
174: swapper_lock();
175: }
176:
177: assert_wait((event_t) &swapin_queue, FALSE);
178: swapper_unlock();
179: (void) splx(s);
180: counter(c_swapin_thread_block++);
181: thread_block(swapin_thread_continue);
182: }
183: }
184:
1.1.1.2 ! root 185: void swapin_thread(void)
1.1 root 186: {
187: stack_privilege(current_thread());
188:
189: swapin_thread_continue();
190: /*NOTREACHED*/
191: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.