实现任务调度,模拟时间片
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
多优先级任务调度: