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/ksched.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  * Copyright (c) 1996, 1997
    3  *      HD Associates, Inc.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by HD Associates, Inc
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 /* ksched: Soft real time scheduling based on "rtprio". */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD: releng/11.2/sys/kern/ksched.c 331722 2018-03-29 02:50:57Z eadler $");
   37 
   38 #include "opt_posix.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/lock.h>
   43 #include <sys/sysctl.h>
   44 #include <sys/kernel.h>
   45 #include <sys/mutex.h>
   46 #include <sys/proc.h>
   47 #include <sys/posix4.h>
   48 #include <sys/resource.h>
   49 #include <sys/sched.h>
   50 
   51 FEATURE(kposix_priority_scheduling, "POSIX P1003.1B realtime extensions");
   52 
   53 /* ksched: Real-time extension to support POSIX priority scheduling. */
   54 
   55 struct ksched {
   56         struct timespec rr_interval;
   57 };
   58 
   59 int
   60 ksched_attach(struct ksched **p)
   61 {
   62         struct ksched *ksched;
   63 
   64         ksched = malloc(sizeof(*ksched), M_P31B, M_WAITOK);
   65         ksched->rr_interval.tv_sec = 0;
   66         ksched->rr_interval.tv_nsec = 1000000000L / hz * sched_rr_interval();
   67         *p = ksched;
   68         return (0);
   69 }
   70 
   71 int
   72 ksched_detach(struct ksched *ks)
   73 {
   74 
   75         free(ks, M_P31B);
   76         return (0);
   77 }
   78 
   79 /*
   80  * XXX About priorities
   81  *
   82  *      POSIX 1003.1b requires that numerically higher priorities be of
   83  *      higher priority.  It also permits sched_setparam to be
   84  *      implementation defined for SCHED_OTHER.  I don't like
   85  *      the notion of inverted priorites for normal processes when
   86  *      you can use "setpriority" for that.
   87  *
   88  */
   89 
   90 /* Macros to convert between the unix (lower numerically is higher priority)
   91  * and POSIX 1003.1b (higher numerically is higher priority)
   92  */
   93 
   94 #define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P))
   95 #define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P))
   96 
   97 #define p4prio_to_tsprio(P) ((PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE) - (P))
   98 #define tsprio_to_p4prio(P) ((PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE) - (P))
   99 
  100 /* These improve readability a bit for me:
  101  */
  102 #define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX)
  103 #define P1B_PRIO_MAX rtpprio_to_p4prio(RTP_PRIO_MIN)
  104 
  105 static __inline int
  106 getscheduler(struct ksched *ksched, struct thread *td, int *policy)
  107 {
  108         struct rtprio rtp;
  109         int e;
  110 
  111         e = 0;
  112         pri_to_rtp(td, &rtp);
  113         switch (rtp.type) {
  114         case RTP_PRIO_FIFO:
  115                 *policy = SCHED_FIFO;
  116                 break;
  117         case RTP_PRIO_REALTIME:
  118                 *policy = SCHED_RR;
  119                 break;
  120         default:
  121                 *policy = SCHED_OTHER;
  122                 break;
  123         }
  124         return (e);
  125 }
  126 
  127 int
  128 ksched_setparam(struct ksched *ksched,
  129     struct thread *td, const struct sched_param *param)
  130 {
  131         int e, policy;
  132 
  133         e = getscheduler(ksched, td, &policy);
  134         if (e == 0)
  135                 e = ksched_setscheduler(ksched, td, policy, param);
  136         return (e);
  137 }
  138 
  139 int
  140 ksched_getparam(struct ksched *ksched, struct thread *td,
  141     struct sched_param *param)
  142 {
  143         struct rtprio rtp;
  144 
  145         pri_to_rtp(td, &rtp);
  146         if (RTP_PRIO_IS_REALTIME(rtp.type))
  147                 param->sched_priority = rtpprio_to_p4prio(rtp.prio);
  148         else {
  149                 if (PRI_MIN_TIMESHARE < rtp.prio) 
  150                         /*
  151                          * The interactive score has it to min realtime
  152                          * so we must show max (64 most likely).
  153                          */ 
  154                         param->sched_priority = PRI_MAX_TIMESHARE -
  155                             PRI_MIN_TIMESHARE;
  156                 else
  157                         param->sched_priority = tsprio_to_p4prio(rtp.prio);
  158         }
  159         return (0);
  160 }
  161 
  162 /*
  163  * XXX The priority and scheduler modifications should
  164  *     be moved into published interfaces in kern/kern_sync.
  165  *
  166  * The permissions to modify process p were checked in "p31b_proc()".
  167  *
  168  */
  169 int
  170 ksched_setscheduler(struct ksched *ksched, struct thread *td, int policy,
  171     const struct sched_param *param)
  172 {
  173         struct rtprio rtp;
  174         int e;
  175 
  176         e = 0;
  177         switch(policy) {
  178         case SCHED_RR:
  179         case SCHED_FIFO:
  180                 if (param->sched_priority >= P1B_PRIO_MIN &&
  181                     param->sched_priority <= P1B_PRIO_MAX) {
  182                         rtp.prio = p4prio_to_rtpprio(param->sched_priority);
  183                         rtp.type = (policy == SCHED_FIFO) ? RTP_PRIO_FIFO :
  184                             RTP_PRIO_REALTIME;
  185                         rtp_to_pri(&rtp, td);
  186                 } else {
  187                         e = EPERM;
  188                 }
  189                 break;
  190         case SCHED_OTHER:
  191                 if (param->sched_priority >= 0 && param->sched_priority <=
  192                     (PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE)) {
  193                         rtp.type = RTP_PRIO_NORMAL;
  194                         rtp.prio = p4prio_to_tsprio(param->sched_priority);
  195                         rtp_to_pri(&rtp, td);
  196                 } else {
  197                         e = EINVAL;
  198                 }
  199                 break;
  200         default:
  201                 e = EINVAL;
  202                 break;
  203         }
  204         return (e);
  205 }
  206 
  207 int
  208 ksched_getscheduler(struct ksched *ksched, struct thread *td, int *policy)
  209 {
  210 
  211         return (getscheduler(ksched, td, policy));
  212 }
  213 
  214 /* ksched_yield: Yield the CPU. */
  215 int
  216 ksched_yield(struct ksched *ksched)
  217 {
  218 
  219         sched_relinquish(curthread);
  220         return (0);
  221 }
  222 
  223 int
  224 ksched_get_priority_max(struct ksched *ksched, int policy, int *prio)
  225 {
  226         int e;
  227 
  228         e = 0;
  229         switch (policy) {
  230         case SCHED_FIFO:
  231         case SCHED_RR:
  232                 *prio = P1B_PRIO_MAX;
  233                 break;
  234         case SCHED_OTHER:
  235                 *prio = PRI_MAX_TIMESHARE - PRI_MIN_TIMESHARE;
  236                 break;
  237         default:
  238                 e = EINVAL;
  239                 break;
  240         }
  241         return (e);
  242 }
  243 
  244 int
  245 ksched_get_priority_min(struct ksched *ksched, int policy, int *prio)
  246 {
  247         int e;
  248 
  249         e = 0;
  250         switch (policy) {
  251         case SCHED_FIFO:
  252         case SCHED_RR:
  253                 *prio = P1B_PRIO_MIN;
  254                 break;
  255         case SCHED_OTHER:
  256                 *prio = 0;
  257                 break;
  258         default:
  259                 e = EINVAL;
  260                 break;
  261         }
  262         return (e);
  263 }
  264 
  265 int
  266 ksched_rr_get_interval(struct ksched *ksched, struct thread *td,
  267     struct timespec *timespec)
  268 {
  269 
  270         *timespec = ksched->rr_interval;
  271         return (0);
  272 }

Cache object: a2ed4fd9711593f16f050ca1171d711b


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