Linux内核同步方式剖析(2)

原子 API 支持一个涵盖许多用例的富函数集。可以使用 atomic_read 读取原子变量中的内容,也可以使用 atomic_add 为一个变量添加指定值。最常用的操作是使用 atomic_inc 使变量递增。也可用减号运算符,它的作用与相加和递增操作相反。清单 2. 演示了这些函数。

清单 2. 简单的算术原子函数                      val = atomic_read( &my_counter );      atomic_add( 1, &my_counter );      atomic_inc( &my_counter );      atomic_sub( 1, &my_counter );      atomic_dec( &my_counter );  

该 API 也支持许多其他常用用例,包括 operate-and-test 例程。这些例程允许对原子变量进行操纵和测试(作为一个原子操作来执行)。一个叫做 atomic_add_negative 的特殊函数被添加到原子变量中,然后当结果值为负数时返回真(true)。这被内核中一些依赖于架构的信号量函数使用。许多函数都不返回变量的值,但两个函数除外。它们会返回结果值( atomic_add_return 和 atomic_sub_return),如清单 3所示。

清单 3. Operate-and-test 原子函数                      if (atomic_sub_and_test( 1, &my_counter )) {     // my_counter is zero    }      if (atomic_dec_and_test( &my_counter )) {     // my_counter is zero    }      if (atomic_inc_and_test( &my_counter )) {     // my_counter is zero    }      if (atomic_add_negative( 1, &my_counter )) {     // my_counter is less than zero    }      val = atomic_add_return( 1, &my_counter ));      val = atomic_sub_return( 1, &my_counter ));  

如果您的架构支持 64 位长类型(BITS_PER_LONG 是 64 的),那么可以使用 long_t atomic 操作。可以在 linux/include/asm-generic/atomic.h 中查看可用的长操作(long operation)。

原子 API 还支持位掩码(bitmask)操作。跟前面提到的算术操作不一样,它只包含设置和清除操作。许多驱动程序使用这些原子操作,特别是 SCSI。位掩码原子操作的使用跟算术操作存在细微的差别,因为其中只有两个可用的操作(设置掩码和清除掩码)。使用这些操作前,需要提供一个值和将要进行操作的位掩码,如清单 4 所示。

<span style="font-size:18px;">清单 4. 位掩码原子函数                      unsigned long my_bitmask;      atomic_clear_mask( 0, &my_bitmask );      atomic_set_mask( (1<<24), &my_bitmask );      </span>  

自旋锁

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjfjf.html