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/sched_policy/real_time.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 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:        real_time.c,v $
   29  * Revision 2.2  93/11/17  18:37:51  dbg
   30  *      policy_param_realtime always has start time.
   31  *      [93/06/21            dbg]
   32  * 
   33  *      Created.
   34  *      [93/05/12            dbg]
   35  * 
   36  */
   37 
   38 /*
   39  *      Common routines for real-time scheduling policies.
   40  */
   41 
   42 #include <kern/clock.h>
   43 #include <kern/mach_timer.h>
   44 #include <kern/run_queues.h>
   45 #include <kern/thread.h>
   46 #include <kern/rt_thread.h>
   47 
   48 #include <ipc/ipc_port.h>
   49 
   50 #include <sched_policy/real_time.h>
   51 
   52 #include <machine/machspl.h>
   53 
   54 /*
   55  *      Set the scheduling parameters for a thread.  If they
   56  *      are not supplied, the thread`s current parameters
   57  *      are used if 'new_policy' is FALSE; otherwise, per-
   58  *      policy defaults are used.  If 'new_policy' is FALSE,
   59  *      limit values are taken from the thread`s processor
   60  *      set; otherwise, the thread`s current limit values
   61  *      are used.
   62  *
   63  *      For EDF, there are no limit values.  Data sets the
   64  *      thread`s period and deadline timers.
   65  */
   66 kern_return_t
   67 rt_thread_set_param(
   68         thread_t        thread,
   69         policy_param_t  param,
   70         natural_t       count,
   71         boolean_t       new_policy,
   72         boolean_t       check_limits)
   73 {
   74         if (count > 0) {
   75             struct policy_param_realtime *pd;
   76             time_spec_t period, deadline, start_time;
   77             boolean_t   periodic;
   78             mach_timer_t wakeup_timer, deadline_timer;
   79 
   80             /*
   81              *  Data supplied.  Set period and deadline, and
   82              *  change timers to match.
   83              */
   84             if (count < POLICY_PARAM_REALTIME_COUNT)
   85                 return KERN_INVALID_VALUE;
   86 
   87             pd = (struct policy_param_realtime *)param;
   88             period = pd->period;
   89             deadline = pd->deadline;
   90 
   91             if (!time_spec_valid(period) || !time_spec_valid(deadline) ||
   92                 !time_spec_valid(pd->start_time))
   93             {
   94                 return KERN_INVALID_VALUE;
   95             }
   96 
   97             /*
   98              *  Treat zero period or deadline as infinite
   99              */
  100             if (!time_spec_nonzero(period)) {
  101                 time_spec_set_infinite(period);
  102             }
  103             if (!time_spec_nonzero(deadline)) {
  104                 time_spec_set_infinite(deadline);
  105             }
  106 
  107             periodic = !time_spec_infinite(period);
  108 
  109             /*
  110              *  Get period and deadline timers
  111              */
  112             wakeup_timer = thread->rt_wakeup_timer;
  113             deadline_timer = thread->rt_deadline_timer;
  114 
  115             switch (pd->start_when) {
  116                 case START_TIME_ABSOLUTE:
  117                     start_time = pd->start_time;
  118                     if (!time_spec_nonzero(start_time)) {
  119                         /*
  120                          *      No start time specified - error
  121                          */
  122                         return KERN_INVALID_ARGUMENT;
  123                     }
  124                     break;
  125 
  126                 case START_TIME_RELATIVE:
  127                     if (wakeup_timer != 0) {
  128                         clock_read(start_time,
  129                                    wakeup_timer->tm_clock);
  130                         time_spec_add(start_time, pd->start_time);
  131                     }
  132                     else {
  133                         return KERN_INVALID_ARGUMENT;
  134                                 /* relative to what? */
  135                     }
  136                     break;
  137 
  138                 case START_TIME_NO_CHANGE:
  139                     if (wakeup_timer != 0 && 
  140                         timer_start_time(wakeup_timer, &start_time))
  141                     {
  142                         /*
  143                          *      Current starting time is the
  144                          *      start of the current period:
  145                          *      the expiration time for the
  146                          *      periodic timer minus the
  147                          *      period of the timer.
  148                          */
  149                     }
  150                     else {
  151                         return KERN_INVALID_ARGUMENT;
  152                                 /* no period */
  153                     }
  154                     break;
  155 
  156                 default:
  157                     return KERN_INVALID_ARGUMENT;
  158             }
  159 
  160             /*
  161              *  If there is no periodic timer, we cannot
  162              *  reset the timers.  Assume that the caller
  163              *  has done so.
  164              */
  165             if (wakeup_timer != 0) {
  166                 /*
  167                  *      If the new period is infinite, cancel the periodic
  168                  *      timer.  Otherwise, reset it to the new period.
  169                  */
  170                 if (periodic) {
  171                     time_spec_t new_wakeup_time;
  172 
  173                     new_wakeup_time = start_time;
  174                     time_spec_add(new_wakeup_time, period);
  175 
  176                     (void) timer_rearm(wakeup_timer,
  177                                 new_wakeup_time,
  178                                 period,
  179                                 TIMER_ABSOLUTE | TIMER_PERIODIC);
  180                 }
  181                 else {
  182                     (void) timer_cancel(wakeup_timer, 0);
  183                 }
  184             }
  185 
  186             if (deadline_timer != 0) {
  187                 /*
  188                  *      If the new deadline is infinite, cancel the
  189                  *      deadline timer.  Otherwise, calculate the
  190                  *      new deadline, and set the timer.
  191                  *
  192                  *      The new deadline_time is start_time +
  193                  *                      new_deadline.
  194                  */
  195                 if (!time_spec_infinite(deadline)) {
  196                     time_spec_t new_deadline_time;
  197 
  198                     new_deadline_time = start_time;
  199                     time_spec_add(new_deadline_time, deadline);
  200 
  201                     (void) timer_rearm(deadline_timer,
  202                                 new_deadline_time,
  203                                 period,
  204                                 TIMER_ABSOLUTE |
  205                                 ((periodic) ? TIMER_PERIODIC
  206                                             : 0)
  207                                 );
  208                 }
  209                 else {
  210                     (void) timer_cancel(deadline_timer, 0);
  211                 }
  212             }
  213 
  214             rt_sched(thread)->period = period;
  215             rt_sched(thread)->deadline = deadline;
  216         }
  217         else {
  218             if (new_policy) {
  219                 /*
  220                  *      Thread is not already running this policy:
  221                  *      use default values.
  222                  *
  223                  *      Defaults are 'infinite' period and deadline.
  224                  */
  225                 rt_sched(thread)->start_time.seconds = 0;
  226                 rt_sched(thread)->start_time.nanoseconds = 0;
  227                 time_spec_set_infinite(rt_sched(thread)->period);
  228                 time_spec_set_infinite(rt_sched(thread)->deadline);
  229             }
  230             /* otherwise no change */
  231         }
  232 
  233         return KERN_SUCCESS;
  234 }
  235 
  236 /*
  237  *      Get the scheduling parameters and limits for a thread.
  238  */
  239 kern_return_t
  240 rt_thread_get_param(
  241         thread_t        thread,
  242         policy_param_t  param,
  243         natural_t       *count)
  244 {
  245         mach_timer_t    wakeup_timer;
  246 
  247         struct policy_param_realtime *pd;
  248 
  249         if (*count < POLICY_PARAM_REALTIME_COUNT)
  250             return KERN_INVALID_VALUE;
  251 
  252         pd = (struct policy_param_realtime *)param;
  253 
  254         pd->period   = rt_sched(thread)->period;
  255         pd->deadline = rt_sched(thread)->deadline;
  256 
  257         wakeup_timer = thread->rt_wakeup_timer;
  258         if (wakeup_timer != 0 &&
  259             timer_start_time(wakeup_timer, &pd->start_time))
  260         {
  261             /*
  262              *  The start of the current period is
  263              *  the expiration time for the periodic
  264              *  timer minus the period of the timer.
  265              */
  266         }
  267         else {
  268             /*
  269              *  Can`t get start time.
  270              */
  271             pd->start_time.seconds = 0;
  272             pd->start_time.nanoseconds = 0;
  273         }
  274         pd->start_when = START_TIME_ABSOLUTE;
  275 
  276         *count = POLICY_PARAM_REALTIME_COUNT;
  277         return KERN_SUCCESS;
  278 }
  279 

Cache object: 1b9bb6c5d09786547594dbdf5a4fd034


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