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/quantum.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:        quantum.c,v $
   29  * Revision 2.2  93/11/17  17:19:04  dbg
   30  *      Separated quantum calculation code from clock update routines
   31  *      and moved into this file.
   32  *      [93/05/11            dbg]
   33  * 
   34  */
   35 
   36 #include <mach/boolean.h>
   37 
   38 #include <kern/processor.h>
   39 #include <kern/sched_policy.h>
   40 #include <kern/thread.h>
   41 
   42 /*
   43  *      Quantum adjustment.
   44  */
   45 
   46 /*
   47  *      Max context switch rate, in microseconds.
   48  */
   49 int     min_quantum = 100 * 1000;       /* 10/second = 100 milliseconds */
   50 
   51 /*
   52  *      Precalculate the appropriate system quanta based on load.  The
   53  *      index into machine_quantum is the number of threads on the
   54  *      processor set queue.  It is limited to the number of processors in
   55  *      the set.
   56  */
   57 
   58 void quantum_set(
   59         processor_set_t pset)
   60 {
   61 #if     NCPUS > 1
   62         register int    i,ncpus;
   63 
   64         ncpus = pset->processor_count;
   65 
   66         for (i = 1; i <= ncpus; i++) {
   67             pset->machine_quantum[i] = ((min_quantum * ncpus) + (i/2)) / i ;
   68         }
   69         pset->machine_quantum[0] = 2 * pset->machine_quantum[1];
   70 
   71         i = (pset->runq.count > pset->processor_count)
   72                 ? pset->processor_count
   73                 : pset->runq.count;
   74         pset->set_quantum = pset->machine_quantum[i];
   75 #else   /* NCPUS > 1 */
   76         default_pset.set_quantum = min_quantum;
   77 #endif  /* NCPUS > 1 */
   78 }
   79 
   80 /*
   81  *      clock_quantum_update:
   82  *
   83  *      Recalculate the quantum and priority for a thread.
   84  *      The number of microseconds that has elapsed since
   85  *      we were last called is passed in.
   86  */
   87 
   88 void
   89 clock_quantum_update(
   90         thread_t        thread,
   91         int             mycpu,
   92         unsigned int    usecs)
   93 {
   94         int             quantum;
   95         processor_t     myprocessor = cpu_to_processor(mycpu);
   96         boolean_t       end_quantum;
   97 
   98 #if     NCPUS > 1
   99         /*
  100          *      Update set_quantum.
  101          */
  102     {
  103         processor_set_t pset = myprocessor->processor_set;
  104 
  105         if (pset == 0) {
  106             /*
  107              * Processor is being reassigned.
  108              *
  109              * Should rewrite processor assignment code to
  110              * block clock interrupts.
  111              */
  112             return;
  113         }
  114 
  115         if (pset->runq.count > pset->processor_count)
  116             pset->set_quantum = pset->machine_quantum[pset->processor_count];
  117         else
  118             pset->set_quantum = pset->machine_quantum[pset->runq.count];
  119 
  120         if (myprocessor->state == PROCESSOR_IDLE)
  121             return;
  122 
  123 #if     MACH_IO_BINDING
  124         if (myprocessor->runq.count != 0)
  125             quantum = min_quantum;
  126         else
  127 #endif
  128             quantum = pset->set_quantum;
  129 
  130         /*
  131          * Runtime quantum adjustment.  Use quantum_adj_index
  132          * to avoid synchronizing quantum expirations.
  133          */
  134         if (quantum != myprocessor->last_quantum &&
  135             pset->processor_count > 1)
  136         {
  137             myprocessor->last_quantum = quantum;
  138             simple_lock(&pset->quantum_adj_lock);
  139             quantum = min_quantum +
  140                         (pset->quantum_adj_index * (quantum - min_quantum))
  141                             / (pset->processor_count - 1);
  142             if (++pset->quantum_adj_index >= pset->processor_count)
  143                 pset->quantum_adj_index = 0;
  144             simple_unlock(&pset->quantum_adj_lock);
  145         }
  146     }
  147 
  148 #else   /* NCPUS > 1 */
  149         quantum = min_quantum;
  150 
  151         if (myprocessor->state == PROCESSOR_IDLE)
  152             return;
  153 #endif  /* NCPUS > 1 */
  154 
  155         /*
  156          * Decrement quantum
  157          */
  158         myprocessor->quantum -= usecs;
  159         if (myprocessor->quantum <= 0) {
  160             /*
  161              * The quantum is up.  Give the thread another.
  162              */
  163             myprocessor->first_quantum = FALSE;
  164             myprocessor->quantum += quantum;
  165             end_quantum = TRUE;
  166         }
  167         else {
  168             end_quantum = FALSE;
  169         }
  170 
  171         CLOCK_SCHED(thread, end_quantum);
  172 }

Cache object: bd3f43f955f4fcae8c65c994a5fac613


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