Itasca C++ Interface
Toggle main menu visibility
Loading...
Searching...
No Matches
spinlock.h
1
#pragma once
2
3
#include "
basedef.h
"
4
#include <cassert>
5
#include <atomic>
6
7
// Spinlock implementation that matches std::mutex interface.
8
// So you can use std::lock_guard, etc.
9
//
10
// I'm aware of all the discussions of why SpinLocks are bad.
11
// The fact remains that timing tests consistently show
12
// F3 slows down considerably if you replace this with std::mutex.
13
// That said - BE CAREFUL because in medium-to-high contention scenarios this does not perform well.
14
15
// If you define this, then the SpinLock is implemented in terms of a std::mutex
16
// shoudl be equivalent to std::mutex
17
//#define USEMUTEX
18
19
20
#ifdef USEMUTEX
21
#include <mutex>
22
class
BASE_EXPORT
SpinLock
:
public
std::mutex {
23
public
:
24
using
mutex::mutex;
25
};
26
#else
27
class
SpinLock
{
28
public
:
30
SpinLock
() {
new
(buffer) std::atomic<bool>(
false
); }
31
SpinLock
(
const
SpinLock
&) {
new
(buffer) std::atomic<bool>(
false
); }
32
SpinLock
(
SpinLock
&&) {
new
(buffer) std::atomic<bool>(
false
); }
33
const
SpinLock
&operator=(
const
SpinLock
&) {
return
*
this
; }
34
const
SpinLock
&operator=(
SpinLock
&&) {
return
*
this
; }
35
37
~SpinLock
() { assert(!get().load()); get().~atomic<
bool
>(); }
38
40
void
lock
() {
while
(get().exchange(
true
)) { } };
41
43
void
unlock
() { get().store(
false
); }
// Added for standard conformity
44
45
bool
try_lock() {
return
!get().exchange(
true
); }
// Added for standard conformity
46
47
private
:
48
std::atomic<bool> &get() {
return
*
reinterpret_cast<
std::atomic<bool> *
>
(buffer); }
49
50
char
buffer[
sizeof
(std::atomic<bool>)];
51
};
52
#endif
53
54
// Standard library looking ReverseLock for people using lock_guard, unique_lock, etc.
55
template
<
typename
T>
56
class
ReverseLock {
57
public
:
58
ReverseLock(T &t) : lock_(t) { t.unlock(); }
59
~ReverseLock() { lock_.lock(); }
60
private
:
61
T &lock_;
62
};
63
64
// Standard library looking ConditionalLock
65
template
<
typename
T>
66
class
ConditionalLock {
67
public
:
68
ConditionalLock(T &t,
bool
use) : lock_(&t), use_(use) {
if
(use_) t.lock(); }
69
ConditionalLock(T *t,
bool
use) : lock_(t), use_(use) {
if
(use_&&t) t->lock(); }
70
~ConditionalLock() {
if
(use_&&lock_) lock_->unlock(); }
71
private
:
72
T *lock_;
73
bool
use_;
74
};
75
76
// Standard library looking ReverseLock for people using lock_guard, unique_lock, etc.
77
template
<
typename
T>
78
class
ReverseSharedLock {
79
public
:
80
ReverseSharedLock(T &t) : lock_(t) { t.unlock_shared(); }
81
~ReverseSharedLock() { lock_.lock_shared(); }
82
private
:
83
T &lock_;
84
};
85
86
// Update Maximum
87
template
<
typename
T>
88
void
atomicMax(std::atomic<T> &maxValue, T
const
&value)
noexcept
{
89
T pvalue = maxValue.load();
90
while
(pvalue < value and not maxValue.compare_exchange_weak(pvalue, value)) { }
91
}
92
93
// Update Minimum
94
template
<
typename
T>
95
void
atomicMin(std::atomic<T> &minValue, T
const
&value)
noexcept
{
96
T pvalue = minValue.load();
97
while
(pvalue > value and not minValue.compare_exchange_weak(pvalue, value)) { }
98
}
99
100
// Wrapper around std::atomic to make it copy-constructable and assignable
101
template
<
typename
T>
102
class
Atomic :
public
std::atomic<T> {
103
public
:
104
using
std::atomic<T>::atomic;
105
106
Atomic(
const
std::atomic<T> &a) : std::atomic<T>(a.load()) { }
107
Atomic(
const
Atomic &a) : std::atomic<T>(a.load()) { }
108
Atomic &operator=(
const
Atomic &a) { std::atomic<T>::store(a.load());
return
*
this
; }
109
};
110
111
//namespace std {
112
// inline void swap(std::atomic<int> &a1,std::atomic<int> &a2) {
113
// int i = a2.load();
114
// a2.store(a1.load());
115
// a1.store(i);
116
// }
117
//}
118
119
// EoF
basedef.h
Base type definitions for the engine.
SpinLock
Definition
spinlock.h:27
SpinLock::unlock
void unlock()
Release the lock.
Definition
spinlock.h:43
SpinLock::lock
void lock()
Acquire a lock using the test-and-set paradigm.
Definition
spinlock.h:40
SpinLock::SpinLock
SpinLock()
By default the QAtomicInt is 0 on creation.
Definition
spinlock.h:30
SpinLock::~SpinLock
~SpinLock()
A SpinLock object can only be destroyed when it has been released.
Definition
spinlock.h:37
BASE_EXPORT
#define BASE_EXPORT
Definition
basedef.h:25
common
base
src
spinlock.h
Generated by
1.18.0