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 namespace embree 11 { 12 /*! system mutex */ 13 class MutexSys { 14 friend struct ConditionImplementation; 15 public: 16 MutexSys(); 17 ~MutexSys(); 18 19 private: 20 MutexSys (const MutexSys& other) DELETED; // do not implement 21 MutexSys& operator= (const MutexSys& other) DELETED; // do not implement 22 23 public: 24 void lock(); 25 bool try_lock(); 26 void unlock(); 27 28 protected: 29 void* mutex; 30 }; 31 32 /*! spinning mutex */ 33 class SpinLock 34 { 35 public: 36 SpinLock()37 SpinLock () 38 : flag(false) {} 39 isLocked()40 __forceinline bool isLocked() { 41 return flag.load(); 42 } 43 lock()44 __forceinline void lock() 45 { 46 while (true) 47 { 48 while (flag.load()) 49 { 50 _mm_pause(); 51 _mm_pause(); 52 } 53 54 bool expected = false; 55 if (flag.compare_exchange_strong(expected,true,std::memory_order_acquire)) 56 break; 57 } 58 } 59 try_lock()60 __forceinline bool try_lock() 61 { 62 bool expected = false; 63 if (flag.load() != expected) { 64 return false; 65 } 66 return flag.compare_exchange_strong(expected,true,std::memory_order_acquire); 67 } 68 unlock()69 __forceinline void unlock() { 70 flag.store(false,std::memory_order_release); 71 } 72 wait_until_unlocked()73 __forceinline void wait_until_unlocked() 74 { 75 while(flag.load()) 76 { 77 _mm_pause(); 78 _mm_pause(); 79 } 80 } 81 82 public: 83 atomic<bool> flag; 84 }; 85 86 /*! safe mutex lock and unlock helper */ 87 template<typename Mutex> class Lock { 88 public: Lock(Mutex & mutex)89 Lock (Mutex& mutex) : mutex(mutex), locked(true) { mutex.lock(); } Lock(Mutex & mutex,bool locked)90 Lock (Mutex& mutex, bool locked) : mutex(mutex), locked(locked) {} ~Lock()91 ~Lock() { if (locked) mutex.unlock(); } lock()92 __forceinline void lock() { assert(!locked); locked = true; mutex.lock(); } isLocked()93 __forceinline bool isLocked() const { return locked; } 94 protected: 95 Mutex& mutex; 96 bool locked; 97 }; 98 } 99