Skip to content

Commit 89e4340

Browse files
committed
Hide debug stages, fix callback creation and calling
1 parent 0fc7954 commit 89e4340

File tree

1 file changed

+82
-65
lines changed

1 file changed

+82
-65
lines changed

include/nbl/system/demote_promote_writer_readers_lock.h

Lines changed: 82 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,34 @@ namespace nbl::system
1313
// Ugly workaround, structs with constevals can't be nested
1414
namespace impl
1515
{
16-
template<typename U>
17-
struct DPWRLStateLock
18-
{
19-
using type = std::atomic<U>;
20-
};
2116

22-
// will fail if `atomic_unsiged_lock_free` doesn't exist or its value type has wrong size
23-
template<typename U> requires (sizeof(std::atomic_unsigned_lock_free::value_type) >= sizeof(U))
24-
struct DPWRLStateLock<U>
25-
{
26-
using type = std::atomic_unsigned_lock_free;
27-
};
17+
template<typename U>
18+
struct DPWRLStateLock
19+
{
20+
using type = std::atomic<U>;
21+
};
2822

29-
struct DPWRLStateSemantics
30-
{
31-
using state_lock_value_t = typename DPWRLStateLock<uint32_t>::type::value_type;
32-
uint32_t currentReaders : 10 = 0;
33-
uint32_t pendingWriters : 10 = 0;
34-
uint32_t pendingUpgrades : 10 = 0;
35-
uint32_t writing : 1 = 0;
36-
uint32_t stateLocked : 1 = 0;
37-
38-
consteval inline operator state_lock_value_t() const
39-
{
40-
return static_cast<state_lock_value_t>((currentReaders << 22) | (pendingWriters << 12) | (pendingUpgrades << 2) | (writing << 1) | stateLocked);
41-
}
42-
};
43-
} //namespace impl
23+
// will fail if `atomic_unsiged_lock_free` doesn't exist or its value type has wrong size
24+
template<typename U> requires (sizeof(std::atomic_unsigned_lock_free::value_type) >= sizeof(U))
25+
struct DPWRLStateLock<U>
26+
{
27+
using type = std::atomic_unsigned_lock_free;
28+
};
29+
30+
struct DPWRLStateSemantics
31+
{
32+
using state_lock_value_t = typename DPWRLStateLock<uint32_t>::type::value_type;
33+
uint32_t currentReaders : 10 = 0;
34+
uint32_t pendingWriters : 10 = 0;
35+
uint32_t pendingUpgrades : 10 = 0;
36+
uint32_t writing : 1 = 0;
37+
uint32_t stateLocked : 1 = 0;
38+
39+
consteval inline operator state_lock_value_t() const
40+
{
41+
return static_cast<state_lock_value_t>((currentReaders << 22) | (pendingWriters << 12) | (pendingUpgrades << 2) | (writing << 1) | stateLocked);
42+
}
43+
};
4444

4545
enum DPWR_LOCK_DEBUG_STAGE
4646
{
@@ -51,19 +51,21 @@ enum DPWR_LOCK_DEBUG_STAGE
5151
PREEMPTED
5252
};
5353

54-
namespace impl
54+
struct DPWRLVoidDebugCallback
5555
{
56-
template<typename T>
57-
concept DPWRLDebugCallback = requires(T t, DPWR_LOCK_DEBUG_STAGE stage) {
58-
{ t(stage) } -> std::same_as<void>;
59-
};
56+
};
57+
58+
template<typename T>
59+
/**
60+
* @brief A valid debug callback overrides `void operator()(DPWR_LOCK_DEBUG_STAGE stage)`
61+
*/
62+
concept DPWRLDebugCallback = requires(T t, DPWR_LOCK_DEBUG_STAGE stage) {
63+
{ t(stage) } -> std::same_as<void>;
64+
} || std::is_same_v<T, DPWRLVoidDebugCallback>;
65+
66+
} //namespace impl
67+
6068

61-
class DPWRLVoidDebugCallback
62-
{
63-
public:
64-
void operator()(DPWR_LOCK_DEBUG_STAGE) {};
65-
};
66-
}
6769

6870
template <impl::DPWRLDebugCallback DebugCallback = impl::DPWRLVoidDebugCallback>
6971
/**
@@ -265,7 +267,7 @@ class demote_promote_writer_readers_lock_debug
265267

266268
private:
267269

268-
constexpr static inline bool usingDebugCallback = std::is_same_v<DebugCallback, impl::DPWRLVoidDebugCallback>;
270+
constexpr static inline bool usingDebugCallback = ! std::is_same_v<DebugCallback, impl::DPWRLVoidDebugCallback>;
269271

270272
struct DefaultPreemptionCheck
271273
{
@@ -286,6 +288,7 @@ class demote_promote_writer_readers_lock_debug
286288
Preempted& preempted = defaultPreempted
287289
)
288290
{
291+
DebugCallback callback = {};
289292
for (uint32_t spinCount = 0; true; spinCount++)
290293
{
291294
const state_lock_value_t oldState = state.fetch_or(flipLock);
@@ -301,14 +304,14 @@ class demote_promote_writer_readers_lock_debug
301304
const state_lock_value_t newState = wasPreempted ? preempted(oldState) : success(oldState);
302305
// new state must unlock the state lock
303306
assert(!(newState & flipLock));
304-
if (usingDebugCallback) DebugCallback(DPWR_LOCK_DEBUG_STAGE::BEFORE_STATE_UPDATE);
307+
if constexpr (usingDebugCallback) callback(impl::DPWR_LOCK_DEBUG_STAGE::BEFORE_STATE_UPDATE);
305308
state.store(newState);
306-
if (usingDebugCallback) DebugCallback(DPWR_LOCK_DEBUG_STAGE::AFTER_STATE_UPDATE);
309+
if constexpr (usingDebugCallback) callback(impl::DPWR_LOCK_DEBUG_STAGE::AFTER_STATE_UPDATE);
307310
if (wasPreempted)
308311
{
309-
if (usingDebugCallback)
312+
if constexpr (usingDebugCallback)
310313
{
311-
DebugCallback(DPWR_LOCK_DEBUG_STAGE::PREEMPTED);
314+
callback(impl::DPWR_LOCK_DEBUG_STAGE::PREEMPTED);
312315
}
313316
else
314317
{
@@ -333,34 +336,48 @@ class demote_promote_writer_readers_lock_debug
333336

334337
namespace impl
335338
{
336-
template <impl::DPWRLDebugCallback DebugCallback = impl::DPWRLVoidDebugCallback>
337-
class dpwr_lock_guard_base
339+
340+
template <impl::DPWRLDebugCallback DebugCallback = impl::DPWRLVoidDebugCallback>
341+
class dpwr_lock_guard_base
342+
{
343+
dpwr_lock_guard_base() : m_lock(nullptr) {}
344+
345+
public:
346+
using dpwr_lock_t = demote_promote_writer_readers_lock_debug<DebugCallback>;
347+
dpwr_lock_guard_base& operator=(const dpwr_lock_guard_base&) = delete;
348+
dpwr_lock_guard_base(const dpwr_lock_guard_base&) = delete;
349+
350+
dpwr_lock_guard_base& operator=(dpwr_lock_guard_base&& rhs) noexcept
338351
{
339-
dpwr_lock_guard_base() : m_lock(nullptr) {}
352+
m_lock = rhs.m_lock;
353+
rhs.m_lock = nullptr;
354+
return *this;
355+
}
356+
dpwr_lock_guard_base(dpwr_lock_guard_base&& rhs) noexcept : dpwr_lock_guard_base()
357+
{
358+
operator=(std::move(rhs));
359+
}
340360

341-
public:
342-
using dpwr_lock_t = typename demote_promote_writer_readers_lock_debug<DebugCallback>;
343-
dpwr_lock_guard_base& operator=(const dpwr_lock_guard_base&) = delete;
344-
dpwr_lock_guard_base(const dpwr_lock_guard_base&) = delete;
361+
/**
362+
* @brief Checks whether this guard is currently locking the lock `lk`
363+
*/
364+
bool hasLocked(dpwr_lock_t& lk) const
365+
{
366+
return m_lock == &lk;
367+
}
345368

346-
dpwr_lock_guard_base& operator=(dpwr_lock_guard_base&& rhs) noexcept
347-
{
348-
m_lock = rhs.m_lock;
349-
rhs.m_lock = nullptr;
350-
return *this;
351-
}
352-
dpwr_lock_guard_base(dpwr_lock_guard_base&& rhs) noexcept : dpwr_lock_guard_base()
353-
{
354-
operator=(std::move(rhs));
355-
}
369+
protected:
370+
dpwr_lock_guard_base(dpwr_lock_t& lk) noexcept : m_lock(&lk) {}
356371

357-
protected:
358-
dpwr_lock_guard_base(dpwr_lock_t& lk) noexcept : m_lock(&lk) {}
372+
dpwr_lock_t* m_lock;
373+
};
359374

360-
dpwr_lock_t* m_lock;
361-
};
362375
} // namespace impl
363376

377+
// Forward declaration required by GCC
378+
template <impl::DPWRLDebugCallback DebugCallback>
379+
class dpwr_write_lock_guard_debug;
380+
364381
template <impl::DPWRLDebugCallback DebugCallback = impl::DPWRLVoidDebugCallback>
365382
class dpwr_read_lock_guard_debug : public impl::dpwr_lock_guard_base<DebugCallback>
366383
{
@@ -404,13 +421,13 @@ class dpwr_write_lock_guard_debug : public impl::dpwr_lock_guard_base<DebugCallb
404421
};
405422

406423
template <impl::DPWRLDebugCallback DebugCallback>
407-
inline dpwr_read_lock_guard_debug<DebugCallback>::dpwr_read_lock_guard_debug(dpwr_write_lock_guard_debug<DebugCallback>&& wl) : impl::dpwr_lock_guard_base(std::move(wl))
424+
inline dpwr_read_lock_guard_debug<DebugCallback>::dpwr_read_lock_guard_debug(dpwr_write_lock_guard_debug<DebugCallback>&& wl) : impl::dpwr_lock_guard_base<DebugCallback>(std::move(wl))
408425
{
409426
this->m_lock->downgrade();
410427
}
411428

412429
template <impl::DPWRLDebugCallback DebugCallback>
413-
inline dpwr_write_lock_guard_debug<DebugCallback>::dpwr_write_lock_guard_debug(dpwr_read_lock_guard_debug<DebugCallback>&& rl) : impl::dpwr_lock_guard_base(std::move(rl))
430+
inline dpwr_write_lock_guard_debug<DebugCallback>::dpwr_write_lock_guard_debug(dpwr_read_lock_guard_debug<DebugCallback>&& rl) : impl::dpwr_lock_guard_base<DebugCallback>(std::move(rl))
414431
{
415432
this->m_lock->upgrade();
416433
}

0 commit comments

Comments
 (0)