# 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`