# [2022q1](http://wiki.csie.ncku.edu.tw/sysprog/schedule) 第 9 週測驗題 ###### tags: `linux2022` :::info 目的: 檢驗學員對 **[並行和多執行緒程式設計](https://hackmd.io/@sysprog/concurrency)** 的認知 ::: 作答表單: * ==[測驗 `1`](https://docs.google.com/forms/d/e/1FAIpQLSf0qSZqImkfHq6ComFcmMTulKSyVbWSClyQ2lIIMgsyeNfS6Q/viewform)== (Linux 核心設計) * ==[測驗 `2`](https://docs.google.com/forms/d/e/1FAIpQLSfeaMhMykb8L884svgFToAdQjtiPH2WLoBc_CCjXG2B4AUyew/viewform)== (Linux 核心實作) ### 測驗 `1` 考慮到一個 [lock-free]((https://hackmd.io/@sysprog/concurrency)) 的軟體計時器實作,測試程式如下: ```c #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include "lf_timer.h" #define EX_HASHSTR(s) #s #define EX_STR(s) EX_HASHSTR(s) #define EXPECT(exp) \ do { \ if (!(exp)) \ fprintf(stderr, "FAILURE @ %s:%u; %s\n", __FILE__, __LINE__, \ EX_STR(exp)), \ abort(); \ } while (0) static void callback(lf_timer_t tim, lf_tick_t tmo, void *arg) { lf_tick_t tck = lf_timer_tick_get(); printf("Timer %d expiration %#" PRIx64 " now %#" PRIx64 "\n", tim, tmo, tck); *(lf_tick_t *) arg = tck; } int main(void) { lf_tick_t exp_a = LF_TIMER_TICK_INVALID; lf_timer_t tim_a = lf_timer_alloc(callback, &exp_a); EXPECT(tim_a != LF_TIMER_NULL); EXPECT(lf_timer_set(tim_a, 1)); EXPECT(!lf_timer_set(tim_a, 1)); lf_timer_tick_set(0); lf_timer_expire(); EXPECT(exp_a == LF_TIMER_TICK_INVALID); lf_timer_tick_set(1); lf_timer_expire(); EXPECT(exp_a == 1); EXPECT(lf_timer_set(tim_a, 2)); EXPECT(lf_timer_reset(tim_a, 3)); lf_timer_tick_set(2); lf_timer_expire(); EXPECT(exp_a == 1); EXPECT(lf_timer_cancel(tim_a)); lf_timer_tick_set(3); lf_timer_expire(); EXPECT(exp_a == 1); EXPECT(!lf_timer_reset(tim_a, UINT64_C(0xFFFFFFFFFFFFFFFE))); EXPECT(lf_timer_set(tim_a, UINT64_C(0xFFFFFFFFFFFFFFFE))); EXPECT(lf_timer_reset(tim_a, UINT64_C(0xFFFFFFFFFFFFFFFE))); lf_timer_expire(); EXPECT(exp_a == 1); lf_timer_tick_set(UINT64_C(0xFFFFFFFFFFFFFFFE)); lf_timer_expire(); EXPECT(exp_a == UINT64_C(0xFFFFFFFFFFFFFFFE)); lf_timer_free(tim_a); printf("timer tests complete\n"); return 0; } ``` 預期執行輸出: ``` Timer 0 expiration 0x1 now 0x1 Timer 0 expiration 0xfffffffffffffffe now 0xfffffffffffffffe timer tests complete ``` 程式碼可參見 [lf_timer](https://gist.github.com/jserv/ee63f467f393153fd865a6b772edc63d),使用 C11 搭配 GNU extension。 請補完程式碼,使其運作符合預期。作答規範: * `COND` 為表示式 * `FF1` 和 `FF2` 為表示式 :::success 延伸問題: 1. 解釋上述程式碼運作原理 2. 參照 [interval-timer](https://github.com/sn0wvall/interval-timer),撰寫 lock-based 實作,並提供可適用於 lock-based 和 lock-free timer 實作的測試程式 (含 benchmark),並解讀實驗結果 ::: --- ### 測驗 `2` 考慮到支援多個生產者—多個消費者的 bounded buffer lockfree 實作: [gist](https://gist.github.com/jserv/d2e27c8d9fc3c3e316fd91039633def5) (部分程式碼隱蔽) 程式碼使用 C11 [Atomics](https://en.cppreference.com/w/c/atomic) 和 [Threads](https://en.cppreference.com/w/c/thread) 撰寫,預期執行輸出: ``` Test: Spsc: null_pointers : PASS Test: Spsc: create : PASS Test: Spsc: empty : PASS Test: Spsc: full : PASS Test: Spsc: sums10000 : PASS Test: Mpsc: null_pointers : PASS Test: Mpsc: create : PASS Test: Mpsc: empty : PASS Test: Mpsc: full : PASS Test: Mpsc: sums10000 : PASS Test: Spmc: null_pointers : PASS Test: Spmc: create : PASS Test: Spmc: empty : PASS Test: Spmc: full : PASS Test: Spmc: sums10000 : PASS Test: Mpmc: null_pointers : PASS Test: Mpmc: create : PASS Test: Mpmc: empty : PASS Test: Mpmc: full : PASS Test: Mpmc: sums10000 : PASS ``` 請補完程式碼,使其執行符合預期。作答規範: * `MMM` 是表示式,依據指定程式碼風格撰寫,以最精簡的形式