这可以原子执行吗?

标签 c assembly arm atomic interrupt

我想知道是否有可能确保 line 被原子执行,因为它可以由 ISR 和 Main 上下文执行。我正在开发 ARM9 (LPC313x) 并使用 RealView 4 (armcc)。

foo() { 
  ..
  stack_var = ++volatile_var; // line
  ..
}

我正在寻找 C166 的任何例程,如 _atomic_、直接汇编代码等。我宁愿不必禁用中断。

非常感谢。

最佳答案

不,我不认为你可以期望 ++volatile_var 是原子的,即使你没有分配。为此使用适当的原子原语。如果你的编译器不提供这样的扩展,你很容易在网上找到短的内联汇编器。我认为,汇编程序指令是调用 ldrexstrex 以在 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/

相关文章:

c - 使用 sscanf 读取带空格的字符串

linux - "call 0x80482f0 <puts@plt>"?只需要澄清 x86 程序集中 'hello world' 程序中的一行代码

assembly - GAS ELF何时需要使用.type,.thumb,.size和.section指令?

使用 NEON 指令的 Linpack 的 clang O3/O2 错误

iphone - 如何在 iOS 设备上编译 ARM 汇编文件和 iOS 模拟器使用常规 C 之间进行选择

java - 如何直接使用ByteBuffer

c - popen 意外返回 -1

c++ - main() 函数返回值的转换是如何工作的?

c - 最少三个值的最佳汇编或编译

assembly - JS和JL x86指令的区别