rev |
line source |
gdunlap@0
|
1 #include <stdio.h>
|
gdunlap@0
|
2 #include <stdlib.h>
|
gdunlap@0
|
3 #include <assert.h>
|
gdunlap@0
|
4
|
gdunlap@0
|
5 #define ASSERT assert
|
gdunlap@0
|
6
|
gdunlap@0
|
7 #include "list.h"
|
gdunlap@0
|
8 #include "sim.h"
|
gdunlap@0
|
9
|
gdunlap@0
|
10
|
gdunlap@0
|
11 #define MAX_VMS 16
|
gdunlap@1
|
12 #define TSLICE 1000
|
gdunlap@0
|
13
|
gdunlap@0
|
14 struct sched_vm {
|
gdunlap@0
|
15 struct list_head queue;
|
gdunlap@0
|
16 int vid;
|
gdunlap@0
|
17 struct vm *v;
|
gdunlap@0
|
18 };
|
gdunlap@0
|
19
|
gdunlap@0
|
20 struct {
|
gdunlap@0
|
21 struct list_head queue;
|
gdunlap@0
|
22 struct sched_vm vms[MAX_VMS];
|
gdunlap@0
|
23 } sched_priv;
|
gdunlap@0
|
24
|
gdunlap@0
|
25
|
gdunlap@0
|
26 void sched_rr_init(void)
|
gdunlap@0
|
27 {
|
gdunlap@0
|
28 printf("%s()\n", __func__);
|
gdunlap@0
|
29 INIT_LIST_HEAD(&sched_priv.queue);
|
gdunlap@0
|
30 }
|
gdunlap@0
|
31
|
gdunlap@0
|
32 void sched_rr_vm_init(int vid)
|
gdunlap@0
|
33 {
|
gdunlap@0
|
34 struct sched_vm *svm;
|
gdunlap@0
|
35
|
gdunlap@0
|
36 printf("%s: vm %d\n", __func__, vid);
|
gdunlap@0
|
37
|
gdunlap@0
|
38 if ( vid > MAX_VMS )
|
gdunlap@0
|
39 {
|
gdunlap@0
|
40 fprintf(stderr, "vid %d > MAX_VMS %d!\n", vid, MAX_VMS);
|
gdunlap@0
|
41 exit(1);
|
gdunlap@0
|
42 }
|
gdunlap@0
|
43
|
gdunlap@0
|
44 svm = sched_priv.vms + vid;
|
gdunlap@0
|
45
|
gdunlap@0
|
46 INIT_LIST_HEAD(&svm->queue);
|
gdunlap@0
|
47
|
gdunlap@0
|
48 svm->vid = vid;
|
gdunlap@0
|
49 svm->v = vm_from_vid(vid);
|
gdunlap@0
|
50
|
gdunlap@0
|
51 }
|
gdunlap@0
|
52
|
gdunlap@2
|
53 void sched_rr_wake(int time, int vid)
|
gdunlap@0
|
54 {
|
gdunlap@2
|
55 struct vm *v;
|
gdunlap@0
|
56 struct sched_vm *svm;
|
gdunlap@0
|
57
|
gdunlap@2
|
58 v = vm_from_vid(vid);
|
gdunlap@2
|
59
|
gdunlap@0
|
60 printf("%s: time %d vid %d\n",
|
gdunlap@0
|
61 __func__, time, v->vid);
|
gdunlap@0
|
62
|
gdunlap@0
|
63 svm = sched_priv.vms + v->vid;
|
gdunlap@0
|
64
|
gdunlap@0
|
65 ASSERT(list_empty(&svm->queue));
|
gdunlap@0
|
66
|
gdunlap@0
|
67 list_add_tail(&svm->queue, &sched_priv.queue);
|
gdunlap@1
|
68
|
gdunlap@1
|
69 /* Never preempt on wake; only kick idle processors */
|
gdunlap@1
|
70 if ( P.idle > 0 )
|
gdunlap@1
|
71 {
|
gdunlap@1
|
72 int i;
|
gdunlap@1
|
73
|
gdunlap@1
|
74 for ( i=0; i<P.count; i++ )
|
gdunlap@1
|
75 if ( P.pcpus[i].idle )
|
gdunlap@1
|
76 break;
|
gdunlap@1
|
77
|
gdunlap@1
|
78 printf(" %s: waking p%d\n", __func__, i);
|
gdunlap@1
|
79 sim_sched_timer(0, i);
|
gdunlap@1
|
80 }
|
gdunlap@0
|
81 }
|
gdunlap@0
|
82
|
gdunlap@0
|
83 struct vm* sched_rr_schedule(int time, int pid)
|
gdunlap@0
|
84 {
|
gdunlap@0
|
85 struct sched_vm *svm;
|
gdunlap@0
|
86 struct vm *next, *prev;
|
gdunlap@0
|
87
|
gdunlap@0
|
88 printf("%s: time %d pid %d\n",
|
gdunlap@0
|
89 __func__, time, pid);
|
gdunlap@0
|
90 prev = current(pid);
|
gdunlap@0
|
91
|
gdunlap@0
|
92 if ( prev )
|
gdunlap@0
|
93 {
|
gdunlap@0
|
94 printf(" current v%d\n", prev->vid);
|
gdunlap@0
|
95 svm = sched_priv.vms + prev->vid;
|
gdunlap@0
|
96
|
gdunlap@0
|
97 if ( svm->v->runstate == RUNSTATE_RUNNING )
|
gdunlap@0
|
98 {
|
gdunlap@0
|
99 printf(" adding to runqueue\n");
|
gdunlap@0
|
100 list_add_tail(&svm->queue, &sched_priv.queue);
|
gdunlap@0
|
101 }
|
gdunlap@0
|
102 }
|
gdunlap@0
|
103
|
gdunlap@0
|
104 /* Take guy on front of runqueue, set new timer */
|
gdunlap@0
|
105 if ( list_empty(&sched_priv.queue) )
|
gdunlap@0
|
106 {
|
gdunlap@0
|
107 printf(" No runnable entities\n");
|
gdunlap@0
|
108 return NULL;
|
gdunlap@0
|
109 }
|
gdunlap@0
|
110
|
gdunlap@0
|
111 svm = list_entry(sched_priv.queue.next, struct sched_vm, queue);
|
gdunlap@0
|
112
|
gdunlap@0
|
113 list_del_init(&svm->queue);
|
gdunlap@0
|
114 next = svm->v;
|
gdunlap@0
|
115
|
gdunlap@0
|
116 sim_sched_timer(TSLICE, pid);
|
gdunlap@0
|
117
|
gdunlap@0
|
118 printf(" next: v%d\n", next->vid);
|
gdunlap@0
|
119
|
gdunlap@0
|
120 return next;
|
gdunlap@0
|
121 }
|
gdunlap@0
|
122
|
gdunlap@0
|
123 struct scheduler sched_rr =
|
gdunlap@0
|
124 {
|
gdunlap@0
|
125 .name="round-robin",
|
gdunlap@4
|
126 .desc="Basic round-robin scheduler.",
|
gdunlap@0
|
127 .ops = {
|
gdunlap@0
|
128 .sched_init = sched_rr_init,
|
gdunlap@0
|
129 .vm_init = sched_rr_vm_init,
|
gdunlap@0
|
130 .wake = sched_rr_wake,
|
gdunlap@0
|
131 .schedule = sched_rr_schedule
|
gdunlap@0
|
132 }
|
gdunlap@0
|
133 };
|