mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-08-03 09:19:49 +00:00
71 lines
2.2 KiB
C++
71 lines
2.2 KiB
C++
// Copyright (c) 2024 microReticulum contributors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#ifndef UI_LXMF_CALLGENERATIONGUARD_H
|
|
#define UI_LXMF_CALLGENERATIONGUARD_H
|
|
|
|
#include <atomic>
|
|
#include <cstdint>
|
|
|
|
namespace UI {
|
|
namespace LXMF {
|
|
|
|
// Atomic admission guard for call setup. Each successful reservation owns a
|
|
// generation until that exact generation releases it; generation zero always
|
|
// means "unowned". Generations eventually repeat after the finite token space
|
|
// wraps, so a token retained for a full cycle can exhibit ABA.
|
|
class CallGenerationGuard {
|
|
public:
|
|
static constexpr uint32_t MAX_GENERATION = 0x7fffffffu;
|
|
|
|
uint32_t tryReserve() {
|
|
const uint32_t generation = nextGeneration();
|
|
uint32_t expected = 0;
|
|
if (!active.compare_exchange_strong(expected, generation,
|
|
std::memory_order_acq_rel,
|
|
std::memory_order_acquire)) {
|
|
return 0;
|
|
}
|
|
return generation;
|
|
}
|
|
|
|
bool owns(uint32_t generation) const {
|
|
return generation != 0 &&
|
|
active.load(std::memory_order_acquire) == generation;
|
|
}
|
|
|
|
uint32_t current() const {
|
|
return active.load(std::memory_order_acquire);
|
|
}
|
|
|
|
bool release(uint32_t generation) {
|
|
if (generation == 0) return false;
|
|
return active.compare_exchange_strong(generation, 0,
|
|
std::memory_order_acq_rel,
|
|
std::memory_order_acquire);
|
|
}
|
|
|
|
private:
|
|
uint32_t nextGeneration() {
|
|
uint32_t generation = counter.load(std::memory_order_relaxed);
|
|
for (;;) {
|
|
const uint32_t next = generation == MAX_GENERATION
|
|
? 1u
|
|
: generation + 1u;
|
|
if (counter.compare_exchange_weak(generation, next,
|
|
std::memory_order_relaxed,
|
|
std::memory_order_relaxed)) {
|
|
return generation;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::atomic<uint32_t> active{0};
|
|
std::atomic<uint32_t> counter{1};
|
|
};
|
|
|
|
} // namespace LXMF
|
|
} // namespace UI
|
|
|
|
#endif // UI_LXMF_CALLGENERATIONGUARD_H
|