mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-05 01:24:14 +01:00
[dxvk] Use separate mutex for completed chunk counter
Fixes a possible deadlock.
This commit is contained in:
parent
f689ddd838
commit
1e11db98d0
@ -131,15 +131,20 @@ namespace dxvk {
|
|||||||
// Avoid locking if we know the sync is a no-op, may
|
// Avoid locking if we know the sync is a no-op, may
|
||||||
// reduce overhead if this is being called frequently
|
// reduce overhead if this is being called frequently
|
||||||
if (seq > m_chunksExecuted.load(std::memory_order_acquire)) {
|
if (seq > m_chunksExecuted.load(std::memory_order_acquire)) {
|
||||||
std::unique_lock<dxvk::mutex> lock(m_mutex);
|
// We don't need to lock the queue here, if synchronization
|
||||||
|
// happens while another thread is submitting then there is
|
||||||
|
// an inherent race anyway
|
||||||
if (seq == SynchronizeAll)
|
if (seq == SynchronizeAll)
|
||||||
seq = m_chunksDispatched.load();
|
seq = m_chunksDispatched.load();
|
||||||
|
|
||||||
auto t0 = dxvk::high_resolution_clock::now();
|
auto t0 = dxvk::high_resolution_clock::now();
|
||||||
|
|
||||||
|
{ std::unique_lock<dxvk::mutex> lock(m_counterMutex);
|
||||||
m_condOnSync.wait(lock, [this, seq] {
|
m_condOnSync.wait(lock, [this, seq] {
|
||||||
return m_chunksExecuted.load() >= seq;
|
return m_chunksExecuted.load() >= seq;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
auto t1 = dxvk::high_resolution_clock::now();
|
auto t1 = dxvk::high_resolution_clock::now();
|
||||||
auto ticks = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0);
|
auto ticks = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0);
|
||||||
|
|
||||||
@ -173,8 +178,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
chunk->executeAll(m_context.ptr());
|
chunk->executeAll(m_context.ptr());
|
||||||
|
|
||||||
|
// Use a separate mutex for the chunk counter, this
|
||||||
|
// will only ever be contested if synchronization is
|
||||||
|
// actually necessary.
|
||||||
|
{ std::unique_lock<dxvk::mutex> lock(m_counterMutex);
|
||||||
m_chunksExecuted += 1;
|
m_chunksExecuted += 1;
|
||||||
m_condOnSync.notify_one();
|
m_condOnSync.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
// Explicitly free chunk here to release
|
// Explicitly free chunk here to release
|
||||||
// references to any resources held by it
|
// references to any resources held by it
|
||||||
|
@ -425,6 +425,7 @@ namespace dxvk {
|
|||||||
Rc<DxvkDevice> m_device;
|
Rc<DxvkDevice> m_device;
|
||||||
Rc<DxvkContext> m_context;
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
|
dxvk::mutex m_counterMutex;
|
||||||
std::atomic<uint64_t> m_chunksDispatched = { 0ull };
|
std::atomic<uint64_t> m_chunksDispatched = { 0ull };
|
||||||
std::atomic<uint64_t> m_chunksExecuted = { 0ull };
|
std::atomic<uint64_t> m_chunksExecuted = { 0ull };
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user