Containers (STL-compatible) StateMachines MessageBus and more for Embedded Systems. See www.etlcpp.com

Committer:
bobbery
Date:
Fri Mar 16 16:34:18 2018 +0000
Revision:
0:b47c2a7920c2
Works after using gcc_generic undef CAPACITY and replacing nullptr by std::nullptr

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bobbery 0:b47c2a7920c2 1 /******************************************************************************
bobbery 0:b47c2a7920c2 2 The MIT License(MIT)
bobbery 0:b47c2a7920c2 3
bobbery 0:b47c2a7920c2 4 Embedded Template Library.
bobbery 0:b47c2a7920c2 5 https://github.com/ETLCPP/etl
bobbery 0:b47c2a7920c2 6 https://www.etlcpp.com
bobbery 0:b47c2a7920c2 7
bobbery 0:b47c2a7920c2 8 Copyright(c) 2017 jwellbelove
bobbery 0:b47c2a7920c2 9
bobbery 0:b47c2a7920c2 10 Permission is hereby granted, free of charge, to any person obtaining a copy
bobbery 0:b47c2a7920c2 11 of this software and associated documentation files(the "Software"), to deal
bobbery 0:b47c2a7920c2 12 in the Software without restriction, including without limitation the rights
bobbery 0:b47c2a7920c2 13 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
bobbery 0:b47c2a7920c2 14 copies of the Software, and to permit persons to whom the Software is
bobbery 0:b47c2a7920c2 15 furnished to do so, subject to the following conditions :
bobbery 0:b47c2a7920c2 16
bobbery 0:b47c2a7920c2 17 The above copyright notice and this permission notice shall be included in all
bobbery 0:b47c2a7920c2 18 copies or substantial portions of the Software.
bobbery 0:b47c2a7920c2 19
bobbery 0:b47c2a7920c2 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
bobbery 0:b47c2a7920c2 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
bobbery 0:b47c2a7920c2 22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
bobbery 0:b47c2a7920c2 23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
bobbery 0:b47c2a7920c2 24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
bobbery 0:b47c2a7920c2 25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
bobbery 0:b47c2a7920c2 26 SOFTWARE.
bobbery 0:b47c2a7920c2 27 ******************************************************************************/
bobbery 0:b47c2a7920c2 28
bobbery 0:b47c2a7920c2 29 #ifndef __ETL_ATOMIC_GCC__
bobbery 0:b47c2a7920c2 30 #define __ETL_ATOMIC_GCC__
bobbery 0:b47c2a7920c2 31
bobbery 0:b47c2a7920c2 32 #include "../platform.h"
bobbery 0:b47c2a7920c2 33 #include "../type_traits.h"
bobbery 0:b47c2a7920c2 34 #include "../char_traits.h"
bobbery 0:b47c2a7920c2 35 #include "../static_assert.h"
bobbery 0:b47c2a7920c2 36 #include "../nullptr.h"
bobbery 0:b47c2a7920c2 37
bobbery 0:b47c2a7920c2 38 #include <stdint.h>
bobbery 0:b47c2a7920c2 39
bobbery 0:b47c2a7920c2 40 namespace etl
bobbery 0:b47c2a7920c2 41 {
bobbery 0:b47c2a7920c2 42 //***************************************************************************
bobbery 0:b47c2a7920c2 43 // Atomic type for pre C++11 GCC compilers that support the builtin 'fetch' functions.
bobbery 0:b47c2a7920c2 44 // Only integral and pointer types are supported.
bobbery 0:b47c2a7920c2 45 //***************************************************************************
bobbery 0:b47c2a7920c2 46 template <typename T>
bobbery 0:b47c2a7920c2 47 class atomic
bobbery 0:b47c2a7920c2 48 {
bobbery 0:b47c2a7920c2 49 public:
bobbery 0:b47c2a7920c2 50
bobbery 0:b47c2a7920c2 51 STATIC_ASSERT(etl::is_integral<T>::value, "Only integral types are supported");
bobbery 0:b47c2a7920c2 52
bobbery 0:b47c2a7920c2 53 atomic()
bobbery 0:b47c2a7920c2 54 : value(0)
bobbery 0:b47c2a7920c2 55 {
bobbery 0:b47c2a7920c2 56 }
bobbery 0:b47c2a7920c2 57
bobbery 0:b47c2a7920c2 58 atomic(T v)
bobbery 0:b47c2a7920c2 59 : value(v)
bobbery 0:b47c2a7920c2 60 {
bobbery 0:b47c2a7920c2 61 }
bobbery 0:b47c2a7920c2 62
bobbery 0:b47c2a7920c2 63 // Assignment
bobbery 0:b47c2a7920c2 64 T operator =(T v)
bobbery 0:b47c2a7920c2 65 {
bobbery 0:b47c2a7920c2 66 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 67
bobbery 0:b47c2a7920c2 68 return v;
bobbery 0:b47c2a7920c2 69 }
bobbery 0:b47c2a7920c2 70
bobbery 0:b47c2a7920c2 71 T operator =(T v) volatile
bobbery 0:b47c2a7920c2 72 {
bobbery 0:b47c2a7920c2 73 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 74
bobbery 0:b47c2a7920c2 75 return v;
bobbery 0:b47c2a7920c2 76 }
bobbery 0:b47c2a7920c2 77
bobbery 0:b47c2a7920c2 78 // Pre-increment
bobbery 0:b47c2a7920c2 79 T operator ++()
bobbery 0:b47c2a7920c2 80 {
bobbery 0:b47c2a7920c2 81 return fetch_add(1) + 1;
bobbery 0:b47c2a7920c2 82 }
bobbery 0:b47c2a7920c2 83
bobbery 0:b47c2a7920c2 84 T operator ++() volatile
bobbery 0:b47c2a7920c2 85 {
bobbery 0:b47c2a7920c2 86 return fetch_add(1) + 1;
bobbery 0:b47c2a7920c2 87 }
bobbery 0:b47c2a7920c2 88
bobbery 0:b47c2a7920c2 89 // Post-increment
bobbery 0:b47c2a7920c2 90 T operator ++(int)
bobbery 0:b47c2a7920c2 91 {
bobbery 0:b47c2a7920c2 92 return fetch_add(1);
bobbery 0:b47c2a7920c2 93 }
bobbery 0:b47c2a7920c2 94
bobbery 0:b47c2a7920c2 95 T operator ++(int) volatile
bobbery 0:b47c2a7920c2 96 {
bobbery 0:b47c2a7920c2 97 return fetch_add(1);
bobbery 0:b47c2a7920c2 98 }
bobbery 0:b47c2a7920c2 99
bobbery 0:b47c2a7920c2 100 // Pre-decrement
bobbery 0:b47c2a7920c2 101 T operator --()
bobbery 0:b47c2a7920c2 102 {
bobbery 0:b47c2a7920c2 103 return fetch_sub(1) + 1;
bobbery 0:b47c2a7920c2 104 }
bobbery 0:b47c2a7920c2 105
bobbery 0:b47c2a7920c2 106 T operator --() volatile
bobbery 0:b47c2a7920c2 107 {
bobbery 0:b47c2a7920c2 108 return fetch_sub(1) + 1;
bobbery 0:b47c2a7920c2 109 }
bobbery 0:b47c2a7920c2 110
bobbery 0:b47c2a7920c2 111 // Post-decrement
bobbery 0:b47c2a7920c2 112 T operator --(int)
bobbery 0:b47c2a7920c2 113 {
bobbery 0:b47c2a7920c2 114 return fetch_sub(1);
bobbery 0:b47c2a7920c2 115 }
bobbery 0:b47c2a7920c2 116
bobbery 0:b47c2a7920c2 117 T operator --(int) volatile
bobbery 0:b47c2a7920c2 118 {
bobbery 0:b47c2a7920c2 119 return fetch_sub(1);
bobbery 0:b47c2a7920c2 120 }
bobbery 0:b47c2a7920c2 121
bobbery 0:b47c2a7920c2 122 // Add
bobbery 0:b47c2a7920c2 123 T operator +=(T v)
bobbery 0:b47c2a7920c2 124 {
bobbery 0:b47c2a7920c2 125 return fetch_add(v) + v;
bobbery 0:b47c2a7920c2 126 }
bobbery 0:b47c2a7920c2 127
bobbery 0:b47c2a7920c2 128 T operator +=(T v) volatile
bobbery 0:b47c2a7920c2 129 {
bobbery 0:b47c2a7920c2 130 return fetch_add(v) + v;
bobbery 0:b47c2a7920c2 131 }
bobbery 0:b47c2a7920c2 132
bobbery 0:b47c2a7920c2 133 // Subtract
bobbery 0:b47c2a7920c2 134 T operator -=(T v)
bobbery 0:b47c2a7920c2 135 {
bobbery 0:b47c2a7920c2 136 return fetch_sub(v) - v;
bobbery 0:b47c2a7920c2 137 }
bobbery 0:b47c2a7920c2 138
bobbery 0:b47c2a7920c2 139 T operator -=(T v) volatile
bobbery 0:b47c2a7920c2 140 {
bobbery 0:b47c2a7920c2 141 return fetch_sub(v) - v;
bobbery 0:b47c2a7920c2 142 }
bobbery 0:b47c2a7920c2 143
bobbery 0:b47c2a7920c2 144 // And
bobbery 0:b47c2a7920c2 145 T operator &=(T v)
bobbery 0:b47c2a7920c2 146 {
bobbery 0:b47c2a7920c2 147 return fetch_and(v) & v;
bobbery 0:b47c2a7920c2 148 }
bobbery 0:b47c2a7920c2 149
bobbery 0:b47c2a7920c2 150 T operator &=(T v) volatile
bobbery 0:b47c2a7920c2 151 {
bobbery 0:b47c2a7920c2 152 return fetch_and(v) & v;
bobbery 0:b47c2a7920c2 153 }
bobbery 0:b47c2a7920c2 154
bobbery 0:b47c2a7920c2 155 // Or
bobbery 0:b47c2a7920c2 156 T operator |=(T v)
bobbery 0:b47c2a7920c2 157 {
bobbery 0:b47c2a7920c2 158 return fetch_or(v) | v;
bobbery 0:b47c2a7920c2 159 }
bobbery 0:b47c2a7920c2 160
bobbery 0:b47c2a7920c2 161 T operator |=(T v) volatile
bobbery 0:b47c2a7920c2 162 {
bobbery 0:b47c2a7920c2 163 return fetch_or(v) | v;
bobbery 0:b47c2a7920c2 164 }
bobbery 0:b47c2a7920c2 165
bobbery 0:b47c2a7920c2 166 // Exclusive or
bobbery 0:b47c2a7920c2 167 T operator ^=(T v)
bobbery 0:b47c2a7920c2 168 {
bobbery 0:b47c2a7920c2 169 return fetch_xor(v) ^ v;
bobbery 0:b47c2a7920c2 170 }
bobbery 0:b47c2a7920c2 171
bobbery 0:b47c2a7920c2 172 T operator ^=(T v) volatile
bobbery 0:b47c2a7920c2 173 {
bobbery 0:b47c2a7920c2 174 return fetch_xor(v) ^ v;
bobbery 0:b47c2a7920c2 175 }
bobbery 0:b47c2a7920c2 176
bobbery 0:b47c2a7920c2 177 // Conversion operator
bobbery 0:b47c2a7920c2 178 operator T () const
bobbery 0:b47c2a7920c2 179 {
bobbery 0:b47c2a7920c2 180 return __sync_fetch_and_add(const_cast<T*>(&value), 0);
bobbery 0:b47c2a7920c2 181 }
bobbery 0:b47c2a7920c2 182
bobbery 0:b47c2a7920c2 183 operator T() volatile const
bobbery 0:b47c2a7920c2 184 {
bobbery 0:b47c2a7920c2 185 return __sync_fetch_and_add(const_cast<T*>(&value), 0);
bobbery 0:b47c2a7920c2 186 }
bobbery 0:b47c2a7920c2 187
bobbery 0:b47c2a7920c2 188 // Is lock free?
bobbery 0:b47c2a7920c2 189 bool is_lock_free() const
bobbery 0:b47c2a7920c2 190 {
bobbery 0:b47c2a7920c2 191 return true;
bobbery 0:b47c2a7920c2 192 }
bobbery 0:b47c2a7920c2 193
bobbery 0:b47c2a7920c2 194 bool is_lock_free() const volatile
bobbery 0:b47c2a7920c2 195 {
bobbery 0:b47c2a7920c2 196 return true;
bobbery 0:b47c2a7920c2 197 }
bobbery 0:b47c2a7920c2 198
bobbery 0:b47c2a7920c2 199 // Store
bobbery 0:b47c2a7920c2 200 void store(T v)
bobbery 0:b47c2a7920c2 201 {
bobbery 0:b47c2a7920c2 202 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 203 }
bobbery 0:b47c2a7920c2 204
bobbery 0:b47c2a7920c2 205 void store(T v) volatile
bobbery 0:b47c2a7920c2 206 {
bobbery 0:b47c2a7920c2 207 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 208 }
bobbery 0:b47c2a7920c2 209
bobbery 0:b47c2a7920c2 210 // Load
bobbery 0:b47c2a7920c2 211 T load()
bobbery 0:b47c2a7920c2 212 {
bobbery 0:b47c2a7920c2 213 return __sync_fetch_and_add(&value, 0);
bobbery 0:b47c2a7920c2 214 }
bobbery 0:b47c2a7920c2 215
bobbery 0:b47c2a7920c2 216 T load() volatile
bobbery 0:b47c2a7920c2 217 {
bobbery 0:b47c2a7920c2 218 return __sync_fetch_and_add(&value, 0);
bobbery 0:b47c2a7920c2 219 }
bobbery 0:b47c2a7920c2 220
bobbery 0:b47c2a7920c2 221 // Fetch add
bobbery 0:b47c2a7920c2 222 T fetch_add(T v)
bobbery 0:b47c2a7920c2 223 {
bobbery 0:b47c2a7920c2 224 return __sync_fetch_and_add(&value, v);
bobbery 0:b47c2a7920c2 225 }
bobbery 0:b47c2a7920c2 226
bobbery 0:b47c2a7920c2 227 T fetch_add(T v) volatile
bobbery 0:b47c2a7920c2 228 {
bobbery 0:b47c2a7920c2 229 return __sync_fetch_and_add(&value, v);
bobbery 0:b47c2a7920c2 230 }
bobbery 0:b47c2a7920c2 231
bobbery 0:b47c2a7920c2 232 // Fetch subtract
bobbery 0:b47c2a7920c2 233 T fetch_sub(T v)
bobbery 0:b47c2a7920c2 234 {
bobbery 0:b47c2a7920c2 235 return __sync_fetch_and_sub(&value, v);
bobbery 0:b47c2a7920c2 236 }
bobbery 0:b47c2a7920c2 237
bobbery 0:b47c2a7920c2 238 T fetch_sub(T v) volatile
bobbery 0:b47c2a7920c2 239 {
bobbery 0:b47c2a7920c2 240 return __sync_fetch_and_sub(&value, v);
bobbery 0:b47c2a7920c2 241 }
bobbery 0:b47c2a7920c2 242
bobbery 0:b47c2a7920c2 243 // Fetch or
bobbery 0:b47c2a7920c2 244 T fetch_or(T v)
bobbery 0:b47c2a7920c2 245 {
bobbery 0:b47c2a7920c2 246 return __sync_fetch_and_or(&value, v);
bobbery 0:b47c2a7920c2 247 }
bobbery 0:b47c2a7920c2 248
bobbery 0:b47c2a7920c2 249 T fetch_or(T v) volatile
bobbery 0:b47c2a7920c2 250 {
bobbery 0:b47c2a7920c2 251 return __sync_fetch_and_or(&value, v);
bobbery 0:b47c2a7920c2 252 }
bobbery 0:b47c2a7920c2 253
bobbery 0:b47c2a7920c2 254 // Fetch and
bobbery 0:b47c2a7920c2 255 T fetch_and(T v)
bobbery 0:b47c2a7920c2 256 {
bobbery 0:b47c2a7920c2 257 return __sync_fetch_and_and(&value, v);
bobbery 0:b47c2a7920c2 258 }
bobbery 0:b47c2a7920c2 259
bobbery 0:b47c2a7920c2 260 T fetch_and(T v) volatile
bobbery 0:b47c2a7920c2 261 {
bobbery 0:b47c2a7920c2 262 return __sync_fetch_and_and(&value, v);
bobbery 0:b47c2a7920c2 263 }
bobbery 0:b47c2a7920c2 264
bobbery 0:b47c2a7920c2 265 // Fetch exclusive or
bobbery 0:b47c2a7920c2 266 T fetch_xor(T v)
bobbery 0:b47c2a7920c2 267 {
bobbery 0:b47c2a7920c2 268 return __sync_fetch_and_xor(&value, v);
bobbery 0:b47c2a7920c2 269 }
bobbery 0:b47c2a7920c2 270
bobbery 0:b47c2a7920c2 271 T fetch_xor(T v) volatile
bobbery 0:b47c2a7920c2 272 {
bobbery 0:b47c2a7920c2 273 return __sync_fetch_and_xor(&value, v);
bobbery 0:b47c2a7920c2 274 }
bobbery 0:b47c2a7920c2 275
bobbery 0:b47c2a7920c2 276 // Exchange
bobbery 0:b47c2a7920c2 277 T exchange(T v)
bobbery 0:b47c2a7920c2 278 {
bobbery 0:b47c2a7920c2 279 return __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 280 }
bobbery 0:b47c2a7920c2 281
bobbery 0:b47c2a7920c2 282 T exchange(T v) volatile
bobbery 0:b47c2a7920c2 283 {
bobbery 0:b47c2a7920c2 284 return __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 285 }
bobbery 0:b47c2a7920c2 286
bobbery 0:b47c2a7920c2 287 // Compare exchange weak
bobbery 0:b47c2a7920c2 288 bool compare_exchange_weak(T& expected, T desired)
bobbery 0:b47c2a7920c2 289 {
bobbery 0:b47c2a7920c2 290 T old = __sync_val_compare_and_swap(&value, expected, desired);
bobbery 0:b47c2a7920c2 291
bobbery 0:b47c2a7920c2 292 if (old == expected)
bobbery 0:b47c2a7920c2 293 {
bobbery 0:b47c2a7920c2 294 return true;
bobbery 0:b47c2a7920c2 295 }
bobbery 0:b47c2a7920c2 296 else
bobbery 0:b47c2a7920c2 297 {
bobbery 0:b47c2a7920c2 298 expected = old;
bobbery 0:b47c2a7920c2 299 return false;
bobbery 0:b47c2a7920c2 300 }
bobbery 0:b47c2a7920c2 301 }
bobbery 0:b47c2a7920c2 302
bobbery 0:b47c2a7920c2 303 bool compare_exchange_weak(T& expected, T desired) volatile
bobbery 0:b47c2a7920c2 304 {
bobbery 0:b47c2a7920c2 305 T old = __sync_val_compare_and_swap(&value, expected, desired);
bobbery 0:b47c2a7920c2 306
bobbery 0:b47c2a7920c2 307 if (old == expected)
bobbery 0:b47c2a7920c2 308 {
bobbery 0:b47c2a7920c2 309 return true;
bobbery 0:b47c2a7920c2 310 }
bobbery 0:b47c2a7920c2 311 else
bobbery 0:b47c2a7920c2 312 {
bobbery 0:b47c2a7920c2 313 expected = old;
bobbery 0:b47c2a7920c2 314 return false;
bobbery 0:b47c2a7920c2 315 }
bobbery 0:b47c2a7920c2 316 }
bobbery 0:b47c2a7920c2 317
bobbery 0:b47c2a7920c2 318 // Compare exchange strong
bobbery 0:b47c2a7920c2 319 bool compare_exchange_strong(T& expected, T desired)
bobbery 0:b47c2a7920c2 320 {
bobbery 0:b47c2a7920c2 321 T old = expected;
bobbery 0:b47c2a7920c2 322
bobbery 0:b47c2a7920c2 323 while (!compare_exchange_weak(old, desired))
bobbery 0:b47c2a7920c2 324 {
bobbery 0:b47c2a7920c2 325 if (memcmp(&old, &expected, sizeof(T)))
bobbery 0:b47c2a7920c2 326 {
bobbery 0:b47c2a7920c2 327 expected = old;
bobbery 0:b47c2a7920c2 328 return false;
bobbery 0:b47c2a7920c2 329 }
bobbery 0:b47c2a7920c2 330 }
bobbery 0:b47c2a7920c2 331
bobbery 0:b47c2a7920c2 332 return true;
bobbery 0:b47c2a7920c2 333 }
bobbery 0:b47c2a7920c2 334
bobbery 0:b47c2a7920c2 335 bool compare_exchange_strong(T& expected, T desired) volatile
bobbery 0:b47c2a7920c2 336 {
bobbery 0:b47c2a7920c2 337 T old = expected;
bobbery 0:b47c2a7920c2 338
bobbery 0:b47c2a7920c2 339 while (!compare_exchange_weak(old, desired))
bobbery 0:b47c2a7920c2 340 {
bobbery 0:b47c2a7920c2 341 if (memcmp(&old, &expected, sizeof(T)))
bobbery 0:b47c2a7920c2 342 {
bobbery 0:b47c2a7920c2 343 expected = old;
bobbery 0:b47c2a7920c2 344 return false;
bobbery 0:b47c2a7920c2 345 }
bobbery 0:b47c2a7920c2 346 }
bobbery 0:b47c2a7920c2 347
bobbery 0:b47c2a7920c2 348 return true;
bobbery 0:b47c2a7920c2 349 }
bobbery 0:b47c2a7920c2 350
bobbery 0:b47c2a7920c2 351 private:
bobbery 0:b47c2a7920c2 352
bobbery 0:b47c2a7920c2 353 atomic& operator =(const atomic&);
bobbery 0:b47c2a7920c2 354 atomic& operator =(const atomic&) volatile;
bobbery 0:b47c2a7920c2 355
bobbery 0:b47c2a7920c2 356 T value;
bobbery 0:b47c2a7920c2 357 };
bobbery 0:b47c2a7920c2 358
bobbery 0:b47c2a7920c2 359 //***************************************************************************
bobbery 0:b47c2a7920c2 360 // Specialisation for pointers.
bobbery 0:b47c2a7920c2 361 //***************************************************************************
bobbery 0:b47c2a7920c2 362 template <typename T>
bobbery 0:b47c2a7920c2 363 class atomic<T*>
bobbery 0:b47c2a7920c2 364 {
bobbery 0:b47c2a7920c2 365 public:
bobbery 0:b47c2a7920c2 366
bobbery 0:b47c2a7920c2 367 atomic()
bobbery 0:b47c2a7920c2 368 : value(std::nullptr)
bobbery 0:b47c2a7920c2 369 {
bobbery 0:b47c2a7920c2 370 }
bobbery 0:b47c2a7920c2 371
bobbery 0:b47c2a7920c2 372 atomic(T v)
bobbery 0:b47c2a7920c2 373 : value(v)
bobbery 0:b47c2a7920c2 374 {
bobbery 0:b47c2a7920c2 375 }
bobbery 0:b47c2a7920c2 376
bobbery 0:b47c2a7920c2 377 // Assignment
bobbery 0:b47c2a7920c2 378 T operator =(T* v)
bobbery 0:b47c2a7920c2 379 {
bobbery 0:b47c2a7920c2 380 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 381
bobbery 0:b47c2a7920c2 382 return v;
bobbery 0:b47c2a7920c2 383 }
bobbery 0:b47c2a7920c2 384
bobbery 0:b47c2a7920c2 385 T operator =(T* v) volatile
bobbery 0:b47c2a7920c2 386 {
bobbery 0:b47c2a7920c2 387 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 388
bobbery 0:b47c2a7920c2 389 return v;
bobbery 0:b47c2a7920c2 390 }
bobbery 0:b47c2a7920c2 391
bobbery 0:b47c2a7920c2 392 // Pre-increment
bobbery 0:b47c2a7920c2 393 T operator ++()
bobbery 0:b47c2a7920c2 394 {
bobbery 0:b47c2a7920c2 395 return fetch_add(1) + 1;
bobbery 0:b47c2a7920c2 396 }
bobbery 0:b47c2a7920c2 397
bobbery 0:b47c2a7920c2 398 T operator ++() volatile
bobbery 0:b47c2a7920c2 399 {
bobbery 0:b47c2a7920c2 400 return fetch_add(1) + 1;
bobbery 0:b47c2a7920c2 401 }
bobbery 0:b47c2a7920c2 402
bobbery 0:b47c2a7920c2 403 // Post-increment
bobbery 0:b47c2a7920c2 404 T operator ++(int)
bobbery 0:b47c2a7920c2 405 {
bobbery 0:b47c2a7920c2 406 return fetch_add(1);
bobbery 0:b47c2a7920c2 407 }
bobbery 0:b47c2a7920c2 408
bobbery 0:b47c2a7920c2 409 T operator ++(int) volatile
bobbery 0:b47c2a7920c2 410 {
bobbery 0:b47c2a7920c2 411 return fetch_add(1);
bobbery 0:b47c2a7920c2 412 }
bobbery 0:b47c2a7920c2 413
bobbery 0:b47c2a7920c2 414 // Pre-decrement
bobbery 0:b47c2a7920c2 415 T operator --()
bobbery 0:b47c2a7920c2 416 {
bobbery 0:b47c2a7920c2 417 return fetch_sub(1) + 1;
bobbery 0:b47c2a7920c2 418 }
bobbery 0:b47c2a7920c2 419
bobbery 0:b47c2a7920c2 420 T operator --() volatile
bobbery 0:b47c2a7920c2 421 {
bobbery 0:b47c2a7920c2 422 return fetch_sub(1) + 1;
bobbery 0:b47c2a7920c2 423 }
bobbery 0:b47c2a7920c2 424
bobbery 0:b47c2a7920c2 425 // Post-decrement
bobbery 0:b47c2a7920c2 426 T operator --(int)
bobbery 0:b47c2a7920c2 427 {
bobbery 0:b47c2a7920c2 428 return fetch_sub(1);
bobbery 0:b47c2a7920c2 429 }
bobbery 0:b47c2a7920c2 430
bobbery 0:b47c2a7920c2 431 T operator --(int) volatile
bobbery 0:b47c2a7920c2 432 {
bobbery 0:b47c2a7920c2 433 return fetch_sub(1);
bobbery 0:b47c2a7920c2 434 }
bobbery 0:b47c2a7920c2 435
bobbery 0:b47c2a7920c2 436 // Add
bobbery 0:b47c2a7920c2 437 T* operator +=(std::ptrdiff_t v)
bobbery 0:b47c2a7920c2 438 {
bobbery 0:b47c2a7920c2 439 return fetch_add(v) + v;
bobbery 0:b47c2a7920c2 440 }
bobbery 0:b47c2a7920c2 441
bobbery 0:b47c2a7920c2 442 T* operator +=(std::ptrdiff_t v) volatile
bobbery 0:b47c2a7920c2 443 {
bobbery 0:b47c2a7920c2 444 return fetch_add(v) + v;
bobbery 0:b47c2a7920c2 445 }
bobbery 0:b47c2a7920c2 446
bobbery 0:b47c2a7920c2 447 // Subtract
bobbery 0:b47c2a7920c2 448 T* operator -=(std::ptrdiff_t v)
bobbery 0:b47c2a7920c2 449 {
bobbery 0:b47c2a7920c2 450 return fetch_sub(v) - v;
bobbery 0:b47c2a7920c2 451 }
bobbery 0:b47c2a7920c2 452
bobbery 0:b47c2a7920c2 453 T* operator -=(std::ptrdiff_t v) volatile
bobbery 0:b47c2a7920c2 454 {
bobbery 0:b47c2a7920c2 455 return fetch_sub(v) - v;
bobbery 0:b47c2a7920c2 456 }
bobbery 0:b47c2a7920c2 457
bobbery 0:b47c2a7920c2 458 // Conversion operator
bobbery 0:b47c2a7920c2 459 operator T () const
bobbery 0:b47c2a7920c2 460 {
bobbery 0:b47c2a7920c2 461 return __sync_fetch_and_add(const_cast<T**>(&value), 0);
bobbery 0:b47c2a7920c2 462 }
bobbery 0:b47c2a7920c2 463
bobbery 0:b47c2a7920c2 464 operator T() volatile const
bobbery 0:b47c2a7920c2 465 {
bobbery 0:b47c2a7920c2 466 return __sync_fetch_and_add(const_cast<T**>(&value), 0);
bobbery 0:b47c2a7920c2 467 }
bobbery 0:b47c2a7920c2 468
bobbery 0:b47c2a7920c2 469 // Is lock free?
bobbery 0:b47c2a7920c2 470 bool is_lock_free() const
bobbery 0:b47c2a7920c2 471 {
bobbery 0:b47c2a7920c2 472 return true;
bobbery 0:b47c2a7920c2 473 }
bobbery 0:b47c2a7920c2 474
bobbery 0:b47c2a7920c2 475 bool is_lock_free() const volatile
bobbery 0:b47c2a7920c2 476 {
bobbery 0:b47c2a7920c2 477 return true;
bobbery 0:b47c2a7920c2 478 }
bobbery 0:b47c2a7920c2 479
bobbery 0:b47c2a7920c2 480 // Store
bobbery 0:b47c2a7920c2 481 void store(T v)
bobbery 0:b47c2a7920c2 482 {
bobbery 0:b47c2a7920c2 483 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 484 }
bobbery 0:b47c2a7920c2 485
bobbery 0:b47c2a7920c2 486 void store(T v) volatile
bobbery 0:b47c2a7920c2 487 {
bobbery 0:b47c2a7920c2 488 __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 489 }
bobbery 0:b47c2a7920c2 490
bobbery 0:b47c2a7920c2 491 // Load
bobbery 0:b47c2a7920c2 492 T load()
bobbery 0:b47c2a7920c2 493 {
bobbery 0:b47c2a7920c2 494 return __sync_fetch_and_add(&value, 0);
bobbery 0:b47c2a7920c2 495 }
bobbery 0:b47c2a7920c2 496
bobbery 0:b47c2a7920c2 497 T load() volatile
bobbery 0:b47c2a7920c2 498 {
bobbery 0:b47c2a7920c2 499 return __sync_fetch_and_add(&value, 0);
bobbery 0:b47c2a7920c2 500 }
bobbery 0:b47c2a7920c2 501
bobbery 0:b47c2a7920c2 502 // Fetch add
bobbery 0:b47c2a7920c2 503 T* fetch_add(std::ptrdiff_t v)
bobbery 0:b47c2a7920c2 504 {
bobbery 0:b47c2a7920c2 505 return __sync_fetch_and_add(&value, v);
bobbery 0:b47c2a7920c2 506 }
bobbery 0:b47c2a7920c2 507
bobbery 0:b47c2a7920c2 508 T* fetch_add(std::ptrdiff_t v) volatile
bobbery 0:b47c2a7920c2 509 {
bobbery 0:b47c2a7920c2 510 return __sync_fetch_and_add(&value, v);
bobbery 0:b47c2a7920c2 511 }
bobbery 0:b47c2a7920c2 512
bobbery 0:b47c2a7920c2 513 // Fetch subtract
bobbery 0:b47c2a7920c2 514 T* fetch_sub(std::ptrdiff_t v)
bobbery 0:b47c2a7920c2 515 {
bobbery 0:b47c2a7920c2 516 return __sync_fetch_and_sub(&value, v);
bobbery 0:b47c2a7920c2 517 }
bobbery 0:b47c2a7920c2 518
bobbery 0:b47c2a7920c2 519 T* fetch_sub(std::ptrdiff_t v) volatile
bobbery 0:b47c2a7920c2 520 {
bobbery 0:b47c2a7920c2 521 return __sync_fetch_and_sub(&value, v);
bobbery 0:b47c2a7920c2 522 }
bobbery 0:b47c2a7920c2 523
bobbery 0:b47c2a7920c2 524 // Exchange
bobbery 0:b47c2a7920c2 525 T exchange(T v)
bobbery 0:b47c2a7920c2 526 {
bobbery 0:b47c2a7920c2 527 return __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 528 }
bobbery 0:b47c2a7920c2 529
bobbery 0:b47c2a7920c2 530 T exchange(T v) volatile
bobbery 0:b47c2a7920c2 531 {
bobbery 0:b47c2a7920c2 532 return __sync_lock_test_and_set(&value, v);
bobbery 0:b47c2a7920c2 533 }
bobbery 0:b47c2a7920c2 534
bobbery 0:b47c2a7920c2 535 // Compare exchange weak
bobbery 0:b47c2a7920c2 536 bool compare_exchange_weak(T& expected, T desired)
bobbery 0:b47c2a7920c2 537 {
bobbery 0:b47c2a7920c2 538 return __sync_bool_compare_and_swap(&value, expected, desired);
bobbery 0:b47c2a7920c2 539 }
bobbery 0:b47c2a7920c2 540
bobbery 0:b47c2a7920c2 541 bool compare_exchange_weak(T& expected, T desired) volatile
bobbery 0:b47c2a7920c2 542 {
bobbery 0:b47c2a7920c2 543 return __sync_bool_compare_and_swap(&value, expected, desired);
bobbery 0:b47c2a7920c2 544 }
bobbery 0:b47c2a7920c2 545
bobbery 0:b47c2a7920c2 546 // Compare exchange strong
bobbery 0:b47c2a7920c2 547 bool compare_exchange_strong(T& expected, T desired)
bobbery 0:b47c2a7920c2 548 {
bobbery 0:b47c2a7920c2 549 T old = expected;
bobbery 0:b47c2a7920c2 550
bobbery 0:b47c2a7920c2 551 while (!compare_exchange_weak(old, desired))
bobbery 0:b47c2a7920c2 552 {
bobbery 0:b47c2a7920c2 553 if (memcmp(&old, &expected, sizeof(T)))
bobbery 0:b47c2a7920c2 554 {
bobbery 0:b47c2a7920c2 555 expected = old;
bobbery 0:b47c2a7920c2 556 return false;
bobbery 0:b47c2a7920c2 557 }
bobbery 0:b47c2a7920c2 558 }
bobbery 0:b47c2a7920c2 559
bobbery 0:b47c2a7920c2 560 return true;
bobbery 0:b47c2a7920c2 561 }
bobbery 0:b47c2a7920c2 562
bobbery 0:b47c2a7920c2 563 bool compare_exchange_strong(T& expected, T desired) volatile
bobbery 0:b47c2a7920c2 564 {
bobbery 0:b47c2a7920c2 565 T old = expected;
bobbery 0:b47c2a7920c2 566
bobbery 0:b47c2a7920c2 567 while (!compare_exchange_weak(old, desired))
bobbery 0:b47c2a7920c2 568 {
bobbery 0:b47c2a7920c2 569 if (memcmp(&old, &expected, sizeof(T)))
bobbery 0:b47c2a7920c2 570 {
bobbery 0:b47c2a7920c2 571 expected = old;
bobbery 0:b47c2a7920c2 572 return false;
bobbery 0:b47c2a7920c2 573 }
bobbery 0:b47c2a7920c2 574 }
bobbery 0:b47c2a7920c2 575
bobbery 0:b47c2a7920c2 576 return true;
bobbery 0:b47c2a7920c2 577 }
bobbery 0:b47c2a7920c2 578
bobbery 0:b47c2a7920c2 579 private:
bobbery 0:b47c2a7920c2 580
bobbery 0:b47c2a7920c2 581 atomic& operator =(const atomic&);
bobbery 0:b47c2a7920c2 582 atomic& operator =(const atomic&) volatile;
bobbery 0:b47c2a7920c2 583
bobbery 0:b47c2a7920c2 584 T* value;
bobbery 0:b47c2a7920c2 585 };
bobbery 0:b47c2a7920c2 586
bobbery 0:b47c2a7920c2 587 typedef etl::atomic<char> atomic_char;
bobbery 0:b47c2a7920c2 588 typedef etl::atomic<signed char> atomic_schar;
bobbery 0:b47c2a7920c2 589 typedef etl::atomic<unsigned char> atomic_uchar;
bobbery 0:b47c2a7920c2 590 typedef etl::atomic<short> atomic_short;
bobbery 0:b47c2a7920c2 591 typedef etl::atomic<unsigned short> atomic_ushort;
bobbery 0:b47c2a7920c2 592 typedef etl::atomic<int> atomic_int;
bobbery 0:b47c2a7920c2 593 typedef etl::atomic<unsigned int> atomic_uint;
bobbery 0:b47c2a7920c2 594 typedef etl::atomic<long> atomic_long;
bobbery 0:b47c2a7920c2 595 typedef etl::atomic<unsigned long> atomic_ulong;
bobbery 0:b47c2a7920c2 596 typedef etl::atomic<long long> atomic_llong;
bobbery 0:b47c2a7920c2 597 typedef etl::atomic<unsigned long long> atomic_ullong;
bobbery 0:b47c2a7920c2 598 typedef etl::atomic<wchar_t> atomic_wchar_t;
bobbery 0:b47c2a7920c2 599 typedef etl::atomic<char16_t> atomic_char16_t;
bobbery 0:b47c2a7920c2 600 typedef etl::atomic<char32_t> atomic_char32_t;
bobbery 0:b47c2a7920c2 601 typedef etl::atomic<uint8_t> atomic_uint8_t;
bobbery 0:b47c2a7920c2 602 typedef etl::atomic<int8_t> atomic_int8_t;
bobbery 0:b47c2a7920c2 603 typedef etl::atomic<uint16_t> atomic_uint16_t;
bobbery 0:b47c2a7920c2 604 typedef etl::atomic<int16_t> atomic_int16_t;
bobbery 0:b47c2a7920c2 605 typedef etl::atomic<uint32_t> atomic_uint32_t;
bobbery 0:b47c2a7920c2 606 typedef etl::atomic<int32_t> atomic_int32_t;
bobbery 0:b47c2a7920c2 607 typedef etl::atomic<uint64_t> atomic_uint64_t;
bobbery 0:b47c2a7920c2 608 typedef etl::atomic<int64_t> atomic_int64_t;
bobbery 0:b47c2a7920c2 609 typedef etl::atomic<int_least8_t> atomic_int_least8_t;
bobbery 0:b47c2a7920c2 610 typedef etl::atomic<uint_least8_t> atomic_uint_least8_t;
bobbery 0:b47c2a7920c2 611 typedef etl::atomic<int_least16_t> atomic_int_least16_t;
bobbery 0:b47c2a7920c2 612 typedef etl::atomic<uint_least16_t> atomic_uint_least16_t;
bobbery 0:b47c2a7920c2 613 typedef etl::atomic<int_least32_t> atomic_int_least32_t;
bobbery 0:b47c2a7920c2 614 typedef etl::atomic<uint_least32_t> atomic_uint_least32_t;
bobbery 0:b47c2a7920c2 615 typedef etl::atomic<int_least64_t> atomic_int_least64_t;
bobbery 0:b47c2a7920c2 616 typedef etl::atomic<uint_least64_t> atomic_uint_least64_t;
bobbery 0:b47c2a7920c2 617 typedef etl::atomic<int_fast8_t> atomic_int_fast8_t;
bobbery 0:b47c2a7920c2 618 typedef etl::atomic<uint_fast8_t> atomic_uint_fast8_t;
bobbery 0:b47c2a7920c2 619 typedef etl::atomic<int_fast16_t> atomic_int_fast16_t;
bobbery 0:b47c2a7920c2 620 typedef etl::atomic<uint_fast16_t> atomic_uint_fast16_t;
bobbery 0:b47c2a7920c2 621 typedef etl::atomic<int_fast32_t> atomic_int_fast32_t;
bobbery 0:b47c2a7920c2 622 typedef etl::atomic<uint_fast32_t> atomic_uint_fast32_t;
bobbery 0:b47c2a7920c2 623 typedef etl::atomic<int_fast64_t> atomic_int_fast64_t;
bobbery 0:b47c2a7920c2 624 typedef etl::atomic<uint_fast64_t> atomic_uint_fast64_t;
bobbery 0:b47c2a7920c2 625 typedef etl::atomic<intptr_t> atomic_intptr_t;
bobbery 0:b47c2a7920c2 626 typedef etl::atomic<uintptr_t> atomic_uintptr_t;
bobbery 0:b47c2a7920c2 627 typedef etl::atomic<size_t> atomic_size_t;
bobbery 0:b47c2a7920c2 628 typedef etl::atomic<ptrdiff_t> atomic_ptrdiff_t;
bobbery 0:b47c2a7920c2 629 typedef etl::atomic<intmax_t> atomic_intmax_t;
bobbery 0:b47c2a7920c2 630 typedef etl::atomic<uintmax_t> atomic_uintmax_t;
bobbery 0:b47c2a7920c2 631 }
bobbery 0:b47c2a7920c2 632
bobbery 0:b47c2a7920c2 633 #endif
bobbery 0:b47c2a7920c2 634