MrSID Decode SDK for LiDAR Reference Manual  1.1.4.4709
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 __GNUG__
21 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
22 #include <bits/atomicity.h>
23 #endif
24 #else
25 #error unknown platform
26 #endif
27 
28 LT_BEGIN_LIDAR_NAMESPACE
29 
30 #if defined _WIN32
31 
32 typedef LONG AtomicInt;
33 
34 inline AtomicInt AtomicIncrement(AtomicInt &value)
35 {
36  return ::InterlockedIncrement(&value);
37 }
38 
39 inline AtomicInt AtomicDecrement(AtomicInt &value)
40 {
41  return ::InterlockedDecrement(&value);
42 }
43 
44 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
45 {
46  return InterlockedCompareExchangePointer(reinterpret_cast<void **>(&value), newValue, oldValue) == oldValue;
47 }
48 
49 #elif defined __GNUG__
50 
51 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
52 typedef _Atomic_word AtomicInt;
53 #else
54 typedef int AtomicInt;
55 #endif
56 
57 inline AtomicInt AtomicIncrement(AtomicInt &value)
58 {
59 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
60  return __exchange_and_add(&value, 1) + 1;
61 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
62  return __gnu_cxx::__exchange_and_add(&value, 1) + 1;
63 #else
64  return __sync_add_and_fetch(&value, 1);
65 #endif
66 }
67 
68 inline AtomicInt AtomicDecrement(AtomicInt &value)
69 {
70 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
71  return __exchange_and_add(&value, -1) - 1;
72 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
73  return __gnu_cxx::__exchange_and_add(&value, -1) - 1;
74 #else
75  return __sync_sub_and_fetch(&value, 1);
76 #endif
77 }
78 
79 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
80 {
81 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
82  // BUG: Old versions of GCC don't have a CAS
83  if(value == oldValue)
84  {
85  value = newValue;
86  return true;
87  }
88  else
89  return false;
90 #else
91  return __sync_bool_compare_and_swap(&value, oldValue, newValue);
92 #endif
93 }
94 
95 #else
96 #error
97 #endif
98 
99 LT_END_LIDAR_NAMESPACE
100 #endif // __LIDAR_ATOMIC_H__

LizardTech