gpt4 book ai didi

c - 在 Linux 内核中设置或清除位的平台独立方式

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:24 25 4
gpt4 key购买 nike

我目前正在阅读 Robert Love 的 Linux Kernel Development 第三版,在解释 set_bit()clear_bit 的部分后我遇到了一个奇怪的陈述() 原子函数及其非原子兄弟函数,__set_bit()__clear_bit():

Unlike the atomic integer operations, code typically has no choice whether to use the bitwise operations—they are the only portable way to set a specific bit.

-p。 183(强调我自己的)

我知道这些操作可以在单个特定于平台的汇编指令中实现,这就是存在这些内联函数的原因。但我很好奇为什么作者说这些是做这些事情的唯一可移植方式。例如,我相信我可以在 unsigned long x 中非原子地设置位 nr 通过在纯 C 中执行此操作:

x |= 1UL << nr;

同样,我可以通过执行以下操作以非原子方式清除 unsigned long x 中的 nr 位:

x &= ~(1UL << nr);

当然,根据编译器的复杂程度,它们可能会编译成几条指令,因此它们可能不如 __set_bit()__clear_bit() 函数。

我是不是漏掉了什么?这个短语只是一个稍微懒惰的简化,还是我上面介绍的设置和清除位的方法有什么不可移植的地方?

编辑:虽然 GCC 相当复杂,但它仍然执行位移,而不是像 __set_bit() 函数那样使用单个指令,即使在 -O3(版本 6.2.1)上。例如:

stephen at greed in ~/code 
$ gcc -g -c set.c -O3

stephen at greed in ~/code
$ objdump -d -M intel -S set.o

set.o: file format elf64-x86-64


Disassembly of section .text.startup:

0000000000000000 <main>:
#include<stdio.h>
int main(int argc, char *argv)
{
unsigned long x = 0;
x |= (1UL << argc);
0: 89 f9 mov ecx,edi
2: be 01 00 00 00 mov esi,0x1
7: 48 83 ec 08 sub rsp,0x8
b: 48 d3 e6 shl rsi,cl
e: bf 00 00 00 00 mov edi,0x0
13: 31 c0 xor eax,eax
15: e8 00 00 00 00 call 1a <main+0x1a>
{
1a: 31 c0 xor eax,eax
x |= (1UL << argc);
1c: 48 83 c4 08 add rsp,0x8
printf("x=%x\n", x);
20: c3 ret

最佳答案

原子整数运算的上下文中,“按位运算”也表示原子运算。

非原子位运算没有什么特别之处(除了它们支持大于 BITS_PER_LONG 的数字),所以 generic implementation总是正确的,并且只需要特定于体系结构的实现来优化性能。

关于c - 在 Linux 内核中设置或清除位的平台独立方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39986521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com