debuggers.hg

view xen/common/sched_rrobin.c @ 3705:4294cfa9fad3

bitkeeper revision 1.1159.212.95 (4204aa0ee0re5Xx1zWrJ9ejxzgRs3w)

Various cleanups. Remove PDB pending simpler GDB stub and/or NetBSD debugger.
Force emacs mode to appropriate tabbing in various files.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Sat Feb 05 11:12:14 2005 +0000 (2005-02-05)
parents 0ef6e8e6e85d
children 88957a238191
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
2 /****************************************************************************
3 * Round Robin Scheduler for Xen
4 *
5 * by Mark Williamson (C) 2004 Intel Research Cambridge
6 */
8 #include <xen/sched.h>
9 #include <xen/sched-if.h>
10 #include <public/sched_ctl.h>
11 #include <xen/ac_timer.h>
12 #include <xen/softirq.h>
13 #include <xen/time.h>
14 #include <xen/slab.h>
16 #define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */
18 static s_time_t rr_slice = MILLISECS(10);
20 /* Only runqueue pointers and domain pointer*/
21 struct rrobin_dom_info
22 {
23 struct list_head run_list;
24 struct domain *domain;
25 };
27 #define RR_INFO(d) ((struct rrobin_dom_info *)d->sched_priv)
28 #define RUNLIST(d) ((struct list_head *)&(RR_INFO(d)->run_list))
29 #define RUNQUEUE(cpu) RUNLIST(schedule_data[cpu].idle)
31 static inline void __add_to_runqueue_head(struct domain *d)
32 {
33 list_add(RUNLIST(d), RUNQUEUE(d->processor));
34 }
36 static inline void __add_to_runqueue_tail(struct domain *d)
37 {
38 list_add_tail(RUNLIST(d), RUNQUEUE(d->processor));
39 }
41 static inline void __del_from_runqueue(struct domain *d)
42 {
43 struct list_head *runlist = RUNLIST(d);
44 list_del(runlist);
45 runlist->next = NULL;
46 }
48 static inline int __task_on_runqueue(struct domain *d)
49 {
50 return (RUNLIST(d))->next != NULL;
51 }
53 /* Initialises the runqueues and creates the domain info cache */
54 static int rr_init_scheduler()
55 {
56 int i;
58 for ( i = 0; i < NR_CPUS; i++ )
59 INIT_LIST_HEAD(RUNQUEUE(i));
61 return 0;
62 }
63 /* Allocates memory for per domain private scheduling data*/
64 static int rr_alloc_task(struct domain *d)
65 {
66 if ( (d->sched_priv = new(struct rrobin_dom_info) == NULL )
67 return -1;
68 memset(d->sched_priv, 0, sizeof(struct rrobin_dom_info));
69 return 0;
70 }
72 /* Setup the rr_dom_info */
73 static void rr_add_task(struct domain *d)
74 {
75 struct rrobin_dom_info *inf;
76 RR_INFO(d)->domain = d;
77 inf = RR_INFO(d);
78 }
80 /* Frees memory used by domain info */
81 static void rr_free_task(struct domain *d)
82 {
83 ASSERT(d->sched_priv != NULL);
84 xfree(d->sched_priv);
85 }
87 /* Initialises idle task */
88 static int rr_init_idle_task(struct domain *d)
89 {
90 if ( rr_alloc_task(d) < 0 )
91 return -1;
93 rr_add_task(d);
95 set_bit(DF_RUNNING, &d->flags);
96 if ( !__task_on_runqueue(d) )
97 __add_to_runqueue_head(d);
99 return 0;
100 }
102 /* Main scheduling function */
103 static task_slice_t rr_do_schedule(s_time_t now)
104 {
105 struct domain *prev = current;
106 int cpu = current->processor;
107 task_slice_t ret;
109 if ( !is_idle_task(prev) )
110 {
111 __del_from_runqueue(prev);
113 if ( domain_runnable(prev) )
114 __add_to_runqueue_tail(prev);
115 }
117 ret.task = list_entry(RUNQUEUE(cpu)->next,
118 struct rrobin_dom_info,
119 run_list)->domain;
120 ret.time = rr_slice;
121 return ret;
122 }
124 /* Set/retrive control parameter(s) */
125 static int rr_ctl(struct sched_ctl_cmd *cmd)
126 {
127 if ( cmd->direction == SCHED_INFO_PUT )
128 {
129 rr_slice = cmd->u.rrobin.slice;
130 }
131 else /* cmd->direction == SCHED_INFO_GET */
132 {
133 cmd->u.rrobin.slice = rr_slice;
134 }
136 return 0;
137 }
139 static void rr_dump_settings()
140 {
141 printk("rr_slice = %llu ", rr_slice);
142 }
144 static void rr_sleep(struct domain *d)
145 {
146 if ( test_bit(DF_RUNNING, &d->flags) )
147 cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ);
148 else if ( __task_on_runqueue(d) )
149 __del_from_runqueue(d);
150 }
152 void rr_wake(struct domain *d)
153 {
154 struct domain *curr;
155 s_time_t now;
156 int cpu = d->processor;
158 if ( unlikely(__task_on_runqueue(d)) )
159 return;
161 __add_to_runqueue_head(d);
163 now = NOW();
165 curr = schedule_data[cpu].curr;
166 if ( is_idle_task(curr) )
167 cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
168 }
171 static void rr_dump_domain(struct domain *d)
172 {
173 printk("%u has=%c ", d->id,
174 test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
175 printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time);
176 }
178 static void rr_dump_cpu_state(int i)
179 {
180 struct list_head *queue;
181 int loop = 0;
182 struct rrobin_dom_info *d_inf;
184 queue = RUNQUEUE(i);
185 printk("QUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue,
186 (unsigned long) queue->next, (unsigned long) queue->prev);
188 printk("%3d: ",loop++);
189 d_inf = list_entry(queue, struct rrobin_dom_info, run_list);
190 rr_dump_domain(d_inf->domain);
192 list_for_each_entry ( d_inf, queue, run_list )
193 {
194 printk("%3d: ",loop++);
195 rr_dump_domain(d_inf->domain);
196 }
197 }
200 struct scheduler sched_rrobin_def = {
201 .name = "Round-Robin Scheduler",
202 .opt_name = "rrobin",
203 .sched_id = SCHED_RROBIN,
205 .init_idle_task = rr_init_idle_task,
206 .alloc_task = rr_alloc_task,
207 .add_task = rr_add_task,
208 .free_task = rr_free_task,
209 .init_scheduler = rr_init_scheduler,
210 .do_schedule = rr_do_schedule,
211 .control = rr_ctl,
212 .dump_settings = rr_dump_settings,
213 .dump_cpu_state = rr_dump_cpu_state,
214 .sleep = rr_sleep,
215 .wake = rr_wake,
216 };