1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include <atomic>
7 #include "intrinsics.h"
8 
9 namespace embree
10 {
11 /* compiler memory barriers */
12 #if defined(__INTEL_COMPILER)
13 //#define __memory_barrier() __memory_barrier()
14 #elif defined(__GNUC__) || defined(__clang__)
15 #  define __memory_barrier() asm volatile("" ::: "memory")
16 #elif  defined(_MSC_VER)
17 #  define __memory_barrier() _ReadWriteBarrier()
18 #endif
19 
20   template <typename T>
21     struct atomic : public std::atomic<T>
22   {
atomicatomic23     atomic () {}
24 
atomicatomic25     atomic (const T& a)
26       : std::atomic<T>(a) {}
27 
atomicatomic28     atomic (const atomic<T>& a) {
29       this->store(a.load());
30     }
31 
32     atomic& operator=(const atomic<T>& other) {
33       this->store(other.load());
34       return *this;
35     }
36   };
37 
38   template<typename T>
atomic_min(std::atomic<T> & aref,const T & bref)39     __forceinline void atomic_min(std::atomic<T>& aref, const T& bref)
40   {
41     const T b = bref.load();
42     while (true) {
43       T a = aref.load();
44       if (a <= b) break;
45       if (aref.compare_exchange_strong(a,b)) break;
46     }
47   }
48 
49   template<typename T>
atomic_max(std::atomic<T> & aref,const T & bref)50     __forceinline void atomic_max(std::atomic<T>& aref, const T& bref)
51   {
52     const T b = bref.load();
53     while (true) {
54       T a = aref.load();
55       if (a >= b) break;
56       if (aref.compare_exchange_strong(a,b)) break;
57     }
58   }
59 }
60