[英]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 从我的研究
atomic_store_explicit
) in non-atomic integer types. 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. atomic_thread_fence
) and then store the value in field
. 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.