X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Fwaiter.hpp;h=cdd0913cc13e7f1957d4b493c4c0d9e3bb3265fc;hb=HEAD;hp=d88fe0f66af96a1029afe019e925fb6d2cb7d809;hpb=28f23191dcbf047429d51950a337a57d7a3f866a;p=lttng-tools.git diff --git a/src/common/waiter.hpp b/src/common/waiter.hpp index d88fe0f66..cdd0913cc 100644 --- a/src/common/waiter.hpp +++ b/src/common/waiter.hpp @@ -14,24 +14,85 @@ #include "macros.hpp" -#include +#include #include #include -struct lttng_waiter { - struct cds_wfs_node wait_queue_node; - int32_t state; +namespace lttng { +namespace synchro { +class waiter; +class wait_queue; + +class waker final { + friend waiter; + +public: + waker(const waker&) noexcept = default; + waker(waker&&) noexcept = default; + waker& operator=(const waker& other) noexcept = default; + waker& operator=(waker&& other) noexcept = default; + + void wake(); + + ~waker() = default; + +private: + explicit waker(int32_t& state) noexcept : _state{ state } + { + } + + std::reference_wrapper _state; }; -void lttng_waiter_init(struct lttng_waiter *waiter); +class waiter final { + friend wait_queue; -void lttng_waiter_wait(struct lttng_waiter *waiter); +public: + waiter(); -/* - * lttng_waiter_wake_up must only be called by a single waker. - * It is invalid for multiple "wake" operations to be invoked - * on a single waiter without re-initializing it before. - */ -void lttng_waiter_wake_up(struct lttng_waiter *waiter); + /* Deactivate copy and assignment. */ + waiter(const waiter&) = delete; + waiter(waiter&&) = delete; + waiter& operator=(const waiter&) = delete; + waiter& operator=(waiter&&) = delete; + ~waiter() = default; + + void arm() noexcept; + void wait(); + + waker get_waker(); + +private: + cds_wfs_node _wait_queue_node; + int32_t _state; +}; + +class wait_queue final { +public: + wait_queue(); + + /* Deactivate copy and assignment. */ + wait_queue(const wait_queue&) = delete; + wait_queue(wait_queue&&) = delete; + wait_queue& operator=(const wait_queue&) = delete; + wait_queue& operator=(wait_queue&&) = delete; + ~wait_queue() = default; + + /* + * Atomically add a waiter to a wait queue. + * A full memory barrier is issued before being added to the wait queue. + */ + void add(waiter& waiter) noexcept; + /* + * Wake every waiter present in the wait queue and remove them from + * the queue. + */ + void wake_all(); + +private: + cds_wfs_stack _stack; +}; +} /* namespace synchro */ +} /* namespace lttng */ #endif /* LTTNG_WAITER_H */