We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Is the operation below an atomic operation in a multitasking environment like RTX-51? If it is not, then what is supposed to do to make it an atomic one except using locking mechanisms?
void func() { int locVal = globalVal++; ... ... }
If it can't be completed in a single instruction then it is non-atomic?
On the 8051: Yes. Other architectures may differ.
If yes, which operations of a C/C++ compiler are atomic in general?
None. Yes, none. You cannot assume that any statement in C will result in an atomic operation. Use proper locking mechanisms when not programming in assembly.
Let me throw one more thing into the mix. On the C166 architectire, the MULx and DIVx instructions are interruptible. The ISR must save the intermediate state of multiplication/division if it intends to execute MULx or DIVx. In a way, it means that even single instructions can be non-atomic. As for the whole discussion, I think the answers can only be as good as the questions. The concept of 'atomicity' is too vague to be applied to all CPU's in general and to the C programming language. You have to ask more specific questions. By the way, the language itself (C90 and C99) has no concept of 'atomicity'. Somewhat related are the keyword volatile and the concept of 'sequence points.'
You cannot assume that any statement in C will result in an atomic operation.
Exactly right. Some compilers may provide language extensions which help achive atimicity. For example, Keil C166 compiler has the intrinsic functions _atomic_() and _endatomic_() which give access to the ATOMIC instruction of the CPU: http://www.keil.com/support/man/docs/c166/c166__atomic_.htm
_atomic_() isn't so much a compiler extension as a specific processor extension in the C166 processor.
Most processors don't have any hardware support for atomic operations, so the compiler would have to disable interrupts. In that case, it is better to have the developer explicitly use any __dis() or similar intrinsic.
the only way to decide/achieve atomicity is knowledge.
Trying to decide atomicity by looking at some C code is futile, if you have any doubt, you need look at the generated assembler.
Erik
Most processors don't have any hardware support for atomic operations, so the compiler would have to disable interrupts.
Unfortunately that only moves the problem elsewhere, but doesn't solve it. The trouble being that in general you have to save the previous state of the interrupt-enable flag before you disable interrupts, so you can clean up after yourself. In order for that saved state to be valid, these two operations have to be combined into an atomic step.
I.e. you need an atomic instruction to work around the lack of an atomic instruction. Chicken/Egg, here we come!
That's not entirely true. C does provide __sigatomic_t in <signal.h> for exactly this purpose. There is a drawback though, in that interrupt handling is usually not mapped to the <signal.h> machinery.
Only if you do things like disabling interrupts in an ISR without re-enabling them before leaving the ISR, or your processor has an interrupt system where there's a window after disabling interrupts in which interrupts can still occur.
And even the venerable 8051 has an atomic "jump if bit is set and clear bit" instruction.
"The trouble being that in general you have to save the previous state of the interrupt-enable flag before you disable interrupts [...]".
From my second post in this thread "This is similar to disabling interrupts, but with an automatic enable, and the program doesn't need to know if interrupts was enabled or disabled when processing the lock instruction or processing instructions with lock flags."
But as noted by Christoph Franck, you seldom have a problem with the atomicity of caching the interrupt flag state before turning off interrupts. The problem is more often the number of instructions needed.
For Keil C51 specifically, see:
#pragma disable
http://www.keil.com/support/man/docs/c51/c51_disable.htm