#位图定义
位图就是按位(bit)来记录、索引某个对象状态的图表(map),即用每一位(bit)来存放每一个对象的某种状态。
#位图使用说明
如果申请一个DECLARE_BITMAP(my_bitmap, 32),也就是unsigned long my_bitmap[1]
| 0 | 1 | 2 |3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|28|30|31
| :------| ------: | :------: |
|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
将数据【0,1,31】存入后,结构变为:
| 0 | 1 | 2 |3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|28|30|31
| :------| ------: | :------: |
|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|
#位图的定义
在include/linux/types.h中定义:
#define BITS_TO_LONGS(bits) \
(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
在include/asm-i386/types.h中定义:
#define BITS_PER_LONG 32
在include/asm-ia64/types.h
#define BITS_PER_LONG 64
在i386模型中:
DECLARE_BITMAP(my_bitmap, 64)结果为:
(64+32-1)/32=2
等价于
unsigned long my_bitmap[2];
在x64模型中
DECLARE_BITMAP(my_bitmap, 64)结果为:
(64+64-1)/64=1
等价于
unsigned long my_bitmap[1];
这相当于说,一个bit表示一个状态
#位图操作
set_bit函数定义:
static inline void set_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
clear_bit函数定义:
static inline void clear_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
KERNEL VERSION: 4.4.174
294 /**
295 * bitmap_find_next_zero_area_off - find a contiguous aligned zero area
296 * @map: The address to base the search on
297 * @size: The bitmap size in bits
298 * @start: The bitnumber to start searching at
299 * @nr: The number of zeroed bits we're looking for
300 * @align_mask: Alignment mask for zero area
301 * @align_offset: Alignment offset for zero area.
302 *
303 * The @align_mask should be one less than a power of 2; the effect is that
304 * the bit offset of all zero areas this function finds plus @align_offset
305 * is multiple of that power of 2.
306 */
307 unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
308 unsigned long size,
309 unsigned long start,
310 unsigned int nr,
311 unsigned long align_mask,
312 unsigned long align_offset)
313 {
314 unsigned long index, end, i;
315 again:
316 index = find_next_zero_bit(map, size, start);
317
318 /* Align allocation */
319 index = __ALIGN_MASK(index + align_offset, align_mask) - align_offset;
320
321 end = index + nr;
322 if (end > size)
323 return end;
324 i = find_next_bit(map, end, index);
325 if (i < end) {
326 start = i + 1;
327 goto again;
328 }
329 return index;
330 }
331 EXPORT_SYMBOL(bitmap_find_next_zero_area_off);
说明:
316行,找到第一个为0的位;319行对齐index,end是为第一个0的index和请求的数量nr的和,如果end大于size也就是map的大小,显然不够分配,则返回end(此时的end大于map的size)。
第324行寻找map中下一个为1的bit,返回值为i。如果i>=end,说明在第一个为0和接着第一个为0后面为1的数量大于nr,说明够分配这么多,则返回index。