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/kern_sched.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  * $FreeBSD: src/sys/posix4/ksched.c,v 1.7.2.1 2000/05/16 06:58:13 dillon Exp $
   33  */
   34 
   35 /*
   36  * ksched: Soft real time scheduling based on "rtprio".
   37  */
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/posix4.h>
   42 #include <sys/proc.h>
   43 #include <sys/kernel.h>
   44 #include <sys/resource.h>
   45 #include <machine/cpu.h>        /* For need_user_resched */
   46 
   47 
   48 /* ksched: Real-time extension to support POSIX priority scheduling.
   49  */
   50 
   51 struct ksched {
   52         struct timespec rr_interval;
   53 };
   54 
   55 int
   56 ksched_attach(struct ksched **p)
   57 {
   58         struct ksched *ksched= p31b_malloc(sizeof(*ksched));
   59 
   60         ksched->rr_interval.tv_sec = 0;
   61         ksched->rr_interval.tv_nsec = 1000000000L / 10; /* XXX */
   62 
   63         *p = ksched;
   64         return 0;
   65 }
   66 
   67 int
   68 ksched_detach(struct ksched *p)
   69 {
   70         p31b_free(p);
   71 
   72         return 0;
   73 }
   74 
   75 /*
   76  * XXX About priorities
   77  *
   78  *      POSIX 1003.1b requires that numerically higher priorities be of
   79  *      higher priority.  It also permits sched_setparam to be
   80  *      implementation defined for SCHED_OTHER.  I don't like
   81  *      the notion of inverted priorites for normal processes when
   82  *      you can use "setpriority" for that.
   83  *
   84  *      I'm rejecting sched_setparam for SCHED_OTHER with EINVAL.
   85  */
   86 
   87 /* Macros to convert between the unix (lower numerically is higher priority)
   88  * and POSIX 1003.1b (higher numerically is higher priority)
   89  */
   90 
   91 #define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P))
   92 #define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P))
   93 
   94 /*
   95  * These improve readability a bit for me:
   96  */
   97 #define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX)
   98 #define P1B_PRIO_MAX rtpprio_to_p4prio(RTP_PRIO_MIN)
   99 
  100 static __inline int
  101 getscheduler(register_t *ret, struct ksched *ksched, struct lwp *lp)
  102 {
  103         int e = 0;
  104 
  105         switch (lp->lwp_rtprio.type) {
  106         case RTP_PRIO_FIFO:
  107                 *ret = SCHED_FIFO;
  108                 break;
  109         case RTP_PRIO_REALTIME:
  110                 *ret = SCHED_RR;
  111                 break;
  112         default:
  113                 *ret = SCHED_OTHER;
  114                 break;
  115         }
  116 
  117         return e;
  118 }
  119 
  120 int
  121 ksched_setparam(register_t *ret, struct ksched *ksched,
  122     struct lwp *lp, const struct sched_param *param)
  123 {
  124         register_t policy;
  125         int e;
  126 
  127         e = getscheduler(&policy, ksched, lp);
  128 
  129         if (e == 0) {
  130                 if (policy == SCHED_OTHER)
  131                         e = EINVAL;
  132                 else
  133                         e = ksched_setscheduler(ret, ksched, lp, policy, param);
  134         }
  135 
  136         return e;
  137 }
  138 
  139 int
  140 ksched_getparam(register_t *ret, struct ksched *ksched,
  141     struct lwp *lp, struct sched_param *param)
  142 {
  143         if (RTP_PRIO_IS_REALTIME(lp->lwp_rtprio.type))
  144                 param->sched_priority = rtpprio_to_p4prio(lp->lwp_rtprio.prio);
  145 
  146         return 0;
  147 }
  148 
  149 /*
  150  * XXX The priority and scheduler modifications should
  151  *     be moved into published interfaces in kern/kern_sync.
  152  *
  153  * The permissions to modify process p were checked in "p31b_proc()".
  154  *
  155  */
  156 int
  157 ksched_setscheduler(register_t *ret, struct ksched *ksched,
  158     struct lwp *lp, int policy, const struct sched_param *param)
  159 {
  160         int e = 0;
  161         struct rtprio rtp;
  162 
  163         switch(policy) {
  164         case SCHED_RR:
  165         case SCHED_FIFO:
  166                 if (param->sched_priority >= P1B_PRIO_MIN &&
  167                     param->sched_priority <= P1B_PRIO_MAX) {
  168                         rtp.prio = p4prio_to_rtpprio(param->sched_priority);
  169                         rtp.type = (policy == SCHED_FIFO) ?
  170                             RTP_PRIO_FIFO : RTP_PRIO_REALTIME;
  171 
  172                         lp->lwp_rtprio = rtp;
  173                         need_user_resched();
  174                 } else {
  175                         e = EPERM;
  176                 }
  177                 break;
  178         case SCHED_OTHER:
  179                 rtp.type = RTP_PRIO_NORMAL;
  180                 rtp.prio = p4prio_to_rtpprio(param->sched_priority);
  181                 lp->lwp_rtprio = rtp;
  182 
  183                 /*
  184                  * XXX Simply revert to whatever we had for last
  185                  *     normal scheduler priorities.
  186                  *     This puts a requirement
  187                  *     on the scheduling code: You must leave the
  188                  *     scheduling info alone.
  189                  */
  190                 need_user_resched();
  191                 break;
  192         }
  193 
  194         return e;
  195 }
  196 
  197 int
  198 ksched_getscheduler(register_t *ret, struct ksched *ksched, struct lwp *lp)
  199 {
  200         return getscheduler(ret, ksched, lp);
  201 }
  202 
  203 /*
  204  * ksched_yield: Yield the CPU.
  205  *
  206  * MPSAFE
  207  */
  208 int
  209 ksched_yield(register_t *ret, struct ksched *ksched)
  210 {
  211         struct lwp *lp;
  212 
  213         if ((lp = curthread->td_lwp) != NULL)
  214                 lp->lwp_proc->p_usched->yield(lp);
  215         return 0;
  216 }
  217 
  218 /*
  219  * MPSAFE
  220  */
  221 int
  222 ksched_get_priority_max(register_t*ret, struct ksched *ksched, int policy)
  223 {
  224         int e = 0;
  225 
  226         switch (policy) {
  227         case SCHED_FIFO:
  228         case SCHED_RR:
  229                 *ret = RTP_PRIO_MAX;
  230                 break;
  231         case SCHED_OTHER:
  232                 *ret =  PRIO_MAX;
  233                 break;
  234         default:
  235                 e = EINVAL;
  236                 break;
  237         }
  238 
  239         return e;
  240 }
  241 
  242 /*
  243  * MPSAFE
  244  */
  245 int
  246 ksched_get_priority_min(register_t *ret, struct ksched *ksched, int policy)
  247 {
  248         int e = 0;
  249 
  250         switch (policy) {
  251         case SCHED_FIFO:
  252         case SCHED_RR:
  253                 *ret = P1B_PRIO_MIN;
  254                 break;
  255         case SCHED_OTHER:
  256                 *ret =  PRIO_MIN;
  257                 break;
  258         default:
  259                 e = EINVAL;
  260                 break;
  261         }
  262         return e;
  263 }
  264 
  265 /*
  266  * MPSAFE
  267  */
  268 int
  269 ksched_rr_get_interval(register_t *ret, struct ksched *ksched,
  270     struct lwp *lp, struct timespec *timespec)
  271 {
  272         *timespec = ksched->rr_interval;
  273 
  274         return 0;
  275 }

Cache object: 47d69be90b9a116cb29dbcb4b4e32b5f


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