I am wondering if any of you C/ASM gurus could help me answer some questions I have regarding some programming fundamentals.
Regarding the ATMELStudio include/avr interrupt.h SEI and CLI interrupt flag functions:
I noticed that the author of this file used "memory barriers" when using the assembly code instruction for setting (SEI) and clearing (CLI) the interrupt flags as follows:
//Enable interrupts: # define sei() __asm__ __volatile__ ("sei" ::: "memory"); //Disable interrupts: # define cli() __asm__ __volatile__ ("cli" ::: "memory");
From my understanding, these assembly instructions simply set the interrupt flag either to 0 or 1. No memory is modified by the assembly code itself. The __asm__ volatile statement will guarantee the assembly code is executed wherever it is called. I don't however understand why the "::: memory" barrier was used in this case, being that we know only the interrupt register value is modified without affecting any memory. It seems like for a simple task such as setting a register flag, the memory barrier will cause unnecessary processing overhead by forcing the storage of values in any cache before executing the asm code and reloading them after the asm code has executed.
Why would the author not simply use the following code to set the interrupt flags and reduce the processing overhead by removing the memory clobbers?:
//Enable interrupts: asm volatile("sei"); //Disable interrupts: asm volatile("cli");
In the atomic.h file, I understand the usefulness of ATOMIC_RESTORESTATE and NONATOMIC_RESTORESTATE since these store the SREG values on entry to memory and restore the SREG values on exit. However, looking at the ATOMIC_FORCEON and NONATOMIC_FORCEOFF options, I am not understanding their usefulness.
How are these two any different from the following code where I manually control CLI on entry and SEI on exit?
What I believe is the equivalent to (ATOMIC_FORCEON):
//Disable interrupts: asm volatile("cli"); x = y+2; //Enable interrupts: asm volatile("sei");
What I believe is the equivalent to (NONATOMIC_FORCEON):
//Enable interrupts: asm volatile("sei"); x = y+2; //Disable interrupts: asm volatile("cli");
Thanks, I appreciate the help!