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 | { |
23 | atomic () {} |
24 | |
25 | atomic (const T& a) |
26 | : std::atomic<T>(a) {} |
27 | |
28 | 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> |
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> |
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 | |