---
# System prepended metadata

title: 'linux2021: new-type'

---

# linux2021: new-type

## 測驗 $\alpha - 1$
在
./include/linux/bitops.h
```cpp
static inline __u64 rol64(__u64 word, unsigned int shift)
{
	return (word << (shift & 63)) | (word >> ((-shift) & 63));
}
static inline __u64 ror64(__u64 word, unsigned int shift)
{
	return (word >> (shift & 63)) | (word << ((-shift) & 63));
}
static inline __u32 rol32(__u32 word, unsigned int shift)
{
	return (word << (shift & 31)) | (word >> ((-shift) & 31));
}
static inline __u32 ror32(__u32 word, unsigned int shift)
{
	return (word >> (shift & 31)) | (word << ((-shift) & 31));
}
...
```

在 ./arch/ia64/include/asm/processor.h 中有使用到這類運算。
```cpp
static inline __u64
ia64_rotr (__u64 w, __u64 n)
{
	return (w >> n) | (w << (64 - n));
}

#define ia64_rotl(w,n)	ia64_rotr((w), (64) - (n))
```

## 測驗 α−2
感覺是要看語法樹那邊是不是能轉換，以及有沒有未定義行為的狀況
:::warning
工程人員說話要精準，避免用「感覺」一詞，你有推論，就該去驗證和查核。
:notes: jserv
:::

## 測驗 β−1
2 的 x 次冪以二進位表示時會在位置 x (位置從最右方為 0 算起)為 1 ，其餘都是 0。
而 2<sup>x</sup> - 1 會造成位置 x 為 0，而在位置 0 到 x - 1 全部是 1。
也就能推導出 2<sup>x</sup> & 2<sup>x</sup> - 1 = 0
所以對於 alignment 是 2 的 x 次冪的對齊，可以直接將原數 sz 加上 mask ，若是沒對齊就會進位到位置 x 的 bit。之後再用 ~mask 將 0 至 x - 1 的 bits 全清為零。
而不是 2 的某次冪的，則是利用 sz + mask 也會產生進位的問題，而後面使用 / alignment 再 * alignment 則是用來對齊，也就是將比 alignment 小的 bits 清為零。

## 測驗 β−2
定義在 ./include/uapi/linux/const.h中的 __ALIGN_KERNEL_MASK 的作法與題目相類似
```
#define __ALIGN_KERNEL(x, a)		__ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
#define __ALIGN_KERNEL_MASK(x, mask)	(((x) + (mask)) & ~(mask))
```
應用如記憶體分頁的對齊(./include/linux/mm.h)
```
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
```
    
## 測驗 γ
可以先將原本的程式先去掉 fork() 來看
```
for (int i = 0; i < N; ++ i) {
    printf("-");
}
```
上面可以知道一個 process 可以產生 N 個 "-"。

再來看 process 數量的變化
```
for (int i = 0; i < N; ++ i) {
    fork();
}
```
可以看出隨著 i 的變化會產生的 child process 數量為：
i = 0 時: 1 = 2<sup>1</sup> - 1
i = 1 時: 3 = 2<sup>2</sup> - 1
i = 2 時: 7 = 2<sup>3</sup> - 1
...
i = N - 1 時: 2<sup>(N - 1) + 1</sup> - 1
所以包含一開始的 process，總共有 1 + (2<sup>N</sup> - 1) = 2<sup>N</sup> 個 process。

因此 2<sup>N</sup> 個 process，每個可以輸出 N 個字元，總共就是 N * 2<sup>N</sup> 個字元輸出。

## 測驗 δ−1
運作原理是利用 mutex 來保證 queue 的操作正確。實作上可以利用 lock_guard 來減少忘了手動解鎖產生的 deadlock。