# 2025q1 Homework3 (kxo)
contributed by < `gnkuan0712` >
{%hackmd NrmQUGbRQWemgwPfhzXj6g %}
> [作業說明](https://hackmd.io/@sysprog/linux2025-kxo/%2F%40sysprog%2Flinux2025-kxo-f)
## 背景知識學習
### [並行程式設計: Atomics 操作](https://hackmd.io/@sysprog/concurrency-atomics)
* Mutex verse Semaphore
* 避免依賴 lock, 考慮使用 Atomics
* Atomics一個操作,要就整個完成,要就完全不做,中間不會被其他執行緒插隊或中斷。
* 比如atomic_fetch_add()
* [第九周測驗](https://hackmd.io/@sysprog/linux2025-quiz9)、[第十周測驗](https://hackmd.io/@sysprog/linux2025-quiz10)
:::danger
說好的進度呢?
:::
### 開發環境
```
$ gcc --version
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
```
## 作業要求
- [ ] 縮減使用者和核心層級的通訊成本,並允許並行的對奕。
- [ ] 參照〈並行程式設計:排程器原理〉,引入若干 coroutine (注意:不得使用 POSIX Thread,採取教材提到的實作方式),分別對應到 AI1, AI2 (具備玩井字遊戲的人工智慧程式,採取不同的演算法,可指定運作於使用者/核心層級) 和鍵盤事件處理,意味著使用者可連續觀看多場「電腦 vs. 電腦」的對弈,當按下 Ctrl-P 時暫停或回復棋盤畫面更新 (但運算仍持續)、當按下 Ctrl-Q 時離開「電腦 vs. 電腦」的對弈,注意不該使用 (n)curses 函式庫。當離開「電腦 vs. 電腦」的對弈時,ttt 應顯示多場對弈的過程,亦即類似 Moves: B2 -> C2 -> C3 -> D3 -> D4 的輸出,儘量重用現有的結構體和程式碼。
> 關於鍵盤事件和終端機畫面的處理機制,可參見 mazu-editor 原始程式碼和〈Build Your Own Text Editor〉。
- [ ] 在「電腦 vs. 電腦」的對弈模式,比照前述 load average 的計算方式,規範針對下棋 AI 的 load 機制,並運用定點數來統計不同 AI 實作機制對系統負載的使用率,整合到畫面輸出,開發過程中應有對應的數學分析和羅列實作考量因素。
- [ ] 對弈的過程中,要在螢幕顯示當下的時間 (含秒數),並持續更新。
- [ ] 原本 kxo 棋盤繪製在核心模式,你應該修改程式碼,使畫面呈現的部分全部在使用者層級,且善用 bitops,降低核心和使用者層級之間的通訊成本,應給予相關量化
- [ ] 自 jserv/ttt 移植 reinforcement learning (RL) 到 kxo 核心模組,使其得以動態切換。
## 執行命令
* 編譯: `make`
* 載入 kxo module: `sudo insmod kxo.ko`
* 執行: `sudo ./xo-user`
* 卸載模組: `sudo rmmod kxo`
* 查看核心訊息: `sudo dmesg`
* 離開: `ctrl + q`
* 上傳
* `sudo git add .`
* 若遇到權限問題導致無法pull `sudo chown -R $(whoami):$(whoami) .`
## 專案架構
`kfifo` 算是kernal space 和 user space 的橋樑(?) kernal space產生的資料會放在這裡面傳遞給user space
### 第一個想解決的問題:
> 想把畫面呈現這部份從 kernal space 移到 kernal space,進而降低多餘傳送的 workload 和區分行為,參考該 [Commit 43dc5ba](https://github.com/sysprog21/kxo/commit/43dc5babcecb6a9863cca1173681811f3777deaf#diff-79363f74f4069cb6e063f0cc38967853aa6cd37540452ed65a5e2baec25fec9d)
* 原本棋盤畫出來是透過在 kernal space 的 `draw_buffer` 傳遞出來,然後傳遞出來的內容除了data之外還有畫格子的那些邊線等等
* 所以僅把 `table[i]` 放入 `draw_buffer[i]`
#### 效能分析
在 `kxo_release` 最後加入下面這一行:
```diff
+ pr_info("kxo: DRAWBUFFER_SIZE = %d, N_GRIDS = %d\n", DRAWBUFFER_SIZE, N_GRIDS);
```
可得到:
```
[421143.829037] kxo: DRAWBUFFER_SIZE = 66, N_GRIDS = 16
```
總共節省了  的資料傳遞。
## Simrupt
> 學習方向:
* 模擬 interrupt 的東西 ?
* Top Halves versus Bottom Halves
## 降低核心和使用者層級之間的通訊成本