---
tags: linux2023
---
# [2023 年暑期 Linux 核心課程](https://hackmd.io/@sysprog/linux2023-summer)第 1 次作業
:::warning
:warning: 作業須知
1. 繳交作業的學員在符合下述規範並獲得授課教師確認後,會收到《Concurrency Primer》和《Demystifying the Linux CPU Scheduler》這二本 **尚未公開釋出** 的電子書草稿
2. 繳交期限為 8 月 13 日,可優先作答下方測驗題 $\alpha$ 到 $\gamma$ 並及早填寫[作答表單](https://docs.google.com/forms/d/e/1FAIpQLSchjBeTO5la96o1rMkUsYcTqPAAWdNqr1oHraqHkUiCHtraVw/viewform),至於測驗題 $\delta$ 可在指定的 [HackMD](https://hackmd.io/) 建立後,再逐步改進和補充
* ==[作答表單](https://docs.google.com/forms/d/e/1FAIpQLSchjBeTO5la96o1rMkUsYcTqPAAWdNqr1oHraqHkUiCHtraVw/viewform)==
* 授課教師會斟酌批改學員提交的作業並藉由 HackMD 上互動,學員越早提交,效果越好
3. 所有程式碼都該符合 C99 或 C11 規範,可搭配 [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html)
6. 作答儘量用簡短的程式碼,且二元運算子 (binary operator,如 `+` [加法], `-` [減法], `*` [乘法], `^`, `&` [逐位元 AND] 等等) 和運算元 (operand) 之間用一個空白字元 (不多不少!) 區隔,如 `(v >> c)`、逗點 (`,`) 後應該有空白或換行符號,並避免非必要的小括號 (即 `(` 和 `)`),也該刪去 (trim) 起始/結尾的空白字元
* 程式碼排版風格可見 [.clang-format](https://github.com/sysprog21/concurrent-programs/blob/master/.clang-format)
7. 顧及批改的便利,本測驗採用 Google 表單自動比對參考答案,難免會有疏漏的答案組合 (特別是程式碼風格的落差),請發訊息到[授課教師的 Facebook 粉絲專頁](https://www.facebook.com/JservFans)告知和討論
8. 一旦上述表單提交後,會由授課教師以電子郵件聯繫 (來自 `<embedded.master2015@gmail.com>`),通知課程事宜和提供電子書
:::
### 測驗 $\alpha$
> 搭配 [Linux 核心原始程式碼巨集: `container_of`](https://hackmd.io/@sysprog/linux-macro-containerof), [Linux 核心的紅黑樹](https://hackmd.io/@sysprog/linux-rbtree)
考慮 S-Tree^名稱沒特別意思,不用去Google搜尋^ 是個嘗試兼具 AVL tree 和 red-black tree 部分特性的 binary search tree (BST) 實作,著重在快速的 insert/delete 操作且合理的 lookup 速度。
測試情境為:
1. 隨機插入 0 到 98 之間的數值到 S-Tree,操作 100 次
2. 自 S-Tree 移去 0 到 98 之間的隨機數,操作 100 次
參考輸出如下:
```
[ After insertions ]
0
4
7
9
10
12
13
14
15
16
17
18
20
21
22
24
26
27
29
34
35
36
38
40
42
43
44
46
48
50
51
54
55
56
57
58
64
66
67
69
70
74
76
77
78
79
80
81
84
85
87
91
92
94
95
97
98
Removing...
52 65 76 30 44 90 16 70 14 93
80 12 93 6 67 70 48 32 40 89
31 90 10 42 75 75 42 5 20 37
80 72 1 57 2 45 47 16 17 61
10 95 73 4 2 39 73 48 71 14
39 3 5 47 45 78 21 85 81 42
23 62 13 22 19 13 68 66 30 83
26 38 77 97 43 79 37 15 26 7
27 65 8 32 14 51 9 35 38 88
75 59 51 87 82 68 98 51 33 27
[ After removals ]
0
18
24
29
34
36
46
50
54
55
56
58
64
69
74
84
91
92
94
```
注意到以下特性:
1. 節點內含數值由小到大輸出
2. `[ After removals ]` 的輸出不包含 `Removing` 指定的數值
3. 程式碼執行時,不會觸發任何 assertion
原始程式碼可見 [main.c](https://gist.github.com/jserv/4dfaf78cf516cc20f4bc55ce388c195d) (部分遮蔽)
作答規範:
* `AAAA`, `BBBB`, `CCCC`, `DDDD`, `EEEE`, `FFFF`, `GGGG` 均該包含 `st_` 開頭的函式或巨集,且不包含 `;` 字元
* 補完程式碼,使其運作符合預期
* 必須符合 [.clang-format](https://github.com/sysprog21/concurrent-programs/blob/master/.clang-format) 規範的程式碼排版風格
* 以最精簡的形式撰寫
:::success
延伸問題:
1. 解釋上述程式碼運作原理
2. 指出上述程式碼可改進之處,特別跟 AVL tree 和 red-black tree 相比,並予以實作
3. 設計效能評比程式,探討上述程式碼和 red-black tree 效能落差
:::
---
### 測驗 $\beta$
> 搭配 [你所不知道的 C 語言: bitwise 操作](https://hackmd.io/@sysprog/c-bitwise), [你所不知道的 C 語言:記憶體管理、對齊及硬體特性](https://hackmd.io/@sysprog/c-memory)
以下程式碼可針對給定的 alignment 數值,輸出大於等於 alignment 的記憶體對齊地址:
```c
#include <stdint.h>
static inline uintptr_t align_up(uintptr_t sz, size_t alignment)
{
uintptr_t mask = alignment - 1;
if ((alignment & mask) == 0) { /* power of two? */
return MMMM;
}
return (((sz + mask) / alignment) * alignment);
}
```
已知 alignment 不為 `0`,參考執行輸出:
```cpp
align_up(120, 4) = 120
align_up(121, 4) = 124
align_up(122, 4) = 124
align_up(123, 4) = 124
```
請填補上述 `MMMM` 標注的程式碼,使得執行結果符合預期。限制只能用 `+`, `-`, `|`, `&`, `^`, `~`, `<<`, `>>` 等運算子,不得出現 [ternary conditional operator](https://en.wikipedia.org/wiki/%3F:) (即 `?` 搭配 `:`),且不該出現 `alignment`
> 必須符合 [.clang-format](https://github.com/sysprog21/concurrent-programs/blob/master/.clang-format) 規範的程式碼排版風格
:::success
延伸問題:
1. 說明上述程式碼的運作原理
2. 在 Linux 核心原始程式碼找出類似 `align_up` 的程式碼,並舉例說明其用法
:::
---
### 測驗 $\gamma$
> 搭配 [並行和多執行緒程式設計](https://hackmd.io/@sysprog/concurrency)
考慮用 POSIX Thread 改寫的 [qsort(3p)](https://man7.org/linux/man-pages/man3/qsort.3p.html) 實作,測試程式用法:
```
usage: qsort-mt [-stv] [-f forkelements] [-h threads] [-n elements]
-l Run the libc version of qsort
-s Test with 20-byte strings, instead of integers
-t Print timing results
-v Verify the integer results
Defaults are 1e7 elements, 2 threads, 100 fork elements
```
選項 `-l` 可指定使用 glibc (或系統預設的 libc) 的 `qsort`。原始程式碼可見 [qsort-mt.c](https://gist.github.com/jserv/38bca4ebfea1c434e1dfc15337f80eeb) (部分遮蔽)
編譯方式:
```shell
$ gcc -Wall -o qsort qsort_mt.c -lpthread
```
請補完程式碼,使其運作符合預期。作答規範:
* `HHHH` 和 `JJJJ` 都包含 `pthread_` 開頭的函式,且均不包含 `;` 字元
* 以最精簡的形式撰寫
* 必須符合 [.clang-format](https://github.com/sysprog21/concurrent-programs/blob/master/.clang-format) 規範的程式碼排版風格
:::success
延伸問題:
1. 解釋上述程式碼運作原理
2. 以 [Thread Sanitizer](https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual) 找出上述程式碼的 data race 並著手修正
3. 研讀 [專題: lib/sort.c](https://hackmd.io/@sysprog/B146OVeHn),提出上述程式碼效能改進之規劃並予以實作
:::
---
### 測驗 $\delta$
回答上述測驗題 $\alpha$ 到 $\gamma$ 的所有延伸問題,建立 [HackMD](https://hackmd.io/) 頁面、設定權限為「==已登入者可編輯==」(這樣授課教師才能給予眉批)、用固定網址發布筆記 (建議命名為 `linux2023-summer-quiz`),並依據下方格式來答覆延伸問題:
* 標題: linux2023: **你的 GitHub 帳號名稱**
* 內文: 用 `## ` 開頭並標注題目,如 `## 測驗` $\alpha-1$ 表示「測驗 $\alpha$」的第一個延伸問題
書寫規範:
* 參照〈[資訊科技詞彙翻譯](https://hackmd.io/@sysprog/it-vocabulary)〉及〈[詞彙對照表](https://hackmd.io/@l10n-tw/glossaries)〉,使用精準且符合台灣風格的科技詞彙
* 無論標題和內文中,中文和英文字元之間要有空白字元或標點符號 (對排版和文字搜尋有利)
* 文字訊息請避免用圖片來表示,否則不好搜尋和分類,尊重視覺障礙者的閱讀權益
延伸閱讀:
* [HackMD: 筆記權限設定](https://hackmd.io/s/how-to-set-permissions-tw)
* [HackMD: 用固定網址發布筆記](https://hackmd.io/s/how-to-share-note-tw)