[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Port of the sedf scheduler to unstable tree.



ChangeSet 1.1346.1.3, 2005/05/02 16:49:43+01:00, sd386@xxxxxxxxxxxxxxxxx

        Port of the sedf scheduler to unstable tree.
        Signed-off: Stephan.Diestelhorst@{cl.cam.ac.uk , inf.tu-dresden.de}



 sched_sedf.c |  499 +++++++++++++++++++++++++++++------------------------------
 schedule.c   |   45 +++++
 2 files changed, 292 insertions(+), 252 deletions(-)


diff -Nru a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   2005-05-09 14:07:34 -04:00
+++ b/xen/common/sched_sedf.c   2005-05-09 14:07:34 -04:00
@@ -1,4 +1,4 @@
-/****************************************************************************
+/*******************************************************************************
  * Simple EDF scheduler for xen
  *
  * by Stephan Diestelhorst (C)  2004 Cambridge University
@@ -20,8 +20,13 @@
 #define PRINT(_f, _a...)  \
 if ((_f)<=SEDFLEVEL) printk(_a );
 
-#ifdef DEBUG
+#ifndef NDEBUG
        #define SEDF_STATS
+       #define CHECK(_p) if ( !(_p) ) \
+       { printk("Check '%s' failed, line %d, file %s\n", #_p , __LINE__,\
+       __FILE__);}
+#else
+       #define CHECK(_p) ((void)0)
 #endif
 
 /*various ways of unblocking domains*/
@@ -48,14 +53,16 @@
 #define EXTRA_WANT_PEN_Q (8)
 #define EXTRA_PEN_Q (0)
 #define EXTRA_UTIL_Q (1)
-
-#define extra_runs(inf) ((inf->extra) & 6)
-#define extra_get_cur_q(inf) (((inf->extra & 6) >> 1)-1)
+#define SEDF_ASLEEP (16)
 
 #define EXTRA_QUANTUM (MICROSECS(500)) 
 #define WEIGHT_PERIOD (MILLISECS(100))
 #define WEIGHT_SAFETY (MILLISECS(5))
 
+#define IMPLY(a, b) (!(a) || (b))
+#define EQ(a, b) ((!!(a)) == (!!(b)))
+
+
 struct sedf_dom_info {
        struct domain           *domain;
 };
@@ -75,12 +82,12 @@
        s_time_t                slice_orig;
        s_time_t                latency;
        
-       /*extra-time status of domain*/
-       short                   extra;
+       /*status of domain*/
+       int                     status;
        /*weights for "Scheduling for beginners/ lazy/ etc." ;)*/
        short                   weight;
-       
-       /*Bookkeeping*/
+        short                   extraweight;
+        /*Bookkeeping*/
        s_time_t                deadl_abs;
        s_time_t                sched_start_abs;
        s_time_t                cputime;
@@ -127,6 +134,11 @@
 #define MIN(x,y) (((x)<(y))?(x):(y))
 #define DIV_UP(x,y) (((x) + (y) - 1) / y)
 
+#define extra_runs(inf) ((inf->status) & 6)
+#define extra_get_cur_q(inf) (((inf->status & 6) >> 1)-1)
+#define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP))
+
+
 static void sedf_dump_cpu_state(int i);
 
 static inline int extraq_on(struct exec_domain *d, int i) {
@@ -137,25 +149,24 @@
 static inline void extraq_add_head(struct exec_domain *d, int i)
 {
     list_add(EXTRALIST(d,i), EXTRAQ(d->processor,i));
+    ASSERT(extraq_on(d, i));
 }
 
 static inline void extraq_add_tail(struct exec_domain *d, int i)
 {
     list_add_tail(EXTRALIST(d,i), EXTRAQ(d->processor,i));
+    ASSERT(extraq_on(d, i));
 }
 
 static inline void extraq_del(struct exec_domain *d, int i)
 {
        struct list_head *list = EXTRALIST(d,i);
-       /*if (!extraq_on(d,i)) {
-               PRINT(0,"extraq_del: domain %i.%i is NOT on L%i extraq "\
-                       "HALTING\n",d->domain->id, d->eid,i);
-               sedf_dump_cpu_state(0);(*((int*)0))++;
-       }*/
+       ASSERT(extraq_on(d,i));
        PRINT(3, "Removing domain %i.%i from L%i extraq\n", d->domain->id,
           d->eid, i);  
        list_del(list);
        list->next = NULL;
+       ASSERT(!extraq_on(d, i));
 }
 
 /* adds a domain to the queue of processes which are aware of extra time. List
@@ -168,11 +179,7 @@
        struct list_head      *cur;
        struct sedf_edom_info *curinf;
        
-       /*if (extraq_on(d,i)) {
-               PRINT(0,"extraq_add_sort_update: domain %i.%i is already on "\
-                       "L%i extraq! HALTING\n",d->domain->id, d->eid, i);
-               sedf_dump_cpu_state(0);(*((int*)0))++;
-       }*/
+       ASSERT(!extraq_on(d,i));
        PRINT(3, "Adding domain %i.%i (score= %i, short_pen= %lli) to L%i "\
                 "extraq\n", d->domain->id, d->eid, EDOM_INFO(d)->score[i],
                 EDOM_INFO(d)->short_block_lost_tot, i);        
@@ -203,11 +210,12 @@
                              curinf->exec_domain->domain->id, 
                              curinf->exec_domain->eid, curinf->score[i]);
                }
+       ASSERT(extraq_on(d,i));
 }
 static inline void extraq_check(struct exec_domain *d) {
        if (extraq_on(d, EXTRA_UTIL_Q)) {
-               PRINT(2,"Dom %i is on extraQ\n",d->domain->id, d->eid);
-               if (!(EDOM_INFO(d)->extra & EXTRA_AWARE) &&
+               PRINT(2,"Dom %i.%i is on L1 extraQ\n",d->domain->id, d->eid);
+               if (!(EDOM_INFO(d)->status & EXTRA_AWARE) &&
                    !extra_runs(EDOM_INFO(d))) {
                        extraq_del(d, EXTRA_UTIL_Q);
                        PRINT(2,"Removed dom %i.%i from L1 extraQ\n",
@@ -216,10 +224,9 @@
        } else {
                PRINT(2,"Dom %i.%i is NOT on L1 extraQ\n",d->domain->id,
                      d->eid);
-               if ((EDOM_INFO(d)->extra & EXTRA_AWARE) && domain_runnable(d))
+               if ((EDOM_INFO(d)->status & EXTRA_AWARE) && sedf_runnable(d))
                {
                        #if (EXTRA == EXTRA_ROUNDR)
-                       /*Favour domains which got short unblocked*/
                        extraq_add_tail(d, EXTRA_UTIL_Q);
                        #elif (EXTRA == EXTRA_SLICE_WEIGHT || \
                               EXTRA == EXTRA_BLOCK_WEIGHT)
@@ -232,39 +239,78 @@
                }
        }
 }
+
+static inline void extraq_check_add_unblocked(struct exec_domain *d, 
+    int priority) {
+       struct sedf_edom_info *inf = EDOM_INFO(d);
+       if (inf->status & EXTRA_AWARE) 
+       #if (EXTRA == EXTRA_ROUNDR)
+               if (priority)
+                       extraq_add_head(d,EXTRA_UTIL_Q);
+               else
+                       extraq_add_tail(d,EXTRA_UTIL_Q);
+       #elif (EXTRA == EXTRA_SLICE_WEIGHT \
+           || EXTRA == EXTRA_BLOCK_WEIGHT)
+               /*put in on the weighted extraq, 
+                 without updating any scores*/
+               extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
+       #else
+               ;
+       #endif
+}
+
+static inline int __task_on_queue(struct exec_domain *d) {
+       return (((LIST(d))->next != NULL) && (LIST(d)->next != LIST(d)));
+}
 static inline void __del_from_queue(struct exec_domain *d)
 {
     struct list_head *list = LIST(d);
+    ASSERT(__task_on_queue(d));
     PRINT(3,"Removing domain %i.%i (bop= %llu) from runq/waitq\n", 
d->domain->id,
           d->eid, PERIOD_BEGIN(EDOM_INFO(d)));
     list_del(list);
     list->next = NULL;
+    ASSERT(!__task_on_queue(d));
 }
 
-/* adds a domain to the queue of processes which wait for the beginning of the
-   next period; this list is therefore sortet by this time, which is simply
-   absol. deadline - period
- */ 
-static inline void __add_to_waitqueue_sort(struct exec_domain *d) {
+typedef int(*list_comparer)(struct list_head* el1, struct list_head* el2);
+
+static inline void list_insert_sort(struct list_head *list,
+    struct list_head *element, list_comparer comp) {
        struct list_head     *cur;
-       struct sedf_edom_info *curinf;
-       
-       PRINT(3,"Adding domain %i.%i (bop= %llu) to waitq\n", d->domain->id,
-       d->eid, PERIOD_BEGIN(EDOM_INFO(d)));
-             
        /*iterate through all elements to find our "hole"*/
-       list_for_each(cur, WAITQ(d->processor)){
-               curinf = list_entry(cur,struct sedf_edom_info,list);
-               if (PERIOD_BEGIN(EDOM_INFO(d)) < PERIOD_BEGIN(curinf))
+       list_for_each(cur,list){
+               if (comp(element, cur) < 0)
                        break;
-               else
-                       PRINT(4,"\tbehind domain %i.%i (bop= %llu)\n",
-                             curinf->exec_domain->domain->id,
-                             curinf->exec_domain->eid, PERIOD_BEGIN(curinf));
        }
        /*cur now contains the element, before which we'll enqueue*/
        PRINT(3,"\tlist_add to %x\n",cur->prev);
-       list_add(LIST(d),cur->prev);
+       list_add(element, cur->prev);
+}  
+#define DOMAIN_COMPARER(name, field, comp1, comp2)          \
+int name##_comp(struct list_head* el1, struct list_head* el2) \
+{                                                           \
+       struct sedf_edom_info *d1, *d2;                     \
+       d1 = list_entry(el1,struct sedf_edom_info, field);  \
+       d2 = list_entry(el2,struct sedf_edom_info, field);  \
+       if ((comp1) == (comp2))                             \
+               return 0;                                   \
+       if ((comp1) < (comp2))                              \
+               return -1;                                  \
+       else                                                \
+               return 1;                                   \
+}
+/* adds a domain to the queue of processes which wait for the beginning of the
+   next period; this list is therefore sortet by this time, which is simply
+   absol. deadline - period
+ */ 
+DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2))
+static inline void __add_to_waitqueue_sort(struct exec_domain *d) {
+       ASSERT(!__task_on_queue(d));
+       PRINT(3,"Adding domain %i.%i (bop= %llu) to waitq\n", d->domain->id,
+             d->eid, PERIOD_BEGIN(EDOM_INFO(d)));
+       list_insert_sort(WAITQ(d->processor), LIST(d), waitq_comp);
+       ASSERT(__task_on_queue(d));
 }
 
 /* adds a domain to the queue of processes which have started their current
@@ -272,30 +318,11 @@
    on this list is running on the processor, if the list is empty the idle
    task will run. As we are implementing EDF, this list is sorted by deadlines.
  */ 
+DOMAIN_COMPARER(runq, list, d1->deadl_abs, d2->deadl_abs)
 static inline void __add_to_runqueue_sort(struct exec_domain *d) {
-       struct list_head     *cur;
-       struct sedf_edom_info *curinf;
-
        PRINT(3,"Adding domain %i.%i (deadl= %llu) to runq\n", d->domain->id,

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.