我需要一个线程保存idx++和idx--操作。禁用中断,即使用临界区是一回事,但我想知道为什么我的操作不是原子的,正如我所期望的那样?下面是使用segger ozone显示的内联汇编代码的C代码:(另外请注意,变量的地址显示32位变量在内存中是32位对齐的,8位和16位变量都是16位对齐的)
volatile static U8 dbgIdx8 = 1000U;
volatile static U16 dbgIdx16 = 1000U;
volatile static U32 dbgIdx32 = 1000U;
个字符
2条答案
按热度按时间ozxc1zmp1#
不能保证
++
和--
是原子的。如果你需要保证原子性,你将不得不找到一些其他的方法。正如@StaceyGirl在评论中指出的那样,您可能可以使用<stdatomic.h>的设施。例如,我看到定义了一个原子
atomic_fetch_add
函数,它的作用类似于您正在努力实现的后缀++
。还有一个atomic_fetch_sub
。或者,您可能有一些编译器内部函数可供您使用,以便以某种特定于处理器的方式执行原子增量。
k0pti3hp2#
但是Cortex M3有特殊的指令来锁定对内存位置的访问。LDREX和STREX。https://developer.arm.com/documentation/100235/0004/the-cortex-m33-instruction-set/memory-access-instructions/ldaex-and-stlex
您可以直接在C代码中使用它们,而不需要使用intrinsic。
1.不要在任何对性能敏感的程序中使用非32位数据类型(您希望锁定尽可能短的时间)。大多数较短的数据类型操作都会添加一些额外的代码。