direct-io.hg

changeset 4372:046ad36e241a

bitkeeper revision 1.1159.170.107 (42497af7aXKR1tJnN7XlLoXsYCxABQ)

cleaned up some statistics code,
new domains are now best effort by default,
fixed possible bug for best effort domains
author sd386@font.cl.cam.ac.uk
date Tue Mar 29 15:57:43 2005 +0000 (2005-03-29)
parents 6bb21b5051a9
children af870801ba62
files xen/common/sched_sedf.c
line diff
     1.1 --- a/xen/common/sched_sedf.c	Wed Mar 09 16:10:08 2005 +0000
     1.2 +++ b/xen/common/sched_sedf.c	Tue Mar 29 15:57:43 2005 +0000
     1.3 @@ -15,10 +15,15 @@
     1.4  
     1.5  //#include <xen/adv_sched_hist.h>
     1.6  
     1.7 -#define SEDFLEVEL 2
     1.8 +//verbosity settings
     1.9 +#define SEDFLEVEL 0
    1.10  #define PRINT(_f, _a...)  \
    1.11  if ((_f)<=SEDFLEVEL) printk(_a );
    1.12  
    1.13 +#ifdef DEBUG
    1.14 +	#define SEDF_STATS
    1.15 +#endif
    1.16 +
    1.17  //various ways of unblocking domains
    1.18  #define UNBLOCK_ISOCHRONOUS_EDF 1
    1.19  #define UNBLOCK_EDF 2
    1.20 @@ -81,15 +86,18 @@ struct sedf_dom_info
    1.21  	s_time_t		short_block_lost_tot;
    1.22  	
    1.23  	//Statistics
    1.24 +	s_time_t		extra_time_tot;
    1.25 +
    1.26 +#ifdef SEDF_STATS
    1.27  	s_time_t		block_time_tot;
    1.28  	s_time_t		penalty_time_tot;
    1.29 -	s_time_t		extra_time_tot;
    1.30  	int			block_tot;
    1.31  	int			short_block_tot;
    1.32  	int			long_block_tot;
    1.33  	int			short_cont;
    1.34  	int			pen_extra_blocks;
    1.35  	int			pen_extra_slices;
    1.36 +#endif
    1.37  };
    1.38  
    1.39  struct sedf_cpu_info {
    1.40 @@ -181,7 +189,7 @@ static inline void extraq_add_sort_updat
    1.41  static inline void extraq_check(struct domain *d) {
    1.42  	if (extraq_on(d, EXTRA_UTIL_Q)) {
    1.43  		PRINT(2,"Dom %i is on extraQ\n",d->id);
    1.44 -		if (!(DOM_INFO(d)->extra & EXTRA_AWARE)) {
    1.45 +		if (!(DOM_INFO(d)->extra & EXTRA_AWARE) && !extra_runs(DOM_INFO(d))) {
    1.46  			extraq_del(d, EXTRA_UTIL_Q);
    1.47  			PRINT(2,"Removed dom %i from L1 extraQ\n",d->id);
    1.48  		}
    1.49 @@ -306,12 +314,12 @@ static void sedf_add_task(struct domain 
    1.50  		inf->extra     = EXTRA_NONE;//EXTRA_AWARE; 
    1.51  	}
    1.52  	else {
    1.53 -		//other domains don't get any execution time at all in the beginning!
    1.54 +		//other domains run in best effort mode
    1.55  		inf->period    = MILLISECS(20);
    1.56  		inf->slice     = 0;
    1.57  		inf->absdead   = 0;
    1.58  		inf->latency   = 0;
    1.59 -		inf->extra     = EXTRA_NONE;//EXTRA_AWARE
    1.60 +		inf->extra     = EXTRA_AWARE;
    1.61  	}
    1.62  	inf->period_orig = inf->period; inf->slice_orig = inf->slice;
    1.63  	INIT_LIST_HEAD(&(inf->list));
    1.64 @@ -481,7 +489,10 @@ static inline void desched_extra_dom(s_t
    1.65  	#endif
    1.66  	{
    1.67  		//domain was running in L1 extraq => score is inverse of utilization and is used somewhat incremental!
    1.68 -		inf->score[EXTRA_UTIL_Q] = (inf->period << 10) / inf->slice;//use fixed point arithmetic with 10 bits
    1.69 +		if (inf->slice)
    1.70 +			inf->score[EXTRA_UTIL_Q] = (inf->period << 10) / inf->slice;//use fixed point arithmetic with 10 bits
    1.71 +		else
    1.72 +			inf->score[EXTRA_UTIL_Q] = 2^10;
    1.73  	}
    1.74  	if (domain_runnable(d))
    1.75  		extraq_add_sort_update(d, i, oldscore);		//add according to score: weighted round robin
    1.76 @@ -529,7 +540,9 @@ static inline task_slice_t sedf_do_extra
    1.77  		runinf->extra |= EXTRA_RUN_PEN;
    1.78  		ret.task = runinf->owner;
    1.79  		ret.time = EXTRA_QUANTUM;
    1.80 +#ifdef SEDF_STATS
    1.81  		runinf->pen_extra_slices++;
    1.82 +#endif
    1.83  	}
    1.84  	else if (!list_empty(extraq[EXTRA_UTIL_Q])) {
    1.85  		//use elements from the normal extraqueue
    1.86 @@ -729,8 +742,10 @@ static inline void unblock_short_cons(st
    1.87  		//we don't have a reasonable amount of time in our slice left :(
    1.88  		unblock_short_vcons(inf, now);						//start in next period!
    1.89  	}
    1.90 +#ifdef SEDF_STATS
    1.91  	else
    1.92  		inf->short_cont++;							//we let the domain run in the current period
    1.93 +#endif
    1.94  }
    1.95  static inline void unblock_short_extra_support(struct sedf_dom_info* inf, s_time_t now) {
    1.96  	/*this unblocking scheme tries to support the domain, by assigning it a priority in extratime distribution
    1.97 @@ -747,7 +762,9 @@ static inline void unblock_short_extra_s
    1.98  		
    1.99  		if (inf->short_block_lost_tot) {
   1.100  			inf->score[0] = (inf->period << 10) / inf->short_block_lost_tot;
   1.101 +#ifdef SEDF_STATS
   1.102  			inf->pen_extra_blocks++;
   1.103 +#endif
   1.104  			if (extraq_on(inf->owner, EXTRA_PEN_Q))
   1.105  				extraq_del(inf->owner, EXTRA_PEN_Q);			//remove domain for possible resorting!
   1.106  			else								//remember that we want to be on the penalty queue,
   1.107 @@ -791,7 +808,9 @@ static inline void unblock_short_burst(s
   1.108  	inf->cputime += now - inf->absblock;						//treat blocked time as consumed by the domain
   1.109  	
   1.110  	if (inf->cputime + EXTRA_QUANTUM <= inf->slice) {
   1.111 +#ifdef SEDF_STATS
   1.112  		inf->short_cont++;							//we let the domain run in the current period
   1.113 +#endif
   1.114  	}
   1.115  	else {
   1.116  		//we don't have a reasonable amount of time in our slice left => switch to burst mode
   1.117 @@ -851,8 +870,7 @@ static inline int should_switch(struct d
   1.118  	switch (get_run_type(cur)) {
   1.119  		case DOMAIN_EDF:
   1.120  			//check whether we need to make an earlier sched-decision
   1.121 -			if ((PERIOD_BEGIN(other_inf) < schedule_data[other->processor].s_timer.expires)
   1.122 -			&& (other_inf->absdead < cur_inf->absdead))
   1.123 +			if ((PERIOD_BEGIN(other_inf) < schedule_data[other->processor].s_timer.expires))
   1.124  				return 1;
   1.125  			else	return 0;
   1.126  		case DOMAIN_EXTRA_PEN:
   1.127 @@ -892,8 +910,9 @@ void sedf_wake(struct domain *d) {
   1.128  		inf->absdead = now + inf->slice;			//initial setup of the deadline
   1.129  		
   1.130  	PRINT(3,"waking up domain %i (deadl= %llu period= %llu now= %llu)\n",d->id,inf->absdead,inf->period,now);
   1.131 -	
   1.132 +#ifdef SEDF_STATS	
   1.133  	inf->block_tot++;
   1.134 +#endif
   1.135  	if (unlikely(now< PERIOD_BEGIN(inf))) {
   1.136  		PRINT(4,"extratime unblock\n");
   1.137  		//this might happen, imagine unblocking in extra-time!
   1.138 @@ -917,7 +936,9 @@ void sedf_wake(struct domain *d) {
   1.139  		if (now < inf->absdead) {
   1.140  			PRINT(4,"short unblocking\n");
   1.141  			//short blocking
   1.142 +#ifdef SEDF_STATS
   1.143  			inf->short_block_tot++;
   1.144 +#endif
   1.145  			#if (UNBLOCK <= UNBLOCK_ATROPOS)
   1.146  			unblock_short_vcons(inf, now);
   1.147  			#elif (UNBLOCK == UNBLOCK_SHORT_RESUME)
   1.148 @@ -940,7 +961,9 @@ void sedf_wake(struct domain *d) {
   1.149  		else {
   1.150  			PRINT(4,"long unblocking\n");
   1.151  			//long blocking
   1.152 +#ifdef SEDF_STATS
   1.153  			inf->long_block_tot++;
   1.154 +#endif
   1.155  			//PRINT(3,"old=%llu ",inf->absdead);
   1.156  			#if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF)
   1.157  			unblock_long_vcons(inf, now);
   1.158 @@ -973,18 +996,22 @@ void sedf_wake(struct domain *d) {
   1.159  	__add_to_waitqueue_sort(d);
   1.160  	PRINT(3,"added to waitq\n");	
   1.161  	
   1.162 +#ifdef SEDF_STATS
   1.163  	//do some statistics here...
   1.164  	if (inf->absblock != 0) {
   1.165  		inf->block_time_tot += now - inf->absblock;
   1.166  		inf->penalty_time_tot += PERIOD_BEGIN(inf) + inf->cputime - inf->absblock;
   1.167  	}
   1.168 +#endif
   1.169  	//sanity check: make sure each extra-aware domain IS on the util-q!
   1.170  	/*if (inf->extra & EXTRA_AWARE) {
   1.171  		if (!extraq_on(d, EXTRA_UTIL_Q))
   1.172  			printf("sedf_wake: domain %i is extra-aware, but NOT on L1 extraq!\n",d->id);
   1.173  	}*/
   1.174 +	
   1.175  	//check whether the awakened task needs to get scheduled before the next sched. decision
   1.176  	//and check, whether we are idling and this domain is extratime aware
   1.177 +	//Save approximation: Always switch to scheduler!
   1.178  	if (should_switch(schedule_data[d->processor].curr, d, now)){
   1.179  #ifdef ADV_SCHED_HISTO
   1.180  		adv_sched_hist_start(d->processor);
   1.181 @@ -1002,6 +1029,7 @@ static void sedf_dump_domain(struct doma
   1.182  		DOM_INFO(d)->score[EXTRA_UTIL_Q], (DOM_INFO(d)->extra & EXTRA_AWARE) ? "yes" : "no", DOM_INFO(d)->extra_time_tot);
   1.183  	if (d->cpu_time !=0)
   1.184  		printf(" (%lu%)", (DOM_INFO(d)->extra_time_tot * 100) / d->cpu_time);
   1.185 +#ifdef SEDF_STATS
   1.186  	if (DOM_INFO(d)->block_time_tot!=0)
   1.187  		printf(" pen=%lu%", (DOM_INFO(d)->penalty_time_tot * 100) / DOM_INFO(d)->block_time_tot);
   1.188  	if (DOM_INFO(d)->block_tot!=0)
   1.189 @@ -1012,6 +1040,7 @@ static void sedf_dump_domain(struct doma
   1.190  		       DOM_INFO(d)->long_block_tot, (DOM_INFO(d)->long_block_tot * 100) / DOM_INFO(d)->block_tot,
   1.191  		       (DOM_INFO(d)->block_time_tot) / DOM_INFO(d)->block_tot,
   1.192  		       (DOM_INFO(d)->penalty_time_tot) / DOM_INFO(d)->block_tot);
   1.193 +#endif
   1.194  	printf("\n");
   1.195  }
   1.196