8#include "pedigree/kernel/Log.h"
9#include "pedigree/kernel/panic.h"
10#include "pedigree/kernel/process/OperationBarrier.h"
11#include "pedigree/kernel/process/TerminationDeferral.h"
12#include "pedigree/kernel/process/Thread.h"
14OperationBarrier::Lease::Lease() : m_Barrier(nullptr) {}
16OperationBarrier::Lease::Lease(
OperationBarrier* barrier) : m_Barrier(barrier) {}
18OperationBarrier::Lease::Lease(Lease&& other) noexcept : m_Barrier(other.m_Barrier) {
19 other.m_Barrier =
nullptr;
22OperationBarrier::Lease::~Lease() {
30 m_Barrier = other.m_Barrier;
31 other.m_Barrier =
nullptr;
36void OperationBarrier::Lease::reset() {
44OperationBarrier::OperationBarrier() : m_Waiters(), m_State(0) {}
46OperationBarrier::~OperationBarrier() {
47 auto guard = m_Waiters.acquire();
48 if (__atomic_load_n(&m_State, __ATOMIC_ACQUIRE) != Closed) {
49 panic(
"OperationBarrier destroyed before close-and-drain completed.");
54 size_t state = __atomic_load_n(&m_State, __ATOMIC_RELAXED);
59 if (state == CountMask) {
60 panic(
"OperationBarrier operation count overflow.");
62 }
while (!__atomic_compare_exchange_n(&m_State, &state, state + 1,
true, __ATOMIC_ACQUIRE,
78 size_t state = __atomic_load_n(&m_State, __ATOMIC_RELAXED);
80 if (!(state & CountMask)) {
81 panic(
"OperationBarrier operation count underflow.");
83 if (state == (Closed | 1)) {
86 auto guard = m_Waiters.acquire();
87 __atomic_fetch_sub(&m_State,
size_t{1}, __ATOMIC_ACQ_REL);
91 }
while (!__atomic_compare_exchange_n(&m_State, &state, state - 1,
true, __ATOMIC_RELEASE,
97 __atomic_fetch_or(&m_State, Closed, __ATOMIC_ACQ_REL);
101 auto guard = m_Waiters.acquire();
103 return __atomic_compare_exchange_n(&m_State, &state, Closed,
false, __ATOMIC_ACQ_REL,
111 auto guard = m_Waiters.acquire();
112 const size_t state = __atomic_load_n(&m_State, __ATOMIC_ACQUIRE);
113 if (!(state & Closed)) {
114 panic(
"OperationBarrier::wait called before close.");
116 if (!(state & CountMask)) {
120 const WaitQueue::WakeReason reason =
122 reinterpret_cast<uintptr_t
>(__builtin_return_address(0)));
132bool OperationBarrier::isOpen() {
133 return !(__atomic_load_n(&m_State, __ATOMIC_ACQUIRE) & Closed);
136bool OperationBarrier::isClosedAndDrained() {
137 auto guard = m_Waiters.acquire();
138 return __atomic_load_n(&m_State, __ATOMIC_ACQUIRE) == Closed;
MUST_USE_RESULT bool tryCloseIfIdle()
MUST_USE_RESULT bool tryAcquire(Lease &lease)
MUST_USE_RESULT bool tryEnter()
void EXPORTED_PUBLIC panic(const char *msg) NORETURN