debuggers.hg
annotate xen/common/sched_rrobin.c @ 3658:0ef6e8e6e85d
bitkeeper revision 1.1159.212.71 (4200f0afX_JumfbEHQex6TdFENULMQ)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xen-unstable.bk
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xen-unstable.bk
author | iap10@labyrinth.cl.cam.ac.uk |
---|---|
date | Wed Feb 02 15:24:31 2005 +0000 (2005-02-02) |
parents | 51052c8b6456 f98fa170a9f4 |
children | bbe8541361dd 4294cfa9fad3 |
rev | line source |
---|---|
mwilli2@1232 | 1 /**************************************************************************** |
mwilli2@1284 | 2 * Round Robin Scheduler for Xen |
mwilli2@1232 | 3 * |
mwilli2@1232 | 4 * by Mark Williamson (C) 2004 Intel Research Cambridge |
mwilli2@1232 | 5 */ |
mwilli2@1232 | 6 |
kaf24@1248 | 7 #include <xen/sched.h> |
kaf24@1248 | 8 #include <xen/sched-if.h> |
kaf24@2827 | 9 #include <public/sched_ctl.h> |
kaf24@1248 | 10 #include <xen/ac_timer.h> |
kaf24@1916 | 11 #include <xen/softirq.h> |
kaf24@1248 | 12 #include <xen/time.h> |
gm281@1937 | 13 #include <xen/slab.h> |
mwilli2@1232 | 14 |
kaf24@1916 | 15 #define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ |
kaf24@1916 | 16 |
mwilli2@1232 | 17 static s_time_t rr_slice = MILLISECS(10); |
mwilli2@1232 | 18 |
gm281@1937 | 19 /* Only runqueue pointers and domain pointer*/ |
gm281@1937 | 20 struct rrobin_dom_info |
gm281@1937 | 21 { |
gm281@1937 | 22 struct list_head run_list; |
gm281@1937 | 23 struct domain *domain; |
gm281@1937 | 24 }; |
gm281@1937 | 25 |
gm281@1937 | 26 #define RR_INFO(d) ((struct rrobin_dom_info *)d->sched_priv) |
gm281@2017 | 27 #define RUNLIST(d) ((struct list_head *)&(RR_INFO(d)->run_list)) |
gm281@1937 | 28 #define RUNQUEUE(cpu) RUNLIST(schedule_data[cpu].idle) |
gm281@1937 | 29 |
gm281@2017 | 30 static inline void __add_to_runqueue_head(struct domain *d) |
gm281@2017 | 31 { |
gm281@2017 | 32 list_add(RUNLIST(d), RUNQUEUE(d->processor)); |
gm281@2017 | 33 } |
gm281@2017 | 34 |
gm281@2017 | 35 static inline void __add_to_runqueue_tail(struct domain *d) |
gm281@2017 | 36 { |
gm281@2017 | 37 list_add_tail(RUNLIST(d), RUNQUEUE(d->processor)); |
gm281@2017 | 38 } |
gm281@2017 | 39 |
gm281@2017 | 40 static inline void __del_from_runqueue(struct domain *d) |
gm281@2017 | 41 { |
gm281@2017 | 42 struct list_head *runlist = RUNLIST(d); |
gm281@2017 | 43 list_del(runlist); |
gm281@2017 | 44 runlist->next = NULL; |
gm281@2017 | 45 } |
gm281@2017 | 46 |
gm281@2017 | 47 static inline int __task_on_runqueue(struct domain *d) |
gm281@2017 | 48 { |
gm281@2017 | 49 return (RUNLIST(d))->next != NULL; |
gm281@2017 | 50 } |
gm281@2017 | 51 |
gm281@1937 | 52 /* Initialises the runqueues and creates the domain info cache */ |
gm281@1937 | 53 static int rr_init_scheduler() |
gm281@1937 | 54 { |
gm281@1937 | 55 int i; |
gm281@1937 | 56 |
gm281@1937 | 57 for ( i = 0; i < NR_CPUS; i++ ) |
gm281@1937 | 58 INIT_LIST_HEAD(RUNQUEUE(i)); |
gm281@1937 | 59 |
gm281@1937 | 60 return 0; |
gm281@1937 | 61 } |
gm281@1937 | 62 /* Allocates memory for per domain private scheduling data*/ |
gm281@1937 | 63 static int rr_alloc_task(struct domain *d) |
gm281@1937 | 64 { |
iap10@3651 | 65 if ( (d->sched_priv = new(struct rrobin_dom_info) == NULL ) |
gm281@1937 | 66 return -1; |
kaf24@2634 | 67 memset(d->sched_priv, 0, sizeof(struct rrobin_dom_info)); |
kaf24@2634 | 68 return 0; |
gm281@1937 | 69 } |
gm281@1937 | 70 |
kaf24@2217 | 71 /* Setup the rr_dom_info */ |
kaf24@2634 | 72 static void rr_add_task(struct domain *d) |
gm281@1937 | 73 { |
gm281@1937 | 74 struct rrobin_dom_info *inf; |
kaf24@2634 | 75 RR_INFO(d)->domain = d; |
kaf24@2634 | 76 inf = RR_INFO(d); |
gm281@1937 | 77 } |
gm281@1937 | 78 |
gm281@1937 | 79 /* Frees memory used by domain info */ |
kaf24@2634 | 80 static void rr_free_task(struct domain *d) |
gm281@1937 | 81 { |
kaf24@2634 | 82 ASSERT(d->sched_priv != NULL); |
iap10@3651 | 83 xfree(d->sched_priv); |
gm281@1937 | 84 } |
gm281@1937 | 85 |
gm281@1937 | 86 /* Initialises idle task */ |
kaf24@2634 | 87 static int rr_init_idle_task(struct domain *d) |
gm281@1937 | 88 { |
kaf24@2634 | 89 if ( rr_alloc_task(d) < 0 ) |
kaf24@2634 | 90 return -1; |
gm281@1937 | 91 |
kaf24@2634 | 92 rr_add_task(d); |
kaf24@2634 | 93 |
kaf24@2634 | 94 set_bit(DF_RUNNING, &d->flags); |
kaf24@2634 | 95 if ( !__task_on_runqueue(d) ) |
kaf24@2634 | 96 __add_to_runqueue_head(d); |
kaf24@2634 | 97 |
gm281@1937 | 98 return 0; |
gm281@1937 | 99 } |
gm281@1937 | 100 |
gm281@1937 | 101 /* Main scheduling function */ |
mwilli2@1232 | 102 static task_slice_t rr_do_schedule(s_time_t now) |
mwilli2@1232 | 103 { |
kaf24@1543 | 104 struct domain *prev = current; |
mwilli2@1232 | 105 int cpu = current->processor; |
mwilli2@1232 | 106 task_slice_t ret; |
gm281@2007 | 107 |
kaf24@2634 | 108 if ( !is_idle_task(prev) ) |
gm281@1937 | 109 { |
gm281@2017 | 110 __del_from_runqueue(prev); |
mwilli2@1232 | 111 |
gm281@1937 | 112 if ( domain_runnable(prev) ) |
gm281@2017 | 113 __add_to_runqueue_tail(prev); |
gm281@1937 | 114 } |
mwilli2@1232 | 115 |
kaf24@2634 | 116 ret.task = list_entry(RUNQUEUE(cpu)->next, |
kaf24@2634 | 117 struct rrobin_dom_info, |
kaf24@2634 | 118 run_list)->domain; |
mwilli2@1232 | 119 ret.time = rr_slice; |
mwilli2@1232 | 120 return ret; |
mwilli2@1232 | 121 } |
mwilli2@1232 | 122 |
gm281@1937 | 123 /* Set/retrive control parameter(s) */ |
mwilli2@1232 | 124 static int rr_ctl(struct sched_ctl_cmd *cmd) |
mwilli2@1232 | 125 { |
kaf24@1916 | 126 if ( cmd->direction == SCHED_INFO_PUT ) |
mwilli2@1284 | 127 { |
mwilli2@1284 | 128 rr_slice = cmd->u.rrobin.slice; |
mwilli2@1284 | 129 } |
mwilli2@1284 | 130 else /* cmd->direction == SCHED_INFO_GET */ |
mwilli2@1284 | 131 { |
mwilli2@1284 | 132 cmd->u.rrobin.slice = rr_slice; |
mwilli2@1284 | 133 } |
mwilli2@1284 | 134 |
mwilli2@1232 | 135 return 0; |
mwilli2@1232 | 136 } |
mwilli2@1232 | 137 |
mwilli2@1232 | 138 static void rr_dump_settings() |
mwilli2@1232 | 139 { |
mwilli2@1232 | 140 printk("rr_slice = %llu ", rr_slice); |
mwilli2@1232 | 141 } |
mwilli2@1232 | 142 |
kaf24@1916 | 143 static void rr_sleep(struct domain *d) |
kaf24@1916 | 144 { |
kaf24@1916 | 145 if ( test_bit(DF_RUNNING, &d->flags) ) |
kaf24@1916 | 146 cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ); |
kaf24@2634 | 147 else if ( __task_on_runqueue(d) ) |
kaf24@2634 | 148 __del_from_runqueue(d); |
kaf24@1916 | 149 } |
kaf24@1916 | 150 |
kaf24@1916 | 151 void rr_wake(struct domain *d) |
mwilli2@1253 | 152 { |
kaf24@1916 | 153 struct domain *curr; |
kaf24@2068 | 154 s_time_t now; |
gm281@2007 | 155 int cpu = d->processor; |
kaf24@1916 | 156 |
kaf24@2634 | 157 if ( unlikely(__task_on_runqueue(d)) ) |
kaf24@1916 | 158 return; |
kaf24@1916 | 159 |
gm281@2017 | 160 __add_to_runqueue_head(d); |
gm281@2007 | 161 |
kaf24@1916 | 162 now = NOW(); |
kaf24@1916 | 163 |
kaf24@1916 | 164 curr = schedule_data[cpu].curr; |
kaf24@2634 | 165 if ( is_idle_task(curr) ) |
kaf24@1916 | 166 cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ); |
mwilli2@1253 | 167 } |
mwilli2@1253 | 168 |
gm281@1937 | 169 |
gm281@1937 | 170 static void rr_dump_domain(struct domain *d) |
gm281@1937 | 171 { |
kaf24@2748 | 172 printk("%u has=%c ", d->id, |
gm281@1937 | 173 test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); |
gm281@1937 | 174 printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); |
gm281@1937 | 175 } |
gm281@1937 | 176 |
gm281@1937 | 177 static void rr_dump_cpu_state(int i) |
gm281@1937 | 178 { |
kaf24@3568 | 179 struct list_head *queue; |
gm281@1937 | 180 int loop = 0; |
gm281@1937 | 181 struct rrobin_dom_info *d_inf; |
gm281@1937 | 182 |
gm281@1937 | 183 queue = RUNQUEUE(i); |
gm281@1937 | 184 printk("QUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, |
gm281@1937 | 185 (unsigned long) queue->next, (unsigned long) queue->prev); |
gm281@1937 | 186 |
gm281@1937 | 187 printk("%3d: ",loop++); |
gm281@1937 | 188 d_inf = list_entry(queue, struct rrobin_dom_info, run_list); |
gm281@1937 | 189 rr_dump_domain(d_inf->domain); |
gm281@1937 | 190 |
kaf24@3568 | 191 list_for_each_entry ( d_inf, queue, run_list ) |
gm281@1937 | 192 { |
gm281@1937 | 193 printk("%3d: ",loop++); |
gm281@1937 | 194 rr_dump_domain(d_inf->domain); |
gm281@1937 | 195 } |
gm281@1937 | 196 } |
gm281@1937 | 197 |
gm281@1937 | 198 |
mwilli2@1232 | 199 struct scheduler sched_rrobin_def = { |
kaf24@1233 | 200 .name = "Round-Robin Scheduler", |
mwilli2@1232 | 201 .opt_name = "rrobin", |
mwilli2@1232 | 202 .sched_id = SCHED_RROBIN, |
gm281@1937 | 203 |
gm281@1937 | 204 .init_idle_task = rr_init_idle_task, |
gm281@1937 | 205 .alloc_task = rr_alloc_task, |
gm281@1937 | 206 .add_task = rr_add_task, |
gm281@1937 | 207 .free_task = rr_free_task, |
gm281@1937 | 208 .init_scheduler = rr_init_scheduler, |
mwilli2@1232 | 209 .do_schedule = rr_do_schedule, |
mwilli2@1232 | 210 .control = rr_ctl, |
mwilli2@1232 | 211 .dump_settings = rr_dump_settings, |
gm281@1937 | 212 .dump_cpu_state = rr_dump_cpu_state, |
kaf24@1916 | 213 .sleep = rr_sleep, |
kaf24@1916 | 214 .wake = rr_wake, |
mwilli2@1232 | 215 }; |
mwilli2@1232 | 216 |
mwilli2@1232 | 217 |