实现任务调度,模拟时间片
1.任务调度
在进行上下文切换时,需要保存和切换以下内容:
- 寄存器:包括通用寄存器(如 EAX、EBX、ECX等)和特殊寄存器(如程序计数器 PC、堆栈指针 SP、基址指针 BP等)。这些寄存器保存了当前进程的执行状态和上下文信息,需要在切换进程时保存当前进程的寄存器值,并恢复下一个进程的寄存器值。
- 堆栈:进程的堆栈空间用于保存局部变量、函数调用信息、返回地址等。在进行上下文切换时,需要保存当前进程的堆栈内容,并切换到下一个进程的堆栈。
- 程序计数器(PC):用于指示当前进程执行的下一条指令的地址。在进行上下文切换时,需要保存当前进程的 PC 值,并将切换到下一个进程的 PC 值设置为相应的地址,以便从正确的地方继续执行。
- 文件描述符和其他系统资源:如果进程打开了文件、套接字或其他系统资源,需要在上下文切换时保存和恢复这些资源的状态,以确保进程切换后能够正常访问它们。
- 其他进程相关的信息:如进程的优先级、状态等也可能需要在上下文切换时保存和恢复。

 构建结构体:
struct tss_struct {
    u32	back_link;	/* 16 high bits zero */ 
    u32	esp0;
    u32	ss0;		/* 16 high bits zero */
    u32	esp1;
    u32	ss1;		/* 16 high bits zero */
    u32	esp2;
    u32	ss2;		/* 16 high bits zero */
    u32	cr3;
    u32	eip;
    u32	eflags;
    u32	eax;
    u32 ecx;
    u32 edx;
    u32 ebx;
    u32	esp;
    u32	ebp;
    u32	esi;
    u32	edi;
    u32	es;		/* 16 high bits zero */
    u32	cs;		/* 16 high bits zero */
    u32	ss;		/* 16 high bits zero */
    u32	ds;		/* 16 high bits zero */
    u32	fs;		/* 16 high bits zero */
    u32	gs;		/* 16 high bits zero */
    u32	ldt;		/* 16 high bits zero */
    u32	trace_bitmap;	/* bits: trace 0, bitmap 16-31 */
};
typedef struct task_struct{
    u32 pid;
    u32 ppid;
    task_func func;
    task_status status;
    ///* tss for this task */
    struct tss_struct tss;
}
保存与恢复图示:
 
2.时间片调度
使用大堆构建优先级队列:
heap*  TASK_QUEUE;
int compare_task_priority(int** item, int i, int j) {
    if ( ((task_struct*)(item[i]))->cycles ==((task_struct*)(item[j]))->cycles)
        return ((task_struct*)(item[i]))->counter > ((task_struct*)(item[j]))->counter;
    return ((task_struct*)(item[i]))->cycles < ((task_struct*)(item[j]))->cycles;
}
void init_task_queue(){
    TASK_QUEUE->len = 0;
    TASK_QUEUE->less = compare_task_priority;
    TASK_QUEUE->item = malloc(NR_TASKS);
    Init(TASK_QUEUE);
}
调度策略如图:
 
task_struct*  get_ready_task(){
    task_struct *next = top_task();
    if (next == NULL)return NULL;
    if(next->end ==1){
        remove_task(0);
        return  get_ready_task();
    }
    if(next->counter >0) next->counter--;
    if(next->counter ==0){
        next->counter = next->priority;
        next->cycles++;
    }
    fix_task(0);
    if(next->status == TASK_SLEEPING){
        return  get_ready_task();
    }
    return next;
}
3.验证
保存与恢复验证:
eax            0x101000            1052672
ecx            0x1000              4096
edx            0x101000            1052672
ebx            0x28                40
esp            0x9fbe4             0x9fbe4
ebp            0x9fbf8             0x9fbf8
esi            0x675               1653
edi            0x7000              28672
eip            0x3399              0x3399 <clock_handler_entry>
eflags         0x2                 [ ]
cs             0x8                 8
ss             0x10                16
ds             0x10                16
es             0x10                16
fs             0x10                16

 
 多优先级任务调度:



















