#pragma once #include "Utilities/types.h" class thread_ctrl; namespace vm { struct waiter_base { u32 addr; u32 mask; thread_ctrl* thread{}; void initialize(u32 addr, u32 size); bool try_notify(); protected: virtual bool test() = 0; }; // Wait until pred() returns true, addr must be aligned to size which must be a power of 2. // It's possible for pred() to be called from any thread once the waiter is registered. template auto wait_op(u32 addr, u32 size, F&& pred) -> decltype(static_cast(pred())) { if (LIKELY(pred())) return; struct waiter : waiter_base { std::conditional_t, F&&> func; waiter(F&& func) : func(std::forward(func)) { } bool test() override { return func(); } }; waiter(std::forward(pred)).initialize(addr, size); } // Notify waiters on specific addr, addr must be aligned to size which must be a power of 2 void notify_at(u32 addr, u32 size); }