Критический раздел через constexpr

Во встроенном программировании необходимо создавать атомарные разделы кода — так называемые критические разделы. Они обычно реализуются с помощью макросов, например, так:

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

То есть при вводе состояния прерывания (включено или отключено) сохраняется; на выходе — восстанавливается. Проблема в том, что для этого нужна дополнительная переменная.

Мой вопрос: возможно ли создавать критические разделы с помощью функций constexpr (и избавиться от макросов, что так всегда)?

1

Решение

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 ().

6

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector