Flag
LibXR::Flag provides a very lightweight set of boolean state utilities. It is suitable for simple states such as “busy or idle”, “request pending”, or “event has occurred”.
Current mainline provides three pieces:
Flag::Atomic: atomic flag for shared state across threads / cores / ISRsFlag::Plain: non-atomic flag for local or externally synchronized useFlag::ScopedRestore<FlagT>: RAII helper that changes a flag on scope entry and restores the previous value on scope exit
Flagis not a mutex and not a spinlock. It only stores and exchanges a boolean state and does not provide critical-section exclusion semantics.
1. Flag::Atomic
Flag::Atomic stores state with std::atomic<uint32_t> and provides these common APIs:
Set()Clear()IsSet()TestAndSet()TestAndClear()Exchange(bool)
Copy construction and copy assignment are disabled.
Typical uses:
- shared “new data / sending / retry needed” markers between ISR and thread contexts
- one-bit state sharing between threads
2. Flag::Plain
Flag::Plain provides almost the same API shape as Flag::Atomic, but stores state as a normal bool.
Characteristics:
- no atomic semantics
- not suitable for concurrent access
- suitable for single-threaded code, or cases already protected by a higher-level lock / critical section
If a flag is only used locally or all accesses are already synchronized elsewhere, Flag::Plain is often the simpler choice.
3. Flag::ScopedRestore<FlagT>
ScopedRestore is an RAII helper:
- on construction it calls
flag.Exchange(set_value)and stores the old value - on destruction it restores the old value automatically
It requires FlagT to provide at least:
bool Exchange(bool set_value);
Typical uses:
- temporarily marking a function as “in progress” and restoring the previous state automatically
- avoiding manual cleanup on early
return
4. Example
#include <libxr.hpp>
LibXR::Flag::Atomic tx_busy;
if (!tx_busy.TestAndSet())
{
// first entry into the transmit path
tx_busy.Clear();
}
LibXR::Flag::Plain in_callback;
{
LibXR::Flag::ScopedRestore<LibXR::Flag::Plain> guard(in_callback, true);
// in_callback is true inside this scope
}
// previous value is restored here
5. Selection guidance
- Shared across threads / ISR: prefer
Flag::Atomic - Local single-thread state: prefer
Flag::Plain - Need “set on entry, restore on exit”: use
ScopedRestore
If you actually need mutual exclusion rather than a simple state bit, use Mutex or another synchronization primitive instead of Flag.