ia64/xen-unstable

changeset 2527:d2d465977f58

bitkeeper revision 1.1159.83.3 (4153213cZidARHCbhOICTEAHCiXaDA)

Merge tetrapod.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno-unstable.bk
into tetrapod.cl.cam.ac.uk:/auto/anfs/scratch/tetris/gm281/xeno-clone/xeno.bk
author gm281@tetrapod.cl.cam.ac.uk
date Thu Sep 23 19:17:16 2004 +0000 (2004-09-23)
parents fb37bc47ff05 22cf388c6f73
children 157757c292d8 120a08713a8c
files BitKeeper/etc/logging_ok xen/common/sched_atropos.c
line diff
     1.1 --- a/BitKeeper/etc/logging_ok	Thu Sep 23 19:05:11 2004 +0000
     1.2 +++ b/BitKeeper/etc/logging_ok	Thu Sep 23 19:17:16 2004 +0000
     1.3 @@ -13,6 +13,7 @@ cl349@freefall.cl.cam.ac.uk
     1.4  cl349@labyrinth.cl.cam.ac.uk
     1.5  djm@kirby.fc.hp.com
     1.6  gm281@boulderdash.cl.cam.ac.uk
     1.7 +gm281@tetrapod.cl.cam.ac.uk
     1.8  iap10@freefall.cl.cam.ac.uk
     1.9  iap10@labyrinth.cl.cam.ac.uk
    1.10  iap10@nidd.cl.cam.ac.uk
     2.1 --- a/xen/common/sched_atropos.c	Thu Sep 23 19:05:11 2004 +0000
     2.2 +++ b/xen/common/sched_atropos.c	Thu Sep 23 19:17:16 2004 +0000
     2.3 @@ -23,26 +23,17 @@
     2.4  #include <hypervisor-ifs/sched_ctl.h>
     2.5  #include <xen/trace.h>
     2.6  
     2.7 -/*
     2.8 - * KAF -- Atropos is broken by the new scheduler interfaces.
     2.9 - * It'll need fixing to get rid of use of ATROPOS_TASK__*
    2.10 - */
    2.11 -#ifdef KAF_KILLED
    2.12 -
    2.13  #define ATROPOS_TASK_UNBLOCKED 16
    2.14  #define ATROPOS_TASK_WAIT      32
    2.15 -
    2.16 -#define Activation_Reason_Allocated 1
    2.17 -#define Activation_Reason_Preempted 2
    2.18 -#define Activation_Reason_Extra     3
    2.19 +#define ATROPOS_TASK_BLOCKED   48
    2.20  
    2.21  /* Atropos-specific per-domain data */
    2.22  struct at_dom_info
    2.23  {
    2.24      /* MAW Xen additions */
    2.25      struct domain *owner;      /* the domain this data belongs to */
    2.26 +    struct list_head run_list; /* runqueue                             */
    2.27      struct list_head waitq;    /* wait queue                           */
    2.28 -    int reason;                /* reason domain was last scheduled     */
    2.29  
    2.30      /* (what remains of) the original fields */
    2.31  
    2.32 @@ -57,26 +48,59 @@ struct at_dom_info
    2.33      s_time_t     latency;        /* Unblocking latency                   */
    2.34  
    2.35      int          xtratime;       /* Prepared to accept extra time?       */
    2.36 +    int          state;          /* Keeps Atropos domain state           */ 
    2.37  };
    2.38  
    2.39  /* Atropos-specific per-CPU data */
    2.40  struct at_cpu_info
    2.41  {
    2.42 +    spinlock_t runq_lock;
    2.43 +    struct list_head runq;  /* run queue */
    2.44 +    spinlock_t waitq_lock;
    2.45      struct list_head waitq; /* wait queue*/
    2.46  };
    2.47  
    2.48  
    2.49  #define DOM_INFO(_p) ((struct at_dom_info *)((_p)->sched_priv))
    2.50 -#define CPU_INFO(_c) ((struct at_cpu_info *)((_c).sched_priv))
    2.51 -#define WAITQ(cpu)   (&CPU_INFO(schedule_data[cpu])->waitq)
    2.52 -#define RUNQ(cpu)    (&schedule_data[cpu].runqueue)
    2.53 +#define CPU_INFO(_c) ((struct at_cpu_info *)((schedule_data[_c]).sched_priv))
    2.54 +#define WAITQ(cpu)   (&CPU_INFO(cpu)->waitq)
    2.55 +#define RUNQ(cpu)    (&CPU_INFO(cpu)->runq)
    2.56 +#define RUNLIST(_d)  (&DOM_INFO(_d)->run_list)
    2.57  
    2.58  #define BESTEFFORT_QUANTUM MILLISECS(5)
    2.59  
    2.60 +static void at_dump_cpu_state(int cpu);
    2.61 +
    2.62  
    2.63  /* SLAB cache for struct at_dom_info objects */
    2.64  static xmem_cache_t *dom_info_cache;
    2.65  
    2.66 +/*
    2.67 + * Wrappers for run-queue management. Must be called with the run_lock
    2.68 + * held.
    2.69 + */
    2.70 +static inline void __add_to_runqueue_head(struct domain *d)
    2.71 +{
    2.72 +    list_add(RUNLIST(d), RUNQ(d->processor));
    2.73 +}
    2.74 +
    2.75 +static inline void __add_to_runqueue_tail(struct domain *d)
    2.76 +{
    2.77 +    list_add_tail(RUNLIST(d), RUNQ(d->processor));
    2.78 +}
    2.79 +
    2.80 +static inline void __del_from_runqueue(struct domain *d)
    2.81 +{
    2.82 +    struct list_head *runlist = RUNLIST(d);
    2.83 +    list_del(runlist);
    2.84 +    runlist->next = NULL;
    2.85 +}
    2.86 +
    2.87 +static inline int __task_on_runqueue(struct domain *d)
    2.88 +{
    2.89 +    return (RUNLIST(d))->next != NULL;
    2.90 +}
    2.91 +
    2.92  
    2.93  /** calculate the length of a linked list */
    2.94  static int q_len(struct list_head *q) 
    2.95 @@ -114,15 +138,17 @@ static inline struct domain *waitq_el(st
    2.96  static void requeue(struct domain *sdom)
    2.97  {
    2.98      struct at_dom_info *inf = DOM_INFO(sdom);
    2.99 -    struct list_head *prev = WAITQ(sdom->processor);
   2.100 +    struct list_head *prev;
   2.101      struct list_head *next;
   2.102  
   2.103 -    if(sdom->state == ATROPOS_TASK_WAIT ||
   2.104 -       sdom->state == ATROPOS_TASK_UNBLOCKED )
   2.105 +
   2.106 +    if(!domain_runnable(sdom)) return;
   2.107 +    
   2.108 +    if(inf->state == ATROPOS_TASK_WAIT ||
   2.109 +        inf->state == ATROPOS_TASK_UNBLOCKED)
   2.110      {
   2.111 -        /* insert into ordered wait queue */
   2.112 +        prev = WAITQ(sdom->processor);
   2.113  
   2.114 -        prev = WAITQ(sdom->processor);
   2.115          list_for_each(next, WAITQ(sdom->processor))
   2.116          {
   2.117              struct at_dom_info *i = 
   2.118 @@ -144,16 +170,17 @@ static void requeue(struct domain *sdom)
   2.119      else if ( domain_runnable(sdom) )
   2.120      {
   2.121          /* insert into ordered run queue */
   2.122 +        
   2.123          prev = RUNQ(sdom->processor);
   2.124  
   2.125          list_for_each(next, RUNQ(sdom->processor))
   2.126          {
   2.127 -            struct domain *p = list_entry(next, struct domain,
   2.128 +            struct at_dom_info *p = list_entry(next, struct at_dom_info,
   2.129                                                 run_list);
   2.130  
   2.131 -            if( DOM_INFO(p)->deadline > inf->deadline || is_idle_task(p) )
   2.132 +            if( p->deadline > inf->deadline || is_idle_task(p->owner) )
   2.133              {
   2.134 -                __list_add(&sdom->run_list, prev, next);
   2.135 +                __list_add(&inf->run_list, prev, next);
   2.136                  break;
   2.137              }
   2.138  
   2.139 @@ -161,12 +188,27 @@ static void requeue(struct domain *sdom)
   2.140          }
   2.141  
   2.142          if ( next == RUNQ(sdom->processor) )
   2.143 -            list_add_tail(&sdom->run_list, RUNQ(sdom->processor));
   2.144 +            list_add_tail(&inf->run_list, RUNQ(sdom->processor));
   2.145 +        
   2.146 +    
   2.147      }
   2.148      /* silently ignore tasks in other states like BLOCKED, DYING, STOPPED, etc
   2.149       * - they shouldn't be on any queue */
   2.150  }
   2.151  
   2.152 +/** at_alloc_task - allocate private info for a task */
   2.153 +static int at_alloc_task(struct domain *p)
   2.154 +{
   2.155 +    ASSERT(p != NULL);
   2.156 +    
   2.157 +    p->sched_priv = xmem_cache_alloc(dom_info_cache);
   2.158 +    if( p->sched_priv == NULL )
   2.159 +        return -1;
   2.160 +    
   2.161 +    return 0;
   2.162 +}
   2.163 +
   2.164 +
   2.165  /* prepare a task to be added to scheduling */
   2.166  static void at_add_task(struct domain *p)
   2.167  {
   2.168 @@ -199,14 +241,15 @@ static void at_add_task(struct domain *p
   2.169              DOM_INFO(p)->slice  = MILLISECS(10);
   2.170          DOM_INFO(p)->latency = SECONDS(10);
   2.171          DOM_INFO(p)->xtratime = 1;
   2.172 -        DOM_INFO(p)->deadline = now + SECONDS(10);
   2.173 +        DOM_INFO(p)->deadline = now;
   2.174 +//        DOM_INFO(p)->deadline = now + SECONDS(10);
   2.175          DOM_INFO(p)->prevddln = 0;
   2.176      }
   2.177  
   2.178 +    INIT_LIST_HEAD(&(DOM_INFO(p)->run_list));
   2.179      INIT_LIST_HEAD(&(DOM_INFO(p)->waitq));
   2.180  }
   2.181  
   2.182 -
   2.183  /**
   2.184   * dequeue - remove a domain from any queues it is on.
   2.185   * @sdom:    the task to remove
   2.186 @@ -214,19 +257,16 @@ static void at_add_task(struct domain *p
   2.187  static void dequeue(struct domain *sdom)
   2.188  {
   2.189      struct at_dom_info *inf = DOM_INFO(sdom);
   2.190 -
   2.191 +    
   2.192      ASSERT(sdom->domain != IDLE_DOMAIN_ID);
   2.193      
   2.194      /* just delete it from all the queues! */
   2.195      list_del(&inf->waitq);
   2.196      INIT_LIST_HEAD(&inf->waitq);
   2.197 +   
   2.198      
   2.199      if(__task_on_runqueue(sdom))
   2.200          __del_from_runqueue(sdom);
   2.201 -
   2.202 -    sdom->run_list.next = NULL;
   2.203 -    sdom->run_list.prev = NULL;
   2.204 -
   2.205  }
   2.206  
   2.207  
   2.208 @@ -254,44 +294,64 @@ static void unblock(struct domain *sdom)
   2.209  {
   2.210      s_time_t time = NOW();
   2.211      struct at_dom_info *inf = DOM_INFO(sdom);
   2.212 -    
   2.213 +
   2.214      dequeue(sdom);
   2.215  
   2.216      /* We distinguish two cases... short and long blocks */
   2.217 -
   2.218      if ( inf->deadline < time )
   2.219      {
   2.220          /* Long blocking case */
   2.221  
   2.222 -	/* The sdom has passed its deadline since it was blocked. 
   2.223 -	   Give it its new deadline based on the latency value. */
   2.224 -	inf->prevddln = time;
   2.225 +	    /* The sdom has passed its deadline since it was blocked. 
   2.226 +	       Give it its new deadline based on the latency value. */
   2.227 +	    inf->prevddln = time;
   2.228  
   2.229          /* Scale the scheduling parameters as requested by the latency hint. */
   2.230 -	inf->deadline = time + inf->latency;
   2.231 +	    inf->deadline = time + inf->latency;
   2.232          inf->slice = inf->nat_slice / ( inf->nat_period / inf->latency );
   2.233          inf->period = inf->latency;
   2.234 -	inf->remain = inf->slice;
   2.235 +	    inf->remain = inf->slice;
   2.236      }
   2.237 -    else
   2.238 +    else 
   2.239      {
   2.240          /* Short blocking case */
   2.241  
   2.242 -	/* We leave REMAIN intact, but put this domain on the WAIT
   2.243 -	   queue marked as recently unblocked.  It will be given
   2.244 -	   priority over other domains on the wait queue until while
   2.245 -	   REMAIN>0 in a generous attempt to help it make up for its
   2.246 -	   own foolishness. */
   2.247 -	if(inf->remain > 0)
   2.248 -            sdom->state = ATROPOS_TASK_UNBLOCKED;
   2.249 +	    /* We leave REMAIN intact, but put this domain on the WAIT
   2.250 +	        queue marked as recently unblocked.  It will be given
   2.251 +	        priority over other domains on the wait queue until while
   2.252 +	        REMAIN>0 in a generous attempt to help it make up for its
   2.253 +	        own foolishness. */
   2.254 +	    if(inf->remain > 0)
   2.255 +            inf->state = ATROPOS_TASK_UNBLOCKED;
   2.256          else
   2.257 -            sdom->state = ATROPOS_TASK_WAIT;
   2.258 +            inf->state = ATROPOS_TASK_WAIT;
   2.259      }
   2.260  
   2.261      requeue(sdom);
   2.262 +}
   2.263  
   2.264 +
   2.265 +static int at_init_idle_task(struct domain *p)
   2.266 +{
   2.267 +    if(at_alloc_task(p) < 0) return -1;
   2.268 +
   2.269 +    at_add_task(p);
   2.270 +
   2.271 +    dequeue(p);
   2.272 +    requeue(p);
   2.273 +
   2.274 +    return 0;
   2.275  }
   2.276  
   2.277 +
   2.278 +static void block(struct domain* sdom)
   2.279 +{
   2.280 +    DOM_INFO(sdom)->state = ATROPOS_TASK_BLOCKED;
   2.281 +    dequeue(sdom);
   2.282 +    requeue(sdom);
   2.283 +}
   2.284 +
   2.285 +
   2.286  /**
   2.287   * ATROPOS - main scheduler function
   2.288   */
   2.289 @@ -301,13 +361,13 @@ task_slice_t ksched_scheduler(s_time_t t
   2.290      s_time_t     newtime;
   2.291      s_time_t      ranfor;	        /* How long the domain ran      */
   2.292      struct domain	*sdom;	        /* tmp. scheduling domain	*/
   2.293 -    int   reason;                       /* reason for reschedule        */
   2.294      int cpu = cur_sdom->processor;      /* current CPU                  */
   2.295      struct at_dom_info *cur_info;
   2.296      static unsigned long waitq_rrobin = 0;
   2.297      int i;
   2.298      task_slice_t ret;
   2.299  
   2.300 +
   2.301      cur_info = DOM_INFO(cur_sdom);
   2.302  
   2.303      ASSERT( cur_sdom != NULL);
   2.304 @@ -333,36 +393,35 @@ task_slice_t ksched_scheduler(s_time_t t
   2.305      dequeue(cur_sdom);
   2.306  
   2.307      if ( domain_runnable(cur_sdom) || 
   2.308 -         (cur_sdom->state == ATROPOS_TASK_UNBLOCKED) )
   2.309 +         (cur_info->state == ATROPOS_TASK_UNBLOCKED) )
   2.310      {
   2.311  
   2.312 -	/* In this block, we are doing accounting for an sdom which has 
   2.313 -	   been running in contracted time.  Note that this could now happen
   2.314 -	   even if the domain is on the wait queue (i.e. if it blocked) */
   2.315 +	    /* In this block, we are doing accounting for an sdom which has 
   2.316 +	        been running in contracted time.  Note that this could now happen
   2.317 +	        even if the domain is on the wait queue (i.e. if it blocked) */
   2.318  
   2.319 -	/* Deduct guaranteed time from the domain */
   2.320 -	cur_info->remain  -= ranfor;
   2.321 +	    /* Deduct guaranteed time from the domain */
   2.322 +	    cur_info->remain  -= ranfor;
   2.323  
   2.324 -	/* If guaranteed time has run out... */
   2.325 -	if ( cur_info->remain <= 0 )
   2.326 +	    /* If guaranteed time has run out... */
   2.327 +	    if ( cur_info->remain <= 0 )
   2.328          {
   2.329 -	    /* Move domain to correct position in WAIT queue */
   2.330 +	        /* Move domain to correct position in WAIT queue */
   2.331              /* XXX sdom_unblocked doesn't need this since it is 
   2.332                 already in the correct place. */
   2.333 -	    cur_sdom->state = ATROPOS_TASK_WAIT;
   2.334 -	}
   2.335 +	        cur_info->state = ATROPOS_TASK_WAIT;
   2.336 +	    }
   2.337      }
   2.338  
   2.339      requeue(cur_sdom);
   2.340  
   2.341 -  deschedule_done:
   2.342 -
   2.343 +deschedule_done:
   2.344      /*****************************
   2.345       * 
   2.346       * We have now successfully descheduled the current sdom.
   2.347       * The next task is the allocate CPU time to any sdom it is due to.
   2.348       *
   2.349 -       ****************************/
   2.350 +     ****************************/
   2.351      cur_sdom = NULL;
   2.352  
   2.353      /*****************************
   2.354 @@ -371,13 +430,14 @@ task_slice_t ksched_scheduler(s_time_t t
   2.355       * period deadline.  If necessary, move them to run queue.
   2.356       *
   2.357       ****************************/
   2.358 +    
   2.359      while(!list_empty(WAITQ(cpu)) && 
   2.360 -	  DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time ) {
   2.361 +	    DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time ) 
   2.362 +    {
   2.363  
   2.364 -	struct at_dom_info *inf = DOM_INFO(sdom);
   2.365 -
   2.366 +	    struct at_dom_info *inf = DOM_INFO(sdom);
   2.367          dequeue(sdom);
   2.368 -
   2.369 +        
   2.370          if ( inf->period != inf->nat_period )
   2.371          {
   2.372              /* This domain has had its parameters adjusted as a result of
   2.373 @@ -392,22 +452,22 @@ task_slice_t ksched_scheduler(s_time_t t
   2.374              }
   2.375          }
   2.376  
   2.377 -	/* Domain begins a new period and receives a slice of CPU 
   2.378 -	 * If this domain has been blocking then throw away the
   2.379 -	 * rest of it's remain - it can't be trusted */
   2.380 -	if (inf->remain > 0) 
   2.381 -	    inf->remain = inf->slice;
   2.382 -    	else 
   2.383 -	    inf->remain += inf->slice;
   2.384 +	    /* Domain begins a new period and receives a slice of CPU 
   2.385 +	     * If this domain has been blocking then throw away the
   2.386 +	     * rest of it's remain - it can't be trusted */
   2.387 +	    if (inf->remain > 0) 
   2.388 +	        inf->remain = inf->slice;
   2.389 +        else 
   2.390 +	        inf->remain += inf->slice;
   2.391  
   2.392 -	inf->prevddln = inf->deadline;
   2.393 -	inf->deadline += inf->period;
   2.394 +	    inf->prevddln = inf->deadline;
   2.395 +	    inf->deadline += inf->period;
   2.396  
   2.397          if ( inf->remain <= 0 )
   2.398 -            sdom->state = ATROPOS_TASK_WAIT;
   2.399 +            inf->state = ATROPOS_TASK_WAIT;
   2.400  
   2.401 -	/* Place on the appropriate queue */
   2.402 -	requeue(sdom);
   2.403 +	    /* Place on the appropriate queue */
   2.404 +	    requeue(sdom);
   2.405      }
   2.406  
   2.407      /*****************************
   2.408 @@ -421,13 +481,11 @@ task_slice_t ksched_scheduler(s_time_t t
   2.409       ****************************/
   2.410      
   2.411      /* we guarantee there's always something on the runqueue */
   2.412 -    cur_sdom = list_entry(RUNQ(cpu)->next,
   2.413 -                          struct domain, run_list);
   2.414 +    cur_info = list_entry(RUNQ(cpu)->next,
   2.415 +                          struct at_dom_info, run_list);
   2.416  
   2.417 -    cur_info = DOM_INFO(cur_sdom);
   2.418 +    cur_sdom = cur_info->owner;
   2.419      newtime = time + cur_info->remain;
   2.420 -    reason  = (cur_info->prevddln > cur_sdom->lastschd) ?
   2.421 -      Activation_Reason_Allocated : Activation_Reason_Preempted;
   2.422  
   2.423      /* MAW - the idle domain is always on the run queue.  We run from the
   2.424       * runqueue if it's NOT the idle domain or if there's nothing on the wait
   2.425 @@ -436,12 +494,13 @@ task_slice_t ksched_scheduler(s_time_t t
   2.426      {
   2.427          struct list_head *item;
   2.428  
   2.429 -	/* Try running a domain on the WAIT queue - this part of the
   2.430 -	   scheduler isn't particularly efficient but then again, we
   2.431 -	   don't have any guaranteed domains to worry about. */
   2.432 +	    /* Try running a domain on the WAIT queue - this part of the
   2.433 +	        scheduler isn't particularly efficient but then again, we
   2.434 +	        don't have any guaranteed domains to worry about. */
   2.435  	
   2.436 -	/* See if there are any unblocked domains on the WAIT
   2.437 -	   queue who we can give preferential treatment to. */
   2.438 +	    /* See if there are any unblocked domains on the WAIT
   2.439 +	        queue who we can give preferential treatment to. */
   2.440 +        
   2.441          list_for_each(item, WAITQ(cpu))
   2.442          {
   2.443              struct at_dom_info *inf =
   2.444 @@ -449,23 +508,24 @@ task_slice_t ksched_scheduler(s_time_t t
   2.445  
   2.446              sdom = inf->owner;
   2.447              
   2.448 -	    if (sdom->state == ATROPOS_TASK_UNBLOCKED) {
   2.449 -		cur_sdom = sdom;
   2.450 -		cur_info  = inf;
   2.451 -		newtime  = time + inf->remain;
   2.452 -		reason   = Activation_Reason_Preempted;
   2.453 -		goto found;
   2.454 +	        if (inf->state == ATROPOS_TASK_UNBLOCKED) 
   2.455 +            { 
   2.456 +		        cur_sdom = sdom;
   2.457 +    		    cur_info  = inf;
   2.458 +	    	    newtime  = time + inf->remain;
   2.459 +		        goto found;
   2.460 +	        }
   2.461  	    }
   2.462 -	}
   2.463  
   2.464          /* init values needed to approximate round-robin for slack time */
   2.465          i = 0;
   2.466          if ( waitq_rrobin >= q_len(WAITQ(cpu)))
   2.467              waitq_rrobin = 0;
   2.468          
   2.469 -	/* Last chance: pick a domain on the wait queue with the XTRA
   2.470 -	   flag set.  The NEXT_OPTM field is used to cheaply achieve
   2.471 -	   an approximation of round-robin order */
   2.472 +        
   2.473 +	    /* Last chance: pick a domain on the wait queue with the XTRA
   2.474 +	        flag set.  The NEXT_OPTM field is used to cheaply achieve
   2.475 +	        an approximation of round-robin order */
   2.476          list_for_each(item, WAITQ(cpu))
   2.477          {
   2.478              struct at_dom_info *inf =
   2.479 @@ -473,11 +533,11 @@ task_slice_t ksched_scheduler(s_time_t t
   2.480              
   2.481              sdom = inf->owner;
   2.482              
   2.483 -            if (inf->xtratime && i >= waitq_rrobin) {
   2.484 +            if (inf->xtratime && i >= waitq_rrobin) 
   2.485 +            {
   2.486                  cur_sdom = sdom;
   2.487                  cur_info  = inf;
   2.488                  newtime = time + BESTEFFORT_QUANTUM;
   2.489 -                reason  = Activation_Reason_Extra;
   2.490                  waitq_rrobin = i + 1; /* set this value ready for next */
   2.491                  goto found;
   2.492              }
   2.493 @@ -502,7 +562,7 @@ task_slice_t ksched_scheduler(s_time_t t
   2.494      /* exhausted its time, cut short the time allocation */
   2.495      if (!list_empty(WAITQ(cpu)))
   2.496      {
   2.497 -	newtime = MIN(newtime,
   2.498 +	    newtime = MIN(newtime,
   2.499                        DOM_INFO(waitq_el(WAITQ(cpu)->next))->deadline);
   2.500      }
   2.501  
   2.502 @@ -512,9 +572,6 @@ task_slice_t ksched_scheduler(s_time_t t
   2.503      ret.task = cur_sdom;
   2.504      ret.time = newtime - time;
   2.505  
   2.506 -    cur_sdom->min_slice = newtime - time;
   2.507 -    DOM_INFO(cur_sdom)->reason = reason;
   2.508 -
   2.509      TRACE_1D(0, cur_sdom->domain);
   2.510   
   2.511      return ret;
   2.512 @@ -531,8 +588,10 @@ static int at_init_scheduler()
   2.513          schedule_data[i].sched_priv = xmalloc(sizeof(struct at_cpu_info));
   2.514          if ( schedule_data[i].sched_priv == NULL )
   2.515              return -1;
   2.516 -        WAITQ(i)->next = WAITQ(i);
   2.517 -        WAITQ(i)->prev = WAITQ(i);
   2.518 +        INIT_LIST_HEAD(WAITQ(i));
   2.519 +        INIT_LIST_HEAD(RUNQ(i));
   2.520 +        spin_lock_init(&CPU_INFO(i)->runq_lock);       
   2.521 +        spin_lock_init(&CPU_INFO(i)->waitq_lock);        
   2.522      }
   2.523  
   2.524      dom_info_cache = xmem_cache_create("Atropos dom info",
   2.525 @@ -542,13 +601,6 @@ static int at_init_scheduler()
   2.526      return 0;
   2.527  }
   2.528  
   2.529 -/* dump relevant per-cpu state for a run queue dump */
   2.530 -static void at_dump_cpu_state(int cpu)
   2.531 -{
   2.532 -    printk("Waitq len: %d Runq len: %d ",
   2.533 -           q_len(WAITQ(cpu)),
   2.534 -           q_len(RUNQ(cpu)));
   2.535 -}
   2.536  
   2.537  /* print relevant per-domain info for a run queue dump */
   2.538  static void at_dump_runq_el(struct domain *p)
   2.539 @@ -558,6 +610,51 @@ static void at_dump_runq_el(struct domai
   2.540  }
   2.541  
   2.542  
   2.543 +/* dump relevant per-cpu state for a run queue dump */
   2.544 +static void at_dump_cpu_state(int cpu)
   2.545 +{
   2.546 +    struct list_head *list, *queue;
   2.547 +    int loop = 0;
   2.548 +    struct at_dom_info *d_inf;
   2.549 +    struct domain *d;
   2.550 +
   2.551 +    queue = RUNQ(cpu);
   2.552 +    printk("\nRUNQUEUE rq %lx   n: %lx, p: %lx\n",  (unsigned long)queue,
   2.553 +    (unsigned long) queue->next, (unsigned long) queue->prev);
   2.554 +
   2.555 +    list_for_each ( list, queue )
   2.556 +    {
   2.557 +        d_inf = list_entry(list, struct at_dom_info, run_list);
   2.558 +        d = d_inf->owner;
   2.559 +        printk("%3d: %d has=%c ", loop++, d->domain, 
   2.560 +                                    test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
   2.561 +        at_dump_runq_el(d);
   2.562 +        printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
   2.563 +        printk("         l: %lx n: %lx  p: %lx\n",
   2.564 +                        (unsigned long)list, (unsigned long)list->next,
   2.565 +                        (unsigned long)list->prev);
   2.566 +    }
   2.567 +
   2.568 +
   2.569 +    queue = WAITQ(cpu);
   2.570 +    printk("\nWAITQUEUE rq %lx   n: %lx, p: %lx\n",  (unsigned long)queue,
   2.571 +    (unsigned long) queue->next, (unsigned long) queue->prev);
   2.572 +
   2.573 +    list_for_each ( list, queue )
   2.574 +    {
   2.575 +        d_inf = list_entry(list, struct at_dom_info, waitq);
   2.576 +        d = d_inf->owner;
   2.577 +        printk("%3d: %d has=%c ", loop++, d->domain, 
   2.578 +                                    test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
   2.579 +        at_dump_runq_el(d);
   2.580 +        printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
   2.581 +        printk("         l: %lx n: %lx  p: %lx\n",
   2.582 +                        (unsigned long)list, (unsigned long)list->next,
   2.583 +                        (unsigned long)list->prev);
   2.584 +    }
   2.585 +       
   2.586 +}
   2.587 +
   2.588  /* set or fetch domain scheduling parameters */
   2.589  static int at_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd)
   2.590  {
   2.591 @@ -585,22 +682,6 @@ static int at_adjdom(struct domain *p, s
   2.592      return 0;
   2.593  }
   2.594  
   2.595 -
   2.596 -/** at_alloc_task - allocate private info for a task */
   2.597 -static int at_alloc_task(struct domain *p)
   2.598 -{
   2.599 -    ASSERT(p != NULL);
   2.600 -
   2.601 -    p->sched_priv = xmem_cache_alloc(dom_info_cache);
   2.602 -    if( p->sched_priv == NULL )
   2.603 -        return -1;
   2.604 -
   2.605 -    memset(p->sched_priv, 0, sizeof(struct at_dom_info));
   2.606 -
   2.607 -    return 0;
   2.608 -}
   2.609 -
   2.610 -
   2.611  /* free memory associated with a task */
   2.612  static void at_free_task(struct domain *p)
   2.613  {
   2.614 @@ -627,23 +708,20 @@ static int at_prn_state(int state)
   2.615  
   2.616      return ret;
   2.617  }
   2.618 -    
   2.619 -#endif /* KAF_KILLED */
   2.620  
   2.621  struct scheduler sched_atropos_def = {
   2.622      .name           = "Atropos Soft Real Time Scheduler",
   2.623      .opt_name       = "atropos",
   2.624      .sched_id       = SCHED_ATROPOS,
   2.625 -#ifdef KAF_KILLED
   2.626      .init_scheduler = at_init_scheduler,
   2.627 +    .init_idle_task = at_init_idle_task,
   2.628      .alloc_task     = at_alloc_task,
   2.629      .add_task       = at_add_task,
   2.630      .free_task      = at_free_task,
   2.631 -    .wake_up        = unblock,
   2.632 +    .wake           = unblock,
   2.633 +    .sleep          = block,
   2.634      .do_schedule    = ksched_scheduler,
   2.635      .adjdom         = at_adjdom,
   2.636      .dump_cpu_state = at_dump_cpu_state,
   2.637 -    .dump_runq_el   = at_dump_runq_el,
   2.638      .prn_state      = at_prn_state,
   2.639 -#endif /* KAF_KILLED */
   2.640  };