FreeBSD/Linux Kernel Cross Reference
sys/kern/thread.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993-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 Software.Distribution@CS.CMU.EDU
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 * HISTORY
28 * $Log: thread.c,v $
29 * Revision 2.34 93/11/17 17:30:37 dbg
30 * If current thread is being terminated and is already inactive,
31 * hold it. The thread terminating it may not yet have called
32 * thread_halt.
33 * [93/08/26 dbg]
34 *
35 * Made obsolete priority routines call new routines directly.
36 * They will work only if the thread is timesharing, or has a
37 * policy parameter that consists of one integer... but by the time
38 * there are any more, the obsolete calls should be gone!
39 * [93/08/18 dbg]
40 *
41 * Added thread_dealloate_nowait for use by AST routines.
42 * [93/07/21 dbg]
43 *
44 * Changed termination protocol to simultaneously clear active and
45 * remove thread_port association.
46 * [93/06/29 dbg]
47 *
48 * Break up thread lock, to simplify interactions between thread
49 * lock and processor set lock and to reduce the amount of code
50 * that runs with interrupts blocked. There are now three locks:
51 * . thread_ref_lock locks the reference count
52 * . thread_sched_lock locks fields involved with scheduling
53 * state machine
54 * . thread_lock locks everything else.
55 *
56 * Revise processor set locking. Order is now:
57 * thread_lock -> pset_lock -> thread_ref_lock
58 *
59 * Move calls to evc_notify_abort into thread_halt.
60 * [93/05/26 dbg]
61 *
62 * Moved scheduling policy fields to end of thread data
63 * structure. The scheduling information is policy-specific.
64 * [93/05/10 dbg]
65 *
66 * Declare continuations as not returning.
67 * [93/05/04 dbg]
68 *
69 * Initialize rt_period and rt_deadline to largest possible
70 * time_spec_t.
71 * [93/04/15 dbg]
72 *
73 * Removed thread->depress_timer.
74 * [93/04/08 dbg]
75 *
76 * Changed global scheduling policy to policy within scheduling
77 * domain.
78 * [93/03/31 dbg]
79 *
80 * Always enable fixed-priority threads.
81 * [93/03/27 dbg]
82 *
83 * Thread->sched_data (quantum for fixed-priority threads) is now
84 * kept in microseconds internally.
85 *
86 * TIMER_RATE is now USAGE_RATE.
87 *
88 * Removed include of kern/sched.h. Moved routines that manipulate
89 * thread state to kern/sched_prim.c: thread_halt,
90 * thread_halt_self, thread_hold, thread_dowait, thread_release,
91 * thread_suspend, thread_resume.
92 *
93 * Added AST_KERNEL_CHECK to reaper thread.
94 * [93/01/28 dbg]
95 *
96 * Revision 2.33 93/08/10 15:11:43 mrt
97 * Conditionalized atm hooks.
98 * [93/07/30 cmaeda]
99 * Included hooks for network interface.
100 * [93/06/09 15:44:22 jcb]
101 *
102 * Revision 2.32 93/05/15 18:55:33 mrt
103 * machparam.h -> machspl.h
104 *
105 * Revision 2.31 93/01/24 13:20:13 danner
106 * Add call to evc_notify_abort to thread_abort; correct call in
107 * thread_terminate.
108 * [93/01/22 danner]
109 *
110 * We must explicitly set "new_thread->pc_sample.buffer = 0;" so
111 * that we don't think we have a sampling buffer.
112 * [93/01/13 rvb]
113 *
114 * Revision 2.30 93/01/21 12:22:49 danner
115 * Add call in thread_deallocate to evc_notify_thread_destroy to
116 * deal with threads terminating while in evc_wait.
117 * [93/01/20 bershad]
118 *
119 * Revision 2.29 93/01/14 17:36:55 danner
120 * Added ANSI function prototypes.
121 * [92/12/29 dbg]
122 *
123 * 64bit cleanup. Proper spl typing.
124 * [92/12/01 af]
125 *
126 * Changed thread_create to hold both the pset and task locks while
127 * inserting the new thread in the lists.
128 * [92/11/20 dbg]
129 *
130 * Fixed pset lock ordering. Pset lock must be taken before task
131 * and thread locks.
132 * [92/10/28 dbg]
133 *
134 * Revision 2.28 92/08/03 17:39:56 jfriedl
135 * removed silly prototypes
136 * [92/08/02 jfriedl]
137 *
138 * Revision 2.27 92/05/21 17:16:33 jfriedl
139 * Appended 'U' to constants that would otherwise be signed.
140 * Changed name of one of the two local 'thread' variables in
141 * processor_set_stack_usage() to 'tmp_thread' for cleanness.
142 * [92/05/16 jfriedl]
143 *
144 * Revision 2.26 92/04/01 19:33:34 rpd
145 * Restored continuation in AST_TERMINATE case of thread_halt_self.
146 * [92/03/22 rpd]
147 *
148 * Revision 2.25 92/03/10 16:24:22 jsb
149 * Remove continuation from AST_TERMINATE case of thread_halt_self
150 * so that "zombie walks" is reachable.
151 * [92/02/25 dlb]
152 *
153 * Revision 2.24 92/02/19 16:07:03 elf
154 * Change calls to compute_priority.
155 * [92/01/19 rwd]
156 *
157 * Revision 2.23 92/01/03 20:18:56 dbg
158 * Make thread_wire really reserve a kernel stack.
159 * [91/12/18 dbg]
160 *
161 * Revision 2.22 91/12/13 14:54:53 jsb
162 * Removed thread_resume_from_kernel.
163 * [91/12/12 17:40:12 af]
164 *
165 * Revision 2.21 91/08/28 11:14:43 jsb
166 * Fixed thread_halt, mach_msg_interrupt interaction.
167 * Added checks for thread_exception_return, thread_bootstrap_return.
168 * [91/08/03 rpd]
169 *
170 * Revision 2.20 91/07/31 17:49:10 dbg
171 * Call pcb_module_init from thread_init.
172 * [91/07/26 dbg]
173 *
174 * When halting a thread: if it is waiting at a continuation with a
175 * known cleanup routine, call the cleanup routine instead of
176 * resuming the thread.
177 * [91/06/21 dbg]
178 *
179 * Revise scheduling state machine.
180 * [91/05/22 dbg]
181 *
182 * Add thread_wire.
183 * [91/05/14 dbg]
184 *
185 * Revision 2.19 91/06/25 10:29:48 rpd
186 * Picked up dlb's thread_doassign no-op fix.
187 * [91/06/23 rpd]
188 *
189 * Revision 2.18 91/05/18 14:34:09 rpd
190 * Fixed stack_alloc to use kmem_alloc_aligned.
191 * [91/05/14 rpd]
192 * Added argument to kernel_thread.
193 * [91/04/03 rpd]
194 *
195 * Changed thread_deallocate to reset timer and depress_timer.
196 * [91/03/31 rpd]
197 *
198 * Replaced stack_free_reserved and swap_privilege with stack_privilege.
199 * [91/03/30 rpd]
200 *
201 * Revision 2.17 91/05/14 16:48:35 mrt
202 * Correcting copyright
203 *
204 * Revision 2.16 91/05/08 12:49:14 dbg
205 * Add volatile declarations.
206 * [91/04/26 14:44:13 dbg]
207 *
208 * Revision 2.15 91/03/16 14:52:40 rpd
209 * Fixed the initialization of stack_lock_data.
210 * [91/03/11 rpd]
211 * Updated for new kmem_alloc interface.
212 * [91/03/03 rpd]
213 * Removed ith_saved.
214 * [91/02/16 rpd]
215 *
216 * Added stack_alloc_max.
217 * [91/02/10 rpd]
218 * Added active_stacks.
219 * [91/01/28 rpd]
220 * Can't use thread_dowait on the current thread now.
221 * Added reaper_thread_continue.
222 * Added stack_free_reserved.
223 * [91/01/20 rpd]
224 *
225 * Removed thread_swappable.
226 * Allow swapped threads on the run queues.
227 * Changed the AST interface.
228 * [91/01/17 rpd]
229 *
230 * Revision 2.14 91/02/05 17:30:14 mrt
231 * Changed to new Mach copyright
232 * [91/02/01 16:19:30 mrt]
233 *
234 * Revision 2.13 91/01/08 15:17:57 rpd
235 * Added KEEP_STACKS support.
236 * [91/01/06 rpd]
237 * Added consider_thread_collect, thread_collect_scan.
238 * [91/01/03 rpd]
239 *
240 * Added locking to the stack package. Added stack_collect.
241 * [90/12/31 rpd]
242 * Changed thread_dowait to discard the stacks of suspended threads.
243 * [90/12/22 rpd]
244 * Added continuation argument to thread_block.
245 * [90/12/08 rpd]
246 *
247 * Changed thread_create to make new threads be swapped.
248 * Changed kernel_thread to swapin the threads.
249 * [90/11/20 rpd]
250 *
251 * Removed stack_free/stack_alloc/etc.
252 * [90/11/12 rpd]
253 *
254 * Changed thread_create to let pcb_init handle all pcb initialization.
255 * [90/11/11 rpd]
256 *
257 * Revision 2.12 90/12/05 23:29:09 af
258 *
259 *
260 * Revision 2.11 90/12/05 20:42:19 af
261 * Added (temporarily, until we define the right new primitive with
262 * the RTMach guys) thread_resume_from_kernel() for internal kernel
263 * use only.
264 *
265 * Revision 2.7.1.1 90/09/25 13:06:04 dlb
266 * Inline thread_hold in thread_suspend and thread_release in
267 * thread_resume (while still holding the thread lock in both).
268 * This eliminates a long-standing MP bug.
269 * [90/09/20 dlb]
270 *
271 * Revision 2.10 90/11/05 14:31:46 rpd
272 * Unified untimeout and untimeout_try.
273 * [90/10/29 rpd]
274 *
275 * Revision 2.9 90/10/25 14:45:37 rwd
276 * Added host_stack_usage and processor_set_stack_usage.
277 * [90/10/22 rpd]
278 *
279 * Removed pausing code in stack_alloc/stack_free.
280 * It was broken and it isn't needed.
281 * Added code to check how much stack is actually used.
282 * [90/10/21 rpd]
283 *
284 * Revision 2.8 90/10/12 12:34:37 rpd
285 * Fixed HW_FOOTPRINT code in thread_create.
286 * Fixed a couple bugs in thread_policy.
287 * [90/10/09 rpd]
288 *
289 * Revision 2.7 90/08/27 22:04:03 dbg
290 * Fixed thread_info to return the correct count.
291 * [90/08/23 rpd]
292 *
293 * Revision 2.6 90/08/27 11:52:25 dbg
294 * Remove unneeded mode parameter to thread_start.
295 * Remove u_zone, thread_deallocate_interrupt.
296 * [90/07/17 dbg]
297 *
298 * Revision 2.5 90/08/07 17:59:04 rpd
299 * Removed tmp_address, tmp_object fields.
300 * Picked up depression abort functionality in thread_abort.
301 * Picked up initialization of max_priority in kernel_thread.
302 * Picked up revised priority computation in thread_create.
303 * Removed in-transit check from thread_max_priority.
304 * Picked up interprocessor-interrupt optimization in thread_dowait.
305 * [90/08/07 rpd]
306 *
307 * Revision 2.4 90/06/02 14:56:54 rpd
308 * Converted to new IPC and scheduling technology.
309 * [90/03/26 22:24:06 rpd]
310 *
311 * Revision 2.3 90/02/22 20:04:12 dbg
312 * Initialize per-thread global VM variables.
313 * Clean up global variables in thread_deallocate().
314 * [89/04/29 mwyoung]
315 *
316 * Revision 2.2 89/09/08 11:26:53 dbg
317 * Allocate thread kernel stack with kmem_alloc_wired to get
318 * separate vm_object for it.
319 * [89/08/18 dbg]
320 *
321 * 19-Aug-88 David Golub (dbg) at Carnegie-Mellon University
322 * Removed all non-MACH code.
323 *
324 * 11-Aug-88 David Black (dlb) at Carnegie-Mellon University
325 * Rewrote exit logic to use new ast mechanism. Includes locking
326 * bug fix to thread_terminate().
327 *
328 * 9-Aug-88 David Black (dlb) at Carnegie-Mellon University
329 * first_quantum replaces preempt_pri.
330 *
331 * Revision 2.3 88/08/06 18:26:41 rpd
332 * Changed to use ipc_thread_lock/ipc_thread_unlock macros.
333 * Eliminated use of kern/mach_ipc_defs.h.
334 * Added definitions of all_threads, all_threads_lock.
335 *
336 * 4-May-88 David Golub (dbg) and David Black (dlb) at CMU
337 * Remove vax-specific code. Add register declarations.
338 * MACH_TIME_NEW now standard. Moved thread_read_times to timer.c.
339 * SIMPLE_CLOCK: clock drift compensation in cpu_usage calculation.
340 * Initialize new fields in thread_create(). Implemented cpu usage
341 * calculation in thread_info(). Added argument to thread_setrun.
342 * Initialization changes for MACH_TIME_NEW.
343 *
344 * 13-Apr-88 David Black (dlb) at Carnegie-Mellon University
345 * Rewrite kernel stack retry code to eliminate races and handle
346 * termination correctly.
347 *
348 * 19-Feb-88 David Kirschen (kirschen) at Encore Computer Corporation
349 * Retry if kernel stacks exhausted on thread_create
350 *
351 * 12-Feb-88 David Black (dlb) at Carnegie-Mellon University
352 * Fix MACH_TIME_NEW code.
353 *
354 * 1-Feb-88 David Golub (dbg) at Carnegie-Mellon University
355 * In thread_halt: mark the victim thread suspended/runnable so that it
356 * will notify the caller when it hits the next interruptible wait.
357 * The victim may not immediately proceed to a clean point once it
358 * is awakened.
359 *
360 * 21-Jan-88 David Golub (dbg) at Carnegie-Mellon University
361 * Use new swapping state machine. Moved thread_swappable to
362 * thread_swap.c.
363 *
364 * 17-Jan-88 David Golub (dbg) at Carnegie-Mellon University
365 * Added new thread interfaces: thread_suspend, thread_resume,
366 * thread_get_state, thread_set_state, thread_abort,
367 * thread_info. Old interfaces remain (temporarily) for binary
368 * compatibility, prefixed with 'xxx_'.
369 *
370 * 29-Dec-87 David Golub (dbg) at Carnegie-Mellon University
371 * Delinted.
372 *
373 * 15-Dec-87 David Golub (dbg) at Carnegie-Mellon University
374 * Made thread_reference and thread_deallocate check for null
375 * threads. Call pcb_terminate when a thread is deallocated.
376 * Call pcb_init with thread pointer instead of pcb pointer.
377 * Add missing case to thread_dowait.
378 *
379 * 9-Dec-87 David Golub (dbg) at Carnegie-Mellon University
380 * Rewrote thread termination to have a terminating thread clean up
381 * after itself.
382 *
383 * 9-Dec-87 David Black (dlb) at Carnegie-Mellon University
384 * Moved reaper invocation to thread_terminate from
385 * thread_deallocate. [XXX temporary pending rewrite.]
386 *
387 * 8-Dec-87 David Black (dlb) at Carnegie-Mellon University
388 * Added call to ipc_thread_disable.
389 *
390 * 4-Dec-87 David Black (dlb) at Carnegie-Mellon University
391 * Set ipc_kernel in kernel_thread().
392 *
393 * 3-Dec-87 David Black (dlb) at Carnegie-Mellon University
394 * Rewrote thread_create(). thread_terminate() must throw away
395 * an extra reference if called on the current thread [ref is
396 * held by caller who will not be returned to.] Locking bug fix
397 * to thread_status.
398 *
399 * 19-Nov-87 Avadis Tevanian (avie) at Carnegie-Mellon University
400 * Eliminated TT conditionals.
401 *
402 * 30-Oct-87 David Golub (dbg) at Carnegie-Mellon University
403 * Fix race condition in thread_deallocate for thread terminating
404 * itself.
405 *
406 * 23-Oct-87 David Golub (dbg) at Carnegie-Mellon University
407 * Correctly set thread_statistics fields.
408 *
409 * 13-Oct-87 David Black (dlb) at Carnegie-Mellon University
410 * Use counts for suspend and resume primitives.
411 *
412 * 5-Oct-87 David Golub (dbg) at Carnegie-Mellon University
413 * MACH_TT: Completely replaced scheduling state machine.
414 *
415 * 30-Sep-87 Michael Young (mwyoung) at Carnegie-Mellon University
416 * Added initialization of thread->flags in thread_create().
417 * Added thread_swappable().
418 * De-linted.
419 *
420 * 30-Sep-87 David Black (dlb) at Carnegie-Mellon University
421 * Rewrote thread_dowait to more effectively stop threads.
422 *
423 * 11-Sep-87 Robert Baron (rvb) at Carnegie-Mellon University
424 * Initialize thread fields and unix_lock.
425 *
426 * 9-Sep-87 David Black (dlb) at Carnegie-Mellon University
427 * Changed thread_dowait to count a thread as stopped if it is
428 * sleeping and will stop immediately when woken up. [i.e. is
429 * sleeping interruptibly]. Corresponding change to
430 * thread_terminate().
431 *
432 * 4-Aug-87 David Golub (dbg) at Carnegie-Mellon University
433 * Moved ipc_thread_terminate to thread_terminate (from
434 * thread_deallocate), to shut out other threads that are
435 * manipulating the thread via its thread_port.
436 *
437 * 29-Jul-87 David Golub (dbg) at Carnegie-Mellon University
438 * Make sure all deallocation calls are outside of locks - they may
439 * block. Moved task_deallocate from thread_deallocate to
440 * thread_destroy, since thread may blow up if task disappears while
441 * thread is running.
442 *
443 * 26-Jun-87 David Black (dlb) at Carnegie-Mellon University
444 * Added update_priority() call to thread_release() for any thread
445 * actually released.
446 *
447 * 23-Jun-87 David Black (dlb) at Carnegie-Mellon University
448 * Initialize thread priorities in thread_create() and kernel_thread().
449 *
450 * 10-Jun-87 Karl Hauth (hauth) at Carnegie-Mellon University
451 * Added code to fill in the thread_statistics structure.
452 *
453 * 1-Jun-87 Avadis Tevanian (avie) at Carnegie-Mellon University
454 * Added thread_statistics stub.
455 *
456 * 21-May-87 Avadis Tevanian (avie) at Carnegie-Mellon University
457 * Clear the thread u-area upon creation of a thread to keep
458 * consistent.
459 *
460 * 4-May-87 Avadis Tevanian (avie) at Carnegie-Mellon University
461 * Call uarea_init to initialize u-area stuff.
462 *
463 * 29-Apr-87 Avadis Tevanian (avie) at Carnegie-Mellon University
464 * Moved call to ipc_thread_terminate into the MACH_TT only branch
465 * to prevent problems with non-TT systems.
466 *
467 * 28-Apr-87 Avadis Tevanian (avie) at Carnegie-Mellon University
468 * Support the thread status information as a MiG refarray.
469 * [NOTE: turned off since MiG is still too braindamaged.]
470 *
471 * 23-Apr-87 Rick Rashid (rfr) at Carnegie-Mellon University
472 * Moved ipc_thread_terminate to thread_deallocate from
473 * thread_destroy to eliminate having the reaper call it after
474 * the task has been freed.
475 *
476 * 18-Mar-87 Avadis Tevanian (avie) at Carnegie-Mellon University
477 * Added reaper thread for deallocating threads that cannot
478 * deallocate themselves (some time ago).
479 *
480 * 17-Mar-87 David Golub (dbg) at Carnegie-Mellon University
481 * De-linted.
482 *
483 * 14-Mar-87 Avadis Tevanian (avie) at Carnegie-Mellon University
484 * Panic if no space left in the kernel map for stacks.
485 *
486 * 6-Mar-87 Avadis Tevanian (avie) at Carnegie-Mellon University
487 * Add kernel_thread routine which starts up kernel threads.
488 *
489 * 4-Mar-87 Avadis Tevanian (avie) at Carnegie-Mellon University
490 * Make thread_terminate work.
491 *
492 * 2-Mar-87 Avadis Tevanian (avie) at Carnegie-Mellon University
493 * New kernel stack allocation mechanism.
494 *
495 * 27-Feb-87 David L. Black (dlb) at Carnegie-Mellon University
496 * MACH_TIME_NEW: Added timer inits to thread_create().
497 *
498 * 24-Feb-87 Avadis Tevanian (avie) at Carnegie-Mellon University
499 * Rewrote thread_suspend/thread_hold and added thread_wait for new
500 * user synchronization paradigm.
501 *
502 * 24-Feb-87 Avadis Tevanian (avie) at Carnegie-Mellon University
503 * Reorded locking protocol in thread_deallocate for the
504 * all_threads_lock (this allows one to reference a thread then
505 * release the all_threads_lock when scanning the thread list).
506 *
507 * 31-Jan-87 Avadis Tevanian (avie) at Carnegie-Mellon University
508 * Merged in my changes for real thread implementation.
509 *
510 * 30-Sep-86 Avadis Tevanian (avie) at Carnegie-Mellon University
511 * Make floating u-area work, maintain list of threads per task.
512 *
513 * 1-Aug-86 Michael Young (mwyoung) at Carnegie-Mellon University
514 * Added initialization for Mach-style IPC.
515 *
516 * 7-Jul-86 Rick Rashid (rfr) at Carnegie-Mellon University
517 * Added thread_in_use_chain to keep track of threads which
518 * have been created but not yet destroyed.
519 *
520 * 31-May-86 Avadis Tevanian (avie) at Carnegie-Mellon University
521 * Initialize thread state field to THREAD_WAITING. Some general
522 * cleanup.
523 *
524 */
525 /*
526 * File: kern/thread.c
527 * Author: Avadis Tevanian, Jr., Michael Wayne Young, David Golub
528 * Date: 1986
529 *
530 * Thread management primitives implementation.
531 */
532
533 #include <cpus.h>
534 #include <hw_footprint.h>
535 #include <mach_host.h>
536 #include <mach_kdb.h>
537 #include <mach_pcsample.h>
538 #include <mach_rt.h>
539 #include <simple_clock.h>
540 #include <mach_debug.h>
541 #include <net_atm.h>
542
543 #include <mach/std_types.h>
544 #include <mach/policy.h>
545 #include <mach/thread_info.h>
546 #include <mach/thread_special_ports.h>
547 #include <mach/thread_status.h>
548 #include <mach/time_value.h>
549 #include <mach/vm_param.h>
550
551 #include <kern/ast.h>
552 #include <kern/clock.h>
553 #include <kern/counters.h>
554 #include <kern/ipc_tt.h>
555 #include <kern/mach_param.h>
556 #include <kern/processor.h>
557 #include <kern/queue.h>
558 #include <kern/sched.h>
559 #include <kern/sched_prim.h>
560 #include <kern/stack.h>
561 #include <kern/syscall_subr.h>
562 #include <kern/thread.h>
563 #include <kern/thread_swap.h>
564 #include <kern/host.h>
565 #include <kern/zalloc.h>
566 #include <sched_policy/standard.h>
567 #include <vm/vm_kern.h>
568 #include <ipc/ipc_kmsg.h>
569 #include <ipc/ipc_port.h>
570 #include <ipc/mach_msg.h>
571 #include <machine/machspl.h> /* for splsched */
572 #include <machine/thread.h> /* for MACHINE_STACK */
573
574 #if MACH_RT
575 #include <kern/rt_thread.h>
576 #endif
577
578 #if NET_ATM
579 #include <chips/nw_mk.h>
580 #endif
581
582 thread_t active_threads[NCPUS];
583 vm_offset_t active_stacks[NCPUS];
584
585 struct zone *thread_zone;
586
587 queue_head_t reaper_queue;
588 decl_simple_lock_data(, reaper_lock)
589
590 /* private */
591 struct thread thread_template;
592
593 #if MACH_DEBUG
594 void stack_init(vm_offset_t stack); /* forward */
595 void stack_finalize(vm_offset_t stack); /* forward */
596
597 #define STACK_MARKER 0xdeadbeefU
598 boolean_t stack_check_usage = FALSE;
599 decl_simple_lock_data(, stack_usage_lock)
600 vm_size_t stack_max_usage = 0;
601 #endif /* MACH_DEBUG */
602
603 /*
604 * Machine-dependent code must define:
605 * pcb_init
606 * pcb_terminate
607 * pcb_collect
608 *
609 * The thread->pcb field is reserved for machine-dependent code.
610 */
611
612 #ifdef MACHINE_STACK
613 /*
614 * Machine-dependent code must define:
615 * stack_alloc_try
616 * stack_alloc
617 * stack_free
618 * stack_handoff
619 * stack_collect
620 * and if MACH_DEBUG:
621 * stack_statistics
622 */
623 #else /* MACHINE_STACK */
624 /*
625 * We allocate stacks from generic kernel VM.
626 * Machine-dependent code must define:
627 * stack_attach
628 * stack_detach
629 * stack_handoff
630 *
631 * The stack_free_list can only be accessed at splsched,
632 * because stack_alloc_try/thread_invoke operate at splsched.
633 */
634
635 decl_simple_lock_data(, stack_lock_data)/* splsched only */
636 #define stack_lock() simple_lock(&stack_lock_data)
637 #define stack_unlock() simple_unlock(&stack_lock_data)
638
639 vm_offset_t stack_free_list; /* splsched only */
640 unsigned int stack_free_count = 0; /* splsched only */
641 unsigned int stack_free_limit = 1; /* patchable */
642
643 unsigned int stack_alloc_hits = 0; /* debugging */
644 unsigned int stack_alloc_misses = 0; /* debugging */
645 unsigned int stack_alloc_max = 0; /* debugging */
646
647 /*
648 * The next field is at the base of the stack,
649 * so the low end is left unsullied.
650 */
651
652 #define stack_next(stack) (*((vm_offset_t *)((stack) + KERNEL_STACK_SIZE) - 1))
653
654 /*
655 * stack_alloc_try:
656 *
657 * Non-blocking attempt to allocate a kernel stack.
658 * Called at splsched with the thread locked.
659 */
660
661 boolean_t stack_alloc_try(
662 thread_t thread,
663 no_return (*resume)(thread_t))
664 {
665 register vm_offset_t stack;
666
667 stack_lock();
668 stack = stack_free_list;
669 if (stack != 0) {
670 stack_free_list = stack_next(stack);
671 stack_free_count--;
672 } else {
673 stack = thread->stack_privilege;
674 }
675 stack_unlock();
676
677 if (stack != 0) {
678 stack_attach(thread, stack, resume);
679 stack_alloc_hits++;
680 return TRUE;
681 } else {
682 stack_alloc_misses++;
683 return FALSE;
684 }
685 }
686
687 /*
688 * stack_alloc:
689 *
690 * Allocate a kernel stack for a thread.
691 * May block.
692 */
693
694 void stack_alloc(
695 thread_t thread,
696 no_return (*resume)(thread_t))
697 {
698 vm_offset_t stack;
699 spl_t s;
700
701 /*
702 * We first try the free list. It is probably empty,
703 * or stack_alloc_try would have succeeded, but possibly
704 * a stack was freed before the swapin thread got to us.
705 */
706
707 s = splsched();
708 stack_lock();
709 stack = stack_free_list;
710 if (stack != 0) {
711 stack_free_list = stack_next(stack);
712 stack_free_count--;
713 }
714 stack_unlock();
715 splx(s);
716
717 if (stack == 0) {
718 /*
719 * Kernel stacks should be naturally aligned,
720 * so that it is easy to find the starting/ending
721 * addresses of a stack given an address in the middle.
722 */
723
724 if (kmem_alloc_aligned(kernel_map, &stack, KERNEL_STACK_SIZE)
725 != KERN_SUCCESS)
726 panic("stack_alloc");
727
728 #if MACH_DEBUG
729 stack_init(stack);
730 #endif /* MACH_DEBUG */
731 }
732
733 stack_attach(thread, stack, resume);
734 }
735
736 /*
737 * stack_free:
738 *
739 * Free a thread's kernel stack.
740 * Called at splsched with the thread locked.
741 */
742
743 void stack_free(
744 thread_t thread)
745 {
746 register vm_offset_t stack;
747
748 stack = stack_detach(thread);
749
750 if (stack != thread->stack_privilege) {
751 stack_lock();
752 stack_next(stack) = stack_free_list;
753 stack_free_list = stack;
754 if (++stack_free_count > stack_alloc_max)
755 stack_alloc_max = stack_free_count;
756 stack_unlock();
757 }
758 }
759
760 /*
761 * stack_collect:
762 *
763 * Free excess kernel stacks.
764 * May block.
765 */
766
767 void stack_collect(void)
768 {
769 register vm_offset_t stack;
770 spl_t s;
771
772 s = splsched();
773 stack_lock();
774 while (stack_free_count > stack_free_limit) {
775 stack = stack_free_list;
776 stack_free_list = stack_next(stack);
777 stack_free_count--;
778 stack_unlock();
779 splx(s);
780
781 #if MACH_DEBUG
782 stack_finalize(stack);
783 #endif /* MACH_DEBUG */
784 kmem_free(kernel_map, stack, KERNEL_STACK_SIZE);
785
786 s = splsched();
787 stack_lock();
788 }
789 stack_unlock();
790 splx(s);
791 }
792 #endif /* MACHINE_STACK */
793
794 /*
795 * stack_privilege:
796 *
797 * stack_alloc_try on this thread must always succeed.
798 */
799
800 void stack_privilege(
801 register thread_t thread)
802 {
803 /*
804 * This implementation only works for the current thread.
805 */
806
807 if (thread != current_thread())
808 panic("stack_privilege");
809
810 if (thread->stack_privilege == 0)
811 thread->stack_privilege = current_stack();
812 }
813
814 void thread_init(void)
815 {
816 thread_zone = zinit(
817 sizeof(struct thread),
818 THREAD_MAX * sizeof(struct thread),
819 THREAD_CHUNK * sizeof(struct thread),
820 FALSE, "threads");
821
822 /*
823 * Fill in a template thread for fast initialization.
824 * [Fields that must be (or are typically) reset at
825 * time of creation are so noted.]
826 */
827
828 /* thread_template.links (none) */
829 thread_template.runq = RUN_QUEUE_HEAD_NULL;
830
831 /* thread_template.task (later) */
832 /* thread_template.thread_list (later) */
833 /* thread_template.pset_threads (later) */
834
835 /* one ref for being alive; one for the guy who creates the thread */
836 thread_template.ref_count = 2;
837 /* thread_template.ref_lock (later) */
838 /* thread_template.lock (later) */
839
840 /* thread_template.pcb (later) */
841 thread_template.kernel_stack = (vm_offset_t) 0;
842 thread_template.stack_privilege = (vm_offset_t) 0;
843
844 thread_template.swap_func = thread_bootstrap_return;
845
846 /* thread_template.sched_lock (later) */
847 thread_template.wait_event = 0;
848 /* thread_template.suspend_count (later) */
849 thread_template.wait_result = KERN_SUCCESS;
850 thread_template.suspend_wait = FALSE;
851 thread_template.state = TH_SUSP | TH_SWAPPED;
852
853 thread_template.active = FALSE; /* reset */
854 thread_template.ast = AST_ZILCH;
855
856 thread_template.user_stop_count = 1;
857
858 timer_init(&(thread_template.user_timer));
859 timer_init(&(thread_template.system_timer));
860 thread_template.user_timer_save.low = 0;
861 thread_template.user_timer_save.high = 0;
862 thread_template.system_timer_save.low = 0;
863 thread_template.system_timer_save.high = 0;
864 thread_template.cpu_delta = 0;
865 thread_template.sched_delta = 0;
866 thread_template.cpu_usage = 0;
867 thread_template.sched_usage = 0;
868 /* thread_template.sched_stamp (later) */
869
870 thread_template.recover = (vm_offset_t) 0;
871 thread_template.vm_privilege = FALSE;
872
873 /* thread_template.<IPC structures> (later) */
874
875 /* thread_template.processor_set (later) */
876 #if NCPUS > 1
877 thread_template.bound_processor = PROCESSOR_NULL;
878 /* thread_template.last_processor (later) */
879 #endif
880
881 #if MACH_PCSAMPLE
882 thread_template.pc_sample.buffer = 0;
883 thread_template.pc_sample.seqno = 0;
884 thread_template.pc_sample.sampletypes = 0;
885 #endif
886
887 #if MACH_RT
888 thread_template.rt_wakeup_timer = 0;
889 thread_template.rt_deadline_timer = 0;
890 thread_template.rt_deadline_port = IP_NULL;
891 #endif /* MACH_RT */
892
893 /* thread_template.policy_index (later) */
894 thread_template.cur_policy = 0;
895 /* thread_template.sched_policy (later) */
896
897 /*
898 * Initialize other data structures used in
899 * this module.
900 */
901
902 queue_init(&reaper_queue);
903 simple_lock_init(&reaper_lock);
904
905 #ifndef MACHINE_STACK
906 simple_lock_init(&stack_lock_data);
907 #endif /* MACHINE_STACK */
908
909 #if MACH_DEBUG
910 simple_lock_init(&stack_usage_lock);
911 #endif /* MACH_DEBUG */
912
913 /*
914 * Initialize any machine-dependent
915 * per-thread structures necessary.
916 */
917
918 pcb_module_init();
919 }
920
921 kern_return_t thread_create(
922 register task_t parent_task,
923 thread_t *child_thread) /* OUT */
924 {
925 register thread_t new_thread;
926 register processor_set_t pset;
927
928 if (parent_task == TASK_NULL)
929 return KERN_INVALID_ARGUMENT;
930
931 /*
932 * Allocate a thread and initialize static fields
933 */
934
935 new_thread = (thread_t) zalloc(thread_zone);
936
937 if (new_thread == THREAD_NULL)
938 return KERN_RESOURCE_SHORTAGE;
939
940 *new_thread = thread_template;
941
942 /*
943 * Initialize runtime-dependent fields
944 */
945
946 new_thread->task = parent_task;
947 simple_lock_init(&new_thread->lock);
948 simple_lock_init(&new_thread->ref_lock);
949 simple_lock_init(&new_thread->sched_lock);
950 new_thread->sched_stamp = sched_tick;
951 new_thread->timer.te_param = new_thread;
952 new_thread->timer.te_clock = sys_clock;
953
954 /*
955 * Create a pcb. The kernel stack is created later,
956 * when the thread is swapped-in.
957 */
958 pcb_init(new_thread);
959
960 ipc_thread_init(new_thread);
961
962 #if NET_ATM
963 new_thread->nw_ep_waited = 0;
964 #endif
965
966 /*
967 * Find the processor set for the parent task.
968 */
969 task_lock(parent_task);
970 if (!parent_task->active) {
971 /*
972 * Parent task is being shut down. Quit now.
973 */
974 ipc_thread_terminate(new_thread);
975 pcb_terminate(new_thread);
976 zfree(thread_zone, (vm_offset_t) new_thread);
977
978 return KERN_FAILURE;
979 }
980
981 pset = parent_task->processor_set;
982 pset_lock(pset);
983 #if MACH_HOST
984 if (!pset->active) {
985 /*
986 * Parent task`s processor set is being deallocated.
987 * Assign thread to default processor set.
988 */
989 pset_unlock(pset);
990 pset = &default_pset;
991 pset_lock(pset);
992 }
993 #endif
994
995 /*
996 * Set the thread`s scheduling policy and parameters
997 * to the default for the task.
998 */
999 new_thread->processor_set = pset; /* for sched_ops to work */
1000
1001 thread_set_initial_policy(new_thread, parent_task);
1002
1003 /*
1004 * Thread is suspended if the task is. Add 1 to
1005 * suspend count since thread is created in suspended
1006 * state.
1007 */
1008 new_thread->suspend_count = parent_task->suspend_count + 1;
1009
1010 /*
1011 * Add the thread to the processor set.
1012 * If the pset is empty, suspend the thread again.
1013 */
1014
1015 pset_reference(pset); /* thread`s ref to pset */
1016 pset_add_thread(pset, new_thread);
1017 if (pset->empty)
1018 new_thread->suspend_count++;
1019
1020 #if HW_FOOTPRINT
1021 /*
1022 * Need to set last_processor. An idle processor
1023 * would be best, but that requires extra locking
1024 * nonsense. Go for tail of processors queue to
1025 * avoid master.
1026 */
1027 if (!pset->empty) {
1028 new_thread->last_processor =
1029 (processor_t)queue_first(&pset->processors);
1030 }
1031 else {
1032 /*
1033 * Thread created in empty processor set. Pick
1034 * master processor as an acceptable legal value.
1035 */
1036 new_thread->last_processor = master_processor;
1037 }
1038 #else /* HW_FOOTPRINT */
1039 /*
1040 * Don't need to initialize because the context switch
1041 * code will set it before it can be used.
1042 */
1043 #endif /* HW_FOOTPRINT */
1044
1045 /*
1046 * Add the thread to the task`s list of threads.
1047 * The new thread holds another reference to the task.
1048 */
1049
1050 parent_task->ref_count++;
1051
1052 parent_task->thread_count++;
1053 queue_enter(&parent_task->thread_list, new_thread, thread_t,
1054 thread_list);
1055
1056 /*
1057 * Finally, mark the thread active.
1058 */
1059
1060 new_thread->active = TRUE;
1061
1062 task_unlock(parent_task);
1063 pset_unlock(pset);
1064
1065 ipc_thread_enable(new_thread);
1066
1067 *child_thread = new_thread;
1068 return KERN_SUCCESS;
1069 }
1070
1071 unsigned int thread_deallocate_stack = 0;
1072
1073 void thread_deallocate(
1074 register thread_t thread)
1075 {
1076 register task_t task;
1077 time_spec_t user_time, system_time;
1078
1079 if (thread == THREAD_NULL)
1080 return;
1081
1082 /*
1083 * First, check for new count > 0 (the common case).
1084 * Only the thread`s reference count needs to be locked.
1085 */
1086 thread_ref_lock(thread);
1087 if (--thread->ref_count > 0) {
1088 thread_ref_unlock(thread);
1089 return;
1090 }
1091
1092 #if NCPUS > 1
1093 /*
1094 * Count is zero. However, the task's thread list has
1095 * an implicit reference to the thread, and may make
1096 * new ones. Its lock also dominates the thread lock.
1097 * To check for this, we temporarily restore the one
1098 * thread reference, unlock the thread, and then lock
1099 * the structures in the proper order (task, then
1100 * thread).
1101 */
1102
1103 thread->ref_count = 1;
1104 thread_ref_unlock(thread);
1105
1106 task = thread->task;
1107
1108 task_lock(task);
1109 thread_ref_lock(thread);
1110
1111 if (--thread->ref_count > 0) {
1112 /*
1113 * Task made an extra reference.
1114 */
1115 thread_ref_unlock(thread);
1116 task_unlock(task);
1117 return;
1118 }
1119 #else /* NCPUS > 1 */
1120 task = thread->task;
1121 #endif /* NCPUS > 1 */
1122
1123 /*
1124 * Thread has no references - we can remove it.
1125 */
1126
1127 /*
1128 * A couple of quick sanity checks
1129 */
1130
1131 if (thread == current_thread()) {
1132 panic("thread deallocating itself");
1133 }
1134 if ((thread->state & ~(TH_RUN | TH_HALTED | TH_SWAPPED)) != TH_SUSP)
1135 panic("unstopped thread destroyed!");
1136
1137 assert(thread->processor_set == PROCESSOR_SET_NULL);
1138
1139 /*
1140 * Remove pending timeouts.
1141 */
1142 timer_elt_remove(&thread->timer);
1143
1144 /*
1145 * Accumulate times for dead threads in task.
1146 */
1147 thread_read_times(thread, &user_time, &system_time);
1148 time_spec_add(task->total_user_time, user_time);
1149 time_spec_add(task->total_system_time, system_time);
1150
1151 /*
1152 * Remove thread from task list.
1153 */
1154 task->thread_count--;
1155 queue_remove(&task->thread_list, thread, thread_t, thread_list);
1156
1157 thread_ref_unlock(thread); /* no more references - safe */
1158 task_unlock(task);
1159
1160 /*
1161 * Deallocate the task reference, since we know the thread
1162 * is not running.
1163 */
1164 task_deallocate(thread->task); /* may block */
1165
1166 /*
1167 * Clean up any machine-dependent resources.
1168 */
1169 if ((thread->state & TH_SWAPPED) == 0) {
1170 spl_t s;
1171 s = splsched();
1172 stack_free(thread);
1173 splx(s);
1174 thread_deallocate_stack++;
1175 }
1176
1177 pcb_terminate(thread);
1178
1179 /*
1180 * Free the thread data structure.
1181 */
1182 zfree(thread_zone, (vm_offset_t) thread);
1183 }
1184
1185 void thread_reference(
1186 register thread_t thread)
1187 {
1188 if (thread == THREAD_NULL)
1189 return;
1190
1191 thread_ref_lock(thread);
1192 thread->ref_count++;
1193 thread_ref_unlock(thread);
1194 }
1195
1196 /*
1197 * A version of thread_deallocate for use by AST routines,
1198 * which cannot block. If the thread`s reference count
1199 * drops to zero, increment it back to one and queue it
1200 * for the reaper thread.
1201 */
1202 void thread_deallocate_nowait(
1203 thread_t thread)
1204 {
1205 thread_ref_lock(thread);
1206 if (--thread->ref_count > 0) {
1207 thread_ref_unlock(thread);
1208 return;
1209 }
1210
1211 thread->ref_count = 1;
1212 thread_ref_unlock(thread);
1213
1214 simple_lock(&reaper_lock);
1215 enqueue_tail(&reaper_queue, (queue_entry_t) thread);
1216 simple_unlock(&reaper_lock);
1217 }
1218
1219 /*
1220 * Internal code for thread_terminate, used by
1221 * thread_terminate, thread_force_terminate, and
1222 * thread_terminate_self.
1223 *
1224 * Thread is inactive and halted.
1225 *
1226 * Removes timers. Removes thread from processor
1227 * set. Deallocates IPC structures, and deallocates
1228 * thread.
1229 */
1230 void thread_terminate_internal(
1231 thread_t thread)
1232 {
1233 processor_set_t pset;
1234
1235 #if MACH_RT
1236 /*
1237 * Shut down and remove the thread`s real-time
1238 * timers, deallocating them if the thread holds
1239 * the only reference.
1240 */
1241 (void) timer_cancel(thread->rt_wakeup_timer, 0);
1242 (void) timer_cancel(thread->rt_deadline_timer, 0);
1243
1244 (void) thread_set_periodic_timers(thread, 0, 0);
1245 #endif
1246
1247 /*
1248 * Halt the thread.
1249 */
1250 (void) thread_halt(thread, TRUE);
1251
1252 /*
1253 * Clean up the thread`s IPC ports.
1254 */
1255 ipc_thread_terminate(thread);
1256
1257 #if NET_ATM
1258 /*
1259 * Clean up ATM connections
1260 */
1261 mk_waited_collect(thread);
1262 #endif
1263 /*
1264 * Remove the thread from its processor set,
1265 * and deallocate the processor set.
1266 */
1267 thread_lock(thread);
1268 pset = thread->processor_set;
1269 if (pset != PROCESSOR_SET_NULL) {
1270 pset_lock(pset);
1271 pset_remove_thread(pset, thread);
1272 thread->processor_set = PROCESSOR_SET_NULL;
1273 pset_unlock(pset);
1274 thread_unlock(thread);
1275 pset_deallocate(pset);
1276 }
1277 else {
1278 thread_unlock(thread);
1279 }
1280
1281 /*
1282 * Deallocate the thread`s reference to
1283 * itself.
1284 */
1285 thread_deallocate(thread);
1286 }
1287
1288 /*
1289 * thread_terminate:
1290 *
1291 * Permanently stop execution of the specified thread.
1292 *
1293 * A thread to be terminated must be allowed to clean up any state
1294 * that it has before it exits. The thread is broken out of any
1295 * wait condition that it is in, and signalled to exit. It then
1296 * cleans up its state and calls thread_halt_self on its way out of
1297 * the kernel. The caller waits for the thread to halt, terminates
1298 * its IPC state, and then deallocates it.
1299 *
1300 * If the caller is the current thread, it must still exit the kernel
1301 * to clean up any state (thread and port references, messages, etc).
1302 * When it exits the kernel, it then terminates its IPC state and
1303 * queues itself for the reaper thread, which will wait for the thread
1304 * to stop and then deallocate it. (A thread cannot deallocate itself,
1305 * since it needs a kernel stack to execute.)
1306 */
1307 kern_return_t thread_terminate(
1308 register thread_t thread)
1309 {
1310 register thread_t cur_thread = current_thread();
1311 register task_t cur_task;
1312 spl_t s;
1313
1314 if (thread == THREAD_NULL)
1315 return KERN_INVALID_ARGUMENT;
1316
1317 if (thread == cur_thread) {
1318
1319 thread_lock(thread);
1320 if (thread->active) {
1321 /*
1322 * Curreht thread is active, and is terminating
1323 * itself. Make thread queue itself for reaper
1324 * when exiting kernel. Reaper will do the rest
1325 * of the work.
1326 */
1327 thread->active = FALSE;
1328 ipc_thread_disable(thread);
1329
1330 s = splsched();
1331 thread_sched_lock(thread);
1332 thread_ast_set(thread, AST_TERMINATE); /* queue for reaper */
1333 thread_sched_unlock(thread);
1334
1335 ast_on(cpu_number(), AST_TERMINATE);
1336 splx(s);
1337
1338 thread_unlock(thread);
1339 return KERN_SUCCESS;
1340 }
1341 else {
1342 /*
1343 * Someone else is already terminating the
1344 * current thread. Just make it halt. The
1345 * thread that is calling thread_terminate
1346 * is (or will be) waiting for this one to
1347 * halt, and will do the rest of the work.
1348 *
1349 * Hold the thread, because the thread that
1350 * is calling thread_terminate may not yet
1351 * have called thread_halt on this thread.
1352 */
1353 thread_hold(thread);
1354
1355 s = splsched();
1356 thread_sched_lock(thread);
1357 thread_ast_set(thread, AST_HALT); /* don`t queue
1358 for reaper */
1359 thread_sched_unlock(thread);
1360
1361 ast_on(cpu_number(), AST_HALT);
1362 splx(s);
1363
1364 thread_unlock(thread);
1365 return KERN_FAILURE;
1366 }
1367 }
1368
1369 /*
1370 * Lock both threads and the current task
1371 * to check termination races and prevent deadlocks.
1372 */
1373 cur_task = cur_thread->task;
1374 task_lock(cur_task);
1375
1376 if ((vm_offset_t)thread < (vm_offset_t)cur_thread) {
1377 thread_lock(thread);
1378 thread_lock(cur_thread);
1379 }
1380 else {
1381 thread_lock(cur_thread);
1382 thread_lock(thread);
1383 }
1384
1385 /*
1386 * If the current thread is being terminated, help out.
1387 */
1388 if (!cur_task->active || !cur_thread->active) {
1389 thread_unlock(cur_thread);
1390 thread_unlock(thread);
1391
1392 task_unlock(cur_task);
1393 (void) thread_terminate(cur_thread);
1394 return KERN_FAILURE;
1395 }
1396
1397 thread_unlock(cur_thread);
1398 task_unlock(cur_task);
1399
1400 /*
1401 * Terminate victim thread.
1402 */
1403 if (!thread->active) {
1404 /*
1405 * Someone else got there first.
1406 */
1407 thread_unlock(thread);
1408
1409 return KERN_FAILURE;
1410 }
1411
1412 /*
1413 * Mark thread inactive, and disable IPC access.
1414 */
1415 thread->active = FALSE;
1416 ipc_thread_disable(thread);
1417
1418 thread_unlock(thread);
1419
1420 /*
1421 * Terminate the thread.
1422 */
1423 thread_terminate_internal(thread);
1424
1425 return KERN_SUCCESS;
1426 }
1427
1428 /*
1429 * thread_force_terminate:
1430 *
1431 * Version of thread_terminate called by task_terminate. thread is
1432 * not the current thread. task_terminate is the dominant operation,
1433 * so we can force this thread to stop.
1434 */
1435 void
1436 thread_force_terminate(
1437 register thread_t thread)
1438 {
1439 /*
1440 * If thread is already being shut down,
1441 * we don`t have to do anything.
1442 */
1443 thread_lock(thread);
1444 if (!thread->active) {
1445 thread_unlock(thread);
1446 return;
1447 }
1448
1449 /*
1450 * Mark thread inactive, and shut down its IPC
1451 * control.
1452 */
1453 thread->active = FALSE;
1454 ipc_thread_disable(thread);
1455
1456 thread_unlock(thread);
1457
1458 /*
1459 * Terminate the thread.
1460 */
1461 thread_terminate_internal(thread);
1462 }
1463
1464 no_return
1465 walking_zombie(void)
1466 {
1467 for (;;)
1468 panic("the zombie walks!");
1469 }
1470
1471 /*
1472 * A thread can only terminate itself when it has
1473 * hit a clean point. It calls this function to
1474 * mark itself as halted, and queue itself for the
1475 * reaper thread. The reaper thread actually
1476 * cleans up the thread.
1477 *
1478 * Thread is already marked inactive.
1479 */
1480 no_return thread_terminate_self(void)
1481 {
1482 thread_t thread = current_thread();
1483 spl_t s;
1484
1485 thread_hold(thread);
1486
1487 s = splsched();
1488 thread_sched_lock(thread);
1489 thread->state |= TH_HALTED;
1490 thread_sched_unlock(thread);
1491 splx(s);
1492
1493 simple_lock(&reaper_lock);
1494 enqueue_tail(&reaper_queue, (queue_entry_t) thread);
1495 simple_unlock(&reaper_lock);
1496 thread_wakeup(&reaper_queue);
1497
1498 counter(c_thread_halt_self_block++);
1499 thread_block_noreturn(walking_zombie);
1500 /*NOTREACHED*/
1501 }
1502
1503 /*
1504 * Return thread's machine-dependent state.
1505 */
1506 kern_return_t thread_get_state(
1507 register thread_t thread,
1508 int flavor,
1509 thread_state_t old_state, /* pointer to OUT array */
1510 natural_t *old_state_count) /*IN/OUT*/
1511 {
1512 kern_return_t ret;
1513
1514 if (thread == THREAD_NULL || thread == current_thread()) {
1515 return KERN_INVALID_ARGUMENT;
1516 }
1517
1518 thread_hold(thread);
1519 (void) thread_dowait(thread, TRUE);
1520
1521 ret = thread_getstatus(thread, flavor, old_state, old_state_count);
1522
1523 thread_release(thread);
1524 return ret;
1525 }
1526
1527 /*
1528 * Change thread's machine-dependent state.
1529 */
1530 kern_return_t thread_set_state(
1531 register thread_t thread,
1532 int flavor,
1533 thread_state_t new_state,
1534 natural_t new_state_count)
1535 {
1536 kern_return_t ret;
1537
1538 if (thread == THREAD_NULL || thread == current_thread()) {
1539 return KERN_INVALID_ARGUMENT;
1540 }
1541
1542 thread_hold(thread);
1543 (void) thread_dowait(thread, TRUE);
1544
1545 ret = thread_setstatus(thread, flavor, new_state, new_state_count);
1546
1547 thread_release(thread);
1548 return ret;
1549 }
1550
1551 kern_return_t thread_info(
1552 register thread_t thread,
1553 int flavor,
1554 thread_info_t thread_info_out, /* pointer to OUT array */
1555 natural_t *thread_info_count) /*IN/OUT*/
1556 {
1557 int state, flags;
1558 spl_t s;
1559
1560 if (thread == THREAD_NULL)
1561 return KERN_INVALID_ARGUMENT;
1562
1563 if (flavor == THREAD_BASIC_INFO) {
1564 register thread_basic_info_t basic_info;
1565 unsigned int sleep_time;
1566 time_spec_t user_time, system_time;
1567
1568 if (*thread_info_count < THREAD_BASIC_INFO_COUNT) {
1569 return KERN_INVALID_ARGUMENT;
1570 }
1571
1572 basic_info = (thread_basic_info_t) thread_info_out;
1573
1574 s = splsched();
1575 thread_sched_lock(thread);
1576
1577 /*
1578 * Update lazy-evaluated scheduler info because someone wants it.
1579 * Grab sleep-time first, since UPDATE_PRIORITY zeros it.
1580 */
1581 sleep_time = sched_tick - thread->sched_stamp;
1582 if ((thread->state & TH_RUN) == 0) {
1583 UPDATE_PRIORITY(thread);
1584 }
1585
1586 /* fill in info */
1587
1588 thread_read_times(thread, &user_time, &system_time);
1589 basic_info->user_time.seconds = user_time.seconds;
1590 basic_info->user_time.microseconds =
1591 user_time.nanoseconds / 1000;
1592 basic_info->system_time.seconds = system_time.seconds;
1593 basic_info->system_time.microseconds =
1594 system_time.nanoseconds / 1000;
1595
1596 switch (thread->sched_policy->name) {
1597 case POLICY_BACKGROUND:
1598 basic_info->base_priority = 32;
1599 basic_info->cur_priority = 32;
1600 break;
1601
1602 case POLICY_TIMESHARE:
1603 {
1604 struct policy_info_timeshare info;
1605 natural_t count;
1606
1607 count = POLICY_INFO_TIMESHARE_COUNT;
1608 (void) THREAD_GET_PARAM(thread,
1609 (policy_param_t)&info,
1610 &count);
1611
1612 basic_info->base_priority = info.base_priority;
1613 basic_info->cur_priority = info.cur_priority;
1614 break;
1615 }
1616
1617 default:
1618 basic_info->base_priority = 0;
1619 basic_info->cur_priority = 0;
1620 break;
1621 }
1622
1623 /*
1624 * To calculate cpu_usage, first correct for timer rate,
1625 * then for 5/8 ageing. The correction factor [3/5] is
1626 * (1/(5/8) - 1).
1627 */
1628 basic_info->cpu_usage = thread->cpu_usage /
1629 (USAGE_RATE/TH_USAGE_SCALE);
1630 basic_info->cpu_usage = (basic_info->cpu_usage * 3) / 5;
1631 #if SIMPLE_CLOCK
1632 /*
1633 * Clock drift compensation.
1634 */
1635 basic_info->cpu_usage =
1636 (basic_info->cpu_usage * 1000000)/sched_usec;
1637 #endif /* SIMPLE_CLOCK */
1638
1639 if (thread->state & TH_SWAPPED)
1640 flags = TH_FLAGS_SWAPPED;
1641 else if (thread->state & TH_IDLE)
1642 flags = TH_FLAGS_IDLE;
1643 else
1644 flags = 0;
1645
1646 if (thread->state & TH_HALTED)
1647 state = TH_STATE_HALTED;
1648 else
1649 if (thread->state & TH_RUN)
1650 state = TH_STATE_RUNNING;
1651 else
1652 if (thread->state & TH_UNINT)
1653 state = TH_STATE_UNINTERRUPTIBLE;
1654 else
1655 if (thread->state & TH_SUSP)
1656 state = TH_STATE_STOPPED;
1657 else
1658 if (thread->state & TH_WAIT)
1659 state = TH_STATE_WAITING;
1660 else
1661 state = 0; /* ? */
1662
1663 basic_info->run_state = state;
1664 basic_info->flags = flags;
1665 basic_info->suspend_count = thread->user_stop_count;
1666 if (state == TH_STATE_RUNNING)
1667 basic_info->sleep_time = 0;
1668 else
1669 basic_info->sleep_time = sleep_time;
1670
1671 thread_sched_unlock(thread);
1672 splx(s);
1673
1674 *thread_info_count = THREAD_BASIC_INFO_COUNT;
1675 return KERN_SUCCESS;
1676 }
1677 else if (flavor == THREAD_SCHED_INFO) {
1678 register thread_sched_info_t sched_info;
1679
1680 if (*thread_info_count < THREAD_SCHED_INFO_COUNT) {
1681 return KERN_INVALID_ARGUMENT;
1682 }
1683
1684 sched_info = (thread_sched_info_t) thread_info_out;
1685
1686 s = splsched();
1687 thread_sched_lock(thread);
1688
1689 sched_info->policy = thread->sched_policy->name;
1690 switch (thread->sched_policy->name) {
1691 case POLICY_BACKGROUND:
1692 sched_info->base_priority = 32;
1693 sched_info->cur_priority = 32;
1694 sched_info->max_priority = 32;
1695 break;
1696
1697 case POLICY_TIMESHARE:
1698 {
1699 struct policy_info_timeshare info;
1700 natural_t count;
1701
1702 count = POLICY_INFO_TIMESHARE_COUNT;
1703 (void) THREAD_GET_PARAM(thread,
1704 (policy_param_t) &info,
1705 &count);
1706
1707 sched_info->base_priority = info.base_priority;
1708 sched_info->cur_priority = info.cur_priority;
1709 sched_info->max_priority = info.max_priority;
1710 }
1711 default:
1712 sched_info->base_priority = 0;
1713 sched_info->cur_priority = 0;
1714 sched_info->max_priority = 0;
1715 break;
1716 }
1717
1718 if (thread->cur_policy != thread->sched_policy) {
1719 sched_info->depressed = TRUE;
1720 sched_info->depress_priority = sched_info->cur_priority;
1721 sched_info->cur_priority = 32;
1722 }
1723 else {
1724 sched_info->depressed = FALSE;
1725 sched_info->depress_priority = -1;
1726 }
1727
1728 thread_sched_unlock(thread);
1729 splx(s);
1730
1731 *thread_info_count = THREAD_SCHED_INFO_COUNT;
1732 return KERN_SUCCESS;
1733 }
1734 else if (flavor == THREAD_POLICY_INFO) {
1735 kern_return_t kr;
1736 thread_policy_info_t policy_info;
1737 natural_t policy_info_count;
1738
1739 if (*thread_info_count < THREAD_POLICY_INFO_COUNT)
1740 return KERN_INVALID_ARGUMENT;
1741
1742 policy_info = (thread_policy_info_t) thread_info_out;
1743
1744 s = splsched();
1745 thread_sched_lock(thread);
1746
1747 policy_info->policy = thread->sched_policy->name;
1748 policy_info->depressed =
1749 (thread->sched_policy != thread->cur_policy);
1750
1751 policy_info_count = *thread_info_count - THREAD_POLICY_INFO_COUNT;
1752 if (policy_info_count > 0) {
1753 /*
1754 * There is room for the detailed scheduling policy
1755 * information.
1756 */
1757 kr = THREAD_GET_PARAM(thread,
1758 (policy_param_t) (policy_info + 1),
1759 &policy_info_count);
1760 if (kr == KERN_SUCCESS)
1761 *thread_info_count = THREAD_POLICY_INFO_COUNT +
1762 policy_info_count;
1763 }
1764 else {
1765 *thread_info_count = THREAD_POLICY_INFO_COUNT;
1766 kr = KERN_SUCCESS;
1767 }
1768
1769 thread_sched_unlock(thread);
1770 splx(s);
1771
1772 return kr;
1773 }
1774
1775 return KERN_INVALID_ARGUMENT;
1776 }
1777
1778 kern_return_t thread_abort(
1779 register thread_t thread)
1780 {
1781 if (thread == THREAD_NULL || thread == current_thread()) {
1782 return KERN_INVALID_ARGUMENT;
1783 }
1784
1785 /*
1786 * Try to force the thread to a clean point.
1787 * If the halt operation fails return KERN_ABORTED.
1788 * ipc code will convert this to an ipc interrupted error code.
1789 */
1790 if (thread_halt(thread, FALSE) != KERN_SUCCESS)
1791 return KERN_ABORTED;
1792
1793 /*
1794 * If the thread was in an exception, abort that too.
1795 */
1796 mach_msg_abort_rpc(thread);
1797
1798 /*
1799 * Also abort any depression.
1800 */
1801 if (thread->cur_policy != thread->sched_policy)
1802 thread_depress_abort(thread);
1803
1804 /*
1805 * Then set it going again.
1806 */
1807 thread_release(thread);
1808
1809 return KERN_SUCCESS;
1810 }
1811
1812 /*
1813 * thread_start:
1814 *
1815 * Start a thread at the specified routine.
1816 * The thread must be in a swapped state.
1817 */
1818
1819 void
1820 thread_start(
1821 thread_t thread,
1822 continuation_t start)
1823 {
1824 thread->swap_func = start;
1825 }
1826
1827 /*
1828 * kernel_thread:
1829 *
1830 * Start up a kernel thread in the specified task.
1831 */
1832
1833 thread_t kernel_thread(
1834 task_t task,
1835 continuation_t start,
1836 void * arg)
1837 {
1838 thread_t thread;
1839
1840 (void) thread_create(task, &thread);
1841 /* release "extra" ref that thread_create gave us */
1842 thread_deallocate(thread);
1843 thread_start(thread, start);
1844 thread->ith_other = arg;
1845
1846 /*
1847 * We ensure that the kernel thread starts with a stack.
1848 * The swapin mechanism might not be operational yet.
1849 */
1850 thread_doswapin(thread);
1851
1852 /*
1853 * Start the thread running.
1854 */
1855 (void) thread_resume(thread);
1856 return thread;
1857 }
1858
1859 /*
1860 * reaper_thread:
1861 *
1862 * This kernel thread runs forever looking for threads to destroy
1863 * (when they request that they be destroyed, of course).
1864 */
1865 no_return reaper_thread(void)
1866 {
1867 register thread_t thread;
1868
1869 for (;;) {
1870
1871 simple_lock(&reaper_lock);
1872
1873 while ((thread = (thread_t) dequeue_head(&reaper_queue))
1874 != THREAD_NULL) {
1875 simple_unlock(&reaper_lock);
1876
1877 /*
1878 * We have a thread to terminate.
1879 */
1880 thread_terminate_internal(thread); /* may block */
1881
1882 /*
1883 * Check for kernel ASTs in loop.
1884 */
1885 AST_KERNEL_CHECK(cpu_number());
1886
1887 simple_lock(&reaper_lock);
1888 }
1889
1890 assert_wait((event_t) &reaper_queue, FALSE);
1891 simple_unlock(&reaper_lock);
1892 counter(c_reaper_thread_block++);
1893 thread_block(reaper_thread);
1894 }
1895 }
1896
1897 #if MACH_HOST
1898 /*
1899 * thread_assign:
1900 *
1901 * Change processor set assignment.
1902 * Caller must hold an extra reference to the thread (if this is
1903 * called directly from the ipc interface, this is an operation
1904 * in progress reference). Caller must hold no locks -- this may block.
1905 */
1906
1907 kern_return_t
1908 thread_assign(
1909 thread_t thread,
1910 processor_set_t new_pset)
1911 {
1912 register processor_set_t old_pset;
1913 register boolean_t old_empty, new_empty;
1914
1915 if (thread == THREAD_NULL || new_pset == PROCESSOR_SET_NULL) {
1916 return KERN_INVALID_ARGUMENT;
1917 }
1918
1919 /*
1920 * Suspend the thread and stop it if it's not the current thread.
1921 */
1922 thread_hold(thread);
1923 if (thread != current_thread())
1924 (void) thread_dowait(thread, TRUE);
1925
1926 /*
1927 * Lock the thread, and find its current processor set.
1928 */
1929 thread_lock(thread);
1930 old_pset = thread->processor_set;
1931 if (old_pset == new_pset) {
1932 /*
1933 * Nothing to do.
1934 */
1935 thread_unlock(thread);
1936 return KERN_SUCCESS;
1937 }
1938
1939 /*
1940 * Lock both psets now, use ordering to avoid deadlocks.
1941 */
1942 Restart:
1943 if ((vm_offset_t)old_pset < (vm_offset_t)new_pset) {
1944 pset_lock(old_pset);
1945 pset_lock(new_pset);
1946 }
1947 else {
1948 pset_lock(new_pset);
1949 pset_lock(old_pset);
1950 }
1951
1952 /*
1953 * Check if new_pset is ok to assign to. If not, reassign
1954 * to default_pset.
1955 */
1956 if (!new_pset->active) {
1957 pset_unlock(old_pset);
1958 pset_unlock(new_pset);
1959 new_pset = &default_pset;
1960 goto Restart;
1961 }
1962
1963 pset_reference(new_pset);
1964
1965 /*
1966 * Move the thread.
1967 * Then drop the lock on the old pset and the thread's
1968 * reference to it.
1969 */
1970 thread_change_psets(thread, old_pset, new_pset);
1971
1972 old_empty = old_pset->empty;
1973 new_empty = new_pset->empty;
1974
1975 /*
1976 * Reset policy and priorities if needed.
1977 */
1978 {
1979 spl_t s;
1980
1981 s = splsched();
1982 thread_sched_lock(thread);
1983 thread_enforce_policy_limits(thread, new_pset);
1984 thread_sched_unlock(thread);
1985 splx(s);
1986 }
1987
1988 thread_unlock(thread);
1989
1990 pset_unlock(old_pset);
1991 pset_unlock(new_pset);
1992
1993 pset_deallocate(old_pset);
1994
1995 /*
1996 * Figure out hold status of thread. Threads assigned to empty
1997 * psets must be held. Therefore:
1998 * If old pset was empty release its hold.
1999 * Release our hold from above unless new pset is empty.
2000 */
2001
2002 if (old_empty)
2003 thread_release(thread);
2004 if (!new_empty)
2005 thread_release(thread);
2006
2007 /*
2008 * If current_thread is assigned, context switch to force
2009 * assignment to happen. This also causes hold to take
2010 * effect if the new pset is empty.
2011 */
2012 if (thread == current_thread()) {
2013 spl_t s;
2014
2015 s = splsched();
2016 ast_on(cpu_number(), AST_BLOCK);
2017 splx(s);
2018 }
2019
2020 return KERN_SUCCESS;
2021 }
2022
2023 /*
2024 * Thread_assign_if_empty:
2025 *
2026 * Move thread to default processor set if its own is
2027 * empty. Return the thread`s processor set if so.
2028 *
2029 * Thread is already suspended.
2030 */
2031 processor_set_t
2032 thread_assign_if_empty(
2033 thread_t thread)
2034 {
2035 processor_set_t old_pset;
2036
2037 thread_lock(thread);
2038 old_pset = thread->processor_set;
2039 if (!old_pset->empty) {
2040 /*
2041 * Don`t have to move thread.
2042 */
2043 thread_unlock(thread);
2044 return PROCESSOR_SET_NULL;
2045 }
2046
2047 /*
2048 * Lock both psets.
2049 */
2050 if ((vm_offset_t) old_pset < (vm_offset_t) &default_pset) {
2051 pset_lock(old_pset);
2052 pset_lock(&default_pset);
2053 }
2054 else {
2055 pset_lock(&default_pset);
2056 pset_lock(old_pset);
2057 }
2058
2059 assert(default_pset.active);
2060
2061 pset_reference(&default_pset);
2062
2063 thread_change_psets(thread, old_pset, &default_pset);
2064
2065 /*
2066 * Reset policy and priorities if needed.
2067 */
2068 {
2069 spl_t s;
2070
2071 s = splsched();
2072 thread_sched_lock(thread);
2073 thread_enforce_policy_limits(thread, &default_pset);
2074 thread_sched_unlock(thread);
2075 splx(s);
2076 }
2077
2078 thread_unlock(thread);
2079
2080 pset_unlock(old_pset);
2081 pset_unlock(&default_pset);
2082
2083 /*
2084 * Old pset was empty, so release thread.
2085 */
2086 thread_release(thread);
2087
2088 return old_pset; /* returns ref */
2089 }
2090
2091 #else /* MACH_HOST */
2092 kern_return_t
2093 thread_assign(
2094 thread_t thread,
2095 processor_set_t new_pset)
2096 {
2097 return KERN_FAILURE;
2098 }
2099 #endif /* MACH_HOST */
2100
2101 /*
2102 * thread_assign_default:
2103 *
2104 * Special version of thread_assign for assigning threads to default
2105 * processor set.
2106 */
2107 kern_return_t
2108 thread_assign_default(
2109 thread_t thread)
2110 {
2111 return thread_assign(thread, &default_pset);
2112 }
2113
2114 /*
2115 * thread_get_assignment
2116 *
2117 * Return current assignment for this thread.
2118 */
2119 kern_return_t thread_get_assignment(
2120 thread_t thread,
2121 processor_set_t *pset)
2122 {
2123 thread_lock(thread);
2124 *pset = thread->processor_set;
2125 pset_reference(*pset);
2126 thread_unlock(thread);
2127
2128 return KERN_SUCCESS;
2129 }
2130
2131 /*
2132 * [ obsolete ]
2133 * thread_priority:
2134 *
2135 * Set priority (and possibly max priority) for thread.
2136 *
2137 * Only works for timesharing policy.
2138 */
2139 kern_return_t
2140 thread_priority(
2141 thread_t thread,
2142 int priority,
2143 boolean_t set_max)
2144 {
2145 struct policy_param_timeshare param;
2146
2147 param.priority = priority;
2148 return thread_set_policy_param(thread,
2149 set_max,
2150 (policy_param_t)¶m,
2151 POLICY_PARAM_TIMESHARE_COUNT);
2152 }
2153
2154 /*
2155 * thread_set_own_priority:
2156 *
2157 * Internal use only; sets the priority of the calling thread,
2158 * and makes it fixed priority.
2159 */
2160 void
2161 thread_set_own_priority(
2162 int priority)
2163 {
2164 thread_t thread = current_thread();
2165 struct policy_param_fixedpri param;
2166
2167 param.priority = priority;
2168 param.no_preempt = TRUE; /* irrelevant for kernel thread */
2169
2170 (void) thread_set_policy(thread,
2171 thread->processor_set,
2172 POLICY_FIXEDPRI,
2173 (policy_param_t)¶m,
2174 POLICY_PARAM_FIXEDPRI_COUNT);
2175 }
2176
2177 /*
2178 * [ obsolete ]
2179 * thread_max_priority:
2180 *
2181 * Reset the max priority for a thread.
2182 *
2183 * Only works for timesharing threads.
2184 */
2185 kern_return_t
2186 thread_max_priority(
2187 thread_t thread,
2188 processor_set_t pset,
2189 int max_priority)
2190 {
2191 struct policy_param_timeshare limit;
2192
2193 limit.priority = max_priority;
2194 return thread_set_policy_limit(thread,
2195 pset,
2196 (policy_param_t)&limit,
2197 POLICY_PARAM_TIMESHARE_COUNT);
2198 }
2199
2200 /*
2201 * [ obsolete ]
2202 * thread_policy:
2203 *
2204 * Set scheduling policy for thread.
2205 *
2206 * Since the old fixed-priority policy is not supported,
2207 * this does nothing.
2208 */
2209 kern_return_t
2210 thread_policy(
2211 thread_t thread,
2212 int policy,
2213 int data)
2214 {
2215 if (thread == THREAD_NULL)
2216 return KERN_INVALID_ARGUMENT;
2217
2218 if (policy == POLICY_TIMESHARE)
2219 return KERN_SUCCESS;
2220 else
2221 return KERN_FAILURE;
2222 }
2223
2224 /*
2225 * thread_wire:
2226 *
2227 * Specify that the target thread must always be able
2228 * to run and to allocate memory.
2229 */
2230 kern_return_t
2231 thread_wire(
2232 host_t host,
2233 thread_t thread,
2234 boolean_t wired)
2235 {
2236 spl_t s;
2237
2238 if (host == HOST_NULL)
2239 return KERN_INVALID_ARGUMENT;
2240
2241 if (thread == THREAD_NULL)
2242 return KERN_INVALID_ARGUMENT;
2243
2244 /*
2245 * This implementation only works for the current thread.
2246 * See stack_privilege.
2247 */
2248 if (thread != current_thread())
2249 return KERN_INVALID_ARGUMENT;
2250
2251 s = splsched();
2252 thread_sched_lock(thread);
2253
2254 if (wired) {
2255 thread->vm_privilege = TRUE;
2256 stack_privilege(thread);
2257 }
2258 else {
2259 thread->vm_privilege = FALSE;
2260 /*XXX stack_unprivilege(thread); */
2261 thread->stack_privilege = 0;
2262 }
2263
2264 thread_sched_unlock(thread);
2265 splx(s);
2266
2267 return KERN_SUCCESS;
2268 }
2269
2270 /*
2271 * thread_collect_scan:
2272 *
2273 * Attempt to free resources owned by threads.
2274 * pcb_collect doesn't do anything yet.
2275 */
2276
2277 void thread_collect_scan(void)
2278 {
2279 #if 0
2280 register thread_t thread, prev_thread;
2281 processor_set_t pset, prev_pset;
2282
2283 prev_thread = THREAD_NULL;
2284 prev_pset = PROCESSOR_SET_NULL;
2285
2286 simple_lock(&all_psets_lock);
2287 queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
2288 pset_lock(pset);
2289 queue_iterate(&pset->threads, thread, thread_t, pset_threads) {
2290 spl_t s = splsched();
2291 thread_sched_lock(thread);
2292
2293 /*
2294 * Only collect threads which are
2295 * not runnable and are swapped.
2296 */
2297
2298 if ((thread->state & (TH_RUN|TH_SWAPPED))
2299 == TH_SWAPPED) {
2300 thread_reference(thread);
2301 thread_sched_unlock(thread);
2302 splx(s);
2303 pset->ref_count++;
2304 pset_unlock(pset);
2305 simple_unlock(&all_psets_lock);
2306
2307 pcb_collect(thread);
2308
2309 if (prev_thread != THREAD_NULL)
2310 thread_deallocate(prev_thread);
2311 prev_thread = thread;
2312
2313 if (prev_pset != PROCESSOR_SET_NULL)
2314 pset_deallocate(prev_pset);
2315 prev_pset = pset;
2316
2317 simple_lock(&all_psets_lock);
2318 pset_lock(pset);
2319 } else {
2320 thread_sched_unlock(thread);
2321 splx(s);
2322 }
2323 }
2324 pset_unlock(pset);
2325 }
2326 simple_unlock(&all_psets_lock);
2327
2328 if (prev_thread != THREAD_NULL)
2329 thread_deallocate(prev_thread);
2330 if (prev_pset != PROCESSOR_SET_NULL)
2331 pset_deallocate(prev_pset);
2332 #endif /* 0 */
2333 }
2334
2335 boolean_t thread_collect_allowed = TRUE;
2336 unsigned thread_collect_last_tick = 0;
2337 unsigned thread_collect_max_rate = 0; /* in seconds */
2338
2339 /*
2340 * consider_thread_collect:
2341 *
2342 * Called by the pageout daemon when the system needs more free pages.
2343 */
2344
2345 void consider_thread_collect(void)
2346 {
2347 /*
2348 * By default, don't attempt thread collection more frequently
2349 * than once a minute.
2350 */
2351
2352 if (thread_collect_max_rate == 0)
2353 thread_collect_max_rate = 60;
2354
2355 if (thread_collect_allowed &&
2356 (sched_tick >
2357 (thread_collect_last_tick + thread_collect_max_rate))) {
2358 thread_collect_last_tick = sched_tick;
2359 thread_collect_scan();
2360 }
2361 }
2362
2363 #if MACH_DEBUG
2364
2365 vm_size_t stack_usage(
2366 register vm_offset_t stack)
2367 {
2368 int i;
2369
2370 for (i = 0; i < KERNEL_STACK_SIZE/sizeof(unsigned int); i++)
2371 if (((unsigned int *)stack)[i] != STACK_MARKER)
2372 break;
2373
2374 return KERNEL_STACK_SIZE - i * sizeof(unsigned int);
2375 }
2376
2377 /*
2378 * Machine-dependent code should call stack_init
2379 * before doing its own initialization of the stack.
2380 */
2381
2382 void stack_init(
2383 register vm_offset_t stack)
2384 {
2385 if (stack_check_usage) {
2386 int i;
2387
2388 for (i = 0; i < KERNEL_STACK_SIZE/sizeof(unsigned int); i++)
2389 ((unsigned int *)stack)[i] = STACK_MARKER;
2390 }
2391 }
2392
2393 /*
2394 * Machine-dependent code should call stack_finalize
2395 * before releasing the stack memory.
2396 */
2397
2398 void stack_finalize(
2399 register vm_offset_t stack)
2400 {
2401 if (stack_check_usage) {
2402 vm_size_t used = stack_usage(stack);
2403
2404 simple_lock(&stack_usage_lock);
2405 if (used > stack_max_usage)
2406 stack_max_usage = used;
2407 simple_unlock(&stack_usage_lock);
2408 }
2409 }
2410
2411 #ifndef MACHINE_STACK
2412 /*
2413 * stack_statistics:
2414 *
2415 * Return statistics on cached kernel stacks.
2416 * *maxusagep must be initialized by the caller.
2417 */
2418
2419 void stack_statistics(
2420 unsigned int *totalp,
2421 vm_size_t *maxusagep)
2422 {
2423 spl_t s;
2424
2425 s = splsched();
2426 stack_lock();
2427 if (stack_check_usage) {
2428 vm_offset_t stack;
2429
2430 /*
2431 * This is pretty expensive to do at splsched,
2432 * but it only happens when someone makes
2433 * a debugging call, so it should be OK.
2434 */
2435
2436 for (stack = stack_free_list; stack != 0;
2437 stack = stack_next(stack)) {
2438 vm_size_t usage = stack_usage(stack);
2439
2440 if (usage > *maxusagep)
2441 *maxusagep = usage;
2442 }
2443 }
2444
2445 *totalp = stack_free_count;
2446 stack_unlock();
2447 splx(s);
2448 }
2449 #endif /* MACHINE_STACK */
2450
2451 kern_return_t host_stack_usage(
2452 host_t host,
2453 vm_size_t *reservedp,
2454 unsigned int *totalp,
2455 vm_size_t *spacep,
2456 vm_size_t *residentp,
2457 vm_size_t *maxusagep,
2458 vm_offset_t *maxstackp)
2459 {
2460 unsigned int total;
2461 vm_size_t maxusage;
2462
2463 if (host == HOST_NULL)
2464 return KERN_INVALID_HOST;
2465
2466 simple_lock(&stack_usage_lock);
2467 maxusage = stack_max_usage;
2468 simple_unlock(&stack_usage_lock);
2469
2470 stack_statistics(&total, &maxusage);
2471
2472 *reservedp = 0;
2473 *totalp = total;
2474 *spacep = *residentp = total * round_page(KERNEL_STACK_SIZE);
2475 *maxusagep = maxusage;
2476 *maxstackp = 0;
2477 return KERN_SUCCESS;
2478 }
2479
2480 kern_return_t processor_set_stack_usage(
2481 processor_set_t pset,
2482 unsigned int *totalp,
2483 vm_size_t *spacep,
2484 vm_size_t *residentp,
2485 vm_size_t *maxusagep,
2486 vm_offset_t *maxstackp)
2487 {
2488 unsigned int total;
2489 vm_size_t maxusage;
2490 vm_offset_t maxstack;
2491
2492 register thread_t *threads;
2493 register thread_t tmp_thread;
2494
2495 unsigned int actual; /* this many things */
2496 unsigned int i;
2497
2498 vm_size_t size, size_needed;
2499 vm_offset_t addr;
2500
2501 if (pset == PROCESSOR_SET_NULL)
2502 return KERN_INVALID_ARGUMENT;
2503
2504 size = 0; addr = 0;
2505
2506 for (;;) {
2507 pset_lock(pset);
2508 if (!pset->active) {
2509 pset_unlock(pset);
2510 return KERN_INVALID_ARGUMENT;
2511 }
2512
2513 actual = pset->thread_count;
2514
2515 /* do we have the memory we need? */
2516
2517 size_needed = actual * sizeof(thread_t);
2518 if (size_needed <= size)
2519 break;
2520
2521 /* unlock the pset and allocate more memory */
2522 pset_unlock(pset);
2523
2524 if (size != 0)
2525 kfree(addr, size);
2526
2527 assert(size_needed > 0);
2528 size = size_needed;
2529
2530 addr = kalloc(size);
2531 if (addr == 0)
2532 return KERN_RESOURCE_SHORTAGE;
2533 }
2534
2535 /* OK, have memory and the processor_set is locked & active */
2536
2537 threads = (thread_t *) addr;
2538 for (i = 0, tmp_thread = (thread_t) queue_first(&pset->threads);
2539 i < actual;
2540 i++,
2541 tmp_thread = (thread_t) queue_next(&tmp_thread->pset_threads)) {
2542 thread_reference(tmp_thread);
2543 threads[i] = tmp_thread;
2544 }
2545 assert(queue_end(&pset->threads, (queue_entry_t) tmp_thread));
2546
2547 /* can unlock processor set now that we have the thread refs */
2548 pset_unlock(pset);
2549
2550 /* calculate maxusage and free thread references */
2551
2552 total = 0;
2553 maxusage = 0;
2554 maxstack = 0;
2555 for (i = 0; i < actual; i++) {
2556 thread_t thread = threads[i];
2557 vm_offset_t stack = 0;
2558
2559 /*
2560 * thread->kernel_stack is only accurate if the
2561 * thread isn't swapped and is not executing.
2562 *
2563 * Of course, we don't have the appropriate locks
2564 * for these shenanigans.
2565 */
2566
2567 if ((thread->state & TH_SWAPPED) == 0) {
2568 int cpu;
2569
2570 stack = thread->kernel_stack;
2571
2572 for (cpu = 0; cpu < NCPUS; cpu++)
2573 if (active_threads[cpu] == thread) {
2574 stack = active_stacks[cpu];
2575 break;
2576 }
2577 }
2578
2579 if (stack != 0) {
2580 total++;
2581
2582 if (stack_check_usage) {
2583 vm_size_t usage = stack_usage(stack);
2584
2585 if (usage > maxusage) {
2586 maxusage = usage;
2587 maxstack = (vm_offset_t) thread;
2588 }
2589 }
2590 }
2591
2592 thread_deallocate(thread);
2593 }
2594
2595 if (size != 0)
2596 kfree(addr, size);
2597
2598 *totalp = total;
2599 *residentp = *spacep = total * round_page(KERNEL_STACK_SIZE);
2600 *maxusagep = maxusage;
2601 *maxstackp = maxstack;
2602 return KERN_SUCCESS;
2603 }
2604 #endif /* MACH_DEBUG */
2605
2606 #if MACH_KDB
2607 #include <ddb/db_output.h>
2608 /*
2609 * Useful in the debugger:
2610 */
2611 void
2612 thread_stats(void)
2613 {
2614 register thread_t thread;
2615 int total = 0, rpcreply = 0;
2616
2617 queue_iterate(&default_pset.threads, thread, thread_t, pset_threads) {
2618 total++;
2619 if (thread->ith_rpc_reply != IP_NULL)
2620 rpcreply++;
2621 }
2622
2623 db_printf("%d total threads.\n", total);
2624 db_printf("%d using rpc_reply.\n", rpcreply);
2625 }
2626 #endif /* MACH_KDB */
Cache object: ebed029d21673a3aab1258a4674b4b7f
|