This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Atomic sections of code

There are several possibilities to protect critical sections of code from being interrupted:

1. Temporarily disabling and enabling interrupts:

void function(void)
{
    EA = 0;
    // atomic_section...
    EA = 1;
}

Disadvantage:
This will change the status of EA if interrupts had not been enabled before.

2. Saving and restoring EA:
http://www.keil.com/forum/1080/

bit ea_saved;

void function(void)
{
    ea_saved = EA;
    EA = 0;
    // atomic_section...
    EA = ea_saved;
}

Disadvantage: if this code can be interrupted between ea_saved=EA and EA=0. If the interrupt service routine decides to disable interrupts, the interrupts will become enabled again when doing EA=ea_saved after the critical section.

3. Using #pragma disable
http://www.keil.com/support/man/docs/c51/c51_disable.htm
http://www.keil.com/forum/1080/

#pragma disable
void function (void)
{
    // atomic_section...
}

Advantage:
Avoids the above problem because the JBC opcode is used to evaluate the current state of EA and clear EA with the same instruction:

; FUNCTION function (BEGIN)
          SETB    C
          JBC     EA,IS_CLEARED
          CLR     C
IS_CLEARED:
          PUSH    PSW

    // atomic_section...

          POP     PSW
          MOV     EA,C
          RET
; FUNCTION function (END)

Disadvantage:
Can be applied to whole functions only.
Requires 1 Byte on the stack.

4. Combination of 2. and 3.

#include <intrins.h>

#define ATOMIC_SECTION_BEGIN    { ea_saved = 1; if (!(_testbit_(EA))) { ea_saved = 0; } }
#define ATOMIC_SECTION_END      { EA = ea_saved; }
#define INTERRUPTS_DISABLE      { EA = 0; ea_saved = 0; }
#define INTERRUPTS_ENABLE       { EA = 1; ea_saved = 1; }

bit ea_saved;

void function(void)
{

ATOMIC_SECTION_BEGIN

    // atomic_section...

ATOMIC_SECTION_END
}

This results in

ATOMIC_SECTION_BEGIN
        SETB    ea_saved
        JBC     EA,?C0007?HB
        CLR     ea_saved

?C0007?HB:

    // atomic_section...

ATOMIC_SECTION_END
        MOV     C,ea_saved
        MOV     EA,C

Advantages:
Pure source code, no inline assembly.
Atomic section can remain inline, no sub-function required.
Only one bit for status saving required.

0