mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 01:24:11 +01:00
[util] Add generic recursive spinlock
This commit is contained in:
parent
55e3240479
commit
da506f5932
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxgi/dxgi_include.h"
|
||||
|
||||
#include "../util/sync/sync_spinlock.h"
|
||||
#include "../util/sync/sync_recursive.h"
|
||||
|
||||
#include <d3d10_1.h>
|
||||
#include <d3d11_1.h>
|
||||
|
@ -2,38 +2,6 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
void D3D10DeviceMutex::lock() {
|
||||
while (!try_lock())
|
||||
dxvk::this_thread::yield();
|
||||
}
|
||||
|
||||
|
||||
void D3D10DeviceMutex::unlock() {
|
||||
if (likely(m_counter == 0))
|
||||
m_owner.store(0, std::memory_order_release);
|
||||
else
|
||||
m_counter -= 1;
|
||||
}
|
||||
|
||||
|
||||
bool D3D10DeviceMutex::try_lock() {
|
||||
uint32_t threadId = GetCurrentThreadId();
|
||||
uint32_t expected = 0;
|
||||
|
||||
bool status = m_owner.compare_exchange_weak(
|
||||
expected, threadId, std::memory_order_acquire);
|
||||
|
||||
if (status)
|
||||
return true;
|
||||
|
||||
if (expected != threadId)
|
||||
return false;
|
||||
|
||||
m_counter += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
D3D10Multithread::D3D10Multithread(
|
||||
IUnknown* pParent,
|
||||
BOOL Protected)
|
||||
|
@ -4,30 +4,6 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Device mutex
|
||||
*
|
||||
* Effectively implements a recursive spinlock
|
||||
* which is used to lock the D3D10 device.
|
||||
*/
|
||||
class D3D10DeviceMutex {
|
||||
|
||||
public:
|
||||
|
||||
void lock();
|
||||
|
||||
void unlock();
|
||||
|
||||
bool try_lock();
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<uint32_t> m_owner = { 0u };
|
||||
uint32_t m_counter = { 0u };
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Device lock
|
||||
*
|
||||
@ -43,7 +19,7 @@ namespace dxvk {
|
||||
D3D10DeviceLock()
|
||||
: m_mutex(nullptr) { }
|
||||
|
||||
D3D10DeviceLock(D3D10DeviceMutex& mutex)
|
||||
D3D10DeviceLock(sync::RecursiveSpinlock& mutex)
|
||||
: m_mutex(&mutex) {
|
||||
mutex.lock();
|
||||
}
|
||||
@ -69,7 +45,7 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
D3D10DeviceMutex* m_mutex;
|
||||
sync::RecursiveSpinlock* m_mutex;
|
||||
|
||||
};
|
||||
|
||||
@ -120,7 +96,7 @@ namespace dxvk {
|
||||
IUnknown* m_parent;
|
||||
BOOL m_protected;
|
||||
|
||||
D3D10DeviceMutex m_mutex;
|
||||
sync::RecursiveSpinlock m_mutex;
|
||||
|
||||
};
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "../util/rc/util_rc.h"
|
||||
#include "../util/rc/util_rc_ptr.h"
|
||||
|
||||
#include "../util/sync/sync_recursive.h"
|
||||
|
||||
#include "../util/util_env.h"
|
||||
#include "../util/util_enum.h"
|
||||
#include "../util/util_error.h"
|
||||
|
@ -2,38 +2,6 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
void D3D9DeviceMutex::lock() {
|
||||
while (!try_lock())
|
||||
dxvk::this_thread::yield();
|
||||
}
|
||||
|
||||
|
||||
void D3D9DeviceMutex::unlock() {
|
||||
if (likely(m_counter == 0))
|
||||
m_owner.store(0, std::memory_order_release);
|
||||
else
|
||||
m_counter -= 1;
|
||||
}
|
||||
|
||||
|
||||
bool D3D9DeviceMutex::try_lock() {
|
||||
uint32_t threadId = GetCurrentThreadId();
|
||||
uint32_t expected = 0;
|
||||
|
||||
bool status = m_owner.compare_exchange_weak(
|
||||
expected, threadId, std::memory_order_acquire);
|
||||
|
||||
if (status)
|
||||
return true;
|
||||
|
||||
if (expected != threadId)
|
||||
return false;
|
||||
|
||||
m_counter += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
D3D9Multithread::D3D9Multithread(
|
||||
BOOL Protected)
|
||||
: m_protected( Protected ) { }
|
||||
|
@ -4,30 +4,6 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Device mutex
|
||||
*
|
||||
* Effectively implements a recursive spinlock
|
||||
* which is used to lock the D3D9 device.
|
||||
*/
|
||||
class D3D9DeviceMutex {
|
||||
|
||||
public:
|
||||
|
||||
void lock();
|
||||
|
||||
void unlock();
|
||||
|
||||
bool try_lock();
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<uint32_t> m_owner = { 0u };
|
||||
uint32_t m_counter = { 0u };
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Device lock
|
||||
*
|
||||
@ -43,7 +19,7 @@ namespace dxvk {
|
||||
D3D9DeviceLock()
|
||||
: m_mutex(nullptr) { }
|
||||
|
||||
D3D9DeviceLock(D3D9DeviceMutex& mutex)
|
||||
D3D9DeviceLock(sync::RecursiveSpinlock& mutex)
|
||||
: m_mutex(&mutex) {
|
||||
mutex.lock();
|
||||
}
|
||||
@ -69,7 +45,7 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
D3D9DeviceMutex* m_mutex;
|
||||
sync::RecursiveSpinlock* m_mutex;
|
||||
|
||||
};
|
||||
|
||||
@ -94,7 +70,7 @@ namespace dxvk {
|
||||
|
||||
BOOL m_protected;
|
||||
|
||||
D3D9DeviceMutex m_mutex;
|
||||
sync::RecursiveSpinlock m_mutex;
|
||||
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,8 @@ util_src = files([
|
||||
|
||||
'sha1/sha1.c',
|
||||
'sha1/sha1_util.cpp',
|
||||
|
||||
'sync/sync_recursive.cpp',
|
||||
])
|
||||
|
||||
util_lib = static_library('util', util_src,
|
||||
|
36
src/util/sync/sync_recursive.cpp
Normal file
36
src/util/sync/sync_recursive.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "sync_recursive.h"
|
||||
#include "sync_spinlock.h"
|
||||
|
||||
namespace dxvk::sync {
|
||||
|
||||
void RecursiveSpinlock::lock() {
|
||||
spin(2000, [this] { return try_lock(); });
|
||||
}
|
||||
|
||||
|
||||
void RecursiveSpinlock::unlock() {
|
||||
if (likely(m_counter == 0))
|
||||
m_owner.store(0, std::memory_order_release);
|
||||
else
|
||||
m_counter -= 1;
|
||||
}
|
||||
|
||||
|
||||
bool RecursiveSpinlock::try_lock() {
|
||||
uint32_t threadId = GetCurrentThreadId();
|
||||
uint32_t expected = 0;
|
||||
|
||||
bool status = m_owner.compare_exchange_weak(
|
||||
expected, threadId, std::memory_order_acquire);
|
||||
|
||||
if (status)
|
||||
return true;
|
||||
|
||||
if (expected != threadId)
|
||||
return false;
|
||||
|
||||
m_counter += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
32
src/util/sync/sync_recursive.h
Normal file
32
src/util/sync/sync_recursive.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "../com/com_include.h"
|
||||
|
||||
namespace dxvk::sync {
|
||||
|
||||
/**
|
||||
* \brief Recursive spinlock
|
||||
*
|
||||
* Implements a spinlock that can be acquired
|
||||
* by the same thread multiple times.
|
||||
*/
|
||||
class RecursiveSpinlock {
|
||||
|
||||
public:
|
||||
|
||||
void lock();
|
||||
|
||||
void unlock();
|
||||
|
||||
bool try_lock();
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<uint32_t> m_owner = { 0u };
|
||||
uint32_t m_counter = { 0u };
|
||||
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user