# [2022q1](http://wiki.csie.ncku.edu.tw/sysprog/schedule) 第 10 週測驗題
###### tags: `linux2022`
:::info
目的: 檢驗學員對 **[Linux 核心設計: 不僅是個執行單元的 Process](https://hackmd.io/@sysprog/linux-process)** 和 **[並行和多執行緒程式設計](https://hackmd.io/@sysprog/concurrency)** 的認知
:::
作答表單:
* ==[測驗 `1`](https://docs.google.com/forms/d/e/1FAIpQLSfwGzix-optnhZtlZ_S_s2hXKZ56vIxLCGvceENIhUrUp1C9Q/viewform)== (Linux 核心設計)
### 測驗 `1`
在 [Linux 核心設計: 不僅是個執行單元的 Process](https://hackmd.io/@sysprog/linux-process) 提及 [futex](https://man7.org/linux/man-pages/man2/futex.2.html),我們可用來實作 lock,可見:
* [Linux futex based Read-Write Lock implementation](https://smoku.xiaoka.com/post/147930509718/linux-futex-based-read-write-lock-implementation)
* [Basics of Futexes](https://eli.thegreenplace.net/2018/basics-of-futexes/)
在 [並行程式設計: POSIX Thread](https://hackmd.io/@sysprog/posix-threads),提及案例: "Mutex and Semaphore" (你今天用對 mutex 了嗎?),提醒要留意細節。參考 [man page `pthread_mutex_unlock()`](https://linux.die.net/man/3/pthread_mutex_lock) 裏面提到:
> If the mutex type is **`PTHREAD_MUTEX_DEFAULT`**, attempting to recursively lock the mutex results in undefined behavior. **Attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior.** Attempting to unlock the mutex if it is not locked results in undefined behavior.
仔細地看 [man page `pthread_mutex_unlock()`](https://linux.die.net/man/3/pthread_mutex_lock) 會發現:
> If the mutex type is **`PTHREAD_MUTEX_ERRORCHECK`**, then error checking shall be provided. If a thread attempts to relock a mutex that it has already locked, an error shall be returned. **If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, an error shall be returned.**
我們需要在初始化 mutex 之際,就指定型態。
`mu` 是我們嘗試使用 futex 的多執行緒執行環境的實作,介面比照 POSIX Thread,針對 Linux/x86-64,程式碼可見: [mu](https://gist.github.com/jserv/03f0a6c9c72b70464f2fd0295cbc936d) (部分遮蔽)
預期執行結果: (地址可能會不同)
```
[thread main] Testing normal mutex
[thread 0x55fd427bd010] Trying to actuire the mutex succeeded
[thread 0x55fd427bd080] Trying to actuire the mutex failed
[thread 0x55fd427bd010] Starting normal mutex test
[thread 0x55fd427bd048] Trying to actuire the mutex failed
[thread 0x55fd427bd0b8] Trying to actuire the mutex failed
[thread 0x55fd427bd0f0] Trying to actuire the mutex failed
[thread main] Threads spawned successfully
[thread main] Sleeping 7 seconds
[thread 0x55fd427bd010] Finishing normal mutex test
[thread 0x55fd427bd080] Starting normal mutex test
[thread 0x55fd427bd080] Finishing normal mutex test
[thread 0x55fd427bd048] Starting normal mutex test
[thread 0x55fd427bd048] Finishing normal mutex test
[thread 0x55fd427bd0b8] Starting normal mutex test
[thread 0x55fd427bd0b8] Finishing normal mutex test
[thread 0x55fd427bd0f0] Starting normal mutex test
[thread 0x55fd427bd0f0] Finishing normal mutex test
---
[thread main] Testing errorcheck mutex
[thread main] Threads spawned successfully
[thread main] Sleeping 5 seconds
[thread 0x55fd427bd010] Starting errorcheck mutex test
[thread 0x55fd427bd010] Trying to lock again would deadlock
[thread 0x55fd427bd048] Trying to unlock a mutex we don't own
[thread 0x55fd427bd010] Finishing errorcheck mutex test
[thread 0x55fd427bd048] Starting errorcheck mutex test
[thread 0x55fd427bd048] Finishing errorcheck mutex test
[thread 0x55fd427bd048] Trying to unlock unlocked mutex
---
[thread main] Testing recursive mutex
[thread main] Threads spawned successfully
[thread main] Sleeping 7 seconds
[thread 0x55fd427bd0f0] Trying to actuire the mutex succeeded
[thread 0x55fd427bd0f0] Starting recursive mutex test
[thread 0x55fd427bd0b8] Trying to actuire the mutex failed
[thread 0x55fd427bd048] Trying to actuire the mutex failed
[thread 0x55fd427bd010] Trying to actuire the mutex failed
[thread 0x55fd427bd080] Trying to actuire the mutex failed
[thread 0x55fd427bd0f0] Finishing recursive mutex test
[thread 0x55fd427bd0b8] Starting recursive mutex test
[thread 0x55fd427bd0b8] Finishing recursive mutex test
[thread 0x55fd427bd048] Starting recursive mutex test
[thread 0x55fd427bd048] Finishing recursive mutex test
[thread 0x55fd427bd010] Starting recursive mutex test
[thread 0x55fd427bd010] Finishing recursive mutex test
[thread 0x55fd427bd080] Starting recursive mutex test
[thread 0x55fd427bd080] Finishing recursive mutex test
```
請補完程式碼,使其符合預期。作答規範:
* `AAAA`, `BBBB`, `CCCC` 都是表示方式,且都該使用 `atomic_bool_cmpxchg` 巨集
* `DDDD` 為整數
:::success
延伸問題:
1. 解釋上述程式碼運作原理,指出其中缺失並改進
2. 實作 PRIO_INHERIT / PRIO_PROTECT mutexes
:::