亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区
Chinaunix
標(biāo)題:
freebsd9.2-處理器間中斷-接收處理
[打印本頁]
作者:
71v5
時間:
2014-07-06 16:16
標(biāo)題:
freebsd9.2-處理器間中斷-接收處理
[從"處理器間中斷-發(fā)送"中的描述可知]:
#define IPI_BITMAP_VECTOR 249
#define IPI_PREEMPT 1
1:已經(jīng)給cpu5發(fā)送了一個中斷向量號為IPI_BITMAP_VECTOR的IPI。
2:并且數(shù)組元素cpu_ipi_pending[5]的第IPI_PREEMPT個bit位被設(shè)置為1。
[從"內(nèi)核如何實現(xiàn)IA32中斷處理"中的描述可知]:
中斷向量號為IPI_BITMAP_VECTOR對應(yīng)的中斷處理程序為函數(shù)IDTVEC(ipi_intr_bitmap_handler)。
此時,cpu5接收到了這個IPI,在執(zhí)行中斷處理程序IDTVEC(ipi_intr_bitmap_handler)前,cpu硬件單元要做一些處理,硬件單元所做的處理可以參考
"內(nèi)核如何實現(xiàn)IA32中斷處理"結(jié)尾的描述。
這里做下面的假設(shè):
1:接收到這個IPI時,cpu5運行在用戶態(tài)。
2:接收到這個IPI時,正在cpu5運行的線程對應(yīng)的struct thread對象簡記為cur_thread。
3:cpu硬件單元已經(jīng)完成了在執(zhí)行中斷處理程序之前的處理。
此時cpu5運行在內(nèi)核態(tài),開始執(zhí)行中斷處理程序IDTVEC(ipi_intr_bitmap_handler),線程cur_thread的內(nèi)核棧如下所示:
******************************* 內(nèi)核棧頂部 高地址方向
* *
* struct pcb對象 *
* *
* *
******************************* <--cur_thread的td_pcb成員指向這里
* *
* 16bytes for vm *
******************************* <--cur_thread的內(nèi)核棧棧頂
* SS *
*******************************
* ESP *
*******************************
* EFLAGS *
*******************************
* CS *
*******************************
* EIP *
******************************* <--執(zhí)行中斷處理程序IDTVEC(ipi_intr_bitmap_handler)時,esp指向這里
* SS *
*******************************
* 0 *
*******************************
* 0 *
*******************************
* EAX *
*******************************
* ECX *
*******************************
* EDX *
*******************************
* EBX *
******************************* 通過struct trapframe類型的數(shù)據(jù)對象來描述
* ESP *
*******************************
* EBP *
*******************************
* ESI *
*******************************
* EDI *
*******************************
* DS *
*******************************
* ES *
*******************************
* FS *
******************************* <--宏P(guān)USH_FRAME和SET_KERNEL_SREGS執(zhí)行完后,esp指向這里
* addr(jmp doreti) *
******************************* <-- 執(zhí)行call ipi_bitmap_handler指令時esp指向這里
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*******************************------ 內(nèi)核棧底部 低地址方向
復(fù)制代碼
[IDTVEC(ipi_intr_bitmap_handler)]-中斷向量號IPI_BITMAP_VECTOR對應(yīng)的中斷處理程序:
304 IDTVEC(ipi_intr_bitmap_handler)
/*******************************************************************************
* 305,宏P(guān)USH_FRAME,該宏如下所示:
將線程cur_thread的用戶態(tài)硬件上下文的一部分壓入內(nèi)核棧中。
306,宏SET_KERNEL_SREGS,如下所示:
設(shè)置內(nèi)核使用的段寄存器。
307:
清DF標(biāo)志,string operations increment the index registers (ESI and/or EDI).
******************************************************/
305 PUSH_FRAME
306 SET_KERNEL_SREGS
307 cld
308
/*******************************************************************
* 309-310:
通過lapic訪問cpu5的local APIC寄存器組。
這里將對local APIC寄存器組中的EOI Register執(zhí)行一個寫操作,這是
APIC要求的,作為對這個寫操作的響應(yīng),cpu將:
Upon receiving an EOI, the APIC clears the highest
priority bit in the ISR and dispatches the next highest
priority interrupt to the processor
**********************************************/
309 movl lapic, %edx
310 movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */
311
312 FAKE_MCOUNT(TF_EIP(%esp))
313
/**********************************************************************
* 314:
通過上面內(nèi)核棧的布局,可以明顯的看出,函數(shù)ipi_bitmap_handler
的參數(shù)是一個struct trapframe類型的對象,而不是指向這個對象的指針。
316:
doreti函數(shù)完成返回中斷前的處理,這個暫時略過。
*********************************/
314 call ipi_bitmap_handler
315 MEXITCOUNT
316 jmp doreti
317 #endif
復(fù)制代碼
[宏P(guān)USH_FRAME]:
/*****************************************************************************************
* Macros to create and destroy a trap frame.
pushal指令:
Pushes the contents of the general-purpose registers onto the stack. The registers
are stored on the stack in the following order: EAX, ECX, EDX, EBX, ESP (original
value), EBP, ESI, and EDI (if the current operand-size attribute is 32)。
*********************************************/
145 #define PUSH_FRAME \
146 pushl $0 ; /* dummy error code */ \
147 pushl $0 ; /* dummy trap type */ \
148 pushal ; /* 8 ints */ \
149 pushl %ds ; /* save data and extra segments ... */ \
150 pushl %es ; \
151 pushl %fs
復(fù)制代碼
[宏SET_KERNEL_SREGS]:
/**********************************************************************************
* Setup the kernel segment registers.
此時cpu5運行在內(nèi)核態(tài),段寄存器也要更改。
173-175:
用內(nèi)核數(shù)據(jù)段的segment selector,即KDSEL加載DS,ES兩個寄存器,訪問內(nèi)核數(shù)據(jù)。
176-177:
用KPSEL加載FS寄存器,這樣就能訪問數(shù)據(jù)對象__pcpu[5],也是宏P(guān)CPU_*的基礎(chǔ)。
******************************************/
172 #define SET_KERNEL_SREGS \
173 movl $KDSEL, %eax ; /* reload with kernel's data segment */ \
174 movl %eax, %ds ; \
175 movl %eax, %es ; \
176 movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \
177 movl %eax, %fs
復(fù)制代碼
[函數(shù)ipi_bitmap_handler]:
/***********************************************************************
* 參數(shù)描述:
frame:用來訪問保存在線程cur_thread內(nèi)核棧上用戶態(tài)硬件上下文。
****************************/
1355 void
1356 ipi_bitmap_handler(struct trapframe frame)
1357 {
/***************************************************************************
* 1360,cpu:PCPU_GET宏獲取當(dāng)前cpu的logical cpu id,這里為5.
*******************************/
1358 struct trapframe *oldframe;
1359 struct thread *td;
1360 int cpu = PCPU_GET(cpuid);
1361 u_int ipi_bitmap;
/**************************************************************************
* 1364:td指向當(dāng)前正在運行線程的struct thread對象,這里為&cur_thread。
1365:
遞增td_intr_nesting_level,即遞增中斷嵌套層數(shù)。
1366-1367:
struct thread對象的td_intr_frame成員,freebsd8.3中沒有該成員,添加的
這個成員個人理解為,該成員在中斷處理程序中使用,用來訪問保存在線程
內(nèi)核棧上的硬件上下文。
1368:
函數(shù)atomic_readandclear_int返回數(shù)組元素cpu_ipi_pending[5]的值,然后
將其清零。
*****************************/
1363 critical_enter();
1364 td = curthread;
1365 td->td_intr_nesting_level++;
1366 oldframe = td->td_intr_frame;
1367 td->td_intr_frame = &frame;
1368 ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
/****************************************************************************
* 三個特殊的IPI如下:
* #define IPI_AST 0
#define IPI_PREEMPT 1
#define IPI_HARDCLOCK 2
* 1369-1386:
依次測試變量的ipi_bitmap的第1,0,2個比特位,檢查發(fā)送
的是上面三個特殊IPI的哪一個,并遞增相應(yīng)的計數(shù)器。
1369-1374:
發(fā)送的是IPI_PREEMPT,此時調(diào)用調(diào)度程序相關(guān)的sched_preempt函數(shù),當(dāng)
sched_preempt函數(shù)執(zhí)行完后,cpu5上的線程cur_thread被成功搶占。
1375-1380:
發(fā)送的是IPI_AST,此時不做處理。
1381-1386:
發(fā)送的是IPI_HARDCLOCK,此時調(diào)用函數(shù)hardclockintr。
******************************************************/
1369 if (ipi_bitmap & (1 << IPI_PREEMPT)) {
1370 #ifdef COUNT_IPIS
1371 (*ipi_preempt_counts[cpu])++;
1372 #endif
1373 sched_preempt(td);
1374 }
1375 if (ipi_bitmap & (1 << IPI_AST)) {
1376 #ifdef COUNT_IPIS
1377 (*ipi_ast_counts[cpu])++;
1378 #endif
1379 /* Nothing to do for AST */
1380 }
1381 if (ipi_bitmap & (1 << IPI_HARDCLOCK)) {
1382 #ifdef COUNT_IPIS
1383 (*ipi_hardclock_counts[cpu])++;
1384 #endif
1385 hardclockintr();
1386 }
/********************************************************
* 1387:將td_intr_frame成員恢復(fù)到之前的值。
1388:遞減td_intr_nesting_level,即中斷嵌套數(shù)減1.
*******************************/
1387 td->td_intr_frame = oldframe;
1388 td->td_intr_nesting_level--;
1389 critical_exit();
1390 }
復(fù)制代碼
[ULE線程調(diào)度-sched_preempt函數(shù)]:
/*******************************************************************
* 函數(shù)sched_preempt就是調(diào)用mi_switch函數(shù)執(zhí)行一個線程切換,執(zhí)行
完后,線程cur_thread被成功搶占。
2130:tdq此時為&tdq_cpu[5].
2132:將tdq_ipipending設(shè)置為0,表示相應(yīng)的IPI已經(jīng)處理。
2133-2143:
再次檢查是否需要搶占線程cur_thread,這里簡單的比較兩個優(yōu)先級。
如果需要搶占,就設(shè)置合適的標(biāo)志來調(diào)用mi_switch函數(shù)完成線程切換。
***********************************/
2122 void
2123 sched_preempt(struct thread *td)
2124 {
2125 struct tdq *tdq;
2126
2127 SDT_PROBE2(sched, , , surrender, td, td->td_proc);
2128
2129 thread_lock(td);
2130 tdq = TDQ_SELF();
2131 TDQ_LOCK_ASSERT(tdq, MA_OWNED);
2132 tdq->tdq_ipipending = 0;
2133 if (td->td_priority > tdq->tdq_lowpri) {
2134 int flags;
2135
2136 flags = SW_INVOL | SW_PREEMPT;
2137 if (td->td_critnest > 1)
2138 td->td_owepreempt = 1;
2139 else if (TD_IS_IDLETHREAD(td))
2140 mi_switch(flags | SWT_REMOTEWAKEIDLE, NULL);
2141 else
2142 mi_switch(flags | SWT_REMOTEPREEMPT, NULL);
2143 }
2144 thread_unlock(td);
2145 }]
復(fù)制代碼
歡迎光臨 Chinaunix (http://www.72891.cn/)
Powered by Discuz! X3.2