⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 program-kernel-sched-comment.html

📁 学习linux的工具书
💻 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 &lt;linux/sched.h>
<br>#include &lt;linux/kernel.h>
<br>#include &lt;signal.h>
<br>#include &lt;linux/sys.h>
<br>#include &lt;asm/system.h>
<br>#include &lt;asm/io.h>
<br>#include &lt;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 = &amp;(init_task.task), *last_task_used_math
=
<br>NULL;
<p>struct task_struct * task[NR_TASKS] = {&amp;(init_task.task), };
<p>long user_stack [ PAGE_SIZE>>2 ] ;
<p>struct {
<br>long * a;
<br>short b;
<br>} stack_start = { &amp; user_stack [PAGE_SIZE>>2] , 0x10 };
<br>/*
<br>*&nbsp; '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()&nbsp;&nbsp;&nbsp; @@协处理器状态保存
<br>{
<br>if (last_task_used_math)
<br>&nbsp; __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));
<br>if (current->used_math)
<br>&nbsp; __asm__("frstor %0"::"m" (current->tss.i387));
<br>else {
<br>&nbsp; __asm__("fninit"::);
<br>&nbsp; current->used_math=1;
<br>}
<br>last_task_used_math=current;
<br>}
<p>/*
<br>*&nbsp; '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>*&nbsp;&nbsp; NOTE!!&nbsp; 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 = &amp;LAST_TASK ; p > &amp;FIRST_TASK ; --p)
<br>&nbsp; if (*p) {
<br>&nbsp;&nbsp; if ((*p)->alarm &amp;&amp; (*p)->alarm &lt; jiffies) {
<br>@@??
<br>&nbsp;&nbsp;&nbsp;&nbsp; (*p)->signal |= (1&lt;&lt;(SIGALRM-1));@@14-1
<br>&nbsp;&nbsp;&nbsp;&nbsp; (*p)->alarm = 0;
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp; if ((*p)->signal &amp;&amp; (*p)->state==TASK_INTERRUPTIBLE)
<br>&nbsp;&nbsp;&nbsp; (*p)->state=TASK_RUNNING;
<br>&nbsp; }
<br>@@ task 1 如何变为TASK_RUNNING??signal 如何得到,alarm如何变非0且&lt;jiffies
<p>/* this is the scheduler proper: */
<br>@@操作系统最重要的函数,调度算法
<br>@@这个循环要找到一个可运行的任务才能退出,会死在这吗?即如没有一个可运行
<br>while (1) {
<br>&nbsp; c = -1;
<br>&nbsp; next = 0;
<br>&nbsp; i = NR_TASKS;
<br>&nbsp; p = &amp;task[NR_TASKS];
<br>&nbsp; while (--i) {
<br>&nbsp;&nbsp; if (!*--p)
<br>&nbsp;&nbsp;&nbsp; continue;
<br>&nbsp;&nbsp; if ((*p)->state == TASK_RUNNING &amp;&amp; (*p)->counter
> c)
<br>&nbsp;&nbsp;&nbsp; c = (*p)->counter, next = i;
<br>&nbsp; }
<br>&nbsp; if (c) break;&nbsp;&nbsp; @@记数大于零
<br>&nbsp; for(p = &amp;LAST_TASK ; p > &amp;FIRST_TASK ; --p)
<br>&nbsp;&nbsp; if (*p)
<br>&nbsp;&nbsp;&nbsp; (*p)->counter = ((*p)->counter >> 1) +
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*p)->priority;
<br>}
<br>switch_to(next);
<br>}
<p>int sys_pause(void)
<br>{
<br>current->state = TASK_INTERRUPTIBLE;&nbsp; @@任务可中断
<br>schedule();
<br>return 0;
<br>}
<p>void sleep_on(struct task_struct **p)
<br>{
<br>struct task_struct *tmp;
<p>if (!p)
<br>&nbsp; return;
<br>if (current == &amp;(init_task.task))
<br>&nbsp; panic("task[0] trying to sleep");
<br>tmp = *p;
<br>*p = current;
<br>current->state = TASK_UNINTERRUPTIBLE;
<br>schedule();
<br>if (tmp)&nbsp;&nbsp;&nbsp; @@激活p,什么时候回来?唤醒上次睡眠的进程
<br>&nbsp; tmp->state=0;
<br>}
<p>void interruptible_sleep_on(struct task_struct **p)
<br>{
<br>struct task_struct *tmp;
<p>if (!p)
<br>&nbsp; return;
<br>if (current == &amp;(init_task.task))
<br>&nbsp; panic("task[0] trying to sleep");
<br>tmp=*p;
<br>*p=current;
<br>repeat: current->state = TASK_INTERRUPTIBLE;
<br>schedule();
<br>if (*p &amp;&amp; *p != current) {
<br>&nbsp; (**p).state=0;
<br>&nbsp; goto repeat;
<br>}
<br>&nbsp;&nbsp; @@好象下不来
<br>*p=NULL;
<br>if (tmp)
<br>&nbsp; tmp->state=0;
<br>}
<p>void wake_up(struct task_struct **p)
<br>{
<br>if (p &amp;&amp; *p) {
<br>&nbsp; (**p).state=0;&nbsp; @@唤醒该进程running
<br>&nbsp; *p=NULL;&nbsp; @@睡眠栈为0
<br>}
<br>}
<p>void do_timer(long cpl)&nbsp; @@定时调度
<br>{
<br>if (cpl)
<br>&nbsp; current->utime++;&nbsp; @@用户态时间加一
<br>else
<br>&nbsp; current->stime++;&nbsp; @@系统态时间加一
<br>if ((--current->counter)>0) return;&nbsp; @@当前记数减一
<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>&nbsp; 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>&nbsp; case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:
<br>&nbsp; case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:
<br>&nbsp; case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:
<br>&nbsp; case SIGCHLD:
<br>&nbsp;&nbsp; i=(long) current->sig_fn[signal-1];
<br>&nbsp;&nbsp; current->sig_fn[signal-1] = (fn_ptr) addr;
<br>&nbsp;&nbsp; current->sig_restorer = (fn_ptr) restorer;
<br>&nbsp;&nbsp; return i;
<br>&nbsp; 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,&amp;(init_task.task.tss));@@init task
tss
<p>set_ldt_desc(gdt+FIRST_LDT_ENTRY,&amp;(init_task.task.ldt));@@init ldt
<br>p = gdt+2+FIRST_TSS_ENTRY;
<br>for(i=1;i&lt;NR_TASKS;i++) {
<br>&nbsp; task[i] = NULL;
<br>&nbsp; p->a=p->b=0;
<br>&nbsp; p++;
<br>&nbsp; p->a=p->b=0;
<br>&nbsp; p++;
<br>}
<br>ltr(0);&nbsp;&nbsp; @@调入task 0的tss
<br>lldt(0);&nbsp; @@调入task 0的ldt
<br>outb_p(0x36,0x43);&nbsp; /* binary, mode 3, LSB/MSB, ch 0 */
<br>outb_p(LATCH &amp; 0xff , 0x40); /* LSB */
<br>outb(LATCH >> 8 , 0x40); /* MSB */
<br>set_intr_gate(0x20,&amp;timer_interrupt); @@irq 0 时钟中断
<br>outb(inb_p(0x21)&amp;~0x01,0x21);
<br>set_system_gate(0x80,&amp;system_call);
<br>}
<br>&nbsp;
<br>&nbsp;
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -