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

📄 00000045.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
ed,&nbsp;on&nbsp;SMP&nbsp;only&nbsp;process&nbsp;not&nbsp;already&nbsp;running&nbsp;on&nbsp;another&nbsp;cpu&nbsp;is&nbsp;eligible&nbsp;to&nbsp;be&nbsp;<BR>&nbsp;scheduled&nbsp;on&nbsp;this&nbsp;cpu.&nbsp;The&nbsp;goodness&nbsp;is&nbsp;calculated&nbsp;by&nbsp;a&nbsp;function&nbsp;called&nbsp;good&nbsp;<BR>ness()&nbsp;which&nbsp;treats&nbsp;realtime&nbsp;processes&nbsp;by&nbsp;making&nbsp;their&nbsp;goodness&nbsp;very&nbsp;high&nbsp;10&nbsp;<BR>00&nbsp;+&nbsp;p-rt_priority,&nbsp;this&nbsp;being&nbsp;greater&nbsp;than&nbsp;1000&nbsp;guarantees&nbsp;that&nbsp;no&nbsp;SCHED_OT&nbsp;<BR>HER&nbsp;process&nbsp;can&nbsp;win&nbsp;so&nbsp;they&nbsp;only&nbsp;contend&nbsp;with&nbsp;other&nbsp;realtime&nbsp;processes&nbsp;that&nbsp;&nbsp;<BR>may&nbsp;have&nbsp;a&nbsp;greater&nbsp;p-rt_priority.&nbsp;The&nbsp;goodness&nbsp;function&nbsp;returns&nbsp;0&nbsp;if&nbsp;the&nbsp;pro&nbsp;<BR>cess'&nbsp;time&nbsp;slice&nbsp;(p-counter)&nbsp;is&nbsp;over.&nbsp;For&nbsp;non-realtime&nbsp;processes&nbsp;the&nbsp;initial&nbsp;<BR>&nbsp;value&nbsp;of&nbsp;goodness&nbsp;is&nbsp;set&nbsp;to&nbsp;p-counter&nbsp;-&nbsp;this&nbsp;way&nbsp;the&nbsp;process&nbsp;is&nbsp;less&nbsp;likely&nbsp;<BR>&nbsp;to&nbsp;get&nbsp;CPU&nbsp;if&nbsp;it&nbsp;already&nbsp;had&nbsp;it&nbsp;for&nbsp;a&nbsp;while,&nbsp;i.e.&nbsp;interactive&nbsp;processes&nbsp;are&nbsp;<BR>&nbsp;favoured&nbsp;more&nbsp;than&nbsp;cpu-bound&nbsp;number&nbsp;crunchers.&nbsp;The&nbsp;arch-specific&nbsp;constant&nbsp;P&nbsp;<BR>ROC_CHANGE_PENALTY&nbsp;attempts&nbsp;to&nbsp;implement&nbsp;&quot;cpu&nbsp;affinity&quot;&nbsp;i.e.&nbsp;give&nbsp;advantage&nbsp;&nbsp;<BR>to&nbsp;a&nbsp;process&nbsp;on&nbsp;the&nbsp;same&nbsp;cpu.&nbsp;It&nbsp;also&nbsp;gives&nbsp;slight&nbsp;advantage&nbsp;to&nbsp;processes&nbsp;wi&nbsp;<BR>th&nbsp;mm&nbsp;pointing&nbsp;to&nbsp;current&nbsp;active_mm&nbsp;or&nbsp;to&nbsp;processes&nbsp;with&nbsp;no&nbsp;(user)&nbsp;address&nbsp;s&nbsp;<BR>pace,&nbsp;i.e.&nbsp;kernel&nbsp;threads.&nbsp;<BR>13.&nbsp;if&nbsp;the&nbsp;current&nbsp;value&nbsp;of&nbsp;goodness&nbsp;is&nbsp;0&nbsp;then&nbsp;the&nbsp;entire&nbsp;list&nbsp;of&nbsp;processes&nbsp;&nbsp;<BR>(not&nbsp;just&nbsp;runqueue!)&nbsp;is&nbsp;examined&nbsp;and&nbsp;their&nbsp;dynamic&nbsp;priorities&nbsp;are&nbsp;recalculat&nbsp;<BR>ed&nbsp;using&nbsp;simple&nbsp;algorithm:&nbsp;<BR>recalculate:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;task_struct&nbsp;*p;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spin_unlock_irq(&amp;runqueue_lock);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;read_lock(&amp;tasklist_lock);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for_each_task(p)&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p-counter&nbsp;=&nbsp;(p-counter&nbsp;&nbsp;1)&nbsp;+&nbsp;p-priority;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;read_unlock(&amp;tasklist_lock);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spin_lock_irq(&amp;runqueue_lock);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>Note&nbsp;that&nbsp;the&nbsp;we&nbsp;drop&nbsp;the&nbsp;runqueue_lock&nbsp;before&nbsp;we&nbsp;recalculate&nbsp;because&nbsp;we&nbsp;go&nbsp;&nbsp;<BR>through&nbsp;entire&nbsp;set&nbsp;of&nbsp;processes&nbsp;which&nbsp;can&nbsp;take&nbsp;a&nbsp;long&nbsp;time&nbsp;whilst&nbsp;the&nbsp;schedu&nbsp;<BR>le()&nbsp;could&nbsp;be&nbsp;called&nbsp;on&nbsp;another&nbsp;cpu&nbsp;and&nbsp;select&nbsp;a&nbsp;process&nbsp;with&nbsp;goodness&nbsp;good&nbsp;&nbsp;<BR>enough&nbsp;for&nbsp;that&nbsp;cpu&nbsp;whilst&nbsp;we&nbsp;on&nbsp;this&nbsp;cpu&nbsp;were&nbsp;forced&nbsp;to&nbsp;recalculate.&nbsp;Ok,&nbsp;ad&nbsp;<BR>mittedly&nbsp;this&nbsp;is&nbsp;somewhat&nbsp;inconsistent&nbsp;because&nbsp;while&nbsp;we&nbsp;(on&nbsp;this&nbsp;cpu)&nbsp;are&nbsp;se&nbsp;<BR>lecting&nbsp;a&nbsp;process&nbsp;with&nbsp;the&nbsp;best&nbsp;goodness,&nbsp;schedule()&nbsp;running&nbsp;on&nbsp;another&nbsp;cpu&nbsp;&nbsp;<BR>could&nbsp;be&nbsp;recalculating&nbsp;dynamic&nbsp;priorities&nbsp;<BR>14.&nbsp;From&nbsp;this&nbsp;point&nbsp;on&nbsp;it&nbsp;is&nbsp;certain&nbsp;that&nbsp;'next'&nbsp;points&nbsp;to&nbsp;the&nbsp;task&nbsp;to&nbsp;be&nbsp;sc&nbsp;<BR>heduled&nbsp;so&nbsp;we&nbsp;initialise&nbsp;next-has_cpu&nbsp;to&nbsp;1&nbsp;and&nbsp;next-processor&nbsp;to&nbsp;this_cpu.&nbsp;T&nbsp;<BR>he&nbsp;runqueue_lock&nbsp;can&nbsp;now&nbsp;be&nbsp;unlocked.&nbsp;<BR>15.&nbsp;If&nbsp;we&nbsp;are&nbsp;switching&nbsp;back&nbsp;to&nbsp;the&nbsp;same&nbsp;task&nbsp;(next&nbsp;==&nbsp;prev)&nbsp;then&nbsp;we&nbsp;can&nbsp;sim&nbsp;<BR>ply&nbsp;reacquire&nbsp;the&nbsp;global&nbsp;kernel&nbsp;lock&nbsp;and&nbsp;return,&nbsp;i.e.&nbsp;skip&nbsp;all&nbsp;the&nbsp;hardware-&nbsp;<BR>level&nbsp;(registers,&nbsp;stack&nbsp;etc.)&nbsp;and&nbsp;VM-related&nbsp;(switch&nbsp;page&nbsp;directory,&nbsp;recalcu&nbsp;<BR>late&nbsp;active_mm&nbsp;etc.)&nbsp;stuff&nbsp;<BR>16.&nbsp;The&nbsp;macro&nbsp;switch_to()&nbsp;is&nbsp;architecture&nbsp;specific&nbsp;and&nbsp;(on&nbsp;i386)&nbsp;it&nbsp;is&nbsp;conce&nbsp;<BR>rned&nbsp;with&nbsp;a)&nbsp;FPU&nbsp;handling&nbsp;b)&nbsp;LDT&nbsp;handling&nbsp;c)&nbsp;reloading&nbsp;segment&nbsp;registers&nbsp;d)&nbsp;&nbsp;<BR>TSS&nbsp;handling&nbsp;and&nbsp;e)&nbsp;reloading&nbsp;debug&nbsp;registers&nbsp;<BR>2.4&nbsp;Linux&nbsp;linked&nbsp;list&nbsp;implementation&nbsp;<BR>Before&nbsp;we&nbsp;go&nbsp;on&nbsp;to&nbsp;examine&nbsp;implementation&nbsp;of&nbsp;wait&nbsp;queues&nbsp;we&nbsp;must&nbsp;acquaint&nbsp;ou&nbsp;<BR>rselves&nbsp;with&nbsp;the&nbsp;Linux&nbsp;standard&nbsp;doubly-linked&nbsp;list&nbsp;implementation&nbsp;because&nbsp;wa&nbsp;<BR>it&nbsp;queues&nbsp;(as&nbsp;well&nbsp;as&nbsp;everything&nbsp;else&nbsp;in&nbsp;Linux)&nbsp;makes&nbsp;heavy&nbsp;use&nbsp;of&nbsp;them&nbsp;and&nbsp;&nbsp;<BR>they&nbsp;are&nbsp;called&nbsp;in&nbsp;jargon&nbsp;&quot;list.h&nbsp;implementation&quot;&nbsp;because&nbsp;the&nbsp;most&nbsp;relevant&nbsp;&nbsp;<BR>file&nbsp;is&nbsp;include/linux/list.h.&nbsp;<BR>The&nbsp;fundamental&nbsp;data&nbsp;structure&nbsp;here&nbsp;is&nbsp;'struct&nbsp;list_head':&nbsp;<BR>struct&nbsp;list_head&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;list_head&nbsp;*next,&nbsp;*prev;&nbsp;<BR>};&nbsp;<BR>#define&nbsp;LIST_HEAD_INIT(name)&nbsp;{&nbsp;&amp;(name),&nbsp;&amp;(name)&nbsp;}&nbsp;<BR>#define&nbsp;LIST_HEAD(name)&nbsp;\&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;list_head&nbsp;name&nbsp;=&nbsp;LIST_HEAD_INIT(name)&nbsp;<BR>#define&nbsp;INIT_LIST_HEAD(ptr)&nbsp;do&nbsp;{&nbsp;\&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ptr)-next&nbsp;=&nbsp;(ptr);&nbsp;(ptr)-prev&nbsp;=&nbsp;(ptr);&nbsp;\&nbsp;<BR>}&nbsp;while&nbsp;(0)&nbsp;<BR>#define&nbsp;list_entry(ptr,&nbsp;type,&nbsp;member)&nbsp;\&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((type&nbsp;*)((char&nbsp;*)(ptr)-(unsigned&nbsp;long)(&amp;((type&nbsp;*)0)-member)))&nbsp;<BR>#define&nbsp;list_for_each(pos,&nbsp;head)&nbsp;\&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(pos&nbsp;=&nbsp;(head)-next;&nbsp;pos&nbsp;!=&nbsp;(head);&nbsp;pos&nbsp;=&nbsp;pos-next)&nbsp;<BR>The&nbsp;first&nbsp;three&nbsp;macros&nbsp;are&nbsp;for&nbsp;initialising&nbsp;an&nbsp;empty&nbsp;list&nbsp;by&nbsp;pointing&nbsp;both&nbsp;n&nbsp;<BR>ext&nbsp;and&nbsp;prev&nbsp;pointers&nbsp;to&nbsp;itself.&nbsp;It&nbsp;is&nbsp;obvious&nbsp;from&nbsp;C&nbsp;syntactical&nbsp;restrictio&nbsp;<BR>ns&nbsp;which&nbsp;ones&nbsp;should&nbsp;be&nbsp;used&nbsp;where&nbsp;-&nbsp;for&nbsp;example,&nbsp;LIST_HEAD_INIT()&nbsp;can&nbsp;be&nbsp;us&nbsp;<BR>ed&nbsp;for&nbsp;structure's&nbsp;element&nbsp;initialisation&nbsp;in&nbsp;declaration,&nbsp;the&nbsp;second&nbsp;can&nbsp;be&nbsp;&nbsp;<BR>used&nbsp;for&nbsp;static&nbsp;variable&nbsp;initialising&nbsp;declarations&nbsp;and&nbsp;the&nbsp;third&nbsp;can&nbsp;be&nbsp;used&nbsp;<BR>&nbsp;inside&nbsp;a&nbsp;function.&nbsp;<BR>The&nbsp;macro&nbsp;list_entry()&nbsp;gives&nbsp;access&nbsp;to&nbsp;individual&nbsp;list&nbsp;element,&nbsp;for&nbsp;example:&nbsp;<BR>&nbsp;(from&nbsp;fs/file_table.c:fs_may_remount_ro())&nbsp;<BR>struct&nbsp;super_block&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;...&nbsp;<BR>&nbsp;&nbsp;&nbsp;struct&nbsp;list_head&nbsp;s_files;&nbsp;<BR>&nbsp;&nbsp;&nbsp;...&nbsp;<BR>}&nbsp;*sb&nbsp;=&nbsp;&amp;some_super_block;&nbsp;<BR>struct&nbsp;file&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;...&nbsp;<BR>&nbsp;&nbsp;&nbsp;struct&nbsp;list_head&nbsp;f_list;&nbsp;<BR>&nbsp;&nbsp;&nbsp;...&nbsp;<BR>}&nbsp;*file;&nbsp;<BR>struct&nbsp;list_head&nbsp;*p;&nbsp;<BR>for&nbsp;(p&nbsp;=&nbsp;sb-s_files.next;&nbsp;p&nbsp;!=&nbsp;&amp;sb-s_files;&nbsp;p&nbsp;=&nbsp;p-next)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;file&nbsp;*file&nbsp;=&nbsp;list_entry(p,&nbsp;struct&nbsp;file,&nbsp;f_list);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do&nbsp;something&nbsp;to&nbsp;'file'&nbsp;<BR>}&nbsp;<BR>A&nbsp;good&nbsp;example&nbsp;of&nbsp;the&nbsp;use&nbsp;of&nbsp;list_for_each()&nbsp;macro&nbsp;is&nbsp;in&nbsp;the&nbsp;scheduler&nbsp;where&nbsp;<BR>&nbsp;we&nbsp;walk&nbsp;the&nbsp;runqueue&nbsp;looking&nbsp;for&nbsp;the&nbsp;process&nbsp;with&nbsp;highest&nbsp;goodness:&nbsp;<BR>static&nbsp;LIST_HEAD(runqueue_head);&nbsp;<BR>struct&nbsp;list_head&nbsp;*tmp;&nbsp;<BR>struct&nbsp;task_struct&nbsp;*p;&nbsp;<BR>list_for_each(tmp,&nbsp;&amp;runqueue_head)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;list_entry(tmp,&nbsp;struct&nbsp;task_struct,&nbsp;run_list);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(can_schedule(p))&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;weight&nbsp;=&nbsp;goodness(p,&nbsp;this_cpu,&nbsp;prev-active_mm);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(weight&nbsp;&nbsp;c)&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;=&nbsp;weight,&nbsp;next&nbsp;=&nbsp;p;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>}&nbsp;<BR>Here&nbsp;p-run_list&nbsp;is&nbsp;declared&nbsp;as&nbsp;'struct&nbsp;list_head&nbsp;run_list'&nbsp;inside&nbsp;task_struc&nbsp;<BR>t&nbsp;structure&nbsp;and&nbsp;serves&nbsp;as&nbsp;anchor&nbsp;to&nbsp;the&nbsp;list.&nbsp;Removing&nbsp;an&nbsp;element&nbsp;from&nbsp;the&nbsp;l&nbsp;<BR>ist&nbsp;and&nbsp;adding&nbsp;(to&nbsp;head&nbsp;or&nbsp;tail&nbsp;of&nbsp;the&nbsp;list)&nbsp;is&nbsp;done&nbsp;by&nbsp;list_del()/list_add(&nbsp;<BR>)/list_add_tail()&nbsp;macros.&nbsp;The&nbsp;examples&nbsp;below&nbsp;are&nbsp;adding&nbsp;and&nbsp;removing&nbsp;a&nbsp;task&nbsp;&nbsp;<BR>from&nbsp;runqueue:&nbsp;<BR>static&nbsp;inline&nbsp;void&nbsp;del_from_runqueue(struct&nbsp;task_struct&nbsp;*&nbsp;p)&nbsp;<BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nr_running--;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list_del(&amp;p-run_list);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p-run_list.next&nbsp;=&nbsp;NULL;&nbsp;<BR>}&nbsp;<BR>static&nbsp;inline&nbsp;void&nbsp;add_to_runqueue(struct&nbsp;task_struct&nbsp;*&nbsp;p)&nbsp;<BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list_add(&amp;p-run_list,&nbsp;&amp;runqueue_head);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nr_running++;&nbsp;<BR>}&nbsp;<BR>static&nbsp;inline&nbsp;void&nbsp;move_last_runqueue(struct&nbsp;task_struct&nbsp;*&nbsp;p)&nbsp;<BR>{&nbsp;<BR>

⌨️ 快捷键说明

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