[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |