您现在的位置是:首页 >其他 >node mask网站首页其他
node mask
typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;//unsigned long bits[1]
当你定义一个 `nodemask_t` 类型的变量时,它将会包含一个名为 `bits` 的数组,数组中的每个元素是一个无符号长整型整数,用于存储一组二进制位,表示节点集合。
如果定义一个 `nodemask_t` 数组变量,可以像下面这样去定义:
#define MAX_NUMNODES 16 // 最大支持的节点数量
#define BITS_PER_LONG (sizeof(long) * 8)
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
typedef struct {
unsigned long bits[BITS_TO_LONGS(MAX_NUMNODES)];
} nodemask_t;
// 将元素n所对应的位设置为1
static inline void node_set(nodemask_t *mask, int n)
{
mask->bits[BIT_WORD(n)] |= BIT_MASK(n);
}
// 将元素n所对应的位设置为0
static inline void node_clear(nodemask_t *mask, int n)
{
mask->bits[BIT_WORD(n)] &= ~BIT_MASK(n);
}
// 判断元素n所对应的位是否被设置为1
static inline int node_isset(const nodemask_t *mask, int n)
{
return !!(mask->bits[BIT_WORD(n)] & BIT_MASK(n));
}
```
其中,`BIT_WORD` 和 `BIT_MASK` 宏分别用于求取 `bits` 数组中下标和该下标中对应的位掩码,`BITS_TO_LONGS()` 宏用于求取 `bits` 数组中元素的数量,等于表达式 `(MAX_NUMNODES + BITS_PER_LONG - 1) / BITS_PER_LONG`。
上述代码中,`node_set()`、`node_clear()` 和 `node_isset()` 函数可用于操作 `nodemask_t` 变量,分别用于将某个元素对应的位设置为 1、将某个元素对应的位设置为 0、判断某个元素对应的位是否已被设置。
`BITS_TO_LONGS()` 宏用于计算一个包含 `nbits` 个二进制位的位图需要多少个 `unsigned long` 类型的整数来表示。它的定义如下:
#define BITS_PER_LONG (sizeof(long) * 8)
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
```
其中,`BITS_PER_LONG` 宏用于计算一个 `unsigned long` 类型的整数包含多少位,它的值是机器字长(如 64 位系统上它的值为 64)。`DIV_ROUND_UP` 宏是一个用于进行整数除法的宏,它的定义如下:
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
它的作用是将不足 `d` 的部分上取整,可以用来计算一个数除以 `d` 的结果,并向上取整到最近的整数。
因此,`BITS_TO_LONGS(nr)` 宏先将参数 `nr` 与 `BITS_PER_LONG` 相除,然后将商加 1,以确保可以容纳所有的 `nbits` 位。简言之,它的主体部分就相当于函数 `ceil(nbits/BITS_PER_LONG)`。最终返回值是 `unsigned long` 数组所需要的元素数量。
举个例子,如果 `BITS_PER_LONG` 是 32(32 位机器),`nr` 是 100,那么 `BITS_TO_LONGS(nr)` 的值将会是 `(100 + 31) / 32`,等于 4。也就是说,需要使用 4 个 `unsigned long` 类型的整数才能表示一个包含 100 个二进制位的位图。