2018-04-03 11:56:02 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <atomic>
|
2018-07-16 18:45:54 +02:00
|
|
|
#include "../thread.h"
|
2018-04-03 11:56:02 +02:00
|
|
|
|
|
|
|
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())
|
2018-07-16 18:45:54 +02:00
|
|
|
dxvk::this_thread::yield();
|
2018-04-03 11:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void unlock() {
|
|
|
|
m_lock.store(0, std::memory_order_release);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool try_lock() {
|
2019-05-07 13:38:02 +02:00
|
|
|
return !m_lock.load()
|
|
|
|
&& !m_lock.exchange(1, std::memory_order_acquire);
|
2018-04-03 11:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
std::atomic<uint32_t> m_lock = { 0 };
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2018-07-16 18:45:54 +02:00
|
|
|
}
|