内核中的位图

#位图定义

位图就是按位(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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值