get_cpu_mask
/* cpu_bit_bitmap[0] is empty - so we can back into it */ #define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x)) #define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1) #define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2) #define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4) const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = { MASK_DECLARE_8(0), MASK_DECLARE_8(8), MASK_DECLARE_8(16), MASK_DECLARE_8(24), #if BITS_PER_LONG > 32 MASK_DECLARE_8(32), MASK_DECLARE_8(40), MASK_DECLARE_8(48), MASK_DECLARE_8(56), #endif };
static inline const struct cpumask *get_cpu_mask(unsigned int cpu) { const unsigned long *p = cpu_bit_bitmap[1 + cpu % BITS_PER_LONG]; p -= cpu / BITS_PER_LONG; return to_cpumask(p); }
#define to_cpumask(bitmap) \ ((struct cpumask *)(1 ? (bitmap) \ : (void *)sizeof(__check_is_bitmap(bitmap))))
上面cpu_bit_bitmap unsigned long型二维数组元素初始化如下:
[0+1][0] = 1<<0, [1+1][0] = 1<<1, [2+1][0] = 1<<2, [3+1][0] = 1<<3, [4+1][0] = 1<<4, [5+1][0] = 1<<5, [6+1][0] = 1<<6, [7+1][0] = 1<<7, [8+1][0] = 1<<8, [9+1][0] = 1<<9, [10+1][0] = 1<<10, [11+1][0] = 1<<11, [12+1][0] = 1<<12, [13+1][0] = 1<<13, [14+1][0] = 1<<14, [15+1][0] = 1<<15, ... [62+1][0] = 1<<62, [63+1][0] = 1<<63,
以NR_CPUS为4、cpu index为2为例,上述cpu_bit_bitmap[][]将是cpu_bit_bitmap[65][1]
p = cpu_bit_bitmap[3]
p -= 0
所以p指向cpu_bit_bitmap[3],这个指向的数据是1ul<<2
此时cpumask_t类型是一个结构体,里面只包含一个unsigned long bits[1]的数组:
typedef struct cpumask { unsigned long bits[1]; } cpumask_t
将1ul << 2转成cpumask_t即得到这个cpu的cpumask
以NR_CPUS为65、cpu index为64为例,上述cpu_bit_bitmap[][]将是cpu_bit_bitmap[65][2]
p = cpu_bit_bitmap[2]
p -= 1
所以p指向cpu_bit_bitmap[2]的前一个位置,即是cpu_bit_bitmap[1][1],将cpu_bit_bitmap[1][1] & cpu_bit_bitmap[2][0]这两个unsigned long型转成cpumask_t类型,此时cpumask_t类型是unsigned long bits[2]类型的struct:
typedef struct cpumask { unsigned long bits[2]; } cpumask_t
超过64个cpu的case这部分还需要再继续确认下...