d9a83bd7be
The original time slice (200ms) is too large for the priority test to generate a satisfactory result in 20s. If we only schedule 5 times a second, there are only 100 pick_next calls to the scheduler. I believe making scheduling more frequently does little harm to the system. Actually more scheduling opportunities may also reveal bugs which are not triggered previously. Adopting smaller time slices also allows us to reduce the time spent on the priority test, which can benefit the autotesting system. Signed-off-by: Junjie Mao <junjie.mao@hotmail.com>
74 lines
2.4 KiB
C
74 lines
2.4 KiB
C
#ifndef __KERN_SCHEDULE_SCHED_H__
|
|
#define __KERN_SCHEDULE_SCHED_H__
|
|
|
|
#include <defs.h>
|
|
#include <list.h>
|
|
#include <skew_heap.h>
|
|
|
|
#define MAX_TIME_SLICE 5
|
|
|
|
struct proc_struct;
|
|
|
|
typedef struct {
|
|
unsigned int expires; //the expire time
|
|
struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
|
|
list_entry_t timer_link; //the timer list
|
|
} timer_t;
|
|
|
|
#define le2timer(le, member) \
|
|
to_struct((le), timer_t, member)
|
|
|
|
// init a timer
|
|
static inline timer_t *
|
|
timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
|
|
timer->expires = expires;
|
|
timer->proc = proc;
|
|
list_init(&(timer->timer_link));
|
|
return timer;
|
|
}
|
|
|
|
struct run_queue;
|
|
|
|
// The introduction of scheduling classes is borrrowed from Linux, and makes the
|
|
// core scheduler quite extensible. These classes (the scheduler modules) encapsulate
|
|
// the scheduling policies.
|
|
struct sched_class {
|
|
// the name of sched_class
|
|
const char *name;
|
|
// Init the run queue
|
|
void (*init)(struct run_queue *rq);
|
|
// put the proc into runqueue, and this function must be called with rq_lock
|
|
void (*enqueue)(struct run_queue *rq, struct proc_struct *proc);
|
|
// get the proc out runqueue, and this function must be called with rq_lock
|
|
void (*dequeue)(struct run_queue *rq, struct proc_struct *proc);
|
|
// choose the next runnable task
|
|
struct proc_struct *(*pick_next)(struct run_queue *rq);
|
|
// dealer of the time-tick
|
|
void (*proc_tick)(struct run_queue *rq, struct proc_struct *proc);
|
|
/* for SMP support in the future
|
|
* load_balance
|
|
* void (*load_balance)(struct rq* rq);
|
|
* get some proc from this rq, used in load_balance,
|
|
* return value is the num of gotten proc
|
|
* int (*get_proc)(struct rq* rq, struct proc* procs_moved[]);
|
|
*/
|
|
};
|
|
|
|
struct run_queue {
|
|
list_entry_t run_list;
|
|
unsigned int proc_num;
|
|
int max_time_slice;
|
|
// For LAB6 ONLY
|
|
skew_heap_entry_t *lab6_run_pool;
|
|
};
|
|
|
|
void sched_init(void);
|
|
void wakeup_proc(struct proc_struct *proc);
|
|
void schedule(void);
|
|
void add_timer(timer_t *timer); // add timer to timer_list
|
|
void del_timer(timer_t *timer); // del timer from timer_list
|
|
void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
|
|
|
|
#endif /* !__KERN_SCHEDULE_SCHED_H__ */
|
|
|