简体   繁体   English

在uint8_t(C)中以原子方式存储值

[英]Atomically storing a value in a uint8_t (C)

Let's assume we have a C structure that contains a uint8_t field: 假设我们有一个包含uint8_t字段的C结构:

typedef struct foo_s {
  uint8_t field;
  // other fields...
} foo_t;

If we want to atomically store a value in field using a particular memory order, what are the possibilities within the C language? 如果我们想使用特定的内存顺序以原子方式在field存储值,那么C语言中的可能性是什么? From what I researched 从我的研究

  • The C11 standard does not allow atomic stores ( atomic_store_explicit ) in non-atomic integer types. C11标准不允许非原子整数类型的原子库( atomic_store_explicit )。 On top of that, there is no atomic integer type in the standard that is guaranteed to have a width of one byte. 最重要的是,标准中没有原子整数类型,保证宽度为一个字节。
  • Another possibility (within C11) is to use a memory fence ( atomic_thread_fence ) and then store the value in field . 另一种可能性(在C11内)是使用内存栅栏( atomic_thread_fence )然后将值存储在field But the standard requires this store to be atomic for the fence to work as intended, so we go back to the issue described in the previous item. 但是标准要求这个商店是原子的,以便围栏按预期工作,所以我们回到上一个项目中描述的问题。

So the solution to our problem seems to be out of the C standard...is there any commonly used mechanism for atomically storing a byte? 所以我们问题的解决方案似乎超出了C标准...是否有任何常用的机制来原子地存储一个字节?

Please note that we cannot change the type of field , since it belongs to a third-party library. 请注意,我们无法更改field类型,因为它属于第三方库。

In GCC, the atomic store asked for can be achieved using __atomic_store_n , which is included in the Atomics extension and does work at the level of granularity of a byte. 在GCC中,要求的原子存储可以使用__atomic_store_n来实现,它包含在Atomics扩展中,并且在一个字节的粒度级别上工作。 The GCC documentation for atomic builtins states that "GCC allows any integral scalar or pointer type that is 1, 2, 4, or 8 bytes in length". 原子内置的GCC 文档声明“GCC允许任何长度为1,2,4或8字节的整数标量或指针类型”。 A peek at the implementation reveals that the HW store works at 4-byte granularity, but the SW will emulate byte stores by using compare and swap operations (ie, making sure that concurrent modifications to any other byte in the word are not lost). 查看实现后发现,HW存储以4字节的粒度工作,但SW将通过使用比较和交换操作来模拟字节存储(即,确保对字中任何其他字节的并发修改不会丢失)。

My understanding is that the atomic modification works in any integer variable such as field - there is no need to change its type or modifiers. 我的理解是原子修改适用于任何整数变量,例如field - 不需要更改其类型或修饰符。

It is not portable, due to endianess and perhaps alignment concerns, but you could alias another union structure to the foo_t structure. 由于endianess和对齐问题,它不可移植,但你可以将另一个union结构别名为foo_t结构。 The alias union structure would have an atomic-sized field that overlaps the entire uint8_t field . 别名联合结构将具有与整个uint8_t field重叠的原子大小的uint8_t field Now you can update the overlapping field atomically. 现在,您可以原子方式更新重叠字段。 Since it overlaps the field, that will also be updated atomically. 由于它与字段重叠,因此也将以原子方式更新。

By alias union structure I mean 通过别名联合结构我​​的意思是

typedef union alias_foo_u
{
    foo_t orig_foo;
    struct alias_foo_s
    {
        atomic_t field_overlap;
        ...
    } alias_foo;
} alias_foo_t;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM