Embedded Multicore Building Blocks V1.0.0
atomic.h
1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_BASE_ATOMIC_H_
28 #define EMBB_BASE_ATOMIC_H_
29 
30 #include <stdint.h>
31 #include <cstddef>
32 #include <cassert>
33 #include <utility>
34 
35 #include <embb/base/internal/atomic/atomic_base.h>
36 #include <embb/base/internal/atomic/atomic_pointer.h>
37 #include <embb/base/internal/atomic/atomic_integer.h>
38 
39 namespace embb {
40 namespace base {
41 #ifdef DOXYGEN
42 
59 template<typename BaseType>
60 class Atomic {
61  public:
71  Atomic();
72 
87  explicit Atomic(BaseType val);
88 
100  BaseType operator=(BaseType val);
101 
113  operator BaseType() const;
114 
128  bool IsArithmetic() const;
129 
141  bool IsInteger() const;
142 
156  bool IsPointer() const;
157 
170  void Store(BaseType val);
171 
183  BaseType Load() const;
184 
198  BaseType Swap(BaseType val);
199 
215  bool CompareAndSwap(BaseType& expected, BaseType desired);
216 
239  BaseType FetchAndAdd(BaseType val);
240 
254  BaseType FetchAndSub(BaseType val);
255 
267  BaseType operator++(int);
268 
280  BaseType operator--(int);
281 
293  BaseType operator++();
294 
306  BaseType operator--();
307 
320  BaseType operator+=(BaseType val);
321 
334  BaseType operator-=(BaseType val);
335 
359  void operator&=(BaseType val);
360 
374  void operator|=(BaseType val);
375 
389  void operator^=(BaseType val);
390 
414  BaseType* operator->();
415 
427  BaseType& operator*();
428 
430 };
431 
432 #else
433 
440 template<typename BaseType>
441 class Atomic : public embb::base::internal::atomic::AtomicBase < BaseType > {
442  public:
446  Atomic() : embb::base::internal::atomic::AtomicBase<BaseType>() {}
447 
453  explicit Atomic(BaseType val) : embb::base::internal::atomic::
454  AtomicBase<BaseType>(val) {}
455 
463  BaseType operator=(BaseType val) {
464  return embb::base::internal::atomic::AtomicBase<BaseType>::
465  operator=(val);
466  }
467 };
468 
475 template<typename BaseType>
476 class Atomic<BaseType*> : public embb::base::internal::atomic::
477  AtomicPointer < BaseType, ptrdiff_t, sizeof(BaseType*) > {
478  public:
479  Atomic() : embb::base::internal::atomic::
480  AtomicPointer<BaseType, ptrdiff_t, sizeof(BaseType*)>() {}
481  explicit Atomic(BaseType* p) : embb::base::internal::atomic::
482  AtomicPointer<BaseType, ptrdiff_t, sizeof(BaseType*)>(p) {}
483 
484  BaseType* operator=(BaseType* p) {
485  return embb::base::internal::atomic::
486  AtomicPointer<BaseType, ptrdiff_t, sizeof(BaseType*)>::operator=(p);
487  }
488 };
489 
496 template<>
497 class Atomic<void*> : public embb::base::internal::atomic::AtomicBase < void* > {
498  public:
499  Atomic() : embb::base::internal::atomic::AtomicBase<void*>() {}
500  explicit Atomic(void* p) : embb::base::internal::atomic::AtomicBase<void*>(p)
501  {}
502 
503  void* operator=(void* p) {
504  return embb::base::internal::atomic::AtomicBase<void*>::operator=(p);
505  }
506 };
507 
512 #define __EMBB_ATOMIC_INTEGER_SPECIALIZATION(T) \
513 template<> \
514 class Atomic<T>: public embb::base::internal::atomic::AtomicInteger<T> { \
515  public: \
516  \
517  Atomic() : embb::base::internal::atomic::AtomicInteger<T>() {} \
518  explicit Atomic(T val) : embb::base::internal::atomic::AtomicInteger<T>(val) \
519  {} \
520  \
521  T operator=(T val) { return embb::base::internal::atomic::AtomicInteger<T>::\
522  operator=(val); } \
523  \
524 }
525 
526 // Specializations for integers
527 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(signed char);
528 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(unsigned char);
529 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(signed short);
530 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(unsigned short);
531 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(signed int);
532 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(unsigned int);
533 
534 #if defined EMBB_PLATFORM_ARCH_CXX11
535 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(signed long);
536 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(unsigned long);
537 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(signed long long);
538 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(unsigned long long);
539 #elif defined EMBB_PLATFORM_ARCH_X86_64
540 __EMBB_ATOMIC_INTEGER_SPECIALIZATION(size_t);
541 #endif
542 
543 #endif
544 } // namespace base
545 } // namespace embb
546 
547 #endif // EMBB_BASE_ATOMIC_H_
Definition: lock_free_mpmc_queue.h:40
Class representing atomic variables.
Definition: atomic.h:60
void operator&=(BaseType val)
Assignment by bitwise AND.
BaseType Swap(BaseType val)
Swap operation.
void operator^=(BaseType val)
Assignment by bitwise XOR.
BaseType Load() const
Load operation.
Atomic()
Default constructor.
void Store(BaseType val)
Store operation.
bool IsInteger() const
Predicate representing integers.
BaseType operator--()
Pre-decrement operation.
BaseType & operator*()
Dereference operation.
BaseType operator+=(BaseType val)
Assignment by sum operation.
BaseType operator-=(BaseType val)
Assignment by difference operation.
void operator|=(BaseType val)
Assignment by bitwise OR.
BaseType operator=(BaseType val)
Assignment operator.
BaseType operator++()
Pre-increment operation.
bool IsArithmetic() const
Predicate representing support for arithmetic operations.
bool CompareAndSwap(BaseType &expected, BaseType desired)
Compare-and-Swap operation (CAS).
BaseType * operator->()
Structure dereference operation.
BaseType FetchAndAdd(BaseType val)
Fetch-and-Add operation.
bool IsPointer() const
Predicate representing pointers.
BaseType FetchAndSub(BaseType val)
Fetch-and-Sub operation.