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/edf.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,1992 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:        edf.c,v $
   29  * Revision 2.3  93/12/23  10:05:13  dbg
   30  *      Removed include of machine/machparam.h.
   31  *      [93/12/14            dbg]
   32  * 
   33  * Revision 2.2  93/11/17  18:37:03  dbg
   34  *      Add per-policy scheduling parameters to thread and run queue.
   35  *      [93/05/10            dbg]
   36  * 
   37  *      Moved common operations to kern/run_queues.c.
   38  *      [93/04/10            dbg]
   39  * 
   40  *      Converted to per-policy run queue structure.
   41  *      [93/04/09            dbg]
   42  * 
   43  *      Merged into microkernel mainline.
   44  * 
   45  *      Changed period to time_spec_t.
   46  *      [92/09/06       savage]
   47  *      Added policy_init()
   48  *      [92/06/01       savage]
   49  *      Created 
   50  *      [92/05/04       takuro]
   51  * 
   52  */
   53 
   54 /*
   55  *      Earliest-deadline-first scheduling policy.  Threads
   56  *      are scheduled in the order of earliest deadline time
   57  *      first.
   58  */
   59 #include <mach_kdb.h>
   60 
   61 #include <mach/boolean.h>
   62 #include <mach/time_spec.h>
   63 #include <mach/realtime_policy.h>
   64 
   65 #include <kern/macro_help.h>
   66 #include <kern/ast.h>
   67 #include <kern/kalloc.h>
   68 #include <kern/run_queues.h>
   69 #include <kern/sched_policy.h>
   70 #include <kern/processor.h>
   71 #include <kern/thread.h>
   72 #include <kern/rt_thread.h>
   73 #include <kern/mach_timer.h>
   74 #include <sched_policy/real_time.h>
   75 #include <ipc/ipc_port.h>
   76 
   77 /*
   78  *      Uses a single run queue, ordered by deadline time.
   79  *      No policy limits.
   80  */
   81 struct edf_run_queue {
   82         struct run_queue rq;            /* common structure */
   83         queue_head_t    edf_queue;      /* queue */
   84 };
   85 typedef struct edf_run_queue *  edf_run_queue_t;
   86 
   87 #define edf_runq(rq)    ((struct edf_run_queue *)(rq))
   88 #define edf_count       rq.rq_count
   89 
   90 /*
   91  *      Choose thread.
   92  */
   93 thread_t
   94 edf_thread_dequeue(
   95         run_queue_t     runq)
   96 {
   97         edf_run_queue_t rq = edf_runq(runq);
   98         queue_entry_t   elt;
   99 
  100         assert(rq->edf_count > 0);
  101         assert(!queue_empty(&rq->edf_queue));
  102 
  103         dequeue_head_macro(&rq->edf_queue, elt);
  104         rq->edf_count--;
  105 
  106         current_processor()->first_quantum = TRUE;      /* XXX */
  107 
  108         return (thread_t) elt;
  109 }
  110 
  111 /*
  112  *      Put a thread onto a run queue in priority order.
  113  *      Return whether it can preempt the current thread.
  114  */
  115 boolean_t edf_thread_enqueue(
  116         run_queue_t     runq,
  117         thread_t        thread,
  118         boolean_t       may_preempt)
  119 {
  120         register edf_run_queue_t rq;
  121         register thread_t       next;
  122         register queue_t        q;
  123         mach_timer_t            timer1, timer2;
  124 
  125         rq = edf_runq(runq);
  126 
  127         q = &rq->edf_queue;
  128         timer1 = thread->rt_deadline_timer;
  129         if (timer1 == 0) {
  130             enqueue_tail_macro(q, (queue_entry_t) thread);
  131             rq->edf_count++;
  132             return FALSE;
  133         }
  134         queue_iterate(q, next, thread_t, links) {
  135             timer2 = next->rt_deadline_timer;
  136             if (timer2 == 0)
  137                 break;
  138             if (time_spec_leq(timer1->tm_expire_time,
  139                               timer2->tm_expire_time))
  140                 break;
  141         }
  142         enqueue_tail_macro((queue_t) next, (queue_entry_t) thread);
  143         rq->edf_count++;
  144 
  145         if (!may_preempt)
  146             return FALSE;
  147 
  148         timer2 = current_thread()->rt_deadline_timer;
  149         if (timer2 == 0)
  150             return TRUE;
  151         return !time_spec_leq(timer2->tm_expire_time, timer1->tm_expire_time);
  152 }
  153 
  154 /*
  155  *      Remove a thread from the run queue.
  156  */
  157 void edf_thread_remqueue(
  158         run_queue_t     runq,
  159         thread_t        thread)
  160 {
  161         edf_run_queue_t rq = edf_runq(runq);
  162                 
  163         remqueue(&rq->edf_queue, (queue_entry_t) thread);
  164         rq->edf_count--;
  165 }
  166 
  167 boolean_t edf_csw_needed(
  168         run_queue_t     runq,
  169         thread_t        thread)
  170 {
  171         edf_run_queue_t rq = edf_runq(runq);
  172         thread_t        th;
  173         mach_timer_t    timer1, timer2;
  174 
  175         th = (thread_t) queue_first(&rq->edf_queue);
  176         timer1 = th->rt_deadline_timer;
  177         timer2 = thread->rt_deadline_timer;
  178 
  179         if (timer1 == 0)
  180             return FALSE;
  181         if (timer2 == 0)
  182             return TRUE;
  183         return time_spec_leq(timer1->tm_expire_time, timer2->tm_expire_time);
  184 }
  185 
  186 extern struct sched_policy      edf_sched_policy;       /* forward */
  187 
  188 run_queue_t
  189 edf_run_queue_alloc(void)
  190 {
  191         edf_run_queue_t rq;
  192 
  193         rq = (edf_run_queue_t) kalloc(sizeof(struct edf_run_queue));
  194         run_queue_init(&rq->rq, &edf_sched_policy);
  195 
  196         queue_init(&rq->edf_queue);
  197 
  198         return &rq->rq;
  199 }
  200 
  201 void
  202 edf_run_queue_free(
  203         run_queue_t     runq)
  204 {
  205         kfree((vm_offset_t) runq, sizeof(struct edf_run_queue));
  206 }
  207 
  208 #if     MACH_KDB
  209 #include <ddb/db_output.h>
  210 void edf_thread_db_print(
  211         thread_t        thread)
  212 {
  213         db_printf("EDF    ");
  214 }
  215 #endif
  216 
  217 /*
  218  *      Statically allocated policy structure.
  219  */
  220 struct sched_policy     edf_sched_policy = {
  221     {
  222         /* sched_ops */
  223         edf_thread_dequeue,
  224         edf_thread_enqueue,
  225         edf_thread_remqueue,
  226 
  227         edf_csw_needed,
  228         ast_check,
  229         0,                      /* no update_priority */
  230 
  231         edf_run_queue_alloc,
  232         edf_run_queue_free,
  233 
  234         rt_runq_set_limit,
  235         rt_runq_get_limit,
  236         rt_thread_set_limit,
  237         rt_thread_set_param,
  238         rt_thread_get_param,
  239         rt_task_set_param,
  240         rt_task_get_param,
  241 
  242 #if     MACH_KDB
  243         edf_thread_db_print
  244 #endif
  245 
  246     },
  247         POLICY_EARLIEST_DEADLINE_FIRST,
  248         "earliest deadline first"
  249 };
  250 

Cache object: 768e041ac30674ab4a56cbac77154f34


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