Linux 2.4 内核说明文档(进程与中断管理篇)(7)
再有一节:
2.10. 原子操作
2.10. 原子操作
目前有两种类型的原子操作:bitmaps 和 atomic_t。对于维护“已分配”或者“释放”单位(这些单位来自于某些大型的以数字标识每个单位的集合)的概念,bitmaps非常便利。释放inodes和块就是例子。这也在某些简单锁中有广泛的应用,例如提供打开设备的互斥访问。这样的例子可以在arch/i386/kernel/microcode.c中被找到。
/*
* Bits in microcode_status. (31 bits of room for future expansion)
*/
#define MICROCODE_IS_OPEN 0 /* set if device is in use */
static unsigned long microcode_status;
Linux下没有必要像清零BSS一样初始化microcode_status。
/*
* We enforce only one user at a time here with open/close.
*/
static int microcode_open(struct inode *inode, struct file *file)
{
if (!capable(CAP_SYS_RAWIO))
return .EPERM;
/* one at a time, please */
if (test_and_set_bit(MICROCODE_IS_OPEN, µcode_status))
return .EBUSY;
MOD_INC_USE_COUNT;
return 0;
}
关于bitmaps的操作有:
void set_bit(int nr, volatile void *addr):在由地址addr指向的bitmap中添加位nr。
void clear_bit(int nr, volatile void *addr):在由地址addr指向的bitmap中清除位nr。
void change_bit(int nr, volatile void *addr):在由地址addr指向的bitmap中绑定位nr。
int test_and_set_bit(int nr, volatile void *addr):设置位nr并返回以前的值。
int test_and_clear_bit(int nr, volatile void *addr):清除位nr并返回以前的值。
int test_and_change_bit(int nr, volatile void *addr):绑定位nr并返回以前的值。
这些操作都使用了LOCK_PREFIX宏,该宏在SMP内核上求总线锁指令前缀的值,在UP上不做任何实际操作。这保证了SMP环境下的访问原子数。
有时位操作不是便利的,作为替代我们采用算法操作,增加、减小、自增、自减。典型的案例就是引用计数。它由atomic_t数据类型和一下步骤实现:
atomic_read(&v):返回atomic_t变量v的值;
atomic_set(&v, i):将atomic_t变量v的值设置为整型i;
void atomic_add(int i, volatile atomic_t *v):将atomic_t变量的值增加i;
void atomic_sub(int i, volatile atomic_t *v):将atomic_t变量减少i;
int atomic_sub_and_test(int i, volatile atomic_t *v):将atomic_t变量减少i,如果新的值是0则返回1,否则返回0;
void atomic_inc(volatile atomic_t *v):atomic_t变量增加1;
void atomic_dec(volatile atomic_t *v):atomic_t变量减少1;
int atomic_dec_and_test(volatile atomic_t *v):atomic_t变量减少1,如果新的值是0则返回1,否则返回0;
int atomic_inc_and_test(volatile atomic_t *v):atomic_t变量增加1,如果新的值是0则返回1,否则返回0;
int atomic_add_negative(int i, volatile atomic_t *v):atomic_t变量增加i,如果结果是负数,返回1;否则返回0。这个操作用于实现semaphores。
文章来源CU社区:Linux 2.4 内核说明文档(进程与中断管理篇)
相关文章