36.html

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

HTML
370
字号
<a name='L236'><i><font color='green'>// 添加定时器函数(定时时间jiffies 滴答数,定时到时调用函数*fn())。( kernel/sched.c,272)</font></i>
<a name='L237'><b>extern</b> <b>void</b> <a href='../S/74.html#L389' title='Defined at 389 in kernel/sched.c.'>add_timer</a> (<b>long</b> jiffies, <b>void</b> (*fn) (<b>void</b>));
<a name='L238'><i><font color='green'>// 不可中断的等待睡眠。( kernel/sched.c, 151 )</font></i>
<a name='L239'><b>extern</b> <b>void</b> <a href='../S/74.html#L219' title='Defined at 219 in kernel/sched.c.'>sleep_on</a> (<b>struct</b> task_struct **p);
<a name='L240'><i><font color='green'>// 可中断的等待睡眠。( kernel/sched.c, 167 )</font></i>
<a name='L241'><b>extern</b> <b>void</b> <a href='../S/74.html#L242' title='Defined at 242 in kernel/sched.c.'>interruptible_sleep_on</a> (<b>struct</b> task_struct **p);
<a name='L242'><i><font color='green'>// 明确唤醒睡眠的进程。( kernel/sched.c, 188 )</font></i>
<a name='L243'><b>extern</b> <b>void</b> <a href='../S/74.html#L272' title='Defined at 272 in kernel/sched.c.'>wake_up</a> (<b>struct</b> task_struct **p);
<a name='L244'>
<a name='L245'><i><font color='green'>/*</font></i>
<a name='L246'><i><font color='green'>* Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall</font></i>
<a name='L247'><i><font color='green'>* 4-TSS0, 5-LDT0, 6-TSS1 etc ...</font></i>
<a name='L248'><i><font color='green'>*/</font></i>
<a name='L249'><i><font color='green'>/*</font></i>
<a name='L250'><i><font color='green'>* 寻找第1 个TSS 在全局表中的入口。0-没有用nul,1-代码段cs,2-数据段ds,3-系统段syscall</font></i>
<a name='L251'><i><font color='green'>* 4-任务状态段TSS0,5-局部表LTD0,6-任务状态段TSS1,等。</font></i>
<a name='L252'><i><font color='green'>*/</font></i>
<a name='L253'><i><font color='green'>// 全局表中第1 个任务状态段(TSS)描述符的选择符索引号。</font></i>
<a name='L254'><font color='darkred'>#define</font> <a href='../R/70.html' title='Multiple refered from 6 places.'>FIRST_TSS_ENTRY</a> 4
<a name='L255'><i><font color='green'>// 全局表中第1 个局部描述符表(LDT)描述符的选择符索引号。</font></i>
<a name='L256'><font color='darkred'>#define</font> <a href='../R/68.html' title='Multiple refered from 3 places.'>FIRST_LDT_ENTRY</a> (<a href='../S/36.html#L254' title='Defined at 254 in include/linux/sched.h.'>FIRST_TSS_ENTRY</a>+1)
<a name='L257'><i><font color='green'>// 宏定义,计算在全局表中第n 个任务的TSS 描述符的索引号(选择符)。</font></i>
<a name='L258'><font color='darkred'>#define</font> <a href='../R/359.html' title='Multiple refered from 2 places.'>_TSS</a>(n) ((((<b>unsigned</b> <b>long</b>) n)&lt;&lt;4)+(<a href='../S/36.html#L254' title='Defined at 254 in include/linux/sched.h.'>FIRST_TSS_ENTRY</a>&lt;&lt;3))
<a name='L259'><i><font color='green'>// 宏定义,计算在全局表中第n 个任务的LDT 描述符的索引号。</font></i>
<a name='L260'><font color='darkred'>#define</font> <a href='../R/333.html' title='Multiple refered from 3 places.'>_LDT</a>(n) ((((<b>unsigned</b> <b>long</b>) n)&lt;&lt;4)+(<a href='../S/36.html#L256' title='Defined at 256 in include/linux/sched.h.'>FIRST_LDT_ENTRY</a>&lt;&lt;3))
<a name='L261'><i><font color='green'>// 宏定义,加载第n 个任务的任务寄存器tr。</font></i>
<a name='L262'><font color='darkred'>#define</font> <a href='../S/74.html#L572' title='Refered from 572 in kernel/sched.c.'>ltr</a>(n) <b>__asm__</b>( "ltr %%ax":: "a" (<a href='../S/36.html#L258' title='Defined at 258 in include/linux/sched.h.'>_TSS</a>(n)))
<a name='L263'><i><font color='green'>// 宏定义,加载第n 个任务的局部描述符表寄存器ldtr。</font></i>
<a name='L264'><font color='darkred'>#define</font> <a href='../S/74.html#L573' title='Refered from 573 in kernel/sched.c.'>lldt</a>(n) <b>__asm__</b>( "lldt %%ax":: "a" (<a href='../S/36.html#L260' title='Defined at 260 in include/linux/sched.h.'>_LDT</a>(n)))
<a name='L265'><i><font color='green'>// 取当前运行任务的任务号(是任务数组中的索引值,与进程号pid 不同)。</font></i>
<a name='L266'><i><font color='green'>// 返回:n - 当前任务号。用于( kernel/traps.c, 79)。</font></i>
<a name='L267'><font color='darkred'>#define</font> <a href='../R/618.html' title='Multiple refered from 31 places.'>str</a>(n) \
<a name='L268'><b>__asm__</b>( "str %%ax\n\t" \       <i><font color='green'>// 将任务寄存器中TSS 段的有效地址??ax</font></i>
<a name='L269'>"subl %2,%%eax\n\t" \           <i><font color='green'>// (eax - FIRST_TSS_ENTRY*8)??eax</font></i>
<a name='L270'>  "shrl $4,%%eax" \             <i><font color='green'>// (eax/16)??eax = 当前任务号。</font></i>
<a name='L271'>: "=a" (n):"a" (0), "i" (<a href='../S/36.html#L254' title='Defined at 254 in include/linux/sched.h.'>FIRST_TSS_ENTRY</a> &lt;&lt; 3))
<a name='L272'><i><font color='green'>/*</font></i>
<a name='L273'><i><font color='green'>* switch_to(n) should switch tasks to task nr n, first</font></i>
<a name='L274'><i><font color='green'>* checking that n isn't the current task, in which case it does nothing.</font></i>
<a name='L275'><i><font color='green'>* This also clears the TS-flag if the task we switched to has used</font></i>
<a name='L276'><i><font color='green'>* tha math co-processor latest.</font></i>
<a name='L277'><i><font color='green'>*/</font></i>
<a name='L278'><i><font color='green'>/*</font></i>
<a name='L279'><i><font color='green'>* switch_to(n)将切换当前任务到任务nr,即n。首先检测任务n 不是当前任务,</font></i>
<a name='L280'><i><font color='green'>* 如果是则什么也不做退出。如果我们切换到的任务最近(上次运行)使用过数学</font></i>
<a name='L281'><i><font color='green'>* 协处理器的话,则还需复位控制寄存器cr0 中的TS 标志。</font></i>
<a name='L282'><i><font color='green'>*/</font></i>
<a name='L283'><i><font color='green'>// 输入:%0 - 新TSS 的偏移地址(*&amp;__tmp.a); %1 - 存放新TSS 的选择符值(*&amp;__tmp.b);</font></i>
<a name='L284'><i><font color='green'>// dx - 新任务n 的选择符;ecx - 新任务指针task[n]。</font></i>
<a name='L285'><i><font color='green'>// 其中临时数据结构__tmp 中,a 的值是32 位偏移值,b 为新TSS 的选择符。在任务切换时,a 值</font></i>
<a name='L286'><i><font color='green'>// 没有用(忽略)。在判断新任务上次执行是否使用过协处理器时,是通过将新任务状态段的地址与</font></i>
<a name='L287'><i><font color='green'>// 保存在last_task_used_math 变量中的使用过协处理器的任务状态段的地址进行比较而作出的。</font></i>
<a name='L288'><font color='darkred'>#define</font> <a href='../S/74.html#L200' title='Refered from 200 in kernel/sched.c.'>switch_to</a>(n) <font color='red'>{</font>\
<a name='L289'><b>struct</b> <font color='red'>{</font><b>long</b> a,b;<font color='red'>}</font> __tmp; \
<a name='L290'><b>__asm__</b>( "cmpl %%ecx,_current\n\t" \    <i><font color='green'>// 任务n 是当前任务吗?(current ==task[n]?)</font></i>
<a name='L291'>  "je 1f\n\t" \                 <i><font color='green'>// 是,则什么都不做,退出。</font></i>
<a name='L292'>  "movw %%dx,%1\n\t" \          <i><font color='green'>// 将新任务的选择符??*&amp;__tmp.b。</font></i>
<a name='L293'>  "xchgl %%ecx,_current\n\t" \  <i><font color='green'>// current = task[n];ecx = 被切换出的任务。</font></i>
<a name='L294'>  "ljmp %0\n\t" \               <i><font color='green'>// 执行长跳转至*&amp;__tmp,造成任务切换。</font></i>
<a name='L295'><i><font color='green'>// 在任务切换回来后才会继续执行下面的语句。</font></i>
<a name='L296'>  "cmpl %%ecx,_last_task_used_math\n\t" \       <i><font color='green'>// 新任务上次使用过协处理器吗?</font></i>
<a name='L297'>  "jne 1f\n\t" \                <i><font color='green'>// 没有则跳转,退出。</font></i>
<a name='L298'>  "clts\n" \                    <i><font color='green'>// 新任务上次使用过协处理器,则清cr0 的TS 标志。</font></i>
<a name='L299'>  "1:"::"m" (*&amp;__tmp.a), "m" (*&amp;__tmp.b),
<a name='L300'>  "d" (<a href='../S/36.html#L258' title='Defined at 258 in include/linux/sched.h.'>_TSS</a> (n)), "c" ((<b>long</b>) task[n]));
<a name='L301'><font color='red'>}</font>
<a name='L302'>
<a name='L303'><i><font color='green'>// 页面地址对准。(在内核代码中没有任何地方引用!!)</font></i>
<a name='L304'><font color='darkred'>#define</font> PAGE_ALIGN(n) (((n)+0xfff)&amp;0xfffff000)
<a name='L305'>
<a name='L306'><i><font color='green'>// 设置位于地址addr 处描述符中的各基地址字段(基地址是base),参见列表后说明。</font></i>
<a name='L307'><i><font color='green'>// %0 - 地址addr 偏移2;%1 - 地址addr 偏移4;%2 - 地址addr 偏移7;edx - 基地址base。</font></i>
<a name='L308'><font color='darkred'>#define</font> <a href='../S/36.html#L325' title='Refered from 325 in include/linux/sched.h.'>_set_base</a>(addr,base) \
<a name='L309'><b>__asm__</b>( "movw %%dx,%0\n\t" \   <i><font color='green'>// 基址base 低16 位(位15-0)??[addr+2]。</font></i>
<a name='L310'>"rorl $16,%%edx\n\t" \          <i><font color='green'>// edx 中基址高16 位(位31-16)??dx。</font></i>
<a name='L311'>  "movb %%dl,%1\n\t" \          <i><font color='green'>// 基址高16 位中的低8 位(位23-16)??[addr+4]。</font></i>
<a name='L312'>  "movb %%dh,%2" \              <i><font color='green'>// 基址高16 位中的高8 位(位31-24)??[addr+7]。</font></i>
<a name='L313'>::"m" (*((addr) + 2)), "m" (*((addr) + 4)), "m" (*((addr) + 7)), "d" (base):"dx")
<a name='L314'><i><font color='green'>// 设置位于地址addr 处描述符中的段限长字段(段长是limit)。</font></i>
<a name='L315'><i><font color='green'>// %0 - 地址addr;%1 - 地址addr 偏移6 处;edx - 段长值limit。</font></i>
<a name='L316'><font color='darkred'>#define</font> <a href='../S/36.html#L327' title='Refered from 327 in include/linux/sched.h.'>_set_limit</a>(addr,limit) \
<a name='L317'><b>__asm__</b>( "movw %%dx,%0\n\t" \   <i><font color='green'>// 段长limit 低16 位(位15-0)??[addr]。</font></i>
<a name='L318'>  "rorl $16,%%edx\n\t" \        <i><font color='green'>// edx 中的段长高4 位(位19-16)??dl。</font></i>
<a name='L319'>  "movb %1,%%dh\n\t" \          <i><font color='green'>// 取原[addr+6]字节??dh,其中高4 位是些标志。</font></i>
<a name='L320'>  "andb $0xf0,%%dh\n\t" \       <i><font color='green'>// 清dh 的低4 位(将存放段长的位19-16)。</font></i>
<a name='L321'>  "orb %%dh,%%dl\n\t" \         <i><font color='green'>// 将原高4 位标志和段长的高4 位(位19-16)合成1 字节,</font></i>
<a name='L322'>  "movb %%dl,%1" \              <i><font color='green'>// 并放会[addr+6]处。</font></i>
<a name='L323'>::"m" (*(addr)), "m" (*((addr) + 6)), "d" (limit):"dx")
<a name='L324'><i><font color='green'>// 设置局部描述符表中ldt 描述符的基地址字段。</font></i>
<a name='L325'><font color='darkred'>#define</font> <a href='../R/592.html' title='Multiple refered from 4 places.'>set_base</a>(ldt,base) <a href='../S/36.html#L308' title='Defined at 308 in include/linux/sched.h.'>_set_base</a>( ((<b>char</b> *)&amp;(ldt)) , base )
<a name='L326'><i><font color='green'>// 设置局部描述符表中ldt 描述符的段长字段。</font></i>
<a name='L327'><font color='darkred'>#define</font> <a href='../R/598.html' title='Multiple refered from 2 places.'>set_limit</a>(ldt,limit) <a href='../S/36.html#L316' title='Defined at 316 in include/linux/sched.h.'>_set_limit</a>( ((<b>char</b> *)&amp;(ldt)) , (limit-1)&gt;&gt;12 )
<a name='L328'><i><font color='green'>// 从地址addr 处描述符中取段基地址。功能与_set_base()正好相反。</font></i>
<a name='L329'><i><font color='green'>// edx - 存放基地址(__base);%1 - 地址addr 偏移2;%2 - 地址addr 偏移4;%3 - addr 偏移7。</font></i>
<a name='L330'><font color='darkred'>#define</font> <a href='../S/36.html#L343' title='Refered from 343 in include/linux/sched.h.'>_get_base</a>(addr) (<font color='red'>{</font>\
<a name='L331'><b>unsigned</b> <b>long</b> __base; \
<a name='L332'><b>__asm__</b>( "movb %3,%%dh\n\t" \   <i><font color='green'>// 取[addr+7]处基址高16 位的高8 位(位31-24)??dh。</font></i>
<a name='L333'>  "movb %2,%%dl\n\t" \          <i><font color='green'>// 取[addr+4]处基址高16 位的低8 位(位23-16)??dl。</font></i>
<a name='L334'>  "shll $16,%%edx\n\t" \        <i><font color='green'>// 基地址高16 位移到edx 中高16 位处。</font></i>
<a name='L335'>  "movw %1,%%dx" \              <i><font color='green'>// 取[addr+2]处基址低16 位(位15-0)??dx。</font></i>
<a name='L336'>:"=d" (__base) \                <i><font color='green'>// 从而edx 中含有32 位的段基地址。</font></i>
<a name='L337'>:"m" (*((addr) + 2)), "m" (*((addr) + 4)), "m" (*((addr) + 7)));
<a name='L338'>__base;
<a name='L339'><font color='red'>}</font>
<a name='L340'>
<a name='L341'>)
<a name='L342'><i><font color='green'>// 取局部描述符表中ldt 所指段描述符中的基地址。</font></i>
<a name='L343'><font color='darkred'>#define</font> <a href='../R/472.html' title='Multiple refered from 9 places.'>get_base</a>(ldt) <a href='../S/36.html#L330' title='Defined at 330 in include/linux/sched.h.'>_get_base</a>( ((<b>char</b> *)&amp;(ldt)) )
<a name='L344'><i><font color='green'>// 取段选择符segment 的段长值。</font></i>
<a name='L345'><i><font color='green'>// %0 - 存放段长值(字节数);%1 - 段选择符segment。</font></i>
<a name='L346'><font color='darkred'>#define</font> <a href='../R/482.html' title='Multiple refered from 7 places.'>get_limit</a>(segment) (<font color='red'>{</font> \
<a name='L347'><b>unsigned</b> <b>long</b> __limit; \
<a name='L348'><b>__asm__</b>( "lsll %1,%0\n\tincl %0": "=r" (__limit): "r" (segment)); \
<a name='L349'>__limit;<font color='red'>}</font>)
<a name='L350'><font color='darkred'>#endif</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [&lt;][&gt;][^][v]<a href='#TOP'>[top]</a>[bottom]<a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
</body>
</html>

⌨️ 快捷键说明

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