# linux2021: sean791022 > [測驗題Link](https://hackmd.io/@sysprog/linux2021-summer/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Flinux2021-summer-quiz?fbclid=IwAR0-iIqxloAqi_HUfVWlo16vn2mhgQSaGzN5qg5mE0aJyPhWqqW36IRv8vc) ## 測驗 α−1 ``` #define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) #define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) ``` [linux/arch/x86/include/asm/xen/interface_32.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/xen/interface_32.h) 在這個檔案上發現 有兩個巨集 對32bit的unsigned 做 12 MSB 和 12 LSB 做交換的動作, 解決%cr3對4GB以上的頁目錄兼容問題 ## 測驗 α−2 感覺對題目不是太了解 但用1帶入每個函式都可以正常的執行 不知道哪裡有問題耶 ```c #include <stdint.h> #include <stdio.h> #define __DECLARE_ROTATE(bits, type) \ static inline type rotl##bits(const type v, int c) \ { \ const int mask = (bits) - (1); \ c &= mask; \ \ return (v << c) | (v >> (-c & mask)); \ } \ \ static inline type rotr##bits(const type v, int c) \ { \ const int mask = (bits) - (1); \ c &= mask; \ \ return (v >> c) | (v << (-c & mask)); \ } #define DECLARE_ROTATE(bits) __DECLARE_ROTATE(bits, uint##bits##_t) DECLARE_ROTATE(64); DECLARE_ROTATE(32); DECLARE_ROTATE(16); DECLARE_ROTATE(8); int main() { printf("L: %lx, R: %lx\n", rotl8(1, 1), rotr8(1, 1)); printf("L: %lx, R: %lx\n", rotl16(1, 1), rotr16(1, 1)); printf("L: %lx, R: %lx\n", rotl32(1, 1), rotr32(1, 1)); printf("L: %lx, R: %lx\n", rotl64(1, 1), rotr64(1, 1)); return 0; } ``` ```bash= tmp/ $ clang -O3 test.c -o test tmp/ $ ./test L: 2, R: 80 L: 2, R: 8000 L: 2, R: 80000000 L: 2, R: 8000000000000000 ``` ## 測驗 β-1 透過mask來判斷bit size是否需要padding, 否則直回傳該bitsize. 不然就回傳計算padding後的size. ps: packing size 計算方式:(size+(ps-1)) / ps) * ps ## 測驗 β-2 [arch/powerpc/boot/page.h](https://github.com/torvalds/linux/blob/master/arch/powerpc/boot/page.h) ```c 21:#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((typeof(addr))(size)-1))) 25:#define _ALIGN(addr,size) _ALIGN_UP(addr,size) ``` 可以看到它用宏的方式定義了 這裡的宏沒有判斷size是否是2次方的直 直接計算, 應該是可以被優化吧 這裡的後半段 以bitwise operator進行 代替了乘法和除法 ```&(~((typeof(addr))(size)-1))) ``` 計算出的結果會與原本相同 而且更省cpu資源了 ## 測驗 γ-1 因為printf會把內容寫到 正常輸出緩衝(standard output buffer, defualt block型態) 直到for迴圈結束才使用fflush()函數, 所以fork()函數在複製父行程的空間時(COW) 也會涵蓋 正常輸出緩衝. 因此每個 child 都會擁有 parent 的buffer, 所以就會迭代下去了直到列印出 子節點總數會有n^2這麼多, 然後buffer迭代數量就是n個 所以總更有`n(n^2)` 個`-`符號列印出來 題目:F(49152) = n(n^2) 輸出: n就成於12囉 ## δ 冏 ## ###### tags: `Linux-quiz`