Kernel Strucure
Critical-Sections
critial-section是一段程式碼,在共享資源的情況下可能會有race condition的發生。
uC/OS-II裡關於critical-section的實作是定義在
OS_ENTER_CRITIAL() 和 OS_EXIT_CRITIAL() 兩個marco裡
關於這兩個macro uC/OS-II有三種實作方式
1. 中斷開啟和關閉的組語指令。
2. 儲存中斷狀態在stack上或從stack上載回中斷狀態。
3. PSW(Processor Status Word) 存入記憶體的變數或從記憶體變數載回。
OS_CRITICAL_METHOD == 1
這是最簡單的作法OS_ENTER_CRITICAL()用Intel組語DI,OS_EXIT_CRITICAL()用EI。
缺點是當有一個程式先DI之後他去呼叫一個function,然後那個function再return卻使用了EI,這樣就造成了進入funtionc前後,Interrupt狀態不一致的,而我們希望他是一致的,比較方便程式撰寫和除錯。
OS_CRITICAL_METHOD == 2
第二種方法是將OS_ENTER_CRITICAL()PSW放進stack裡後再DI,藉此將interrupt status紀錄下來,
OS_EXIT_CRITICAL()再去將PSW pop回去, 回到之前的status。
#define OS_ENTER_CRITICAL () \
asm(" PUSH PSW ") \
asm(" DI ")
#define OS_EXIT_CRITICAL() \
asm(" POP PSW ")
缺點是如果compiler不是很支援in line code的最佳化時,compiler可能不會知道SP有改變,
或是如果在OS_EXIT_CRITICAL前SP的指標被換了,那可能就會造成錯誤效果。
OS_CRITICAL_METHOD == 3
有些compiler有提供方法(C function)去取得PSW的值,然後將它存在local variable裡。
之後離開critical section後再從variable裡resotre回PSW裡。
這種方法解決的前兩種方法可能會遇到的問題。
void uCOS_II_Service(arguments)
{
OS_CPU_SR cpu_sr;
.
cpu_sr = get_processor_psw();
disabl_interrupts();
.
/* Critical section */
.
set_processor_psw(cpu_sr);
}
沒有留言:
張貼留言