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/priority.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,1991,1990,1989,1988,1987 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  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:        priority.c,v $
   29  * Revision 2.8  93/05/15  18:56:43  mrt
   30  *      machparam.h -> machspl.h
   31  * 
   32  * Revision 2.7  93/01/14  17:35:42  danner
   33  *      Added check to thread_quantum_update for processor not in a
   34  *      processor set (when being reassigned).  This should be fixed in
   35  *      processor assignment code instead.
   36  *      [92/10/23            dbg]
   37  *      Removed unnecessary include of machine/mach_param.h
   38  *      [92/12/16            af]
   39  *      Proper spl typing.
   40  *      [92/12/01            af]
   41  * 
   42  *      Added check thread_quantum_update for processor not in a
   43  *      processor set (when being reassigned).  This should be fixed in
   44  *      processor assignment code instead.
   45  *      [92/10/23            dbg]
   46  *      Proper spl typing.
   47  *      [92/12/01            af]
   48  * 
   49  *      Added check thread_quantum_update for processor not in a
   50  *      processor set (when being reassigned).  This should be fixed in
   51  *      processor assignment code instead.
   52  *      [92/10/23            dbg]
   53  * 
   54  * Revision 2.6  92/08/03  17:38:38  jfriedl
   55  *      removed silly prototypes
   56  *      [92/08/02            jfriedl]
   57  * 
   58  * Revision 2.5  92/05/21  17:15:03  jfriedl
   59  *      tried prototypes.
   60  *      [92/05/20            jfriedl]
   61  * 
   62  * Revision 2.4  91/05/14  16:45:17  mrt
   63  *      Correcting copyright
   64  * 
   65  * Revision 2.3  91/02/05  17:28:22  mrt
   66  *      Changed to new Mach copyright
   67  *      [91/02/01  16:15:50  mrt]
   68  * 
   69  * Revision 2.2  90/06/02  14:55:24  rpd
   70  *      Updated to new scheduling technology.
   71  *      [90/03/26  22:13:58  rpd]
   72  * 
   73  * Revision 2.1  89/08/03  15:45:28  rwd
   74  * Created.
   75  * 
   76  * 24-Mar-89  David Golub (dbg) at Carnegie-Mellon University
   77  *      Added thread_set_priority.
   78  *
   79  * 14-Jan-89  David Golub (dbg) at Carnegie-Mellon University
   80  *      Split into two new files: mach_clock (for timing) and priority
   81  *      (for priority calculation).
   82  *
   83  *  9-Aug-88  David Black (dlb) at Carnegie-Mellon University
   84  *      thread->first_quantum replaces runrun.
   85  *
   86  *  4-May-88  David Black (dlb) at Carnegie-Mellon University
   87  *      MACH_TIME_NEW is now standard.
   88  *      Do ageing here on clock interrupts instead of in
   89  *      recompute_priorities.  Do accurate usage calculations.
   90  *
   91  * 18-Nov-87  Avadis Tevanian (avie) at Carnegie-Mellon University
   92  *      Delete previous history.
   93  */ 
   94 /*
   95  *      File:   clock_prim.c
   96  *      Author: Avadis Tevanian, Jr.
   97  *      Date:   1986
   98  *
   99  *      Clock primitives.
  100  */
  101 
  102 #include <cpus.h>
  103 
  104 #include <mach/boolean.h>
  105 #include <mach/kern_return.h>
  106 #include <mach/machine.h>
  107 #include <kern/host.h>
  108 #include <kern/mach_param.h>
  109 #include <kern/sched.h>
  110 #include <kern/thread.h>
  111 #include <kern/time_out.h>
  112 #include <kern/time_stamp.h>
  113 #include <machine/machspl.h>
  114 
  115 
  116 
  117 /*
  118  *      USAGE_THRESHOLD is the amount by which usage must change to
  119  *      cause a priority shift that moves a thread between run queues.
  120  */
  121 
  122 #ifdef  PRI_SHIFT_2
  123 #if     PRI_SHIFT_2 > 0
  124 #define USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT))
  125 #else   /* PRI_SHIFT_2 > 0 */
  126 #define USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT))
  127 #endif  /* PRI_SHIFT_2 > 0 */
  128 #else   /* PRI_SHIFT_2 */
  129 #define USAGE_THRESHOLD (1 << (PRI_SHIFT + 2 + SCHED_SHIFT))
  130 #endif  /* PRI_SHIFT_2 */
  131 
  132 /*
  133  *      thread_quantum_update:
  134  *
  135  *      Recalculate the quantum and priority for a thread.
  136  *      The number of ticks that has elapsed since we were last called
  137  *      is passed as "nticks."
  138  */
  139 
  140 void thread_quantum_update(mycpu, thread, nticks, state)
  141         register int            mycpu;
  142         register thread_t       thread;
  143         int                     nticks;
  144         int                     state;
  145 {
  146         register int                    quantum;
  147         register processor_t            myprocessor;
  148 #if     NCPUS > 1
  149         register processor_set_t        pset;
  150 #endif
  151         spl_t                           s;
  152 
  153         myprocessor = cpu_to_processor(mycpu);
  154 #if     NCPUS > 1
  155         pset = myprocessor->processor_set;
  156         if (pset == 0) {
  157             /*
  158              * Processor is being reassigned.
  159              * Should rewrite processor assignment code to
  160              * block clock interrupts.
  161              */
  162             return;
  163         }
  164 #endif  /* NCPUS > 1 */
  165 
  166         /*
  167          *      Account for thread's utilization of these ticks.
  168          *      This assumes that there is *always* a current thread.
  169          *      When the processor is idle, it should be the idle thread.
  170          */
  171 
  172         /*
  173          *      Update set_quantum and calculate the current quantum.
  174          */
  175 #if     NCPUS > 1
  176         pset->set_quantum = pset->machine_quantum[
  177                 ((pset->runq.count > pset->processor_count) ?
  178                   pset->processor_count : pset->runq.count)];
  179 
  180         if (myprocessor->runq.count != 0)
  181                 quantum = min_quantum;
  182         else
  183                 quantum = pset->set_quantum;
  184 #else   /* NCPUS > 1 */
  185         quantum = min_quantum;
  186         default_pset.set_quantum = quantum;
  187 #endif  /* NCPUS > 1 */
  188                 
  189         /*
  190          *      Now recompute the priority of the thread if appropriate.
  191          */
  192 
  193         if (state != CPU_STATE_IDLE) {
  194                 myprocessor->quantum -= nticks;
  195 #if     NCPUS > 1
  196                 /*
  197                  *      Runtime quantum adjustment.  Use quantum_adj_index
  198                  *      to avoid synchronizing quantum expirations.
  199                  */
  200                 if ((quantum != myprocessor->last_quantum) &&
  201                     (pset->processor_count > 1)) {
  202                         myprocessor->last_quantum = quantum;
  203                         simple_lock(&pset->quantum_adj_lock);
  204                         quantum = min_quantum + (pset->quantum_adj_index *
  205                                 (quantum - min_quantum)) / 
  206                                         (pset->processor_count - 1);
  207                         if (++(pset->quantum_adj_index) >=
  208                             pset->processor_count)
  209                                 pset->quantum_adj_index = 0;
  210                         simple_unlock(&pset->quantum_adj_lock);
  211                 }
  212 #endif  /* NCPUS > 1 */
  213                 if (myprocessor->quantum <= 0) {
  214                         s = splsched();
  215                         thread_lock(thread);
  216                         if (thread->sched_stamp != sched_tick) {
  217                                 update_priority(thread);
  218                         }
  219                         else {
  220                             if (
  221 #if     MACH_FIXPRI
  222                                 (thread->policy == POLICY_TIMESHARE) &&
  223 #endif  /* MACH_FIXPRI */
  224                                 (thread->depress_priority < 0)) {
  225                                     thread_timer_delta(thread);
  226                                     thread->sched_usage +=
  227                                         thread->sched_delta;
  228                                     thread->sched_delta = 0;
  229                                     compute_my_priority(thread);
  230                             }
  231                         }
  232                         thread_unlock(thread);
  233                         (void) splx(s);
  234                         /*
  235                          *      This quantum is up, give this thread another.
  236                          */
  237                         myprocessor->first_quantum = FALSE;
  238 #if     MACH_FIXPRI
  239                         if (thread->policy == POLICY_TIMESHARE) {
  240 #endif  /* MACH_FIXPRI */
  241                                 myprocessor->quantum += quantum;
  242 #if     MACH_FIXPRI
  243                         }
  244                         else {
  245                                 /*
  246                                  *    Fixed priority has per-thread quantum.
  247                                  *    
  248                                  */
  249                                 myprocessor->quantum += thread->sched_data;
  250                         }
  251 #endif  /* MACH_FIXPRI */
  252                 }
  253                 /*
  254                  *      Recompute priority if appropriate.
  255                  */
  256                 else {
  257                     s = splsched();
  258                     thread_lock(thread);
  259                     if (thread->sched_stamp != sched_tick) {
  260                         update_priority(thread);
  261                     }
  262                     else {
  263                         if (
  264 #if     MACH_FIXPRI
  265                             (thread->policy == POLICY_TIMESHARE) &&
  266 #endif  /* MACH_FIXPRI */
  267                             (thread->depress_priority < 0)) {
  268                                 thread_timer_delta(thread);
  269                                 if (thread->sched_delta >= USAGE_THRESHOLD) {
  270                                     thread->sched_usage +=
  271                                         thread->sched_delta;
  272                                     thread->sched_delta = 0;
  273                                     compute_my_priority(thread);
  274                                 }
  275                         }
  276                     }
  277                     thread_unlock(thread);
  278                     (void) splx(s);
  279                 }
  280                 /*
  281                  * Check for and schedule ast if needed.
  282                  */
  283                 ast_check();
  284         }
  285 }
  286 

Cache object: 1418e6a41557bb2a2f499982cad7cf32


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