#include <list.h>
|
|
#include <sync.h>
|
|
#include <proc.h>
|
|
#include <sched.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <default_sched.h>
|
|
|
|
// the list of timer
|
|
static list_entry_t timer_list;
|
|
|
|
static struct sched_class *sched_class;
|
|
|
|
static struct run_queue *rq;
|
|
|
|
static inline void
|
|
sched_class_enqueue(struct proc_struct *proc) {
|
|
if (proc != idleproc) {
|
|
sched_class->enqueue(rq, proc);
|
|
}
|
|
}
|
|
|
|
static inline void
|
|
sched_class_dequeue(struct proc_struct *proc) {
|
|
sched_class->dequeue(rq, proc);
|
|
}
|
|
|
|
static inline struct proc_struct *
|
|
sched_class_pick_next(void) {
|
|
return sched_class->pick_next(rq);
|
|
}
|
|
|
|
static void
|
|
sched_class_proc_tick(struct proc_struct *proc) {
|
|
if (proc != idleproc) {
|
|
sched_class->proc_tick(rq, proc);
|
|
}
|
|
else {
|
|
proc->need_resched = 1;
|
|
}
|
|
}
|
|
|
|
static struct run_queue __rq;
|
|
|
|
void
|
|
sched_init(void) {
|
|
list_init(&timer_list);
|
|
|
|
sched_class = &default_sched_class;
|
|
|
|
rq = &__rq;
|
|
rq->max_time_slice = MAX_TIME_SLICE;
|
|
sched_class->init(rq);
|
|
|
|
cprintf("sched class: %s\n", sched_class->name);
|
|
}
|
|
|
|
void
|
|
wakeup_proc(struct proc_struct *proc) {
|
|
assert(proc->state != PROC_ZOMBIE);
|
|
bool intr_flag;
|
|
local_intr_save(intr_flag);
|
|
{
|
|
if (proc->state != PROC_RUNNABLE) {
|
|
proc->state = PROC_RUNNABLE;
|
|
proc->wait_state = 0;
|
|
if (proc != current) {
|
|
sched_class_enqueue(proc);
|
|
}
|
|
}
|
|
else {
|
|
warn("wakeup runnable process.\n");
|
|
}
|
|
}
|
|
local_intr_restore(intr_flag);
|
|
}
|
|
|
|
void
|
|
schedule(void) {
|
|
bool intr_flag;
|
|
struct proc_struct *next;
|
|
local_intr_save(intr_flag);
|
|
{
|
|
current->need_resched = 0;
|
|
if (current->state == PROC_RUNNABLE) {
|
|
sched_class_enqueue(current);
|
|
}
|
|
if ((next = sched_class_pick_next()) != NULL) {
|
|
sched_class_dequeue(next);
|
|
}
|
|
if (next == NULL) {
|
|
next = idleproc;
|
|
}
|
|
next->runs ++;
|
|
if (next != current) {
|
|
proc_run(next);
|
|
}
|
|
}
|
|
local_intr_restore(intr_flag);
|
|
}
|
|
|