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_swap.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_swap.c,v $
   29  * Revision 2.13  93/11/17  17:31:37  dbg
   30  *      Break up thread lock.
   31  *      [93/05/26            dbg]
   32  * 
   33  *      Added AST_KERNEL_CHECK to swapper thread.  Added ANSI
   34  *      function prototypes.  Declare non-returning functions
   35  *      as returning 'no_return'.
   36  *      [93/05/04            dbg]
   37  * 
   38  * Revision 2.12  93/05/15  18:56:04  mrt
   39  *      machparam.h -> machspl.h
   40  * 
   41  * Revision 2.11  93/01/14  17:37:17  danner
   42  *      Corrected casts for thread_wakeup and assert_wait.
   43  *      [93/01/12            danner]
   44  *      64bit cleanup. Proper spl typing.
   45  *      [92/12/01            af]
   46  * 
   47  * Revision 2.10  92/08/03  17:40:14  jfriedl
   48  *      removed silly prototypes
   49  *      [92/08/02            jfriedl]
   50  * 
   51  * Revision 2.9  92/05/21  17:16:48  jfriedl
   52  *      tried prototypes.
   53  *      [92/05/20            jfriedl]
   54  * 
   55  * Revision 2.8  91/07/31  17:50:04  dbg
   56  *      Revise scheduling state machine.
   57  *      [91/07/30  17:07:03  dbg]
   58  * 
   59  * Revision 2.7  91/05/14  16:49:08  mrt
   60  *      Correcting copyright
   61  * 
   62  * Revision 2.6  91/03/16  14:53:09  rpd
   63  *      Removed thread_swapout.
   64  *      [91/02/24            rpd]
   65  *      Added swapin_thread_continue.
   66  *      Simplified the state machine.  Now it uses only
   67  *      TH_SW_IN, TH_SW_OUT, TH_SW_COMING_IN.
   68  *      [91/01/20            rpd]
   69  * 
   70  *      Simplified thread_swapin.
   71  *      [91/01/17            rpd]
   72  * 
   73  * Revision 2.5  91/02/05  17:30:40  mrt
   74  *      Changed to new Mach copyright
   75  *      [91/02/01  16:20:14  mrt]
   76  * 
   77  * Revision 2.4  91/01/08  15:18:20  rpd
   78  *      Added continuation argument to thread_block.
   79  *      [90/12/08            rpd]
   80  * 
   81  *      Removed swapout_thread, swapout_threads,
   82  *      swapout_scan, thread_swapout.
   83  *      [90/11/11            rpd]
   84  * 
   85  * Revision 2.3  90/06/02  14:57:18  rpd
   86  *      In thread_swapout, free the thread's cached message buffer.
   87  *      [90/04/23            rpd]
   88  *      Converted to new processor set technology.
   89  *      [90/03/26  22:26:32  rpd]
   90  * 
   91  * Revision 2.2  89/12/08  19:52:35  rwd
   92  *      Added call to zone_gc()
   93  *      [89/11/21            rwd]
   94  * 
   95  * Revision 2.1  89/08/03  15:48:24  rwd
   96  * Created.
   97  * 
   98  * Revision 2.4  88/10/27  10:50:40  rpd
   99  *      Changed includes to the new style.  Removed extraneous semis
  100  *      from the swapper_lock/swapper_unlock macros.
  101  *      [88/10/26  14:49:09  rpd]
  102  * 
  103  * 15-Jun-88  Michael Young (mwyoung) at Carnegie-Mellon University
  104  *      Fix improper handling of swapper_lock() in swapin_thread().
  105  *      Problem discovery and elegant recoding due to Richard Draves.
  106  *
  107  *  4-May-88  David Golub (dbg) at Carnegie-Mellon University
  108  *      Remove vax-specific code.
  109  *
  110  *  1-Mar-88  David Black (dlb) at Carnegie-Mellon University
  111  *      Logic change due to replacement of wait_time field in thread
  112  *      with sched_stamp.  Extra argument to thread_setrun().
  113  *
  114  * 25-Jan-88  Richard Sanzi (sanzi) at Carnegie-Mellon University
  115  *      Notify pcb module that pcb is about to be unwired by calling
  116  *      pcb_synch(thread).
  117  *      
  118  * 21-Jan-88  David Golub (dbg) at Carnegie-Mellon University
  119  *      Fix lots more race conditions (thread_swapin called during
  120  *      swapout, thread_swapin called twice) by adding a swapper state
  121  *      machine to each thread.  Moved thread_swappable here from
  122  *      kern/thread.c.
  123  *
  124  * 12-Nov-87  David Golub (dbg) at Carnegie-Mellon University
  125  *      Fix race condition in thread_swapout: mark thread as swapped
  126  *      before swapping out its stack, so that an intervening wakeup
  127  *      will put it on the swapin list.
  128  *
  129  *  5-Oct-87  David Golub (dbg) at Carnegie-Mellon University
  130  *      Changed to new scheduling state machine.
  131  *
  132  * 15-Sep-87  Michael Young (mwyoung) at Carnegie-Mellon University
  133  *      De-linted.
  134  *
  135  *  5-Sep-87  Michael Young (mwyoung) at Carnegie-Mellon University
  136  *      Added check for THREAD_SWAPPABLE in swapout_scan().
  137  *
  138  * 14-Jul-87  David Golub (dbg) at Carnegie-Mellon University
  139  *      Truncate the starting address and round up the size given to
  140  *      vm_map_pageable, when wiring/unwiring kernel stacks.
  141  *      KERNEL_STACK_SIZE is not necessarily a multiple of page_size; if
  142  *      it isn't, forgetting to round the address and size to page
  143  *      boundaries results in panic.  Kmem_alloc and kmem_free, used in
  144  *      thread.c to allocate and free kernel stacks, already round to
  145  *      page boundaries.
  146  *
  147  * 26-Jun-87  Michael Young (mwyoung) at Carnegie-Mellon University
  148  *      Add thread_swapout_allowed flag to make it easy to turn
  149  *      off swapping when debugging.
  150  *
  151  *  4-Jun-87  David Golub (dbg) at Carnegie-Mellon University
  152  *      Pass correct number of parameters to lock_init - initialize
  153  *      swap_lock as sleepable instead of calling lock_sleepable
  154  *      separately.
  155  *
  156  *  1-Apr-87  Avadis Tevanian (avie) at Carnegie-Mellon University
  157  *      Include vm_param.h to pick up KERNEL_STACK_SIZE definition.
  158  *
  159  * 20-Mar-87  Avadis Tevanian (avie) at Carnegie-Mellon University
  160  *      Lower ipl before calling thread_swapout().
  161  *
  162  * 19-Mar-87  David Golub (dbg) at Carnegie-Mellon University
  163  *      Fix one race condition in this (not so buggy) version - since
  164  *      thread_swapin can be called from interrupts, must raise IPL when
  165  *      locking swapper_lock.
  166  *
  167  * 09-Mar-87  Avadis Tevanian (avie) at Carnegie-Mellon University
  168  *      Created, based somewhat loosely on the earlier (which was a highly
  169  *      buggy, race condition filled version).
  170  *
  171  */
  172 /*
  173  *
  174  *      File:   kern/thread_swap.c
  175  *      Author: Avadis Tevanian, Jr.
  176  *      Date:   1987
  177  *
  178  *      Mach thread swapper:
  179  *              Find idle threads to swap, freeing up kernel stack resources
  180  *              at the expense of allowing them to execute.
  181  *
  182  *              Swap in threads that need to be run.  This is done here
  183  *              by the swapper thread since it cannot be done (in general)
  184  *              when the kernel tries to place a thread on a run queue.
  185  *
  186  *      Note: The act of swapping a thread in Mach does not mean that
  187  *      its memory gets forcibly swapped to secondary storage.  The memory
  188  *      for the task corresponding to a swapped thread is paged out
  189  *      through the normal paging mechanism.
  190  *
  191  */
  192 
  193 #include <ipc/ipc_kmsg.h>
  194 #include <kern/counters.h>
  195 #include <kern/thread.h>
  196 #include <kern/lock.h>
  197 #include <vm/vm_map.h>
  198 #include <vm/vm_kern.h>
  199 #include <mach/vm_param.h>
  200 #include <kern/sched_prim.h>
  201 #include <kern/stack.h>
  202 #include <kern/processor.h>
  203 #include <kern/thread_swap.h>
  204 #include <machine/machspl.h>            /* for splsched */
  205 
  206 
  207 
  208 queue_head_t            swapin_queue;
  209 decl_simple_lock_data(, swapper_lock_data)
  210 
  211 #define swapper_lock()          simple_lock(&swapper_lock_data)
  212 #define swapper_unlock()        simple_unlock(&swapper_lock_data)
  213 
  214 /*
  215  *      swapper_init: [exported]
  216  *
  217  *      Initialize the swapper module.
  218  */
  219 void swapper_init(void)
  220 {
  221         queue_init(&swapin_queue);
  222         simple_lock_init(&swapper_lock_data);
  223 }
  224 
  225 /*
  226  *      thread_swapin: [exported]
  227  *
  228  *      Place the specified thread in the list of threads to swapin.  It
  229  *      is assumed that the thread is locked, therefore we are at splsched.
  230  *
  231  *      We don't bother with stack_alloc_try to optimize swapin;
  232  *      our callers have already tried that route.
  233  */
  234 
  235 void thread_swapin(
  236         thread_t        thread)
  237 {
  238         switch (thread->state & TH_SWAP_STATE) {
  239             case TH_SWAPPED:
  240                 /*
  241                  *      Swapped out - queue for swapin thread.
  242                  */
  243                 thread->state = (thread->state & ~TH_SWAP_STATE)
  244                                 | TH_SW_COMING_IN;
  245                 swapper_lock();
  246                 enqueue_tail(&swapin_queue, (queue_entry_t) thread);
  247                 swapper_unlock();
  248                 thread_wakeup((event_t) &swapin_queue);
  249                 break;
  250 
  251             case TH_SW_COMING_IN:
  252                 /*
  253                  *      Already queued for swapin thread, or being
  254                  *      swapped in.
  255                  */
  256                 break;
  257 
  258             default:
  259                 /*
  260                  *      Already swapped in.
  261                  */
  262                 panic("thread_swapin");
  263         }
  264 }
  265 
  266 /*
  267  *      thread_doswapin:
  268  *
  269  *      Swapin the specified thread.  If it should be runnable, then put
  270  *      it on a run queue.  No locks should be held on entry, as it is
  271  *      likely that this routine will sleep (waiting for stack allocation).
  272  */
  273 void thread_doswapin(
  274         register thread_t thread)
  275 {
  276         spl_t   s;
  277 
  278         /*
  279          *      Allocate the kernel stack.
  280          */
  281 
  282         stack_alloc(thread, thread_continue);
  283 
  284         /*
  285          *      Place on run queue.  
  286          */
  287 
  288         s = splsched();
  289         thread_sched_lock(thread);
  290         thread->state &= ~(TH_SWAPPED | TH_SW_COMING_IN);
  291         if (thread->state & TH_RUN)
  292                 thread_setrun(thread, TRUE);
  293         thread_sched_unlock(thread);
  294         splx(s);
  295 }
  296 
  297 /*
  298  *      swapin_thread: [exported]
  299  *
  300  *      This procedure executes as a kernel thread.  Threads that need to
  301  *      be swapped in are swapped in by this thread.
  302  */
  303 no_return swapin_thread_continue(void)
  304 {
  305         for (;;) {
  306                 register thread_t thread;
  307                 spl_t s;
  308 
  309                 s = splsched();
  310                 swapper_lock();
  311 
  312                 while ((thread = (thread_t) dequeue_head(&swapin_queue))
  313                                                         != THREAD_NULL) {
  314                         swapper_unlock();
  315                         splx(s);
  316 
  317                         thread_doswapin(thread);                /* may block */
  318 
  319                         AST_KERNEL_CHECK(cpu_number());
  320 
  321                         s = splsched();
  322                         swapper_lock();
  323                 }
  324 
  325                 assert_wait((event_t) &swapin_queue, FALSE);
  326                 swapper_unlock();
  327                 splx(s);
  328                 counter(c_swapin_thread_block++);
  329                 thread_block(swapin_thread_continue);
  330         }
  331 }
  332 
  333 no_return swapin_thread(void)
  334 {
  335         stack_privilege(current_thread());
  336 
  337         swapin_thread_continue();
  338         /*NOTREACHED*/
  339 }

Cache object: 46f4fe086a11ab163500f2feb8e35ff5


[ 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.