這個是副產品, 在寫 process switch 這系列時, 順到想的, 因為不是很好表達, 我只在 mosut 講這個, 並沒有想要 blog 一篇, 不過還是寫出來好了, 最主要是給我回憶用的。
我一直在思考, 如何才能用程式碼來表達出 race condition, 而不是老師上課教的, 只能用冥想的方式來理解。
以前老師的例子就是
a=0;
proc_a:
a=a+1;
proc_b:
a=a+1;
若是 a 的初始值為 0, 由於 a=a+1 會被 c compiler 編譯成 3 個指令:
mov 0x804a018,%eax
add $0x1,%eax
mov %eax,0x804a018
所以若不一次做完這 3 個組合語言指令, 在 proc_a, proc_b 執行過後, a 的值可能只被加了一次, 最終結果不是 2, 而是 1。
以下的程式碼便是用來產生這樣的結果, 由於我可以決定 int $0x30 的位置, 所以可以很容易複製這樣的行為, 若是靠 timer 來中斷, 要遇到這樣的巧合就很難控制了。
程式很短, 但不代表他很簡單, 需要了解
x86 process switch implementation(0),
x86 process switch implementation(1), 否則應該看不懂這篇。
L66 ~ 68 是一個完整的 a=a+1; 而 L54 ~ 57 被我安插了 int $0x30, 導致 a=a+1 不能完整執行就會 switch 要另外一個 process, 這個程式的表現一樣要使用 bochs single step, 在 blog 上我只能儘量表達清楚, 無法帶你跑一次 (其實我可以錄下 bochs 畫面, 不過不用這麼折磨我吧)。
那麼要如何解決這問題, 其中之一是使用 spin lock, x86 可以參考 test and set 指令實作出 spin lock, 將這 3 個指令保護下來, 一次做完這 3 個指令:
http://en.wikipedia.org/wiki/X86_instruction_listings
http://en.wikipedia.org/wiki/Test-and-set
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。