Could this be atomically executed?

I would like to know whether it is possible to guarantee that it lineis executed atomically, given that it can be executed both in ISR and in Main. I am working on ARM9 (LPC313x) and using RealView 4 (armcc).

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

I am looking for any procedure, for example _atomic_for C166, direct assembly code, etc. I would prefer not to disable interrupts.

Many thanks.

+5
source share
2 answers

C166 _atomic_, , , . ARM , .

, swp ( __swp, RealView) . ldrex/strex, , ARM 5, ARM9. http://infocenter.arm.com/help/topic/com.arm.doc.dui0491c/CJAHDCHB.html http://infocenter.arm.com/help/topic/com.arm.doc.dui0489c/Chdbbbai.html .

( RealView) :

{
    /* Loop until lock acquired */
    while (__swp(LOCKED, &lockvar) == LOCKED);
    ..
    /* Critical section */
    ..
    lockvar = UNLOCKED;
}

ISR, .

, , , , , , .

+6

, , , ++volatile_var , . . , . , ldrex strex .

: , , , .

: 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;
  }
}
+8

All Articles