【问题标题】:C atomic read modify writeC原子读修改写
【发布时间】:2017-11-25 14:14:41
【问题描述】:

C 中是否有任何函数可以进行原子读取-修改-写入? 我希望在单个原子块中读取一个值,然后设置为 0。

对于 C++,有 std::atomic::exchange() 正是我正在寻找的。 C 中有没有等价的东西?

代码如下:

void interruptHandler(void) {
    /* Callback attached to 3rd party device driver, indicating hardware fault */
    /* Set global variable bit masked flag to indicate interrupt */
    faultsBitMask |= 0x1;
}

void auditPoll(*faults) {
    *faults = faultsBitMask;
    /* !!! Need to prevent interrupt pre-empt here !!! */
    /* Combine these two lines to a single read-modify-write? */
    faultsBitMask = 0;
}

目标架构是 PowerPC。

感谢您的帮助!

【问题讨论】:

  • C11 标准添加了atomic operations。如果你的编译器足够新,你可以使用它们。
  • C11 原子类型和操作已与 C++11 规范同步指定。它们应该在 C 和 C++ 之间是二进制兼容的。
  • 感谢@Someprogrammerdude 和@JensGustedt!

标签: c atomic powerpc


【解决方案1】:

如果您使用的是 GCC,请尝试使用 GCC builtin __atomic_exchange__atomic_compare_exchange_n

【讨论】:

    【解决方案2】:

    是的,<stdatomic.h> 标头包含一个与 C++ 版本非常相似的类型泛型函数 atomic_exchange

    _Atomic int n = 10;
    
    #include <stdatomic.h>
    
    int main(void) { return atomic_exchange(&n, 0); }
    

    【讨论】:

    • 这不是全部,信号处理程序上下文中的原子需要特别注意。另外你真的不需要原子交换来做你正在做的事情,请看我的回答。
    • @JensGustedt:嗯,这就是 OP 要求的。她没有说这是为了信号处理程序。
    【解决方案3】:

    您似乎想将原子与信号处理程序一起使用。如果 C11 原子类型是“无锁”的,那么它们可以做到这一点,但通常它们是。您可以使用ATOMIC_INT_LOCK_FREE 测试int 的此属性。

    对于您的情况,您甚至不需要原子交换功能。在原子变量上

    faultsBitMask |= 0x1;
    

    将始终是原子读-修改-写操作。

    【讨论】:

    • 这是否取决于操作系统?语言本身是否没有在信号处理程序周围指定任何关于缓存失效的内容?
    • 是的,只要宏说明您的数据类型是无锁的,这与平台无关。
    • 嗨 Jens,这不适用于信号处理程序。 interruptHandler() 是来自第 3 方 Broadcom SDK 的回调。它在 Broadcom 硬件设备出现故障时触发,并指示发生了什么故障。
    • @Splaty,更好的是,您不必检查无锁和限定变量,因为 _Atomic 应该是您需要对代码进行的唯一更改。
    • 嗯,我想我仍然需要 atomic_exchange() 进行阅读和清除,对吧? { *faults = faultsBitMask;故障位掩码 = 0; }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2011-01-16
    相关资源
    最近更新 更多