#include #include #include #include #include #include #include #include #include #include #include #include #include /* New VCPUs will be appended to the below linked list. The VCPU on the head of the list will be scheduled and then moved to the end of the list.*/ static struct vcpu *vcpu_list_head = NULL; static struct vcpu *vcpu_list_tail = NULL; static struct vcpu *head; unsigned int vcpus = 0; /* Move the head VCPU to the end */ static inline void increment_run_queue(void){ (struct vcpu) (vcpu_list_tail)->sched_priv = vcpu_list_head; vcpu_list_tail = vcpu_list_head; vcpu_list_head = VCPU_NEXT(vcpu_list_tail); (vcpu_list_tail)->sched_priv = NULL; } /* Add a VCPU */ int rrobin_vcpu_init(struct vcpu *v){ if(vcpu_list_head == NULL){ vcpu_list_tail = v; vcpu_list_head = vcpu_list_tail; } else{ vcpu_list_tail = v; (struct vcpu) vcpu_list_tail->sched_priv = vcpu_list_tail; } v->sched_priv = NULL; return 0; } /*Remove a VCPU*/ void rrobin_vcpu_destroy(struct vcpu *v){ if(v == vcpu_list_head){ vcpu_list_head = VCPU_NEXT(v); } else{ struct vcpu *last = NULL; struct vcpu *current = vcpu_list_head; while((current != v) && (current != NULL)){ last = current; current = VCPU_NEXT(current); } if(current != NULL){ last->sched_priv = VCPU_NEXT(current); } } } /* Pick a VCPU from the list */ struct task_slice rrobin_schedule(s_time_t now){ struct task_slice ret; ret.time = MILLISECS(10); /* Time quantum to scan the VCPU list to find a runnable VCPU */ head = vcpu_list_head; /* Since its round robin, we pick the head of the list for scheduling and later move it back */ do{ /* Find a runnable CPU in the list */ increment_run_queue(); if(vcpu_runnable(vcpu_list_head)){ ret.task = vcpu_list_head; } }while(head != vcpu_list_head); /* If no runnable VCPU is found, return the idle task */ ret.task = ((struct vcpu) __get_per_cpu(schedule_data).idle); return ret; } struct scheduler sched_rrobin_def = { .name = "Round robin Scheduler", .opt_name = "rrobin", .sched_id = XEN_SCHEDULER_RR, .init_vcpu = rrobin_vcpu_init, .destroy_vcpu = rrobin_vcpu_destroy, .do_schedule = rrobin_schedule, };