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
BASE_EXPORT
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
35
~SpinLock
() { assert(!get().load()); get().~atomic<
bool
>(); }
36
38
inline
void
lock
() {
while
(get().exchange(
true
)) { } };
39
41
inline
void
unlock
() { get().store(
false
); }
// Added for standard conformity
42
43
inline
bool
try_lock() {
return
!get().exchange(
true
); }
// Added for standard conformity
44
45
private
:
46
void
operator=(
const
SpinLock &) =
delete
;
47
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
87
88
// EoF
basedef.h
Base type definitions for the engine.
SpinLock
Definition
spinlock.h:27
SpinLock::unlock
void unlock()
Release the lock.
Definition
spinlock.h:41
SpinLock::lock
void lock()
Acquire a lock using the test-and-set paradigm.
Definition
spinlock.h:38
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:35
BASE_EXPORT
#define BASE_EXPORT
Definition
basedef.h:24
common
base
src
spinlock.h
Generated by
1.18.0