diff --git a/src/util/sync/sync_signal.h b/src/util/sync/sync_signal.h new file mode 100644 index 00000000..4303d01c --- /dev/null +++ b/src/util/sync/sync_signal.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include + +namespace dxvk::sync { + + /** + * \brief Signal + * + * Acts as a simple CPU fence which can be signaled by one + * thread and waited upon by one more thread. Waiting on + * more than one thread is not supported. + */ + class Signal : public RcObject { + + public: + + Signal() + : m_signaled(false) { } + Signal(bool signaled) + : m_signaled(signaled) { } + ~Signal() { } + + Signal (const Signal&) = delete; + Signal& operator = (const Signal&) = delete; + + /** + * \brief Notifies signal + * Wakes any waiting thread. + */ + void notify() { + std::lock_guard lock(m_mutex); + m_signaled.store(true); + m_cond.notify_one(); + } + + /** + * \brief Waits for signal + * + * Blocks the calling thread until another + * thread wakes it up, then resets it to + * the non-signaled state. + */ + void wait() { + if (!m_signaled.exchange(false)) { + std::unique_lock lock(m_mutex); + m_cond.wait(lock, [this] { + return m_signaled.exchange(false); + }); + } + } + + private: + + std::atomic m_signaled; + std::mutex m_mutex; + std::condition_variable m_cond; + + }; + +}