gdunlap/sched-sim.hg

annotate sched_rr.c @ 7:e274ac3f81ff

c01: Allow wake to preempt running processes
author George Dunlap <gdunlap@xensource.com>
date Tue Oct 20 18:00:17 2009 +0100 (2009-10-20)
parents f7c1a67cf976
children
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 };