📄 4.html
字号:
<center><A HREF="#Content">[目录]</A></center>
<hr><br><A NAME="I409" ID="I409"></A><center><b><font size=+2>sched.c</font></b></center><br>
|schedule<br>
|do_softirq // manages post-IRQ work<br>
|for each task<br>
|calculate counter<br>
|prepare_to__switch // does anything<br>
|switch_mm // change Memory context (change CR3 value)<br>
|switch_to (assembler)<br>
|SAVE ESP<br>
|RESTORE future_ESP<br>
|SAVE EIP<br>
|push future_EIP *** push parameter as we did a call<br>
|jmp __switch_to (it does some TSS work)<br>
|__switch_to()<br>
..<br>
|ret *** ret from call using future_EIP in place of call address<br>
new_task<p>
<br>
/*<br>
* 'sched.c' is the main kernel file. It contains scheduling primitives<br>
* (sleep_on, wakeup, schedule etc) as well as a number of simple system<br>
* call functions (type getpid(), which just extracts a field from<br>
* current-task<br>
*/<br>
#include<br>
#include<br>
#include<br>
#include<br>
#include<br>
#include<br>
#include<br>
#define LATCH (1193180/HZ)<br>
extern void mem_use(void);<br>
extern int timer_interrupt(void);<br>
extern int system_call(void);<br>
union task_union {<br>
struct task_struct task;<br>
char stack[PAGE_SIZE];<br>
};<br>
static union task_union init_task = {INIT_TASK,};<br>
long volatile jiffies=0;<br>
long startup_time=0;<br>
struct task_struct *current = &(init_task.task), *last_task_used_math =<br>
NULL;<br>
struct task_struct * task[NR_TASKS] = {&(init_task.task), };<br>
long user_stack [ PAGE_SIZE>>2 ] ;<br>
struct {<br>
long * a;<br>
short b;<br>
} stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };<br>
/*<br>
* 'math_state_restore()' saves the current math information in the<br>
* old math state array, and gets the new ones from the current task<br>
*/<br>
void math_state_restore() @@协处理器状态保存<br>
{<br>
if (last_task_used_math)<br>
__asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));<br>
if (current->used_math)<br>
__asm__("frstor %0"::"m" (current->tss.i387));<br>
else {<br>
__asm__("fninit"::);<br>
current->used_math=1;<br>
}<br>
last_task_used_math=current;<br>
}<br>
/*<br>
* 'schedule()' is the scheduler function. This is GOOD CODE! There<br>
* probably won't be any reason to change this, as it should work well<br>
* in all circumstances (ie gives IO-bound processes good response etc).<br>
* The one thing you might take a look at is the signal-handler code<br>
here.<br>
*<br>
* NOTE!! Task 0 is the 'idle' task, which gets called when no other<br>
* tasks can run. It can not be killed, and it cannot sleep. The 'state'<br>
* information in task[0] is never used.<br>
*/<br>
void schedule(void)<br>
{<br>
int i,next,c;<br>
struct task_struct ** p;<br>
/* check alarm, wake up any interruptible tasks that have got a signal<br>
*/<br>
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)<br>
if (*p) {<br>
if ((*p)->alarm && (*p)->alarm < jiffies) {<br>
@@??<br>
(*p)->signal |= (1<<(SIGALRM-1));@@14-1<br>
(*p)->alarm = 0;<br>
}<br>
if ((*p)->signal && (*p)->state==TASK_INTERRUPTIBLE)<br>
(*p)->state=TASK_RUNNING;<br>
}<br>
@@ task 1 如何变为TASK_RUNNING??signal 如何得到,alarm如何变非0且 /* this is the<br>
scheduler proper: */<br>
@@操作系统最重要的函数,调度算法<br>
@@这个循环要找到一个可运行的任务才能退出,会死在这吗?即如没有一个可运行<br>
while (1) {<br>
c = -1;<br>
next = 0;<br>
i = NR_TASKS;<br>
p = &task[NR_TASKS];<br>
while (--i) {<br>
if (!*--p)<br>
continue;<br>
if ((*p)->state == TASK_RUNNING && (*p)->counter > c)<br>
c = (*p)->counter, next = i;<br>
}<br>
if (c) break; @@记数大于零<br>
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)<br>
if (*p)<br>
(*p)->counter = ((*p)->counter >> 1) +<br>
(*p)->priority;<br>
}<br>
switch_to(next);<br>
}<br>
int sys_pause(void)<br>
{<br>
current->state = TASK_INTERRUPTIBLE; @@任务可中断<br>
schedule();<br>
return 0;<br>
}<br>
void sleep_on(struct task_struct **p)<br>
{<br>
struct task_struct *tmp;<br>
if (!p)<br>
return;<br>
if (current == &(init_task.task))<br>
panic("task[0] trying to sleep");<br>
tmp = *p;<br>
*p = current;<br>
current->state = TASK_UNINTERRUPTIBLE;<br>
schedule();<br>
if (tmp) @@激活p,什么时候回来?唤醒上次睡眠的进程<br>
tmp->state=0;<br>
}<br>
void interruptible_sleep_on(struct task_struct **p)<br>
{<br>
struct task_struct *tmp;<br>
if (!p)<br>
return;<br>
if (current == &(init_task.task))<br>
panic("task[0] trying to sleep");<br>
tmp=*p;<br>
*p=current;<br>
repeat: current->state = TASK_INTERRUPTIBLE;<br>
schedule();<br>
if (*p && *p != current) {<br>
(**p).state=0;<br>
goto repeat;<br>
}<br>
@@好象下不来<br>
*p=NULL;<br>
if (tmp)<br>
tmp->state=0;<br>
}<br>
void wake_up(struct task_struct **p)<br>
{<br>
if (p && *p) {<br>
(**p).state=0; @@唤醒该进程running<br>
*p=NULL; @@睡眠栈为0<br>
}<br>
}<br>
void do_timer(long cpl) @@定时调度<br>
{<br>
if (cpl)<br>
current->utime++; @@用户态时间加一<br>
else<br>
current->stime++; @@系统态时间加一<br>
if ((--current->counter)>0) return; @@当前记数减一<br>
current->counter=0;<br>
if (!cpl) return;<br>
schedule();<br>
}<br>
int sys_alarm(long seconds)<br>
{<br>
current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;<br>
return seconds;<br>
}<br>
int sys_getpid(void)<br>
{<br>
return current->pid;<br>
}<br>
int sys_getppid(void)<br>
{<br>
return current->father;<br>
}<br>
int sys_getuid(void)<br>
{<br>
return current->uid;<br>
}<br>
int sys_geteuid(void)<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -