Question

In embedded programming there is a need to create atomic sections of code - so called critical sections. They are usually implemented via macros, for example, like this:

#define ENTER_CRITICAL() int saved_status_ = CPU_STATUS_REGISTER; __disable_irq();
#define EXIT_CRITICAL()  CPU_STATUS_REGISTER = saved_status_

I.e. on entering the status of interrupts (enabled or disabled) is saved; on exit - it is restored. The problem is that additional variable is needed for this.

My question is: is it possible to make critical sections via constexpr functions (and to get rid of macros what so ever)?

Was it helpful?

Solution

RAII solution would be traditional:

struct CriticalSection {
  int saved_status_;
  void Enter() {
    saved_status_ = CPU_STATUS_REGISTER;
    __disable_irq();
  }
  CriticalSection() { Enter(); }
  void Exit() {
    CPU_STATUS_REGISTER = saved_status_;
  }
  ~CriticalSection() {
    Exit(); // Can you call this more than once safely?  Dunno.
  }
};

you'd use it like this:

void foo() {
  // unprotected code goes here
  {
    CriticalSection _;
    // protected code goes here
  }
  // unprotected code goes here
}

Doing this without any state is not possible, because CPU_STATUS_REGISTER is a run time value. State in C/C++ is mostly stored in variables.

I strongly suspect that, under any non-trivial optimization level, the above RAII class will compile to the exact same code that your macros compiled to, except you no longer have to remember to EXIT_CRITICAL().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top