linux内核中clear_bit用法,Linux 内核里的数据结构——位数组位数组声明体系结构特定的位操作通用位操作链接...

Linux 内核中的位数组和位操作

除了不同的基于链式和树的数据结构以外,Linux 内核也为位数组(或称为位图(bitmap))提供了 API。位数组在 Linux 内核里被广泛使用,并且在以下的源代码文件中包含了与这样的结构搭配使用的通用 API:

除了这两个文件之外,还有体系结构特定的头文件,它们为特定的体系结构提供优化的位操作。我们将探讨 x86_64 体系结构,因此在我们的例子里,它会是

头文件。正如我上面所写的,位图在 Linux 内核中被广泛地使用。例如,位数组常常用于保存一组在线/离线处理器,以便系统支持热插拔的 CPU(你可以在 cpumasks 部分阅读更多相关知识 ),一个位数组(bit array)可以在 Linux 内核初始化等期间保存一组已分配的中断处理。

因此,本部分的主要目的是了解位数组(bit array)是如何在 Linux 内核中实现的。让我们现在开始吧。

位数组声明

在我们开始查看位图操作的 API 之前,我们必须知道如何在 Linux 内核中声明它。有两种声明位数组的通用方法。第一种简单的声明一个位数组的方法是,定义一个 unsigned long 的数组,例如:

unsigned long my_bitmap[8]

第二种方法,是使用 DECLARE_BITMAP 宏,它定义于 include/linux/types.h 头文件:

#define DECLARE_BITMAP(name,bits) \    unsigned long name[BITS_TO_LONGS(bits)]

我们可以看到 DECLARE_BITMAP 宏使用两个参数:name - 位图名称;

bits - 位图中位数;

并且只是使用 BITS_TO_LONGS(bits) 元素展开 unsigned long 数组的定义。 BITS_TO_LONGS 宏将一个给定的位数转换为 long 的个数,换言之,就是计算 bits 中有多少个 8 字节元素:

#define BITS_PER_BYTE           8

#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))

因此,例如 DECLARE_BITMAP(my_bitmap, 64) 将产生:(((64) + (64) - 1) / (64)) 1

与:

unsigned long my_bitmap[1];

在能够声明一个位数组之后,我们便可以使用它了。

体系结构特定的位操作

我们已经看了上面提及的一对源文件和头文件,它们提供了位数组操作的 API。其中重要且广泛使用的位数组 API 是体系结构特定的且位于已提及的头文件中 arch/x86/include/asm/bitops.h。

首先让我们查看两个最重要的函数:set_bit;

clear_bit.

我认为没有必要解释这些函数的作用。从它们的名字来看,这已经很清楚了。让我们直接查看它们的实现。如果你浏览 arch/x86/include/asm/bitops.h 头文件,你将会注意到这些函数中的每一个都有原子性和非原子性两种变体。在我们开始深入这些函数的实现之前,首先,我们必须了解一些有关原子(atomic)操作的知识。

简而言之,原子操作保证两个或以上的操作不会并发地执行同一数据。x86 体系结构提供了一系列原子指令,例如, xchg、cmpxchg 等指令。除了原子指令,一些非原子指令可以在 lock 指令的帮助下具有原子性。现在你已经对原子操作有了足够的了解,我们可以接着探讨 set_bit 和 clear_bit 函数的实现。

我们先考虑函数的非原子性(non-atomic)变体。非原子性的 set_bit 和 clear_bit 的名字以双下划线开始。正如我们所知道的,所有这些函数都定义于 arch/x86/include/asm/bitops.h 头文件,并且第一个函数就是 __set_bit:

static inline void __set_bit(long nr, volatile unsigned long *addr) {    asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值