




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Lecture8
LinuxInterruptandtimer中斷機制中斷基本知識異常處理外部中斷處理中斷的后半部分處理機制一、中斷基本知識1.中斷向量Intelx86系列微機共支持256種向量中斷,按0~255編號,即賦予一個中斷類型碼,linux中稱其為中斷向量。所有的256種中斷可分為中斷和異常兩大類。異常又分為故障和陷阱,它們的共同特點是既不使用中斷控制器,又不能被屏蔽。中斷又分為外部可屏蔽中斷和外部非屏蔽中斷。所有的I/O設備產生的中斷請求均引起可屏蔽中斷,而緊急事件引起的故障產生非屏蔽中斷。非屏蔽中斷的向量和異常的向量是固定的,而可屏蔽中斷的向量可以通過對中斷控制器的編程來實現。從0~31的向量對應于異常和非屏蔽中斷從32~47的向量分配給屏蔽中斷從48~255的向量用來標志軟中斷(由intn指令產生),
linux只用了一個:128(0x80)向量異常和非屏蔽中斷0 除法出錯 SIGFPE 故障 被0除1 調試 SIGTRAP 故障/陷阱 對程序進行逐步調試2 非屏蔽中斷(NMI)3 斷點 SIGTRAP 陷阱 由Int3斷點指令引起4 溢出 SIGSEGV 陷阱 當into(checkforoverflow)指令被執行5 邊界檢查 SIGSEGV 故障 當bound指令被執行6 非法操作碼 SIGILL 故障 當CPU檢查到一個無效操作碼7 設備不可用 SIGSEGV 故障 隨著CR0的TS設置,ESCAPE或MMX指令被執行8 雙重故障 SIGSEGV 故障 處理器不能串行處理異常引起9 協處理器段越界 SIGFPE 故障 因外部的數學協處理器引起的問題(僅用在80386)10 無效TSS SIGSEGV 故障 要切換到的進程具有無效的TSS11 段不存在 SIGBUS 故障 引用一個不存在的內存段12 棧段異常 SIGSEGV 故障 試圖超越棧段界限,或由ss標志的段不在內存13 通用保護 SIGSEGV 故障 違反了Intelx86保護模式下的一個保護規則14 頁異常 SIGSEGV 故障 尋址的頁不在內存,或違反了一種分頁保護機制15 Intel保留16 浮點出錯 SIGFPE 故障 浮點單元用信號通知一個錯誤情況,如溢出17 對齊檢查 SIGSEGV 故障 操作數的地址沒有被正確地排列18~31Intel保留2.外設可屏蔽中斷Intelx86通過兩片中斷控制器8259A來響應15個外部中斷源,每個8259A可管理8個中斷源。并非每個設備都可以向中斷線(與中斷控制器相連的每條線)上發中斷信號,只有擁有了某條中斷線的控制權,才可以向這條中斷線上發送信號。中斷線是非常寶貴的資源,必須采取只有當設備需要中斷的時候才申請占用一個IRQ,或者是在申請IRQ時采用共享中斷的方式。外設可屏蔽中斷
32 IRQ0 時鐘
33 IRQ1 鍵盤
35 IRQ3 tty2 36 IRQ4 tty1 37 IRQ5 XTWinchester 38 IRQ6 軟驅
39 IRQ7 打印機
40 IRQ8 實時時鐘
41 IRQ9 重定向的IRQ2 45 IRQ13 FPU異常
46 IRQ14 ATWinchester8259A執行的操作監視中斷線,檢查產生的IRQ信號如果在中斷線上產生了一個IRQ信號把接收的IRQ信號轉換成一個對應的向量。(IRQn的缺省向量是n+32)把這個向量存放在8259A的一個I/O端口,從而允許CPU通過數據總線讀此向量。把產生的信號發送到CPU的INTR引腳——發出一個中斷。等待,直到CPU確認這個中斷信號,然后把它寫進PIC的一個I/O端口,此時清INTR線返回第一步8259A對外部I/O請求的屏蔽可分為兩種情況:
a清除EFLAGS的IF位,禁止所有外部的I/O中斷請求
b中斷控制器中有一個8位的中斷屏蔽寄存器,每位對應于8259A中的一條中斷線,如果要禁用某條中斷線,把IRM相應位置1中斷路由的邏輯圖3.中斷描述符表IDTIntel系統利用中斷描述符表將中斷向量和其處理程序對應起來。IDT是一個描述符數組,每一個元素由8個字節組成,叫做門描述符。每個中斷向量對應一個門描述符。中斷描述符表
DLP 段描述符的特權級 偏移量 入口函數地址的偏移量
P 段是否在內存中的標志 段選擇符 入口函數所處代碼段的選擇符
D 標志位,1=32位,0=16位
XXX 三位門類型碼
偏移量31~16|P|DPL|0DXXX|000|?????
段選擇符|
偏移量15~0任務門類型碼為101,門中包含一個進程的TSS段選擇符,不使用偏移量,故不包含一個函數的入口地址,Linux中一般不用任務門進行任務切換。中斷門
類型碼為110,控制權通過中斷門進入處理程序時關中斷。中斷門中的DPL為0,所有的中斷處理程序都由中斷門激活,并全部限制在內核態。中斷時清IF標志,關中斷以防止中斷嵌套。陷阱門類型碼為111,控制權通過陷阱門進入處理程序時不關中斷,即IF標志位不變。系統門是Linux內核特別設置的,用來讓用戶態的進程訪問Intel的陷阱門,DPL為3。通過系統門激活3,4,5,0x80中斷。4.IDT的初始化Linux內核在系統的初始化階段進行大量的初始化操作初始化可編程控制器8259A8259A內部有4個中斷命令字寄存器,8259A初始化的目的是為了寫入有關命令字,并利用8259A內部的相應寄存器鎖存這些命令字,以控制8259A的工作。對IDTR進行初始化把IDT表的起始地址裝入IDTR用setup_idt()函數填充IDT表中的256個表項在對IDT表進行了預初始化后,內核將在啟用分頁功能后對IDT表進行第二遍的初始化,用實際的陷阱和中斷處理程序替換空的處理程序。注意:在Intel體系結構中提供了四個特權級,編號從0到3,其中0是最高特權級,3級是最低特權級。系統中每個段都有自己的特權級,系統中每個任務也都有自己的特權級。特權級低的任務不能直接調用高特權級的子程序,也不能存取高特權級的數據段。DPL——描述符的特權級CPL——當前任務的特權級注意:CPU為保護模式增設了一個IDTR,用來存放中斷描述符表在內存的起始地址。
中斷處理與當前進程有關。中斷處理程序運行在當前進程的地址空間,使用的是當前進程的系統堆棧。32位基地址16位界限4716150中斷描述符表寄存器IDTR5.中斷和異常的硬件處理要求在一個中斷和異常發生后,cpu將做以下事情:確定所發生的異常或中斷向量i通過IDTR寄存器找到IDT表,讀取IDT表第i項該中斷處理程序所在段的DPL必須小于或等于當前代碼段的CPL對于軟中斷,要求CPL<=中斷或陷阱門的DPL硬件中斷不檢查特權級檢查是否發生了特權級的變化,即是否需要切換堆棧發生中斷時系統運行在核心態發生中斷時系統運行在用戶態二、異常
異常是cpu內部出現的中斷,即在cpu在執行特定指令時出現的非法情況。非屏蔽中斷是在計算機內部硬件出錯時引起的異常情況,intel把非屏蔽中斷作為一種異常來處理。在CPU處理一個異常處理程序時,不再為其他異常或可屏蔽中斷請求服務。Linux異常中斷向量在0~31之間,目前發布了大約20種。內核對異常處理程序的調用分成三個部分:在內核棧中保存寄存器的值先是順序壓入各寄存器的值,并調整棧頂滿足pt_regs結構。(要注意當異常發生時,如果控制單元沒有自動地把一個硬件錯誤代碼插入到棧中。系統會自動執行一條push$0指令,在棧中墊入一個空值。如果錯誤代碼已經壓入堆棧,則接下來把異常處理函數的地址壓入堆棧。)最后壓入指向pt_regs的指針和錯誤代碼。用call指令調用異常處理函數(使用當前棧頂的兩個參數)通過ret_from_exception從異常退出,并進行異常善后處理。有無激活的底半處理,有則轉入底半處理。被中斷進程運行在核心態,簡單彈出棧頂各寄存器的值,恢復被中斷的進程。被中斷進程運行在用戶態,如當前進程需要調度,則運行調度函數,重新調度進程。如當前進程不需要調度,但如果當前進程上有待處理信號,則先處理信號再彈出寄存器值,并返回被中斷進程。如果沒有待處理信號則彈出寄存器值,返回被中斷進程。
內核堆棧指針ESP用戶棧的SS用戶棧的ESPEFLAGS用戶空間的CSEIP錯誤碼或0函數地址DSEAXEBPEDIESIEDXECXEBX進入異常處理程序時內核堆棧示意圖內核堆棧指針ESP用戶棧的SS用戶棧的ESPEFLAGS用戶空間的CSEIP-1ESDSEAXEBPEDIESIEDXECXEBX錯誤碼ESP異常處理程序被調用后內核堆棧示意圖三、外部中斷Linux把每個外部中斷處理程序分為兩個部分:固定部分:由系統所定義,設置在IDT中,不能隨意修改。可變部分:由各個設備驅動程序定義,在設備初始化時設定,在不需要時可以將其清除或卸載。發生外部中斷時,系統經過中斷處理的固定部分進入可變部分。在處理外部中斷的過程中,通常關掉中斷,所以中斷處理程序越短愈好。(一)固定部分外部中斷初始化函數init_IRQ()中利用IRQn_interrupt創建0~15號中斷門,并根據IRQ號填入IDT表中。每個外部中斷處理程序的固定部分所做的工作為:將IRQ號壓入堆棧將各通用寄存器的值壓入堆棧(SAVE_ALL)
將中斷返回地址ret_from_intr壓入堆棧利用jmp指令跳轉到do_IRQ()執行(do_IRQ根據堆棧中的IRQ號完成真正的中斷處理)(二)可變部分由于外部中斷處理程序具有可變部分,而且由于硬件限制,許多外部設備不得不共享同一個IRQ,并且各IRQ對應的處理程序可以在運行中動態改變。Linux為每一個IRQ設置了一個隊列,即中斷請求隊列。對于224個中斷向量,每一個IRQ,Linux都用一個irq_desc_t結構來描述,稱為IRQ描述符,形成一個irq_desc[]數組。
typedefstruct{ unsignedintstatus; //中斷線狀態
hw_irq_controller*handler; //指向hw_interrupt_type描述符
structirqaction*action; //單鏈表指針
unsignedintdepth; //0表示可用,每用一次加1
spinlock_tlock; // }__cacheline_alignedirq_desc_t;1.可變部分的數據結構Status:描述IRQ中斷線狀態的一組標志#defineIRQ_INPROGRESS1#defineIRQ_DISABLED2#defineIRQ_PENDING4#defineIRQ_REPLAY8#defineIRQ_AUTODETECT16#defineIRQ_WAITING32handler:指向hw_interrupt_type描述符,該結構是對中斷控制器的操作。
structhw_interrupt_type{//是對一個中斷控制器的抽象,其主要內容是對中斷控制器的操作
constchar*typename; //控制器的可讀名
unsignedint(*startup)(unsignedintirq); //等同于enable void(*shutdown)(unsignedintirq); //等同于disable
void(*handle)(unsignedintirq); void(*enable)(unsignedintirq); // void(*disable)(unsignedintirq); //
void(*ack)(unsignedintirq); // void(*end)(unsignedintirq); // void(*set_affinity)(unsignedintirq,unsignedlongmask); // }typedefstructhw_interrupt_typehw_irq_controller;action:指向一個單項鏈表的指針,此鏈表是對中斷服務例程進行描述的irqaction結構。depth;如果啟用該中斷線,depth則為0。如果禁用不止一次,則為一個正數。注意:disable_irq()和enable_irq()
對IRQ描述符的初始化由init_ISA_irqs()完成2.中斷服務例程及描述符irqaciton中斷服務例程描述符irqaction,描述了一個外部中斷處理的可變部分。
structirqaction{ void(*handler)(int,void*,structpt_regs); //指向一個具體的中斷服務例程
unsignedlongflags; //一組標志描述中斷線與I/O設備之間的關系
unsignedlongmask; // constchar*name; //I/O設備名
void*dev_id; //指定I/O設備的主設備號和次設備號
structirqaction*next; }handler:指向一個具體I/O設備的中斷服務例程,這是允許多個設備共享同一中斷線的關鍵。
flags:用一組標志來描述中斷線與I/O設備之間的關系:
SA_INTERRUPTSA_SHIRQSA_SAMPLE_RANDOMSA_PROBEname:I/O設備名
dev_id:指定I/O設備的主設備號和次設備號。
next:指向irqaction描述表鏈表的下一個元素。3.對數組irq_decsc所作的初始化
4.中斷請求隊列的初始化在設備驅動程序的初始化階段,每個設備驅動程序都要創建自己的irqaction結構,通過request_irq()函數將對應的中斷服務例程掛入中斷請求隊列。
intrequest_irq(unsignedintirq,void(*handler)(int,void*,structpt_regs*),unsignedlongirqflags,constchar*devname,void*dev_id)檢查參數的合法性向內核內存管理器申請一塊內存,用于建立irqaction結構根據參數填寫申請到的irqaction結構調用函數setup_x86_irq,將填寫好的irqaction結構掛到irq_desc[irq]的action隊列上。setup_x86_irq(unsignedintirq,structirqaction*new)在數組irq_desc[]中找到參數irq對應的action隊列如果隊列不為空,說明有多個設備共享該IRQ號,檢查共享的合法性,并將新irqaction結構掛在對應action隊列的末尾。如果隊列為空,則將irqaction結構掛在對應action隊列的頭部。并填寫對應數組項的其它域。
5.釋放中斷處理程序利用free_irq()函數來完成
voidfree_irq(unsignedintirq,void*dev_id)
根據irq找到某條中斷線,若該中斷線是非共享的,則刪除處理程序的同時禁用該中斷線。若該中斷線是共享的,則僅刪除dev_id對應的處理程序,該中斷線只有在刪除了所有的處理程序才會被禁用。6.中斷處理程序的執行外部中斷處理函數do_IRQ()函數handle_IRQ_event()函數voiddo_IRQ(structpt_regsregs)從棧頂取出IRQ號根據取出的IRQ號從irq_desc[]數組中找到對應的hw_interrupt_type類型,并執行其handle子程序。handle執行完后,中斷的上半部分已經完成。檢查底半處理是否需要執行。do_IRQ執行完畢則返回。
staticvoiddo_8259A_IRQ(unsignedintirq,structpt_regs*regs)
向8259A發送信號,暫時禁止目前處理的IRQ中斷清除irq_desc[irq].status中的IRQ_REPLAY和IRQ_WAITING位若IRQ的狀態中包含IRQ_DISABLE|IRQ_INPROGRESS,則說明該IRQ被禁止或正在處理,則不能坐任何工作,返回。否則,將irq_desc[irq].status中加入IRQ_INPROGRESS位,并找到該IRQ對應的action隊列。如果action隊列為空,則返回調用handle_IRQ_event(),處理action隊列。從handle_IRQ_event()返回,去掉IRQ標記中的IRQ_INPROGRESS位,表示該中斷處理已完成。解除對該IRQ中斷的禁用inthandle_IRQ_event(unsignedintirq,structpt_regs*regs,
structirqaction*action)調用函數irq_enter(cpu,irq),阻止進入底半處理對于慢速中斷,在做上半部分處理時允許再次中斷,故打開中斷。進入循環,順序調用action隊列上的各個處理函數,完成真正的中斷處理。關掉中斷調用irq_exit(cpu,irq),允許進入底半處理。7.從中斷返回do_IRQ的返回地址是ret_from_intr在ret_from_intr處檢查被中斷程序的運行模式若被中斷程序運行在核心態,則彈出棧頂各寄存器的值并恢復該進程的執行。若被中斷進程運行在用戶態,則要視其是否需要調度和該進程上是否有信號來分別處理。8.自動探測IRQ號探測IRQ號的順序P96probe_irq_on()函數probe_irq_off()函數四、中斷處理的后半部分中斷服務例程一般是在中斷請求關閉的情況下執行的,而關中斷時間過長,會導致cpu不能及時響應其他的中斷請求,從而造成中斷的丟失。故Linux在設計內核時,希望盡可能快地處理完中斷,把更多的處理向后推遲。Linux定義了兩種中斷,快速中斷和慢速中斷。慢速中斷本身可以再被中斷,快速中斷不允許再被中斷。因此,內核把中斷處理的可變部分分成兩個部分,前半部分和后半部分,前半部分內核立即執行,而后半部分留著稍后處理。補充:對于后半部分通常在中斷一返回就可以馬上執行,且在后半部分運行時,允許響應所有的中斷。1.bottomhalf(bh)機制與bh機制相關的數據結構intbh_mask_count[32];unsignedlongbh_active;unsignedlongbh_mask;void(*bh_base[32])(void);bh_mask_count[]是底半處理的屏蔽計數,每個底半處理對應其中的一項。指針數組bh_base[]的每一項都指向一個底半處理程序。bh_active表示底半程序是否被激活。bh_mask表示是否安裝了底半處理程序。他們中的每一位都對應著數組中一項。只有在安裝并激活了第N個底半處理時,才能調用第N個底半處理程序bh的初始化由init_bh()完成將相應的底半處理程序注冊到bh_base[]中的操作。inlinevoidinit_bh(intnr,void(*routine)(void))bh卸載卸載已注冊的底半處理
inlinevoidremove_bh(intnr)將bh_mask中的相應位清0,表示該底半處理不可再用清除在數組bh_base中注冊的處理函數禁止和恢復bhinlinevoiddisable_bh(intnr)將變量bh_mask的nr位清0,表示底半處理不可再用。將bh_mask_count[nr]加1inlinevoidenable_bh(intnr)將bh_mask_count[nr]減1如果其為0,則將變量bh_mask的nr位置1,表示底半處理可用。bh的執行首先利用mark_bh(intnr)激活bh_active中的nr位。每次執行完do_IRQ()中的中斷服務例程以后,每次系統調用結束之前,以及當被中斷進程運行在用戶態且需要調度,在作進程調度之前,在do_bottom_half()中執行相應的bh函數,且do_bottom_half()對bh的執行是在關中斷的情況下執行的。在do_bottom_half()中真正的底半操作由run_bottom_half()完成調用宏get_active_bhs(),取出激活且安裝的底半處理。調用宏clear_active_bh(),將上一步取出項所對應的變量bh_active中的激活位清0根據取出的激活位,順序執行在bh_base[]中注冊的底半處理操作bh機制的特點:具有“串行化”的特點,不適合于多cpu結構。2.軟中斷機制軟中斷機制也是推遲內核函數的執行,與bh函數嚴格的串行執行相比,軟中斷在任何時候都不需要串行化,同一個軟中斷的兩個實例完全可能在兩個CPU上同時執行。因此軟中斷是可重入的,這給網絡部分帶來了好處。軟中斷本身是一種機制,既包含了bh機制,也包含了tasklet機制。軟中斷的執行首先用open_softirq進行初始化,然后通過softirq_init()執行軟中斷。一個注冊的軟中斷必須在標記以后才會被執行。通常中斷處理程序會在返回前標記它的軟中斷,使其在稍后執行。內核在do_IRQ()中執行完一個中斷請求隊列中的中斷服務例程以后,都要檢查是否有軟中斷請求在等待執行。在檢測到軟中斷請求后,在調用do_softirq()來執行軟中斷服務例程。軟中斷機制的特點其執行是“并行的”,可以重入的,即允許不同的cpu同時進入對軟中斷服務例程的執行,但不能讓它們相互干擾。3.tasklet機制是建立在軟中斷機制的基礎上,與bh機制類似。tasklet的初始化方法很多,可以靜態創建,也可以動態創建。動態創建的方法之一:由tasklet_init()完成tasklet的使用通過調用tasklet_schedule(),激活它的tasklet_struct中指針所指向的服務程序。在tasklet被調用以后,只要有可能就盡可能早的運行,若某個tasklet還沒得到運行機會之前又有一個相同的tasklet又被調度了,經過檢查重復后,他只運行一次。若它已開始運行,那么新的tasklet會被重新調度并且再次運行。tasklet的特點同一個tasklet只能運行在一個cpu上,而不同的tasklet可以同時運行在不同的cpu上,即tasklet是非重入的。IRQ鎖軟IRQ鎖 有時不希望系統做底半處理,如系統正在做底半處理時被中斷,此時不希望在中斷的上半部分處理完以后再次進入底半處理。unsignedintlocal_bh_count[NR_CPUS]start_bh_atomic(void)用來禁止底半處理
end_bh_atomic(void)恢復底半處理
softirq_trylock(cpu)判斷是否允許進入底半處理
softirq_endlock(cpu)允許底半處理以上4個函數是在關中斷情況下執行.硬IRQ鎖 除了軟件IRQ鎖以外,Linux還提供硬IRQ鎖,一般情況下,硬件的開中斷和關中斷不受限制,但在特殊情況下必需限制硬件的開關中斷,如在做中斷的上半部分處理時的開中斷就必需限制。硬IRQ鎖通過unsignedintlocal_irq_count[NR_CPUS]來實現。IRQ鎖的作用 底半處理既使用了軟IRQ鎖,也使用了硬IRQ鎖。實際上,定義IRQ鎖的目的主要是為了控制底半處理的重入。Linux的時鐘管理時鐘中斷時鐘中斷處理過程底半處理系統時間更新進程時間片定時器中斷和時鐘中斷時鐘中斷是需要操作系統內核特別處理的一個外部中斷時鐘中斷是操作系統的脈搏:維護系統時間、統計運行數據、設計計時時鐘、促使進程切換、監督系統工作時鐘中斷時間系統(即時鐘)是計算機系統非常重要的組成部分PC機有兩個時鐘源:實時時鐘(RTC)和OS時鐘RTC也叫CMOS時鐘,是主板上的一塊靠電池供電的晶片(晶振),獨立于OS,也稱為硬件時鐘,為計算機提供計時標準,是最底層的時鐘數據OS時鐘由硬件(定時/計數器)和軟件(時鐘中斷處理程序)組成。定時/計數器從RTC接收輸入脈沖,并計數,每次計數到期就產生一個輸出脈沖,再從頭計數
可編程定時/計數器由計數硬件和通信寄存器組成,通信寄存器負責在計數硬件和操作系統之間通信時鐘中斷產生過程IRQ08259A-1中斷控制器8253/8254定時/記數器RTC晶振1.193180MHzOut0Out1Out2DRAM刷新揚聲器接CPU中斷輸入端時鐘中斷處理過程OS注冊時鐘中斷處理程序timer_interrupt1、定時/計數器產生輸出脈沖時,中斷處理器送出中斷信號,CPU根據IRQ號查中斷描述符表IDT,找到并執行中斷處理程序IRQ00_interrupt2、跳到do_IRQ3、do_IRQ執行handle程序do_8259A_IRQ4、do_8259A_IRQ執行timer_interrupt5、timer_interrupt調用do_timer完成上半部分處理。do_timer定義如下:voiddo_timer(structpt_regs*regs){ (*(unsignedlong*)&jiffies)++;lost_ticks++; mark_bh(TIMER_BH);if(!user_mode(regs))lost_ticks_system++; if(tq_timer) mark_bh(TQUEUE_BH);}6、timer_interrupt返回后,do_8259A_IRQ返回到do_IRQ7、底半處理8、返回到ret_from_intr,這里或者返回到被中斷的進程,或者啟動調度程序,完成新一輪調度底半處理1、時鐘底半處理函數timer_bh定義2、時鐘任務隊列處理函數tqueue_bh定義3、底半處理的工作(1)更新系統時間(2)更新當前進程時間片(3)處理老定時器(4)處理新定時器(5)處理時鐘任務隊列系統時間系統時間結構
structtimeval{inttv_sec;//秒
inttv_usec;//微秒
}初始化:函數time_init從CMOS時鐘取出當前時間,通過函數mktime轉化成自1970-01-0100:00:00以來的秒數,存入全局變量xtime.tv_sec中,將xtime.tv_usec初始化為0累計系統時間
voidupdate_wall_time(unsignedlongticks)
其中ticks是從上次時鐘中斷底半處理以來已經過去的tick數,一般為1。
update_wall_time完成的工作Xtime.tv_usec+=tick+time_adjust_step;根據變量time_adj、time_phase調整xtime.tv_usec;Ticks--;如果ticks>0,則轉第一步調整xtime值,累計秒數,減少微秒數:if(xtime.tv_usec>=1000000){xtime.tv_usec-=1000000;xtime.tv_sec++;second_overflow();}時間的轉換和修改
LINUX提供多個系統調用來轉換和設置系統時間更新進程時間片反映進程運行情況,若時間片用完則通知當前進程放棄CPU通過函數update_process_times更新時間片(1)計算從上次底半處理后在用戶態發生的時鐘中斷次數:user=ticks-system;
(2)如果當前進程不是0號進程,則a.進程時間片減ticks:current->counter-=ticks;b.若時間片已用完,則要求進程放棄CPU:
if(p->counter<0){p->counter=0;p->need_resched=1;}c.根據user調整變量kstat中的統計信息
(3)調用函數update_one_process修改當前進程的其它與時間相關的信息函數update_one_processa.累計進程在當前CPU消耗的用戶態時間:
p->per_cpu_utime[cpu]+=user;b.累計進程在當前CPU消耗的核心態時間:
p->per_cpu_stime[cpu]+=system;c.累計進程消耗的用戶態時間:
p->times.tms_utime+=user;d.累計進程消耗的核心態時間:
p->times.tms_stime+=system;e.若進程消耗總時間超過當前時間界限,則在總量達到整秒時向進程發送SIGXCPU信號f.若進程消耗總時間超過最大時間界限,則向進程發送SIGKILL信號,強行殺死進程
h.若進程定義有virtual定時器,則根據消耗的用戶態時間處理它
i.若進程定義有prof定時器,則根據消耗的用戶態和核心態時間處理它定時器在進程運行時,系統提供的virtual和prof定時器可以實現定時為了在任何時候都能夠定時,LINUX提供兩類根據系統時間定時且與進程狀態無關的定時器:老定時器和新定時器老定時器結構
structtimer_struct{unsignedlongexpires;//終止時間
void(*fn)(void);//到期要執行的函數
}最多有32個老定時器系統定義一個位圖timer_active來標識已注冊并處于活動狀態的定時器,如果某位被置1則相應的定時器活動通過以下函數在底半處理中檢查并處理老定時器:
run_old_timers
順序搜索位圖,發現某位被設置就檢查是否到期。如果到期就清除位圖中該定時器的標記,表示處理完成;執行定時器指定操作tp->fn();每處理一個定時器就開一次中斷sti()新定時器新定時器結構
structtimer_list{structtimer_list*next;structtimer_list*prev;unsignedlongexpires;//終止時間
unsignedlongdata;void(*function)(unsignedlong);};其中data是傳給處理函數function的參數next和prev兩個指針將定時器連成雙向鏈表tvecstv5tv4tv301234indexindextimer_l
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件設計師項目管理相關試題及答案
- 2025年制造業綠色供應鏈與綠色供應鏈管理技術發展趨勢報告
- 網絡裝備的選購建議與試題及答案
- 應對西方政治制度考試的策略試題及答案
- 網絡工程師在項目管理中的重要性試題及答案
- 獨辟蹊徑2025年信息工程試題及答案
- 機電工程國際合作試題及答案
- 公共政策對生態環境保護的促進作用試題及答案
- 機電工程實驗技能考查試題及答案2025
- 機電工程中環境保護的實踐與試題與答案
- 《國際物流學》課程教學大綱
- 自行車銷售合同
- 喀斯特地區山林治理的生態恢復措施
- 足浴技師補助協議書
- 理化因素所致的疾病總論
- 餐飲股東合作協議書范本(2篇)
- 法定傳染病監測與報告管理
- GB/T 22795-2008混凝土用膨脹型錨栓型式與尺寸
- 藍莓栽培技術課件
- 部編五年級下冊道德與法治第二單元《公共生活靠大家》知識要點復習課件
- 清淤工程施工記錄表
評論
0/150
提交評論