#include #include #include #include #include #include #include #include #define EDOM_INFO(d) ((struct rrobin_vcpu_info *)((d)->sched_priv)) #define CPU_INFO(cpu) \ ((struct rrobin_cpu_info *)per_cpu(schedule_data, cpu).sched_priv) #define RUNQ(cpu) (&CPU_INFO(cpu)->runnableq) struct list_head *vcpu_list_head; struct list_head *head; struct list_head *vcpu_list_tail; /*struct list_head *runq = RUNQ(cpu);*/ struct list_head *runq; struct rrobin_vcpu_info { struct list_head list; struct vcpu *vcpu; }; struct rrobin_cpu_info { struct list_head runnableq; }; /* Add a VCPU */ static int rrobin_vcpu_init(struct vcpu *v){ struct rrobin_vcpu_info *inf; if ( (v->sched_priv = xmalloc(struct rrobin_vcpu_info)) == NULL ) return 1; memset(v->sched_priv, 0, sizeof(struct rrobin_vcpu_info)); inf = EDOM_INFO(v); inf->vcpu = v; /* Allocate per-CPU context if this is the first domain to be added. */ if ( unlikely(per_cpu(schedule_data, v->processor).sched_priv == NULL) ) { per_cpu(schedule_data, v->processor).sched_priv = xmalloc(struct rrobin_cpu_info); BUG_ON(per_cpu(schedule_data, v->processor).sched_priv == NULL); memset(CPU_INFO(v->processor), 0, sizeof(*CPU_INFO(v->processor))); INIT_LIST_HEAD(RUNQ(v->processor)); } INIT_LIST_HEAD(&(inf->list)); return 0; } static void rrobin_vcpu_destroy(struct vcpu *v) { xfree(v->sched_priv); } static inline void increment_run_queue(void){ vcpu_list_head = runq; vcpu_list_tail = (vcpu_list_head)->prev; head = vcpu_list_head; vcpu_list_tail = vcpu_list_head; vcpu_list_head = (vcpu_list_tail)->next; vcpu_list_tail = head; } struct task_slice rrobin_schedule(s_time_t now){ /*struct list_head temp; */ int cpu = smp_processor_id(); /*struct rrobin_vcpu_info *inf = EDOM_INFO(current);*/ struct rrobin_vcpu_info *runinf; struct vcpu *temp; struct task_slice ret; ret.time = MILLISECS(10); /* Time quantum to scan the VCPU list to find a runnable VCPU */ runq = RUNQ(cpu); if ( !list_empty(runq) ){ runinf = list_entry(runq->next,struct rrobin_vcpu_info,list); temp = runinf->vcpu; ret.task = temp; } increment_run_queue(); return ret; } struct scheduler sched_rrobin_def = { .name = "Round robin Scheduler", .opt_name = "rrobin", .sched_id = XEN_SCHEDULER_SEDF, .init_vcpu = rrobin_vcpu_init, .destroy_vcpu = rrobin_vcpu_destroy, .do_schedule = rrobin_schedule, };