📄 scheduler.h
字号:
/*文件名: scheduler.h 说明: 进程调度程序 作者: marsinfan 日期: 2005/12/20*/#ifndef scheduler_h#define scheduler_h#include <fairysky/types.h>#include <fairysky/list.h>#include <fairysky/limits.h>#include <fairysky/fs.h>#include <fairysky/signal.h>#include <asm/memory.h>//进程状态#define TASK_RUNNING 1 //可运行#define TASK_INTERRUPTIBLE 2 //可中断睡眠#define TASK_UNINTERRUPTIBLE 4 //不可中断睡眠#define TASK_ZOMBIE 8 //僵死#define TASK_STOPPED 16 //停止#define task0_page_dir 0x00010000/* TSS 结构描述 */typedef struct{ /* TSS for 386+ */ u32 link; u32 esp0; u32 ss0; u32 esp1; u32 ss1; u32 esp2; u32 ss2; u32 cr3; u32 eip; u32 eflags; u32 eax; u32 ecx; u32 edx; u32 ebx; u32 esp; u32 ebp; u32 esi; u32 edi; u32 es; u32 cs; u32 ss; u32 ds; u32 fs; u32 gs; u32 ldtr; u16 trace; u16 io_map_addr;} __attribute__((packed)) tss_struct;typedef struct task_struct{ struct list_head list; /* these are hardcoded - don't touch */ s32 state; //进程状态 s32 counter; //运行时间片 s32 priority; //优先级 s32 signal; //信号,按位 struct sigaction sigaction[NSIG]; //信号执行的函数 s32 signal_blocked; //被掩码的信号,位图 //很多不通类型的信息 s32 exit_code; //进程退出码 //int dumpable:1; //int swappable:1; u32 start_code, //代码开始处 end_code, //代码结束处 end_data, //总长度(代码结束处+数据段长度) brk, start_stack; //堆栈开始的处 pid_t pid; //进程的pid s32 pgrp; //组id s32 session; s32 leader; //int groups[NGROUPS]; struct task_struct *p_original_parent; //原始的父进程 struct task_struct *p_parent; //父进程 struct task_struct *p_child; //记录最近创建的子进程(如果要知道所有的子进程,需要遍历进程列表) struct task_struct *p_younger_sibling; //记录最近创建的弟进程 struct task_struct *p_older_sibling; //兄进程 s32 alarm; /* * For ease of programming... Normal sleeps don't need to * keep track of a wait-queue: every task has an entry of it's own */ //struct wait_queue wait; uid_t uid; //用户id uid_t euid; //有效用户id uid_t suid; //保存的用户id,好像没有用啊 gid_t gid; //组id gid_t egid; //有效组id gid_t sgid; //保存的组id //u32 timeout; //u32 it_real_value, it_prof_value, it_virt_value; //u32 it_real_incr, it_prof_incr, it_virt_incr; s32 user_time, //用户态运行时间(滴答数) system_time, //内核态运行时间(滴答数) //cutime, //子进程用户态运行时间(滴答数),好像没有用啊 //cstime, //子进程内核态运行时间(滴答数),好像没有用啊 start_time; //进程开始的时间 //u32 min_flt, maj_flt; //u32 cmin_flt, cmaj_flt; //struct rlimit rlim[RLIM_NLIMITS]; //u32 flags; /* per process flags, defined below */ u16 rss; //常驻内存的页面数,暂时不用 //char comm[8]; //文件系统信息 //int link_count; s32 tty; /* -1 if no tty, so it must be signed */ u16 umask; //文件创建属性屏蔽位 struct inode *pwd; //当前工作目录i节点 struct inode *root; //根目录i节点 struct inode *executable; //执行文件i节点 struct file *file_pointer[NR_OPEN]; //进程使用的文件表结构 u32 close_on_exec; /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ //struct desc_struct ldt[3]; /* tss for this task */ tss_struct tss; u32 original_esp0; //这个暂时加上,用于记录内核堆栈的启始处} __attribute__((packed)) task_struct_t;#endiftypedef union{ task_struct_t task; char stack[PAGE_SIZE];} __attribute__((packed)) stack_struct;/*#define switch_to(prev, next, last) do {\__asm__ __volatile__ ( \ "pushl %%esi\n\t" \ "pushl %%edi\n\t" \ "pushl %%ebp\n\t" \ "movl %%esp, %0\n\t" \ 把当前进程的esp保存到自己pcb中 "movl %3, %%esp\n\t" \ 把待调度的进程pcb中esp写到寄存器esp,这样进程的堆栈指针已经切换 "movl $1f, %1\n\t" \ 再把当前进程下次被调度运行的eip保存到自己pcb中(下次运行从"1:\t"开始 ) "pushl %4\n\t" \ 这里够成了一个call调用,把待调度进程上次保存的eip("m" (next->tss.eip))压栈 "jmp __switch_to\n" \ 然后跳转到__switch_to函数中,当执行到函数__switch_to中的ret指令时,就形成了进程的切换(看上条指令) "1:\t" \ "popl %%ebp\n\t" \ "popl %%edi\n\t" \ "popl %%esi\n\t" \ :"=m" (prev->tss.esp0), "=m" (prev->tss.eip), \ "=b" (last) \ :"m" (next->tss.esp0), "m" (next->tss.eip), \ "a" (prev), "d" (next), "b" (prev) \ ); \} while (0)*//*#define switch_to(prev, next, last) do {\__asm__ __volatile__ ( \ "pushl %%esi\n\t" \ "pushl %%edi\n\t" \ "pushl %%ebp\n\t" \ "movl %%esp, %0\n\t" \ "movl %3, %%esp\n\t" \ "movl $1f, %1\n\t" \ "pushl %4\n\t" \ "jmp __switch_to\n" \ "1:\t" \ "popl %%ebp\n\t" \ "popl %%edi\n\t" \ "popl %%esi\n\t" \ :"=m" (prev->tss.esp0), "=m" (prev->tss.eip), \ "=b" (last) \ :"m" (next->tss.esp0), "m" (next->tss.eip), \ "a" (prev), "d" (next), "b" (prev) \ ); \} while (0)*/#define switch_to(prev, next, last) do {\__asm__ __volatile__ ( \ "pushl %%esi\n\t" \ "pushl %%edi\n\t" \ "pushl %%ebp\n\t" \ "movl %%esp, %0\n\t" \ "movl %3, %%esp\n\t" \ "movl $1f, %1\n\t" \ "pushl %4\n\t" \ "jmp __switch_to\n" \ "1:\t" \ "popl %%ebp\n\t" \ "popl %%edi\n\t" \ "popl %%esi\n\t" \ :"=m" (prev->tss.esp0), "=m" (prev->tss.eip), \ "=b" (last) \ :"m" (next->tss.esp0), "m" (next->tss.eip), \ "a" (prev), "d" (next), "b" (prev) \ ); \} while (0)typedef void (*dotimefun_ptr)(s32 handle);//定时器的结构描述typedef struct{ struct list_head list; s32 timer; dotimefun_ptr timer_dirver; u32 handle;} timer_struct;extern task_struct_t *current;extern task_struct_t *pinit_task; //可调度的进程队列,第一个就是进程0extern task_struct_t *sleep_task;extern u32 jiffies;extern int need_resched;extern void scheduler();extern void wake_up(task_struct_t *task);extern void add_run_queue(task_struct_t *task);extern void remove_run_queue(task_struct_t *task);extern void move_run_to_wait(task_struct_t *task);extern void move_wait_to_run(task_struct_t *task);extern void add_wait_queue(task_struct_t *task);extern void remove_wait_queue(task_struct_t *task);extern void spring_timer();#define CURRENT_TIME 0//(startup_time + (jiffies+jiffies_offset) / HZ)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -