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 个二进制位的位图。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值