--- tags: linux2022 --- # 2022-04-04 yyyyuwen contributed by < [`yuwen`](https://github.com/yyyyuwen) > > [作業要求](https://hackmd.io/@sysprog/linux2022-quiz8/https%3A%2F%2Fhackmd.io%2F%40sysprog%2FHyo0W7OQ5) ### 測驗1 memchr_opt 透過 `memchr_opt` 傳入的參數分別為 * `const void *src_void` :memort area * `int c` :the byte to search for * `size_t length` :the size of its area 在 64–bit Size 底下, `long` 代表 8 byte。 可以得知程式碼中一開始先去檢查是否小於 8 byte ```c= /* Nonzero if either X or Y is not aligned on a "long" boundary */ #define UNALIGNED(X) ((long) X & (sizeof(long) - 1)) while (UNALIGNED(src)) { if (!length--) return NULL; if (*src == d) return (void *) src; src++; } ``` `TOO_SMALL` 是在檢查長度是否超出 8 byte ```c /* Threshhold for punting to the bytewise iterator */ #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) ``` `d` 是要搜尋的字元,先將d擴展為 8 byte 來做後續的搜尋 ```c= unsigned long *asrc = (unsigned long *) src; unsigned long mask = d << 8 | d; mask = mask << 16 | mask; for (unsigned int i = 32; i < LBLOCKSIZE * 8; i <<= 1) mask = (mask << i) | mask; ``` ``` 例如 d = 2e 第二行 mask = 2e2e 第三行 mask = 2e2e2e2e 第五行 mask = 2e2e2e2e2e2e2e2e ``` 當要搜尋的句子長度 >= `LBLOCKSIZE` 時,一次 8 byte 遞迴下去找直到找到為止,若找不到則跳出 `while` 並回傳NULL。 ```c= while (length >= LBLOCKSIZE) { /* XXXXX: Your implementation should appear here */ // 如果有找到 if (DETECT_CHAR(*asrc, mask)) { // 取得該位址的字串 src = (unsigned char *) asrc; while (length-- != 0) { // find the target char if (*src++ == d) return (void *) (src - 1); } } else { // 一次減少 8 byte length -= LBLOCKSIZE; // 這邊宣告的是double的型態,當指標+1 等於一次前進8 byte asrc += 1; } } ``` 測試 ```c= int main() { const char str[] = "http://wiki.csie.ncku.edu.tw"; const char ch = 'n'; const char ch1 = '/'; const char ch2 = '.'; char *ret = memchr_opt(str, ch, strlen(str)); printf("String after |%c| is - |%s|\n", ch, ret); char *ret1 = memchr_opt(str, ch1, strlen(str)); printf("String after |%c| is - |%s|\n", ch1, ret1); char *ret2 = memchr_opt(str, ch2, strlen(str)); printf("String after |%c| is - |%s|\n", ch2, ret2); return 0; } ``` 結果 ``` String after |n| is - |ncku.edu.tw| String after |/| is - |//wiki.csie.ncku.edu.tw| String after |.| is - |.csie.ncku.edu.tw| ``` ### 測驗2 ### 測驗3