Essentia  2.1-beta6-dev
atomic.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Essentia
5  *
6  * Essentia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef ESSENTIA_ATOMIC_H
21 #define ESSENTIA_ATOMIC_H
22 
23 
24 #if defined(__EMSCRIPTEN__)
25 
26 namespace essentia {
27 
28 class Atomic {
29  public:
30  int _a;
31 
32  inline Atomic(const int &i = 0) : _a(i) {}
33 
34  inline operator int () const { return _a; }
35 
36  inline void add(const int& i) {
37  // Javascript is single-threaded
38  _a += i;
39  }
40 
41  inline void operator-=(const int &i) { add(-i); }
42  inline void operator+=(const int &i) { add(i); }
43 
44  inline void operator++() { add(1); }
45  inline void operator--() { add(-1); }
46 };
47 
48 } // namespace essentia
49 
50 
51 // life's easy in C++11
52 #elif __cplusplus >= 201103L
53 
54 
55 #include <atomic>
56 
57 namespace essentia {
58 typedef std::atomic<int> Atomic;
59 }
60 
61 
62 #elif defined(OS_WIN32)
63 
64 
65 #include <windows.h>
66 
67 namespace essentia {
68 
69 class Atomic {
70  private:
71  LONG volatile i_;
72 
73  public:
74  inline Atomic(const int &i = 0) : i_(i) {}
75 
76  inline operator int() const { return i_; }
77 
78  inline void operator-=(const int &i) {
79  InterlockedExchangeAdd(&i_, -i);
80  }
81 
82  inline void operator+=(const int &i) {
83  InterlockedExchangeAdd(&i_, i);
84  }
85 
86  inline void operator++() {
87  InterlockedIncrement(&i_);
88  }
89 
90  inline void operator--() {
91  InterlockedDecrement(&i_);
92  }
93 };
94 
95 } // namespace essentia
96 
97 
98 #elif defined(OS_MAC)
99 
100 #include <libkern/OSAtomic.h>
101 namespace essentia {
102 
103 class Atomic {
104  private:
105  int32_t i_;
106 
107  public:
108  inline Atomic(const int &i = 0) : i_(i) {}
109 
110  inline operator int() const { return i_; }
111 
112  inline void operator-=(const int &i) {
113  OSAtomicAdd32Barrier(-i, &i_);
114  }
115 
116  inline void operator+=(const int &i) {
117  OSAtomicAdd32Barrier(i, &i_);
118  }
119 
120  inline void operator++() {
121  OSAtomicIncrement32Barrier(&i_);
122  }
123 
124  inline void operator--() {
125  OSAtomicDecrement32Barrier(&i_);
126  }
127 };
128 
129 } // namespace essentia
130 
131 
132 #elif defined(OS_LINUX)
133 
134 #include <ext/atomicity.h>
135 
136 namespace essentia {
137 
138 class Atomic {
139  public:
140  _Atomic_word _a;
141 
142  inline Atomic(const int &i = 0) : _a(i) {}
143 
144  inline operator int () const { return _a; }
145 
146  inline void add(const int& i) {
147 // not sure 4.0 is the correct version, it happened somewhere between 3.3 and 4.1
148 #if GCC_VERSION >= 40000
149  __gnu_cxx::__atomic_add(&_a,i);
150 #else
151  __atomic_add(&_a, i);
152 #endif
153  }
154 
155  inline void operator-=(const int &i) { add(-i); }
156  inline void operator+=(const int &i) { add(i); }
157 
158  inline void operator++() { add(1); }
159  inline void operator--() { add(-1); }
160 };
161 
162 } // namespace essentia
163 
164 
165 #endif
166 
167 #endif // ESSENTIA_ATOMIC_H
Array1D< T > & operator-=(Array1D< T > &A, const Array1D< T > &B)
Definition: tnt_array1d_utils.h:174
Array1D< T > & operator+=(Array1D< T > &A, const Array1D< T > &B)
Definition: tnt_array1d_utils.h:156
Definition: algorithm.h:28