MrSID Decode SDK for LiDAR Reference Manual  1.1.3.4427
Atomic.h
Go to the documentation of this file.
1 /* //////////////////////////////////////////////////////////////////////////
2 // //
3 // This code is Copyright (c) 2008-2010 LizardTech, Inc, 1008 Western //
4 // Avenue, Suite 200, Seattle, WA 98104. Unauthorized use or distribution //
5 // prohibited. Access to and use of this code is permitted only under //
6 // license from LizardTech, Inc. Portions of the code are protected by //
7 // US and foreign patents and other filings. All Rights Reserved. //
8 // //
10 /* PUBLIC */
11 
12 #ifndef __LIDAR_ATOMIC_H__
13 #define __LIDAR_ATOMIC_H__
14 
15 #include "lidar/Base.h"
16 
17 #if defined _WIN32
18 #define NOMINMAX
19 #include <windows.h>
20 #elif defined __APPLE__
21 #include <libkern/OSAtomic.h>
22 #elif defined __GNUG__
23 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
24 #include <bits/atomicity.h>
25 #endif
26 #else
27 #error unknown platform
28 #endif
29 
30 LT_BEGIN_LIDAR_NAMESPACE
31 
32 #if defined _WIN32
33 
34 typedef LONG AtomicInt;
35 
36 inline AtomicInt AtomicIncrement(AtomicInt &value)
37 {
38  return ::InterlockedIncrement(&value);
39 }
40 
41 inline AtomicInt AtomicDecrement(AtomicInt &value)
42 {
43  return ::InterlockedDecrement(&value);
44 }
45 
46 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
47 {
48  return InterlockedCompareExchangePointer(reinterpret_cast<void **>(&value), newValue, oldValue) == oldValue;
49 }
50 
51 #elif defined __APPLE__
52 
53 typedef int32_t AtomicInt;
54 
55 inline AtomicInt AtomicIncrement(AtomicInt &value)
56 {
57  return OSAtomicIncrement32Barrier(&value);
58 }
59 
60 inline AtomicInt AtomicDecrement(AtomicInt &value)
61 {
62  return OSAtomicDecrement32Barrier(&value);
63 }
64 
65 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
66 {
67  return ::OSAtomicCompareAndSwapPtrBarrier(oldValue, newValue, reinterpret_cast<void **>(&value));
68 }
69 
70 
71 #elif defined __GNUG__
72 
73 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
74 typedef _Atomic_word AtomicInt;
75 #else
76 typedef int AtomicInt;
77 #endif
78 
79 inline AtomicInt AtomicIncrement(AtomicInt &value)
80 {
81 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
82  return __exchange_and_add(&value, 1) + 1;
83 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
84  return __gnu_cxx::__exchange_and_add(&value, 1) + 1;
85 #else
86  return __sync_add_and_fetch(&value, 1);
87 #endif
88 }
89 
90 inline AtomicInt AtomicDecrement(AtomicInt &value)
91 {
92 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
93  return __exchange_and_add(&value, -1) - 1;
94 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
95  return __gnu_cxx::__exchange_and_add(&value, -1) - 1;
96 #else
97  return __sync_sub_and_fetch(&value, 1);
98 #endif
99 }
100 
101 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
102 {
103 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
104  // BUG: Old versions of GCC don't have a CAS
105  if(value == oldValue)
106  {
107  value = newValue;
108  return true;
109  }
110  else
111  return false;
112 #else
113  return __sync_bool_compare_and_swap(&value, oldValue, newValue);
114 #endif
115 }
116 
117 #else
118 #error
119 #endif
120 
121 LT_END_LIDAR_NAMESPACE
122 #endif // __LIDAR_ATOMIC_H__

LizardTech