1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
4
5
6 /////////////////////////////////////////////////////////////////////////
7 /// @file atomic.h
8 ///
9 /// @brief Wrappers and utilities for atomics.
10 /////////////////////////////////////////////////////////////////////////
11
12 #pragma once
13
14 #include <OpenImageIO/oiioversion.h>
15 #include <OpenImageIO/platform.h>
16
17 #include <atomic>
18 #define OIIO_USE_STDATOMIC 1
19
20
21
22 OIIO_NAMESPACE_BEGIN
23
24 using std::atomic;
25 typedef atomic<int> atomic_int;
26 typedef atomic<long long> atomic_ll;
27
28
29
30 /// Atomically set avar to the minimum of its current value and bval.
31 template<typename T>
32 OIIO_FORCEINLINE void
atomic_min(atomic<T> & avar,const T & bval)33 atomic_min(atomic<T>& avar, const T& bval)
34 {
35 do {
36 T a = avar.load();
37 if (a <= bval || avar.compare_exchange_weak(a, bval))
38 break;
39 } while (true);
40 }
41
42
43 /// Atomically set avar to the maximum of its current value and bval.
44 template<typename T>
45 OIIO_FORCEINLINE void
atomic_max(atomic<T> & avar,const T & bval)46 atomic_max(atomic<T>& avar, const T& bval)
47 {
48 do {
49 T a = avar.load();
50 if (a >= bval || avar.compare_exchange_weak(a, bval))
51 break;
52 } while (true);
53 }
54
55
56
57 // Add atomically to a float and return the original value.
58 OIIO_FORCEINLINE float
atomic_fetch_add(atomic<float> & a,float f)59 atomic_fetch_add(atomic<float>& a, float f)
60 {
61 do {
62 float oldval = a.load();
63 float newval = oldval + f;
64 if (a.compare_exchange_weak(oldval, newval))
65 return oldval;
66 } while (true);
67 }
68
69
70 // Add atomically to a double and return the original value.
71 OIIO_FORCEINLINE double
atomic_fetch_add(atomic<double> & a,double f)72 atomic_fetch_add(atomic<double>& a, double f)
73 {
74 do {
75 double oldval = a.load();
76 double newval = oldval + f;
77 if (a.compare_exchange_weak(oldval, newval))
78 return oldval;
79 } while (true);
80 }
81
82
83 OIIO_NAMESPACE_END
84