Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/common/sys/mutex.h
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "platform.h"
7
#include "intrinsics.h"
8
#include "atomic.h"
9
10
#define CPU_CACHELINE_SIZE 64
11
namespace embree
12
{
13
/*! system mutex */
14
class MutexSys {
15
friend struct ConditionImplementation;
16
public:
17
MutexSys();
18
~MutexSys();
19
20
private:
21
MutexSys (const MutexSys& other) DELETED; // do not implement
22
MutexSys& operator= (const MutexSys& other) DELETED; // do not implement
23
24
public:
25
void lock();
26
bool try_lock();
27
void unlock();
28
29
protected:
30
void* mutex;
31
};
32
33
/*! spinning mutex */
34
class SpinLock
35
{
36
public:
37
38
SpinLock ()
39
: flag(false) {}
40
41
__forceinline bool isLocked() {
42
return flag.load();
43
}
44
45
__forceinline void lock()
46
{
47
while (true)
48
{
49
while (flag.load())
50
{
51
_mm_pause();
52
_mm_pause();
53
}
54
55
bool expected = false;
56
if (flag.compare_exchange_strong(expected,true,std::memory_order_acquire))
57
break;
58
}
59
}
60
61
__forceinline bool try_lock()
62
{
63
bool expected = false;
64
if (flag.load() != expected) {
65
return false;
66
}
67
return flag.compare_exchange_strong(expected,true,std::memory_order_acquire);
68
}
69
70
__forceinline void unlock() {
71
flag.store(false,std::memory_order_release);
72
}
73
74
__forceinline void wait_until_unlocked()
75
{
76
while(flag.load())
77
{
78
_mm_pause();
79
_mm_pause();
80
}
81
}
82
83
public:
84
atomic<bool> flag;
85
};
86
87
class PaddedSpinLock : public SpinLock
88
{
89
private:
90
MAYBE_UNUSED char padding[CPU_CACHELINE_SIZE - sizeof(SpinLock)];
91
};
92
/*! safe mutex lock and unlock helper */
93
template<typename Mutex> class Lock {
94
public:
95
Lock (Mutex& mutex) : mutex(mutex), locked(true) { mutex.lock(); }
96
Lock (Mutex& mutex, bool locked) : mutex(mutex), locked(locked) {}
97
~Lock() { if (locked) mutex.unlock(); }
98
__forceinline void lock() { assert(!locked); locked = true; mutex.lock(); }
99
__forceinline bool isLocked() const { return locked; }
100
protected:
101
Mutex& mutex;
102
bool locked;
103
};
104
}
105
106