📄 program-kernel-sched-comment.html
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Author" content="Edward Fu">
<meta name="GENERATOR" content="Mozilla/4.05 [zh-CN] (X11; I; Linux 2.1.127 i686) [Netscape]">
<title>Freesoft Linux FAQ -- 内核原代码sched.c的注释</title>
</head>
<body>
/*
<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
<p>* call functions (type getpid(), which just extracts a field from
<br>* current-task
<br>*/
<br>#include <linux/sched.h>
<br>#include <linux/kernel.h>
<br>#include <signal.h>
<br>#include <linux/sys.h>
<br>#include <asm/system.h>
<br>#include <asm/io.h>
<br>#include <asm/segment.h>
<p>#define LATCH (1193180/HZ)
<p>extern void mem_use(void);
<p>extern int timer_interrupt(void);
<br>extern int system_call(void);
<p>union task_union {
<br>struct task_struct task;
<br>char stack[PAGE_SIZE];
<br>};
<p>static union task_union init_task = {INIT_TASK,};
<p>long volatile jiffies=0;
<br>long startup_time=0;
<br>struct task_struct *current = &(init_task.task), *last_task_used_math
=
<br>NULL;
<p>struct task_struct * task[NR_TASKS] = {&(init_task.task), };
<p>long user_stack [ PAGE_SIZE>>2 ] ;
<p>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>}
<p>/*
<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).
<p>* 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'
<p>* information in task[0] is never used.
<br>*/
<br>void schedule(void)
<br>{
<br>int i,next,c;
<br>struct task_struct ** p;
<p>/* check alarm, wake up any interruptible tasks that have got a signal
<br>*/
<p>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且<jiffies
<p>/* this is the 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>}
<p>int sys_pause(void)
<br>{
<br>current->state = TASK_INTERRUPTIBLE; @@任务可中断
<br>schedule();
<br>return 0;
<br>}
<p>void sleep_on(struct task_struct **p)
<br>{
<br>struct task_struct *tmp;
<p>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>}
<p>void interruptible_sleep_on(struct task_struct **p)
<br>{
<br>struct task_struct *tmp;
<p>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>}
<p>void wake_up(struct task_struct **p)
<br>{
<br>if (p && *p) {
<br> (**p).state=0; @@唤醒该进程running
<br> *p=NULL; @@睡眠栈为0
<br>}
<br>}
<p>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>}
<p>int sys_alarm(long seconds)
<br>{
<br>current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
<br>return seconds;
<br>}
<p>int sys_getpid(void)
<br>{
<br>return current->pid;
<br>}
<p>int sys_getppid(void)
<br>{
<br>return current->father;
<br>}
<p>int sys_getuid(void)
<br>{
<br>return current->uid;
<br>}
<p>int sys_geteuid(void)
<br>{
<br>return current->euid;
<br>}
<p>int sys_getgid(void)
<br>{
<br>return current->gid;
<br>}
<p>int sys_getegid(void)
<br>{
<br>return current->egid;
<br>}
<p>int sys_nice(long increment)
<br>{
<br>if (current->priority-increment>0)
<br> current->priority -= increment;
<br>return 0;
<br>}
<p>int sys_signal(long signal,long addr,long restorer)
<br>{
<br>long i;
<p>switch (signal) {
<br> case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:
<br> case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:
<br> case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:
<br> case SIGCHLD:
<br> i=(long) current->sig_fn[signal-1];
<br> current->sig_fn[signal-1] = (fn_ptr) addr;
<br> current->sig_restorer = (fn_ptr) restorer;
<br> return i;
<br> default: return -1;
<br>}
<br>}
<p>void sched_init(void)
<br>{
<br>int i;
<br>struct desc_struct * p;
<p>set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));@@init task
tss
<p>set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));@@init ldt
<br>p = gdt+2+FIRST_TSS_ENTRY;
<br>for(i=1;i<NR_TASKS;i++) {
<br> task[i] = NULL;
<br> p->a=p->b=0;
<br> p++;
<br> p->a=p->b=0;
<br> p++;
<br>}
<br>ltr(0); @@调入task 0的tss
<br>lldt(0); @@调入task 0的ldt
<br>outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */
<br>outb_p(LATCH & 0xff , 0x40); /* LSB */
<br>outb(LATCH >> 8 , 0x40); /* MSB */
<br>set_intr_gate(0x20,&timer_interrupt); @@irq 0 时钟中断
<br>outb(inb_p(0x21)&~0x01,0x21);
<br>set_system_gate(0x80,&system_call);
<br>}
<br>
<br>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -