/*
* linux/mykernel/myinterrupt.c
*
* Kernel internal my_timer_handler
*
*/
/*
* Headers are omitted.
*/
#define CREATE_TRACE_POINTS
#include
#include"mypcb.h"
#define SLICING 1000
extern tPCB task[MAX_TASK_NUM];
extern tPCB *my_current_task;
extern volatile int my_need_schedule;
volatile int time_count =0;
/*
* 每发生一次时间中断,就会调用一次my_timer_handler函数。
* 需要注意的是,对于不同的进程,time_count和my_need_schedule变量是不同的实例。
*/
void my_timer_handler(void)
{
if(time_count % SLICING == 0 && my_need_schedule != TRUE){
printk(KERN_NOTICE ">>>>>>>>>>>>>>>>>my_timer_handlerhere<<<<<<<<<<<<<<<<<<
");
my_need_schedule = TRUE;
}
time_count ++;
return;
}
void my_schedule(void){
tPCB *next;
tPCB *prev;
if(my_current_task == NULL
|| my_current_task->next == NULL){
printk(KERN_ERR "Error occurs in my_schedule!");
return;
}
printk(KERN_NOTICE ">>>>>>>>>>>>>>>>>my_schedule<<<<<<<<<<<<<<<<<<
");
next = my_current_task->next;
prev = my_current_task;
if(next->state == RUNNABLE){
/* switch to next process */
asm volatile(
"pushl %%ebp
" /* save prev process’s ebp */
"movl %%esp,%0
" /* save prev process’s esp */
"movl %2,%%esp
" /* restore next process's ebp */
"movl $start,%1
" /* save eip, $start就是指标号start:的代码在内存中存储的地址*/
"pushl %3
"
"ret
" /* restore next process's eip */
"start:
" /* next process starts here */
"popl %%ebp
" /* restore next process's ebp */
:"=m"(prev->thread.sp),"=m"(prev->thread.ip)
:"m"(next->thread.sp),"m"(next->thread.ip)
);
my_current_task = next;
printk(KERN_NOTICE ">>>>>> switch from process %d toprocess %d <<<<<<
",
prev->pid, next->pid);
}else{
next->state = RUNNABLE;
my_current_task= next;
printk(KERN_NOTICE ">>>>>> switch from process %d toprocess %d <<<<<<
",
prev->pid, next->pid);
/* switch to next process */
asm volatile(
"pushl %%ebp
" /* save prev process’s ebp */
"movl %%esp,%0
" /* save prev process’s esp */
"movl %2,%%esp
" /* restore next process's sp to esp */
"movl %2,%%ebp
"
/* restore next process's sp to ebp
* because the process has never run before
* hence, bp equals to sp
*/
"movl $start,%1
" /* save eip */
"pushl %3
" /* restore next process's eip, here eip->my_process */
"ret
"
:"=m"(prev->thread.sp),"=m"(prev->thread.ip)
:"m"(next->thread.sp),"m"(next->thread.ip)
);
}
}