I want to be able to modify a non-atomic variable in interrupt context or application context without ever blocking. To prevent the ISR from blocking, I use an atomic flag to guard the non-atomic data.
#include <atomic>
#include <cstdint>
using CountLock = std::atomic<bool>;
static_assert(CountLock::is_always_lock_free, "count lock must be lock free");
#define TARGET_COUNT (1000)
CountLock count_locked{false};
uint64_t count{0}; // non-atomic on 32-bit system
// In interrupt
void MyISR()
{
// Don't modify count if locked
if (count_locked)
return;
++count; // non-atomic
if (count == TARGET_COUNT)
// Do something
}
// Application code (not in interrupt)
void setCount(uint64_t newCount)
{
// lock count while we are setting it
count_locked = true;
count = newCount;
count_locked = false;
}
- Does this correctly guard the data?
- Is the compiler allowed to compile out the count_locked variable or reorder instructions such that the data is outside the lock?
- Am I correct in thinking nothing needs to be marked volatile?
- Is this equivalent to a mutex?