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
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