libqi  1.14
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
atomic.hpp
1 /*
2  * Copyright (c) 2012 Aldebaran Robotics. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the COPYING file.
5  */
6 
7 #pragma once
8 
9 #ifndef _LIBQI_QI_ATOMIC_HPP_
10 #define _LIBQI_QI_ATOMIC_HPP_
11 
12 #ifdef _MSC_VER
13 # include <windows.h>
14 # pragma intrinsic(_InterlockedIncrement16)
15 # pragma intrinsic(_InterlockedDecrement16)
16 # pragma intrinsic(_InterlockedIncrement)
17 # pragma intrinsic(_InterlockedDecrement)
18 
19 extern "C" long __cdecl _InterlockedIncrement(long volatile *);
20 extern "C" long __cdecl _InterlockedDecrement(long volatile *);
21 extern "C" short __cdecl _InterlockedIncrement16(short volatile *);
22 extern "C" short __cdecl _InterlockedDecrement16(short volatile *);
23 #endif
24 
25 #include <qi/config.hpp>
26 
27 namespace qi
28 {
29  template <typename T>
30  class QI_API atomic
31  {
32  public:
33  atomic()
34  : _value(0)
35  {
36  }
37 
38  atomic(T value)
39  : _value(value)
40  {
41  }
42 
43  /* prefix operators */
44  T operator++();
45  T operator--();
46 
47  T operator*()
48  {
49  return _value;
50  }
51 
52  private:
53  T _value;
54  };
55 
56 #ifdef __GNUC__
57  template <typename T>
59  {
60  return __sync_add_and_fetch(&_value, 1);
61  }
62 
63  template <typename T>
64  T atomic<T>::operator--()
65  {
66  return __sync_sub_and_fetch(&_value, 1);
67  }
68 #endif
69 
70 #ifdef _MSC_VER
71  template<>
72  inline short atomic<short>::operator++()
73  {
74  return _InterlockedIncrement16(&_value);
75  }
76 
77  template<>
78  inline short atomic<short>::operator--()
79  {
80  return _InterlockedDecrement16(&_value);
81  }
82 
83  template <>
84  inline long atomic<long>::operator++()
85  {
86  return _InterlockedIncrement(&_value);
87  }
88 
89  template <>
90  inline long atomic<long>::operator--()
91  {
92  return _InterlockedDecrement(&_value);
93  }
94 #endif
95 }
96 
97 #endif // _LIBQI_QI_ATOMIC_HPP_