diff --git a/src/dxvk/dxvk_include.h b/src/dxvk/dxvk_include.h index e10a017b..11690202 100644 --- a/src/dxvk/dxvk_include.h +++ b/src/dxvk/dxvk_include.h @@ -12,6 +12,8 @@ #include "../util/rc/util_rc.h" #include "../util/rc/util_rc_ptr.h" +#include "../util/sync/sync_spinlock.h" + #include "./vulkan/dxvk_vulkan_extensions.h" #include "./vulkan/dxvk_vulkan_loader.h" #include "./vulkan/dxvk_vulkan_names.h" diff --git a/src/util/sync/sync_spinlock.h b/src/util/sync/sync_spinlock.h new file mode 100644 index 00000000..b9d55106 --- /dev/null +++ b/src/util/sync/sync_spinlock.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +namespace dxvk::sync { + + /** + * \brief Spin lock + * + * A low-overhead spin lock which can be used to + * protect data structures for a short duration + * in case the structure is not likely contested. + */ + class Spinlock { + + public: + + Spinlock() { } + ~Spinlock() { } + + Spinlock (const Spinlock&) = delete; + Spinlock& operator = (const Spinlock&) = delete; + + void lock() { + while (!this->try_lock()) + std::this_thread::yield(); + } + + void unlock() { + m_lock.store(0, std::memory_order_release); + } + + bool try_lock() { + uint32_t expected = 0; + return m_lock.compare_exchange_strong(expected, 1, + std::memory_order_acquire, + std::memory_order_relaxed); + } + + private: + + std::atomic m_lock = { 0 }; + + }; + +} \ No newline at end of file