mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 11:52:12 +01:00
[util] Introduce CallbackFence
This commit is contained in:
parent
5844315853
commit
893da94fb3
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "../rc/util_rc.h"
|
#include "../rc/util_rc.h"
|
||||||
|
|
||||||
@ -89,5 +91,70 @@ namespace dxvk::sync {
|
|||||||
dxvk::condition_variable m_cond;
|
dxvk::condition_variable m_cond;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Callback signal
|
||||||
|
*
|
||||||
|
* CPU-side fence with the ability to call a
|
||||||
|
* function when signaled to a given value.
|
||||||
|
*/
|
||||||
|
class CallbackFence final : public Signal {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CallbackFence()
|
||||||
|
: m_value(0ull) { }
|
||||||
|
|
||||||
|
explicit CallbackFence(uint64_t value)
|
||||||
|
: m_value(value) { }
|
||||||
|
|
||||||
|
uint64_t value() const {
|
||||||
|
return m_value.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal(uint64_t value) {
|
||||||
|
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||||
|
m_value.store(value, std::memory_order_release);
|
||||||
|
m_cond.notify_all();
|
||||||
|
|
||||||
|
for (auto i = m_callbacks.begin(); i != m_callbacks.end(); ) {
|
||||||
|
if (value >= i->first) {
|
||||||
|
i->second();
|
||||||
|
i = m_callbacks.erase(i);
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait(uint64_t value) {
|
||||||
|
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||||
|
m_cond.wait(lock, [this, value] {
|
||||||
|
return value <= m_value.load(std::memory_order_acquire);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
void setCallback(uint64_t value, Fn&& proc) {
|
||||||
|
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
if (value > this->value())
|
||||||
|
m_callbacks.emplace_back(std::piecewise_construct,
|
||||||
|
std::make_tuple(value),
|
||||||
|
std::make_tuple(proc));
|
||||||
|
else
|
||||||
|
proc();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::atomic<uint64_t> m_value;
|
||||||
|
dxvk::mutex m_mutex;
|
||||||
|
dxvk::condition_variable m_cond;
|
||||||
|
|
||||||
|
std::list<std::pair<uint64_t, std::function<void ()>>> m_callbacks;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user