Try   HackMD

linux2021: sean791022

測驗題Link

測驗 α−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

在這個檔案上發現 有兩個巨集 對32bit的unsigned 做 12 MSB 和 12 LSB 做交換的動作, 解決%cr3對4GB以上的頁目錄兼容問題

測驗 α−2

感覺對題目不是太了解 但用1帶入每個函式都可以正常的執行 不知道哪裡有問題耶

#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;
}
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

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