在进一步分析之前,本文我们先来熟悉下OpenHarmony
鸿蒙轻内核提供的位操作模块,在互斥锁等模块对位操作有使用。位操作是指对二进制数的bit
位进行操作。程序可以设置某一变量为状态字,状态字中的每一bit
位(标志位)可以具有自定义的含义。
本文中所涉及的源码,以OpenHarmony LiteOS-A
内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 获取。
1 位操作的宏定义
位操作模块提供对32位无符号整数数值的bit
位进行操作,bit
位取值为0-31,以0开始计算,从左向右,第0位,第1位。。。第31位等。⑴处定义的宏OS_BITMAP_MASK
如下,也就是十进制31。如果传入的比特位pos
大于31,会通过逻辑与运算截断(pos & OS_BITMAP_MASK)
,只取低5位,确保不会大于31,避免溢出。⑵处定义的位图掩码全是1。
⑴ #define OS_BITMAP_MASK 0x1FU
⑵ #define OS_BITMAP_WORD_MASK ~0UL
在文件kernel\include\los_bitmap.h
中定义了常用的位操作相关的宏。宏BITMAP_WORD
根据参数x
计算出需要操作第几个状态字,由于计算状态字的使用的是UINTPTR
,状态字可以是32位、也可以是64位。后文,我们默认以32位进行讲解。宏BITMAP_FIRST_WORD_MASK
传入的参数是位操作的开始bit
位数,用于计算需要进行位操作的掩码,从开始位全部是1,宏BITMAP_LAST_WORD_MASK
传入的参数是位操作的结束bit
位数,用于计算需要进行位操作的掩码,结束位之前全部是1。宏BITMAP_NUM_WORDS
传入位数,计算状态字的数量。
#define _ONE(x) (1 + ((x) - (x)))
#define BIT(n) (1U << (n))
#define BIT_GET(x, bit) ((x) & (_ONE(x) << (bit)))
#define BIT_SHIFT(x, bit) (((x) >> (bit)) & 1)
#define BITS_GET(x, high, low) ((x) & (((_ONE(x) << ((high) + 1)) - 1) & ~((_ONE(x) << (low)) - 1)))
#define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((_ONE(x) << ((high) - (low) + 1)) - 1))
#define BIT_SET(x, bit) (((x) & (_ONE(x) << (bit))) ? 1 : 0)
#define BITMAP_BITS_PER_WORD (sizeof(UINTPTR) * 8)
#define BITMAP_NUM_WORDS(x) (((x) + BITMAP_BITS_PER_WORD - 1) / BITMAP_BITS_PER_WORD)
#define BITMAP_WORD(x) ((x) / BITMAP_BITS_PER_WORD)
#define BITMAP_BIT_IN_WORD(x) ((x) & (BITMAP_BITS_PER_WORD - 1))
#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITMAP_BITS_PER_WORD))
#define BITMAP_LAST_WORD_MASK(nbits) \
(((nbits) % BITMAP_BITS_PER_WORD) ? (1UL << ((nbits) % BITMAP_BITS_PER_WORD)) - 1 : ~0UL)
#define BITMAP_BITS_PER_INT (sizeof(INTPTR) * 8)
#define BITMAP_BIT_IN_INT(x) ((x) & (BITMAP_BITS_PER_INT - 1))
#define BITMAP_INT(x) ((x) / BITMAP_BITS_PER_INT)
#define BIT_MASK(x) (((x) >= sizeof(UINTPTR) * 8) ? (0UL - 1) : ((1UL << (x)) - 1))
2 位操作常用功能
OpenHarmo