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
11namespace 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 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