# 2019q1W7上: 鄭珮彣 ###### tags: `linux2019` ## 測驗 `1` ```cpp static inline size_t find_next_bit(const unsigned long *bitmap, size_t bits, size_t start) { unsigned long t; size_t l = BITS_TO_LONGS(bits); size_t first_long = start / BITS_PER_LONG; size_t long_lower = start - (start % BITS_PER_LONG); if (start >= bits) return bits; t = bitmap[first_long] & BITMAP_FIRST_WORD_MASK(start); for (size_t i = first_long + 1; !t && i < l; i++) { long_lower += BITS_PER_LONG; t = bitmap[i]; } if (!t) return bits; size_t pos; pos = long_lower + bitops_ffs(t) - 1; if (pos >= bits) return bits; return pos; } ``` ## 測驗 `2` ```clike #include <time.h> #include <stdlib.h> int main(void) { unsigned long test[BITS_TO_LONGS(MAX_TEST_BITS)]; int i, j; srand(time(NULL)); for (i = 0; i < BITS_TO_LONGS(MAX_TEST_BITS); i++) { test[i] = rand() % BITS_TO_LONGS(MAX_TEST_BITS); for (j = i - 1; j >= 0; j--) if (test[i] == test[j]) i--; } for (int i = 1; i < MAX_TEST_BITS; i++) { bitmap_fill(test, i); assert(find_next_bit(test, i, 0) == 0); bitmap_zero(test, i); assert(find_next_bit(test, i, 0) == i); } return 0; } ``` ## 測驗 `3` :::info 參見 [Kernel’s Bug Reporting](https://lkw.readthedocs.io/en/latest/doc/06_kernel_bug_reporting.html) 和 [BUG 使用的討論](https://yarchive.net/comp/linux/BUG.html) ::: ```clike #include <assert.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <string.h> #include <stdio.h> #define BITS_PER_BYTE 8 #define BITOPS_BUILD_BUG_ON(e) ((void)sizeof(char[1 - 2 * !!(e)])) #define BITS_PER_LONG (sizeof(unsigned long) * BITS_PER_BYTE) /** * bitops_ffs() - find (least significant) first set bit plus one * @x: unsigned long to check * Return: plus-one index of first set bit; zero when x is zero */ static inline size_t bitops_ffs(unsigned long x) { size_t i = 1; BITOPS_BUILD_BUG_ON(BITS_PER_LONG != 32 && BITS_PER_LONG != 64); if (x == 0) return 0; if (BITS_PER_LONG == 64) { if ((0x00000000fffffffful & x) == 0) { i += 32; x >>= 32; } } if ((0x0000fffful & x) == 0) { i += 16; x >>= 16; } if ((0x00fful & x) == 0) { i += 8; x >>= 8; } if ((0x0ful & x) == 0) { i += 4; x >>= 4; } if ((0x3ul & x) == 0) { i += 2; x >>= 2; } if ((0x1ul & x) == 0) { i += 1; x >>= 1; } return i; } int main() { unsigned long x ; x=16;//x=10000 bitops_ffs(x); printf("%ld\n", bitops_ffs(x)); } ``` >輸出結果 ``` 5 ``` ## 測驗 `4` ```clike #include <assert.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <string.h> #include <stdio.h> #include <limits.h> #define BITS_PER_BYTE 8 #define BITOPS_BUILD_BUG_ON(e) ((void)sizeof(char[1 - 2 * !!(e)])) #define BITS_PER_LONG (sizeof(unsigned long) * BITS_PER_BYTE) /** * bitops_ffz() - find (least significant) first zero bit plus one * @x: unsigned long to check * * Return: plus-one index of first zero bit; zero when x is ULONG_MAX */ static inline size_t bitops_ffz(unsigned long x) { x=~x; size_t i = 1; BITOPS_BUILD_BUG_ON(BITS_PER_LONG != 32 && BITS_PER_LONG != 64); if (~x == ULONG_MAX) return 0; if (x == 0) return 1; if (BITS_PER_LONG == 64) { if ((0x00000000fffffffful & x) == 0) { i += 32; x >>= 32; } } if ((0x0000fffful & x) == 0) { i += 16; x >>= 16; } if ((0x00fful & x) == 0) { i += 8; x >>= 8; } if ((0x0ful & x) == 0) { i += 4; x >>= 4; } if ((0x3ul & x) == 0) { i += 2; x >>= 2; } if ((0x1ul & x) == 0) { i += 1; x >>= 1; } return i; } int main() { unsigned long x ; x=7;//x=0111 bitops_ffz(x); printf("%ld\n", bitops_ffz(x)); } ``` >輸出結果 ``` 4 ```
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.