临界区通过constexpr

Critical section via constexpr

本文关键字:constexpr 临界区      更新时间:2023-10-16

在嵌入式编程中,需要创建代码的原子部分——即所谓的临界部分。它们通常通过宏实现,例如:

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

。在进入中断状态(启用或禁用)时保存;一退出,它就恢复了。问题是需要额外的变量。

我的问题是:是否有可能通过constexpr函数来创建临界区(并摆脱宏等等)?

RAII解决方案将是传统的:

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.
  }
};

你可以这样使用:

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

在没有任何状态的情况下这样做是不可能的,因为CPU_STATUS_REGISTER是一个运行时值。C/c++中的状态主要存储在变量中。

我强烈怀疑,在任何重要的优化级别下,上述RAII类都将编译成与宏编译成的完全相同的代码,只是您不再需要记住EXIT_CRITICAL()。