Home > Software design >  Cortex M3, STM32, thumb2: My inc and dec operations are not atomic, but should be. What's wrong
Cortex M3, STM32, thumb2: My inc and dec operations are not atomic, but should be. What's wrong

Time:10-24

I need a thread save idx and idx-- operation. Disabling interrupts, i.e. use critical sections, is one thing, but I want to understand why my operations are not atomic, as I expect ? Here is the C-code with inline assembler code shown, using segger ozone: (Also please notice, the address of the variables show that the 32 bit variable is 32-bit-aligned in memory, and the 8- and 16-bit variables are both 16 bit aligned)

volatile static U8 dbgIdx8 = 1000U;
volatile static U16 dbgIdx16 = 1000U;
volatile static U32 dbgIdx32 = 1000U;
      dbgIdx8   ;
     080058BE   LDR            R3, [PC, #48]                 
     080058C0   LDRB           R3, [R3]
     080058C2   UXTB           R3, R3
     080058C4   ADDS           R3, #1
     080058C6   UXTB           R2, R3
     080058C8   LDR            R3, [PC, #36]                 
     080058CA   STRB           R2, [R3]

      dbgIdx16   ;
     080058CC   LDR            R3, [PC, #36]                 
     080058CE   LDRH           R3, [R3]
     080058D0   UXTH           R3, R3
     080058D2   ADDS           R3, #1
     080058D4   UXTH           R2, R3
     080058D6   LDR            R3, [PC, #28]                 
     080058D8   STRH           R2, [R3]

      dbgIdx32   ;
     080058DA   LDR            R3, [PC, #28]                 
     080058DC   LDR            R3, [R3]
     080058DE   ADDS           R3, #1
     080058E0   LDR            R2, [PC, #20]                 
     080058E2   STR            R3, [R2]

CodePudding user response:

There is no guarantee that and -- are atomic. If you need guaranteed atomicity, you will have to find some other way.

As @StaceyGirl points out in a comment, you might be able to use the facilities of <stdatomic.h>. For example, I see there's an atomic atomic_fetch_add function defined, which acts like the postfix you're striving for. There's an atomic_fetch_sub, too.

Alternatively, you might have some compiler intrinsics available to you for performing an atomic increment in some processor-specific way.

CodePudding user response:

The postfix increment operator in dbgIdx8 ; is not atomic because the C compiler does save the current value of dbgIdx8then do any operations on it (in this case there is nothing) then do the incrementing.

To achieve atomic operation use the prefix increment operator like dbgIdx8;

CodePudding user response:

The variables are marked as volatile which tells the compiler to assume that it can be used or modified in an unknown way. So the processor will load value to a register, perform the required operations, and store result back to a memory location. There is no "in-memory" arithmetic in Cortex-M3.

However, removing keyword volatile might, or might not make an operation atomic. It depends on the operations done before and after increment. There is no guarantee.

  • Related