首页 > 技术文章 > Linux 内核数据结构bitmap

danxi 2017-02-06 13:33 原文

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define MAX_PRIO 10000
  5 #define BITS_PER_LONG 32
  6 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
  7 
  8 #define BIT(nr)            (1UL << (nr))
  9 #define BIT_MASK(nr)        (1UL << ((nr) % BITS_PER_LONG))
 10 #define BIT_WORD(nr)        ((nr) / BITS_PER_LONG)
 11 #define BITS_PER_BYTE        8
 12 
 13 #define BITS_TO_LONGS(nr)    DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 14 
 15 #define DECLARE_BITMAP(name,bits) \
 16     unsigned long name[BITS_TO_LONGS(bits)]
 17 
 18 static inline void __set_bit(int nr, volatile unsigned long *addr)
 19 {
 20     unsigned long mask = BIT_MASK(nr);
 21     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 22 
 23     *p  |= mask;
 24 }
 25 
 26 static inline void __clear_bit(int nr, volatile unsigned long *addr)
 27 {
 28     unsigned long mask = BIT_MASK(nr);
 29     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 30 
 31     *p &= ~mask;
 32 }
 33 
 34 static inline void __change_bit(int nr, volatile unsigned long *addr)
 35 {
 36     unsigned long mask = BIT_MASK(nr);
 37     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 38 
 39     *p ^= mask;
 40 }
 41 
 42 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 43 {
 44     unsigned long mask = BIT_MASK(nr);
 45     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 46     unsigned long old = *p;
 47 
 48     *p = old | mask;
 49     return (old & mask) != 0;
 50 }
 51 
 52 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 53 {
 54     unsigned long mask = BIT_MASK(nr);
 55     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 56     unsigned long old = *p;
 57 
 58     *p = old & ~mask;
 59     return (old & mask) != 0;
 60 }
 61 
 62 static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 63 {
 64     unsigned long mask = BIT_MASK(nr);
 65     unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 66     unsigned long old = *p;
 67 
 68     *p = old ^ mask;
 69     return (old & mask) != 0;
 70 }
 71 
 72 static inline int test_bit(int nr, const volatile unsigned long *addr)
 73 {
 74     return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
 75 }
 76 
 77 #ifndef container_of
 78 /**
 79  * container_of - cast a member of a structure out to the containing structure
 80  * @ptr:    the pointer to the member.
 81  * @type:    the type of the container struct this is embedded in.
 82  * @member:    the name of the member within the struct.
 83  *
 84  */
 85 #define container_of(ptr, type, member) ({            \
 86     const typeof(((type *)0)->member) * __mptr = (ptr);    \
 87     (type *)((char *)__mptr - offsetof(type, member)); })
 88 #endif
 89 
 90 #define list_entry(ptr, type, member) container_of(ptr, type, member)
 91 
 92 int _tmain(int argc, _TCHAR* argv[])
 93 {
 94     DECLARE_BITMAP(bitmap1, MAX_PRIO);
 95     DECLARE_BITMAP(bitmap2, MAX_PRIO);
 96     int i;
 97 
 98     /* 00000000 - 99999999 使用一个bitmap */
 99     int num1 = 9999;
100     int num2 = 9999;
101 
102     char buff[32] = {0};
103 
104     for (i = 0; i < MAX_PRIO; i++) {
105         
106         __clear_bit(i, bitmap1);
107         __clear_bit(i, bitmap2);
108     }
109 
110     __set_bit(num1, bitmap1);
111     __set_bit(num2, bitmap2);
112 
113     printf("bitmap size = %d\n", sizeof(bitmap1)/sizeof(long));
114     printf("bitmap = %d\n", test_bit(num1, bitmap1));
115     printf("bitmap = %d\n", test_bit(num2, bitmap2));
116     printf("atoi : %d\n", atoi("0010"));
117     printf("%.4d%.4d\n", num1, num2);
118 121     return 0;
122 }

 

推荐阅读