gdunlap/sched-sim.hg

changeset 1:ec2d50e41437

Handle multiple cpus.
author George Dunlap <gdunlap@xensource.com>
date Tue Oct 13 17:29:50 2009 +0100 (2009-10-13)
parents d27bb3c56e71
children 1d7310217c5a
files sched_rr.c sim.h simulator.c workloads.c
line diff
     1.1 --- a/sched_rr.c	Tue Oct 13 16:06:36 2009 +0100
     1.2 +++ b/sched_rr.c	Tue Oct 13 17:29:50 2009 +0100
     1.3 @@ -9,7 +9,7 @@
     1.4  
     1.5  
     1.6  #define MAX_VMS 16
     1.7 -#define TSLICE 2000
     1.8 +#define TSLICE 1000
     1.9  
    1.10  struct sched_vm {
    1.11      struct list_head queue;
    1.12 @@ -62,6 +62,19 @@ void sched_rr_wake(int time, struct vm *
    1.13      ASSERT(list_empty(&svm->queue));
    1.14  
    1.15      list_add_tail(&svm->queue, &sched_priv.queue);
    1.16 +
    1.17 +    /* Never preempt on wake; only kick idle processors */
    1.18 +    if ( P.idle > 0 )
    1.19 +    {
    1.20 +        int i;
    1.21 +
    1.22 +        for ( i=0; i<P.count; i++ )
    1.23 +            if ( P.pcpus[i].idle )
    1.24 +                break;
    1.25 +
    1.26 +        printf(" %s: waking p%d\n", __func__, i);
    1.27 +        sim_sched_timer(0, i);
    1.28 +    }
    1.29  }
    1.30  
    1.31  struct vm* sched_rr_schedule(int time, int pid)
     2.1 --- a/sim.h	Tue Oct 13 16:06:36 2009 +0100
     2.2 +++ b/sim.h	Tue Oct 13 17:29:50 2009 +0100
     2.3 @@ -2,6 +2,7 @@
     2.4  #define __SIM_H
     2.5  
     2.6  #include "stats.h"
     2.7 +#include "workload.h"
     2.8  
     2.9  enum runstate {
    2.10      RUNSTATE_RUNNING,
    2.11 @@ -55,16 +56,26 @@ struct scheduler {
    2.12      struct sched_ops ops;
    2.13  };
    2.14  
    2.15 -#define MAX_PCPU
    2.16 +#define MAX_PCPU 16
    2.17  struct global_pcpu_data {
    2.18 -    int count;
    2.19 +    int count, idle;
    2.20      struct pcpu {
    2.21          int pid;
    2.22 +        int idle; /* Indicates may be woken up if work appears */
    2.23          struct vm* current;
    2.24      } pcpus[MAX_PCPU];
    2.25  };
    2.26  extern struct global_pcpu_data P;
    2.27  
    2.28 +
    2.29 +#ifdef VM_DATA_PUBLIC
    2.30 +struct global_vm_data {
    2.31 +    int count;
    2.32 +    struct vm vms[MAX_VMS];
    2.33 +};
    2.34 +extern struct global_vm_data V;
    2.35 +#endif
    2.36 +
    2.37  struct vm* vm_from_vid(int vid);
    2.38  #define current(_pid) (P.pcpus[(_pid)].current)
    2.39  void sim_sched_timer(int time, int pid);
     3.1 --- a/simulator.c	Tue Oct 13 16:06:36 2009 +0100
     3.2 +++ b/simulator.c	Tue Oct 13 17:29:50 2009 +0100
     3.3 @@ -46,10 +46,13 @@ struct {
     3.4  } sim;
     3.5  
     3.6  
     3.7 -struct {
     3.8 +#ifndef VM_DATA_PUBLIC
     3.9 +struct global_vm_data {
    3.10      int count;
    3.11      struct vm vms[MAX_VMS];
    3.12 -} V;
    3.13 +};
    3.14 +#endif
    3.15 +struct global_vm_data V;
    3.16  
    3.17  extern struct scheduler sched_rr;
    3.18  int default_scheduler = 0;
    3.19 @@ -66,7 +69,7 @@ struct {
    3.20      const struct scheduler * scheduler;
    3.21  } opt = {
    3.22      .time_limit = 100000,
    3.23 -    .pcpu_count = 1,
    3.24 +    .pcpu_count = 2,
    3.25      .workload = NULL,
    3.26  };
    3.27  
    3.28 @@ -110,13 +113,13 @@ void sim_insert_event(int time, int type
    3.29      if ( !evt )
    3.30          evt = (struct event *)malloc(sizeof(*evt));
    3.31  
    3.32 -    printf(" [insert t%d %s param%d]\n",
    3.33 -           evt->time, event_name[evt->type], evt->param);
    3.34 -
    3.35      evt->time = time;
    3.36      evt->type = type;
    3.37      evt->param = param;
    3.38  
    3.39 +    printf(" [insert t%d %s param%d]\n",
    3.40 +           evt->time, event_name[evt->type], evt->param);
    3.41 +
    3.42      INIT_LIST_HEAD(&evt->event_list);
    3.43  
    3.44      list_for_each(pos, &sim.events)
    3.45 @@ -161,7 +164,12 @@ void vm_next_event(struct vm *v)
    3.46  
    3.47  struct vm* vm_from_vid(int vid)
    3.48  {
    3.49 -    ASSERT(vid < V.count);
    3.50 +    if ( vid >= V.count )
    3.51 +    {
    3.52 +        fprintf(stderr, "%s: v%d >= V.count %d!\n",
    3.53 +                __func__, vid, V.count);
    3.54 +        exit(1);
    3.55 +    }
    3.56  
    3.57      return V.vms + vid;
    3.58  }
    3.59 @@ -232,6 +240,18 @@ void vm_preempt(int now, struct vm *v)
    3.60  /* Callbacks the scheduler may make */
    3.61  void sim_sched_timer(int time, int pid)
    3.62  {
    3.63 +    if ( pid >= P.count )
    3.64 +    {
    3.65 +        fprintf(stderr, "%s: p%d >= P.count %d\n",
    3.66 +                __func__, pid, P.count);
    3.67 +        exit(1);
    3.68 +    }
    3.69 +
    3.70 +    if ( P.pcpus[pid].idle )
    3.71 +    {
    3.72 +        P.pcpus[pid].idle = 0;
    3.73 +        P.idle--;
    3.74 +    }
    3.75      sim_insert_event(sim.now + time, EVT_TIMER, pid, 1);
    3.76  }
    3.77  
    3.78 @@ -363,9 +383,21 @@ void simulate(void)
    3.79                      sim_runstate_change(sim.now, prev, RUNSTATE_RUNNABLE);
    3.80              }
    3.81  
    3.82 -            sim_runstate_change(sim.now, next, RUNSTATE_RUNNING);
    3.83 +            
    3.84              P.pcpus[pid].current = next;
    3.85 -            next->processor = pid;
    3.86 +            if ( next )
    3.87 +            {
    3.88 +                if ( next != prev )
    3.89 +                {
    3.90 +                    sim_runstate_change(sim.now, next, RUNSTATE_RUNNING);
    3.91 +                    next->processor = pid;
    3.92 +                }
    3.93 +            }
    3.94 +            else
    3.95 +            {
    3.96 +                P.pcpus[pid].idle = 1;
    3.97 +                P.idle++;
    3.98 +            }
    3.99          }
   3.100          break;
   3.101          default:
   3.102 @@ -389,9 +421,12 @@ void init(void)
   3.103  
   3.104      /* Initialize pcpus */
   3.105      P.count = opt.pcpu_count;
   3.106 +    P.idle = 0;
   3.107      for ( i=0; i<P.count; i++ )
   3.108      {
   3.109          P.pcpus[i].pid = i;
   3.110 +        P.pcpus[i].idle = 1;
   3.111 +        P.idle++;
   3.112          P.pcpus[i].current = NULL;
   3.113      }
   3.114  
   3.115 @@ -400,6 +435,7 @@ void init(void)
   3.116  
   3.117      /* Initialize vms */
   3.118      w=opt.workload;
   3.119 +    V.count = 0;
   3.120      for ( vid=0; vid<w->vm_count; vid++)
   3.121      {
   3.122          struct vm *v = V.vms+vid;
   3.123 @@ -447,10 +483,6 @@ void init(void)
   3.124              break;
   3.125          }
   3.126      }
   3.127 -
   3.128 -    /* Insert initial scheduler timer */
   3.129 -    for ( i=0; i<P.count; i++)
   3.130 -        sim_insert_event(sim.now, EVT_TIMER, i, 1);
   3.131  }
   3.132  
   3.133  void report(void)
     4.1 --- a/workloads.c	Tue Oct 13 16:06:36 2009 +0100
     4.2 +++ b/workloads.c	Tue Oct 13 17:29:50 2009 +0100
     4.3 @@ -4,6 +4,48 @@ const int default_workload = 0;
     4.4  struct workload builtin_workloads[] =
     4.5  {
     4.6      {
     4.7 +        .name="r1",
     4.8 +        .vm_count=3,
     4.9 +        .vm_workloads = {
    4.10 +            { .phase_count = 2,
    4.11 +              .list = {
    4.12 +                    {
    4.13 +                    .type=PHASE_RUN,
    4.14 +                    .time=70
    4.15 +                    },
    4.16 +                    {
    4.17 +                    .type=PHASE_BLOCK,
    4.18 +                    .time=250
    4.19 +                    },
    4.20 +                }
    4.21 +            },
    4.22 +            { .phase_count = 2,
    4.23 +              .list = {
    4.24 +                    {
    4.25 +                    .type=PHASE_RUN,
    4.26 +                    .time=500
    4.27 +                    },
    4.28 +                    {
    4.29 +                    .type=PHASE_BLOCK,
    4.30 +                    .time=500
    4.31 +                    },
    4.32 +                }
    4.33 +            },
    4.34 +            { .phase_count = 2,
    4.35 +              .list = {
    4.36 +                    {
    4.37 +                    .type=PHASE_RUN,
    4.38 +                    .time=1295
    4.39 +                    },
    4.40 +                    {
    4.41 +                    .type=PHASE_BLOCK,
    4.42 +                    .time=5
    4.43 +                    },
    4.44 +                }
    4.45 +            },
    4.46 +        }
    4.47 +    },
    4.48 +    {
    4.49          .name="Sx3",
    4.50          .vm_count=3,
    4.51          .vm_workloads = {