#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BEEP "inb $97, %al;\n\ outb %al, $0x80;\n\ movb $3, %al;\n\ outb %al, $97;\n\ outb %al, $0x80;\n\ movb $-74, %al;\n\ outb %al, $67;\n\ outb %al, $0x80;\n\ movb $-119, %al;\n\ outb %al, $66;\n\ outb %al, $0x80;\n\ movb $15, %al;\n\ outb %al, $66;" /* CPU Run Queue */ static struct vcpu *vcpu_list_head = NULL ; static struct vcpu *vcpu_list_tail = NULL ; static spinlock_t lock; unsigned int vcpus = 0 ; static void trivial_init_func(void) { // unsigned long flags; spin_lock_init(&lock); // printk("t_init_func:Wait\n"); // spin_lock_irqsave(&lock, flags); } /* Add a VCPU */ static int trivial_init_vcpu (struct vcpu *v) { //asm volatile(BEEP); unsigned long flags; printk("t_init:Wait\n"); spin_lock_irqsave(&lock, flags); if ( vcpu_list_head == NULL) { vcpu_list_head = vcpu_list_tail = v ; } else { vcpu_list_tail->sched_priv = (void*)v ; vcpu_list_tail = v; } spin_unlock_irqrestore(&lock, flags); v->sched_priv = NULL ; printk("t_init:free"); return 0; } /* Remove a VCPU */ static void trivial_destroy_vcpu(struct vcpu *v){ struct vcpu *curr = NULL; struct vcpu *last = NULL; //asm volatile(BEEP); unsigned long flags; printk("t_destroy:wait\n"); spin_lock_irqsave(&lock, flags); if(v == vcpu_list_head) { vcpu_list_head = (struct vcpu*)(vcpu_list_head->sched_priv); } else { last = NULL; curr = vcpu_list_head; while(curr != NULL) { if(curr == v) { last = (struct vcpu*)(curr->sched_priv); break; } last = curr; curr = (struct vcpu*)(curr->sched_priv); } if(curr != NULL) { last->sched_priv = curr->sched_priv; } } spin_unlock_irqrestore(&lock, flags); printk("destroy:free"); } static inline void increment_run_queue(void) { //asm volatile(BEEP); unsigned long flags; printk("t_irq:wait\n"); spin_lock_irqsave(&lock, flags); vcpu_list_tail->sched_priv = (void*)vcpu_list_head; vcpu_list_tail = vcpu_list_head; vcpu_list_head = (struct vcpu*)(vcpu_list_tail->sched_priv); vcpu_list_tail->sched_priv = NULL; spin_unlock_irqrestore(&lock, flags); printk("irq:free"); } /* Pick a VCPU to run */ static struct task_slice trivial_do_schedule(s_time_t now) { //int cpu = smp_processor_id(); struct task_slice ret ; /* F i x e d −s i z e quantum */ struct vcpu *head = vcpu_list_head ; // asm volatile(BEEP); ret.time = MILLISECS(10) ; do { /* F i n d a r u n n a b l e VCPU */ increment_run_queue() ; if (vcpu_runnable (vcpu_list_head)) { ret.task = vcpu_list_head ; return ret; } } while (head != vcpu_list_head) ; /* Return the idle task if there isn’t one */ ret.task = ((struct vcpu *)(per_cpu(schedule_data,vcpus).idle)); return ret; } struct scheduler sched_trivial_def = { .name = "Trivial Round Robin Scheduler" , .opt_name = "trivial" , .sched_id = 6 , .init = trivial_init_func, .init_domain = NULL, .destroy_domain = NULL, .init_vcpu = trivial_init_vcpu , .destroy_vcpu = trivial_destroy_vcpu , .sleep = NULL, .wake = NULL, .do_schedule = trivial_do_schedule , .pick_cpu = NULL, .adjust = NULL , .dump_settings = NULL, .dump_cpu_state = NULL, .tick_suspend = NULL, .tick_resume = NULL, };