Lab4: Wait for Event
UART is a typical example for wait queue. When a task call for uart_read, you should put it into the wait queue if there is no data to be read. In the uart read interrupt handler, it can put the task back to runqueue and the task could read bytes from buffer after getting scheduled.
大致上的流程
- 在 read 時,若發現 ring buffer 資料不足,將 task 放入 wait queue
- irq handler 在收到任意數量的資料後,將 wait queue 上所有 task 倒回 run queue
read()、irq handler 是與 schedule() 同時運行,所以對共同存取的 run queue 和 wait queue 應該要有 lock 保護。
在上一個 lock 的實作中,是設計成 task 無法取得 lock 時將自身放入 run queue,但由於 irq handler 是特殊的存在無法被視為 task,因此以 disable interrupt 作為 lock 的替代方案。(另一種作法是採用 lock-free ring-buffer,但要在正確的變數、正確的時機以 atmoic 方式存取變數,難度頗高作罷)
1 | disable_irq(); |
實際運作流程
irq handler 可能發生在 read() 前或是 schedule() 後或是兩者中間,這邊展示發生在中間的情況

能見到 task 狀態轉變:RUNNING→BLOCKED→RUNNABLE,不就是恐龍書出現的狀態圖?
