|
|
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:
1.1.1.3 ! root 89: void thread_swapin(thread_t thread)
1.1 root 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();
1.1.1.3 ! root 99: enqueue_tail(&swapin_queue, &(thread->links));
1.1 root 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: */
1.1.1.3 ! root 126: void thread_doswapin(thread_t thread)
1.1 root 127: {
128: spl_t s;
129:
130: /*
131: * Allocate the kernel stack.
132: */
133:
134: stack_alloc(thread, thread_continue);
135:
136: /*
137: * Place on run queue.
138: */
139:
140: s = splsched();
141: thread_lock(thread);
142: thread->state &= ~(TH_SWAPPED | TH_SW_COMING_IN);
143: if (thread->state & TH_RUN)
144: thread_setrun(thread, TRUE);
145: thread_unlock(thread);
146: (void) splx(s);
147: }
148:
149: /*
150: * swapin_thread: [exported]
151: *
152: * This procedure executes as a kernel thread. Threads that need to
153: * be swapped in are swapped in by this thread.
154: */
1.1.1.3 ! root 155: void __attribute__((noreturn)) swapin_thread_continue(void)
1.1 root 156: {
157: for (;;) {
1.1.1.3 ! root 158: thread_t thread;
1.1 root 159: spl_t s;
160:
161: s = splsched();
162: swapper_lock();
163:
164: while ((thread = (thread_t) dequeue_head(&swapin_queue))
165: != THREAD_NULL) {
166: swapper_unlock();
167: (void) splx(s);
168:
169: thread_doswapin(thread); /* may block */
170:
171: s = splsched();
172: swapper_lock();
173: }
174:
175: assert_wait((event_t) &swapin_queue, FALSE);
176: swapper_unlock();
177: (void) splx(s);
178: counter(c_swapin_thread_block++);
179: thread_block(swapin_thread_continue);
180: }
181: }
182:
1.1.1.2 root 183: void swapin_thread(void)
1.1 root 184: {
185: stack_privilege(current_thread());
186:
187: swapin_thread_continue();
188: /*NOTREACHED*/
189: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.