我想知道是否有可能确保 line
被原子执行,因为它可以由 ISR 和 Main 上下文执行。我正在开发 ARM9 (LPC313x) 并使用 RealView 4 (armcc)。
foo() {
..
stack_var = ++volatile_var; // line
..
}
我正在寻找 C166 的任何例程,如 _atomic_
、直接汇编代码等。我宁愿不必禁用中断。
非常感谢。
最佳答案
不,我不认为你可以期望 ++volatile_var
是原子的,即使你没有分配。为此使用适当的原子原语。如果你的编译器不提供这样的扩展,你很容易在网上找到短的内联汇编器。我认为,汇编程序指令是调用 ldrex
和 strex
以在 arm 上进行原子交换。
编辑:问题中要求的特定处理器类型似乎没有实现这些指令。
编辑: 以下内容应该适用于 gcc,对于另一个编译器,可能必须调整 __asm__
部分。
inline
size_t arm_ldrex(size_t volatile*ptr) {
size_t ret;
__asm__ volatile ("ldrex %0,[%1]\t@ load exclusive\n"
: "=&r" (ret)
: "r" (ptr)
: "cc", "memory"
);
return ret;
}
inline
_Bool arm_strex(size_t volatile*ptr, size_t val) {
size_t error;
__asm__ volatile ("strex %0,%1,[%2]\t@ store exclusive\n"
: "=&r" (error)
: "r" (val), "r" (ptr)
: "cc", "memory"
);
return !error;
}
inline
size_t atomic_add_fetch(size_t volatile *object, size_t operand) {
for (;;) {
size_t oldval = arm_ldrex(object);
size_t newval = oldval + operand;
if (arm_strex(object, newval)) return newval;
}
}
关于这可以原子执行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5418621/