mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[util] Add generic spin function
This commit is contained in:
parent
3835230ce5
commit
55e3240479
@ -1,10 +1,35 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include "../thread.h"
|
#include "../thread.h"
|
||||||
|
|
||||||
|
#include "../util_bit.h"
|
||||||
|
#include "../util_likely.h"
|
||||||
|
|
||||||
namespace dxvk::sync {
|
namespace dxvk::sync {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generic spin function
|
||||||
|
*
|
||||||
|
* Blocks calling thread until a condition becomes
|
||||||
|
* \c true, calling \c yield every few iterations.
|
||||||
|
* \param [in] spinCount Number of probes between each yield
|
||||||
|
* \param [in] fn Condition to test
|
||||||
|
*/
|
||||||
|
template<typename Fn>
|
||||||
|
void spin(uint32_t spinCount, const Fn& fn) {
|
||||||
|
while (unlikely(!fn())) {
|
||||||
|
for (uint32_t i = 1; i < spinCount; i++) {
|
||||||
|
_mm_pause();
|
||||||
|
if (fn())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dxvk::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Spin lock
|
* \brief Spin lock
|
||||||
*
|
*
|
||||||
@ -13,7 +38,7 @@ namespace dxvk::sync {
|
|||||||
* in case the structure is not likely contested.
|
* in case the structure is not likely contested.
|
||||||
*/
|
*/
|
||||||
class Spinlock {
|
class Spinlock {
|
||||||
constexpr static uint32_t SpinCount = 200;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Spinlock() { }
|
Spinlock() { }
|
||||||
@ -23,14 +48,7 @@ namespace dxvk::sync {
|
|||||||
Spinlock& operator = (const Spinlock&) = delete;
|
Spinlock& operator = (const Spinlock&) = delete;
|
||||||
|
|
||||||
void lock() {
|
void lock() {
|
||||||
while (unlikely(!try_lock())) {
|
spin(200, [this] { return try_lock(); });
|
||||||
for (uint32_t i = 1; i < SpinCount; i++) {
|
|
||||||
if (try_lock())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dxvk::this_thread::yield();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlock() {
|
void unlock() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user