The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/thread.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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)&param,
 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)&param,
 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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.