2012-04-09 22 views
9

我正在研究各種OS設計,希望爲DCPU-16編寫一個簡單的多任務操作系統。然而,我所讀到的關於搶先式多任務實施的一切都以中斷爲中心。這聽起來像是在16位硬件和軟件時代,合作式多任務處理更爲常見,但這需要每個程序都以多任務處理的方式編寫。在無中斷DCPU-16上可以實現搶先式多任務操作系統嗎?

有沒有辦法在無中斷架構上實現搶先式多任務處理?我所能想到的只是一個能動態切換任務的解釋器,但這會帶來巨大的性能下降(如果必須解析每個操作並且不讓任何東西在本機運行,可能會達到10-20x +的量級)想象)。

+0

注意DCPU-16現在有中斷的下一個「功能」和指針數據的任務。 – blueshift 2012-05-05 03:42:32

+0

是嗎?截至2014年5月4日,網站上提供的文檔版本(http://0x10c.com/doc/dcpu-16.txt)仍然是1.1,並且沒有中斷。有沒有關於新功能的文檔? – 2012-05-05 03:58:23

+0

我假設你沒有reddit或使用論壇。檢查[這個壞男孩(規範1.7)](http://pastebin.com/raw.php?i=Q4JvQvnM)了!我們在freenode IRC#0x10c-dev上討論這個問題,如果你想放棄的話。 – blueshift 2012-05-05 04:00:00

回答

4

搶先式多任務通常通過讓中斷例程向調度器發佈狀態更改/感興趣的事件來實現,該事件決定要暫停哪些任務以及根據優先級啓動/繼續哪些新任務。但是,當正在運行的任務調用OS例程時,可能會發生其他有趣的事件,這可能會產生相同的效果。

但重要的是某個事件在某處被注意到,而調度程序決定運行的人。因此,您可以使所有此類事件信號/調度僅在OS調用中發生。

您可以在各種任務應用程序代碼中的「方便」點向調度程序添加令人震驚的調用,以使您的系統更頻繁地切換。無論是隻是切換,還是使用一些背景信息,如自上次調用以來經過的時間都是調度程序的詳細信息。

你的系統不會像中斷驅動那樣快速響應,但是你已經通過選擇你所選擇的CPU來做出響應。

+1

所以這有合作性多任務的缺點,因爲沒有嚴格的上限,CPU可以在沒有觸發調度器的情況下運行多長時間(例如,如果進程進入不涉及任何OS調用的循環),但是因爲它爲調度目的劫持OS調用,它可以在任何使OS調用的程序上工作? – 2012-04-09 05:21:59

+2

@AndrewG。究竟。這就是Classic Mac OS如何添加多任務,最初是作爲系統5中的擴展。對OS的適當調用被視爲合作性多任務機會。正如你所說,沒有嚴格的上限 - 例如一個大概由設計錯誤引起的進程在沒有OS調用的情況下進入無限循環會掛起整個系統。 – Tommy 2012-04-09 05:31:30

+0

@Tommy這是一個硬件看門狗定時器,它聲明CPU復位和內存重置例程,將堆棧退回到程序入口點。看到我的解釋爲什麼這不是非常瘋狂。 – 2012-04-09 05:39:46

2

我認爲你的評估是正確的。如果調度程序可以中斷(在非變形的字典意義上)正在運行的任務並自動切換到另一個任務,則會發生搶先式多任務處理。所以必須有某種角色提示調度員採取行動。如果沒有中斷設備(從技術角度來說是變化的),那麼一般情況下你可以做的事情很少。

但是,不是轉換到完整的解釋器,而是發生的一個想法是動態重新編程提供的程序代碼。所以在進入一個進程之前,調度程序知道完整的進程狀態,包括它將要輸入的程序計數器值。然後它可以從那裏向前掃描,替換第二十個指令代碼或下一個不是立即在程序計數器處的跳轉指令代碼,跳回調度器。當進程返回時,調度器將原始指令放回。如果是跳轉(有條件的或其他),則它也會適當地實現跳轉。

當然,只有程序代碼不能動態修改自己時,該方案纔有效。在這種情況下,您可以對其進行預處理,以便事先知道跳躍沒有進行線性搜索的位置。你可以在技術上允許寫得很好的自修改代碼,如果它願意提名所有可能被修改的地址的話,那麼你絕對可以避免那些在你的調度程序動態修改中的代碼。

你最終會運行一個解釋器,但只能用於跳轉。

4

其實,是的。最有效的方法是簡單地在加載程序中修補運行時間。內核/守護進程的東西可以有更好的響應性的自定義補丁。更好的是,如果你有權訪問所有的源代碼,你可以在編譯器中打補丁。

該補丁可以由各種分佈式調度程序組成。每個程序都可以修補爲具有非常低延遲的定時器;在加載時,它會設置計時器,並且在每次從計劃程序返回時,都會重置計時器。一個簡單的方法將允許代碼簡單地做一個

if (timer - start_timer) yield to scheduler; 

這不會產生太大的性能影響。主要的麻煩在於找到好的方法來將它們彈出。在每個函數調用之間都是一個開始,如果您真的需要搶佔響應,檢測循環並插入它們是原始但有效的。

這不是完美的,但它會工作。

主要問題是確保定時器返回是低延遲;這樣它只是一個比較和分支。此外,處理異常 - 以某種方式導致代碼中導致無限循環的錯誤。您可以在技術上使用相當簡單的硬件看門狗定時器,並在不清除任何RAM的情況下在CPU上發出復位信號;一個in-RAM例程會在RESET向量指向的地方執行,這將檢查和解開堆棧回程序調用(從而使程序崩潰但保留其他所有內容)。這就像一個暴力破解程序。或者你可以用這種方式將它改變爲多任務,RESET作爲一箇中斷,但這要困難得多。

所以...是的。這可能但很複雜;使用來自JIT編譯器和動態翻譯器(仿真器使用它們)的技術。

這是一個混亂的解釋,我知道,但我很累。如果不夠清楚,我明天可以回來清理。

順便說一句,在CPU中斷程序中聲明覆位聽起來很瘋狂,但它是一種久經考驗和成熟的技術。 Windows的早期版本甚至將它運行在兼容模式下,我認爲386是正確的,因爲無法從16位模式切換回32位。其他處理器和操作系統也完成了它。

編輯:所以我做了一些關於DCPU的研究,哈哈。它不是一個真正的CPU。我不知道你是否可以在Notch的模擬器中聲明重置,我會問他。方便的技術,就是。

+0

將自己的建議總結爲自動合作多任務是否準確? – Tommy 2012-04-09 05:33:24

+1

簡短摘要是:-P – 2012-04-09 05:34:50

0

另一種方式是保持基於事件隊列小任務(如目前的GUI應用程序)

這也是合作的,但具有不需要OS調用您剛剛從任務返回的效果,然後它會繼續下一個任務

如果再需要繼續你需要傳遞您需要將任務隊列

+0

這不需要系統上的所有程序都將其處理分解爲以OS調用結尾的小任務(基本上是多任務協作)?或者你會動態檢查和重寫任務? – 2012-04-09 15:28:09

+0

@AndrewG。我不是在第二句話中說的嗎?但是,是的,是的,雖然更多的是當你完成後返回隊列 – 2012-04-09 15:30:12

+0

你是對的,我誤讀了。好的謝謝。 – 2012-04-09 15:31:09

相關問題