74.html

来自「linux 0.11中文版 有注释」· HTML 代码 · 共 632 行 · 第 1/4 页

HTML
632
字号
<html>
<head>
<title>kernel/sched.c</title>
<meta name='robots' content='noindex,nofollow'>
<meta name='generator' content='GLOBAL-5.4.1'>
</head>
<body text='#191970' bgcolor='#f5f5dc' vlink='gray'>
<a name='TOP'><h2><a href='../mains.html'>root</a>/<a href='../files/104.html'>kernel</a>/sched.c</h2>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L36'>[^]</a><a href='#L547'>[v]</a>[top]<a href='#BOTTOM'>[bottom]</a><a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
<hr>
<h2>DEFINITIONS</h2>
This source file includes following definitions.
<ol>
<li><a href='#L36' title='Defined at 36.'>show_task</a>
<li><a href='#L49' title='Defined at 49.'>show_stat</a>
<li><a href='#L106' title='Defined at 106.'>math_state_restore</a>
<li><a href='#L146' title='Defined at 146.'>schedule</a>
<li><a href='#L208' title='Defined at 208.'>sys_pause</a>
<li><a href='#L219' title='Defined at 219.'>sleep_on</a>
<li><a href='#L242' title='Defined at 242.'>interruptible_sleep_on</a>
<li><a href='#L272' title='Defined at 272.'>wake_up</a>
<li><a href='#L298' title='Defined at 298.'>ticks_to_floppy_on</a>
<li><a href='#L332' title='Defined at 332.'>floppy_on</a>
<li><a href='#L342' title='Defined at 342.'>floppy_off</a>
<li><a href='#L351' title='Defined at 351.'>do_floppy_timer</a>
<li><a href='#L389' title='Defined at 389.'>add_timer</a>
<li><a href='#L436' title='Defined at 436.'>do_timer</a>
<li><a href='#L483' title='Defined at 483.'>sys_alarm</a>
<li><a href='#L495' title='Defined at 495.'>sys_getpid</a>
<li><a href='#L502' title='Defined at 502.'>sys_getppid</a>
<li><a href='#L509' title='Defined at 509.'>sys_getuid</a>
<li><a href='#L516' title='Defined at 516.'>sys_geteuid</a>
<li><a href='#L523' title='Defined at 523.'>sys_getgid</a>
<li><a href='#L530' title='Defined at 530.'>sys_getegid</a>
<li><a href='#L538' title='Defined at 538.'>sys_nice</a>
<li><a href='#L547' title='Defined at 547.'>sched_init</a>
</ol>
<hr>
<pre>
<a name='L1'><i><font color='green'>/*</font></i>
<a name='L2'><i><font color='green'> * linux/kernel/sched.c</font></i>
<a name='L3'><i><font color='green'> *</font></i>
<a name='L4'><i><font color='green'> * (C) 1991 Linus Torvalds</font></i>
<a name='L5'><i><font color='green'> */</font></i>
<a name='L6'>
<a name='L7'><i><font color='green'>/*</font></i>
<a name='L8'><i><font color='green'> * 'sched.c' is the main kernel file. It contains scheduling primitives</font></i>
<a name='L9'><i><font color='green'> * (sleep_on, wakeup, schedule etc) as well as a number of simple system</font></i>
<a name='L10'><i><font color='green'> * call functions (type getpid(), which just extracts a field from</font></i>
<a name='L11'><i><font color='green'> * current-task</font></i>
<a name='L12'><i><font color='green'> */</font></i>
<a name='L13'><i><font color='green'>/*</font></i>
<a name='L14'><i><font color='green'> * 'sched.c'是主要的内核文件。其中包括有关调度的基本函数(sleep_on、wakeup、schedule 等)以及</font></i>
<a name='L15'><i><font color='green'> * 一些简单的系统调用函数(比如getpid(),仅从当前任务中获取一个字段)。</font></i>
<a name='L16'><i><font color='green'> */</font></i>
<a name='L17'><font color='darkred'>#include</font> &lt;<a href='36.html'>linux/sched.h</a>&gt;        <i><font color='green'>// 调度程序头文件。定义了任务结构task_struct、第1 个初始任务</font></i>
<a name='L18'><i><font color='green'>// 的数据。还有一些以宏的形式定义的有关描述符参数设置和获取的</font></i>
<a name='L19'><i><font color='green'>// 嵌入式汇编函数程序。</font></i>
<a name='L20'><font color='darkred'>#include</font> &lt;<a href='34.html'>linux/kernel.h</a>&gt;       <i><font color='green'>// 内核头文件。含有一些内核常用函数的原形定义。</font></i>
<a name='L21'><font color='darkred'>#include</font> &lt;<a href='37.html'>linux/sys.h</a>&gt;          <i><font color='green'>// 系统调用头文件。含有72 个系统调用C 函数处理程序,以'sys_'开头。</font></i>
<a name='L22'><font color='darkred'>#include</font> &lt;linux/fdreg.h&gt;        <i><font color='green'>// 软驱头文件。含有软盘控制器参数的一些定义。</font></i>
<a name='L23'><font color='darkred'>#include</font> &lt;<a href='25.html'>asm/system.h</a>&gt;         <i><font color='green'>// 系统头文件。定义了设置或修改描述符/中断门等的嵌入式汇编宏。</font></i>
<a name='L24'><font color='darkred'>#include</font> &lt;<a href='22.html'>asm/io.h</a>&gt;             <i><font color='green'>// io 头文件。定义硬件端口输入/输出宏汇编语句。</font></i>
<a name='L25'><font color='darkred'>#include</font> &lt;<a href='24.html'>asm/segment.h</a>&gt;        <i><font color='green'>// 段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。</font></i>
<a name='L26'>
<a name='L27'><font color='darkred'>#include</font> &lt;<a href='39.html'>signal.h</a>&gt;             <i><font color='green'>// 信号头文件。定义信号符号常量,sigaction 结构,操作函数原型。</font></i>
<a name='L28'>
<a name='L29'><font color='darkred'>#define</font> <a href='../R/343.html' title='Multiple refered from 4 places.'>_S</a>(nr) (1&lt;&lt;((nr)-1))    <i><font color='green'>// 取信号nr 在信号位图中对应位的二进制数值。信号编号1-32。</font></i>
<a name='L30'><i><font color='green'>// 比如信号5 的位图数值 = 1&lt;&lt;(5-1) = 16 = 00010000b。</font></i>
<a name='L31'><font color='darkred'>#define</font> <a href='../S/74.html#L167' title='Refered from 167 in kernel/sched.c.'>_BLOCKABLE</a> (~(<a href='../D/584.html' title='Multiple defined in 2 places.'>_S</a>(<a href='../S/39.html#L22' title='Defined at 22 in include/signal.h.'>SIGKILL</a>) | <a href='../D/584.html' title='Multiple defined in 2 places.'>_S</a>(<a href='../S/39.html#L32' title='Defined at 32 in include/signal.h.'>SIGSTOP</a>)))       <i><font color='green'>// 除了SIGKILL 和SIGSTOP 信号以外其它都是</font></i>
<a name='L32'><i><font color='green'>// 可阻塞的(…10111111111011111111b)。</font></i>
<a name='L33'>
<a name='L34'><i><font color='green'>// 显示任务号nr 的进程号、进程状态和内核堆栈空闲字节数(大约)。</font></i>
<a name='L35'><b>void</b>
<a name='L36'><a href='../S/74.html#L55' title='Refered from 55 in kernel/sched.c.'>show_task</a> (<b>int</b> nr, <b>struct</b> task_struct *p)
<a name='L37'><font color='red'>{</font>
<a name='L38'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>, j = 4096 - <b>sizeof</b> (<b>struct</b> task_struct);
<a name='L39'>
<a name='L40'>  <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("%d: pid=%d, state=%d, ", nr, p-&gt;pid, p-&gt;state);
<a name='L41'>  <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0;
<a name='L42'>  <b>while</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; j &amp;&amp; !((<b>char</b> *) (p + 1))[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])       <i><font color='green'>// 检测指定任务数据结构以后等于0 的字节数。</font></i>
<a name='L43'>    <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++;
<a name='L44'>  <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("%d (of %d) chars free in kernel stack\n\r", <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>, j);
<a name='L45'><font color='red'>}</font>
<a name='L46'>
<a name='L47'><i><font color='green'>// 显示所有任务的任务号、进程号、进程状态和内核堆栈空闲字节数(大约)。</font></i>
<a name='L48'><b>void</b>
<a name='L49'><a href='../S/61.html#L272' title='Refered from 272 in kernel/chr_drv/keyboard.S.'>show_stat</a> (<b>void</b>)
<a name='L50'><font color='red'>{</font>
<a name='L51'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L52'>
<a name='L53'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)        <i><font color='green'>// NR_TASKS 是系统能容纳的最大进程(任务)数量(64 个),</font></i>
<a name='L54'>    <b>if</b> (task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])                <i><font color='green'>// 定义在include/kernel/sched.h 第4 行。</font></i>
<a name='L55'>      <a href='../S/74.html#L36' title='Defined at 36 in kernel/sched.c.'>show_task</a> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>, task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]);
<a name='L56'><font color='red'>}</font>
<a name='L57'>
<a name='L58'><i><font color='green'>// 定义每个时间片的滴答数?。</font></i>
<a name='L59'><font color='darkred'>#define</font> <a href='../R/113.html' title='Multiple refered from 2 places.'>LATCH</a> (1193180/<a href='../S/36.html#L5' title='Defined at 5 in include/linux/sched.h.'>HZ</a>)
<a name='L60'>
<a name='L61'><b>extern</b> <b>void</b> mem_use (<b>void</b>);     <i><font color='green'>// [??]没有任何地方定义和引用该函数。</font></i>
<a name='L62'>
<a name='L63'><b>extern</b> <b>int</b> timer_interrupt (<b>void</b>);      <i><font color='green'>// 时钟中断处理程序(kernel/system_call.s,176)。</font></i>
<a name='L64'><b>extern</b> <b>int</b> system_call (<b>void</b>);  <i><font color='green'>// 系统调用中断处理程序(kernel/system_call.s,80)。</font></i>
<a name='L65'>
<a name='L66'><b>union</b> task_union
<a name='L67'><font color='red'>{</font>                               <i><font color='green'>// 定义任务联合(任务结构成员和stack 字符数组程序成员)。</font></i>
<a name='L68'>  <b>struct</b> task_struct task;      <i><font color='green'>// 因为一个任务数据结构与其堆栈放在同一内存页中,所以</font></i>
<a name='L69'>  <b>char</b> stack[<a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a>];        <i><font color='green'>// 从堆栈段寄存器ss 可以获得其数据段选择符。</font></i>
<a name='L70'><font color='red'>}</font>;
<a name='L71'>
<a name='L72'><b>static</b> <b>union</b> task_union init_task = <font color='red'>{</font> <a href='../S/36.html#L177' title='Defined at 177 in include/linux/sched.h.'>INIT_TASK</a>, <font color='red'>}</font>;     <i><font color='green'>// 定义初始任务的数据(sched.h 中)。</font></i>
<a name='L73'>
<a name='L74'><b>long</b> <b>volatile</b> jiffies = 0;      <i><font color='green'>// 从开机开始算起的滴答数时间值(10ms/滴答)。</font></i>
<a name='L75'><i><font color='green'>// 前面的限定符volatile,英文解释是易变、不稳定的意思。这里是要求gcc 不要对该变量进行优化</font></i>
<a name='L76'><i><font color='green'>// 处理,也不要挪动位置,因为也许别的程序会来修改它的值。</font></i>
<a name='L77'><b>long</b> startup_time = 0;          <i><font color='green'>// 开机时间。从1970:0:0:0 开始计时的秒数。</font></i>
<a name='L78'><b>struct</b> task_struct *current = &amp;(init_task.task);        <i><font color='green'>// 当前任务指针(初始化为初始任务)。</font></i>
<a name='L79'><b>struct</b> task_struct *last_task_used_math = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>; <i><font color='green'>// 使用过协处理器任务的指针。</font></i>
<a name='L80'>
<a name='L81'><b>struct</b> task_struct *task[<a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a>] = <font color='red'>{</font> &amp;(init_task.task), <font color='red'>}</font>;    <i><font color='green'>// 定义任务指针数组。</font></i>
<a name='L82'>
<a name='L83'><b>long</b> user_stack[<a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a> &gt;&gt; 2];        <i><font color='green'>// 定义系统堆栈指针,4K。指针指在最后一项。</font></i>
<a name='L84'>
<a name='L85'><i><font color='green'>// 该结构用于设置堆栈ss:esp(数据段选择符,指针),见head.s,第23 行。</font></i>
<a name='L86'><b>struct</b>
<a name='L87'><font color='red'>{</font>
<a name='L88'>  <b>long</b> *a;
<a name='L89'>  <b>short</b> b;
<a name='L90'><font color='red'>}</font>
<a name='L91'>stack_start =
<a name='L92'><font color='red'>{</font>
<a name='L93'>&amp;user_stack[<a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a> &gt;&gt; 2], 0x10<font color='red'>}</font>;
<a name='L94'>
<a name='L95'><i><font color='green'>/*</font></i>
<a name='L96'><i><font color='green'> * 'math_state_restore()' saves the current math information in the</font></i>
<a name='L97'><i><font color='green'> * old math state array, and gets the new ones from the current task</font></i>
<a name='L98'><i><font color='green'> */</font></i>
<a name='L99'><i><font color='green'>/*</font></i>
<a name='L100'><i><font color='green'> * 将当前协处理器内容保存到老协处理器状态数组中,并将当前任务的协处理器</font></i>
<a name='L101'><i><font color='green'> * 内容加载进协处理器。</font></i>
<a name='L102'><i><font color='green'> */</font></i>
<a name='L103'><i><font color='green'>// 当任务被调度交换过以后,该函数用以保存原任务的协处理器状态(上下文)并恢复新调度进来的</font></i>
<a name='L104'><i><font color='green'>// 当前任务的协处理器执行状态。</font></i>
<a name='L105'><b>void</b>
<a name='L106'>math_state_restore ()
<a name='L107'><font color='red'>{</font>
<a name='L108'>  <b>if</b> (last_task_used_math == current)   <i><font color='green'>// 如果任务没变则返回(上一个任务就是当前任务)。</font></i>
<a name='L109'>    <b>return</b>;                     <i><font color='green'>// 这里所指的"上一个任务"是刚被交换出去的任务。</font></i>
<a name='L110'>  <b>__asm__</b> ("fwait");            <i><font color='green'>// 在发送协处理器命令之前要先发WAIT 指令。</font></i>
<a name='L111'>  <b>if</b> (last_task_used_math)
<a name='L112'>    <font color='red'>{</font>                           <i><font color='green'>// 如果上个任务使用了协处理器,则保存其状态。</font></i>
<a name='L113'>      <b>__asm__</b> ("fnsave %0"::"m" (last_task_used_math-&gt;tss.i387));
<a name='L114'>    <font color='red'>}</font>
<a name='L115'>  last_task_used_math = current;        <i><font color='green'>// 现在,last_task_used_math 指向当前任务,</font></i>
<a name='L116'>  <i><font color='green'>// 以备当前任务被交换出去时使用。</font></i>
<a name='L117'>  <b>if</b> (current-&gt;used_math)
<a name='L118'>    <font color='red'>{</font>                           <i><font color='green'>// 如果当前任务用过协处理器,则恢复其状态。</font></i>
<a name='L119'>      <b>__asm__</b> ("frstor %0"::"m" (current-&gt;tss.i387));

⌨️ 快捷键说明

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