(萊昂氏unix原始碼分析導讀-18) 再談中斷與陷入
從產生原因看,中斷和陷入也有巨大的差別。
硬體中斷由外部事件造成,屬於非同步事件,往往與當前程序毫無關係;
陷入則不同,它常常都是同步的(如除0錯),並與當前程序上下文相關。
除此之外,陷入還用來實現系統呼叫——核心為user程序提供了大量的服務,這些服務就是通過系統呼叫
來訪問的。PDP11提供了trap指令來使user程序進入核心,進行系統呼叫。
由於系統呼叫的存在,核心在邏輯上可以分為上下兩層。上層用於為user程序提供服務,並對陷入和系統
呼叫提供響應,這部分可看作是所有程序共享的程式庫。而下層在用於處理硬體中斷,它們非同步產生,
其執行也不依賴於當前程序——儘管與當前程序可能毫無關係,中斷處理程式仍會借用當前程序的kernel stack。
系統呼叫程式碼被所有程序所共享,因此必須小心進行設計,以避免因核心資料結構共享造成的衝突和不一致
的情況。一個總的設計原則是,避免核心狀態下的程序搶佔。即如果程序正在核心態執行,其執行最好不受打擾,
除非它因等待系統資源或事件自行放棄cpu。
當然,如果不加處理程序在核心的執行過程中也會被硬體中斷搶佔。對於硬體中斷,有幾種處理方式:
(1)可能的話,可以通過設定優先順序來遮蔽某些硬體中斷;
強調一點,當上下兩層共享某核心資源時,上層程式在佔用該資源前要遮蔽下層中斷。否則,
中斷髮生後,中斷處理程式將無法獲取該資源——對系統呼叫等同步處理程式來說,它可以通過sleep等待
資源;但中斷本身為非同步事件,使它等待是無意義的。
(2)某些重要的中斷不能遮蔽,但可以在其中斷處理程式中加以判斷,
如為核心時發生的中斷,則只執行必要的操作。
因此,在程式碼中會有很多對前狀態的檢查,以確定在中斷髮生時,程序是否處於核心態。