MrSID Decode SDK for LiDAR Reference Manual  1.1.3.4427
Atomic.h
Go to the documentation of this file.
00001 /* //////////////////////////////////////////////////////////////////////////
00002 //                                                                         //
00003 // This code is Copyright (c) 2008-2010 LizardTech, Inc, 1008 Western      //
00004 // Avenue, Suite 200, Seattle, WA 98104.  Unauthorized use or distribution //
00005 // prohibited.  Access to and use of this code is permitted only under     //
00006 // license from LizardTech, Inc.  Portions of the code are protected by    //
00007 // US and foreign patents and other filings. All Rights Reserved.          //
00008 //                                                                         //
00010 /* PUBLIC */
00011 
00012 #ifndef __LIDAR_ATOMIC_H__
00013 #define __LIDAR_ATOMIC_H__
00014 
00015 #include "lidar/Base.h"
00016 
00017 #if defined _WIN32
00018 #define NOMINMAX
00019 #include <windows.h>
00020 #elif defined __APPLE__
00021 #include <libkern/OSAtomic.h>
00022 #elif defined __GNUG__
00023 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00024 #include <bits/atomicity.h>
00025 #endif
00026 #else
00027 #error unknown platform
00028 #endif
00029 
00030 LT_BEGIN_LIDAR_NAMESPACE
00031 
00032 #if defined _WIN32
00033 
00034 typedef LONG AtomicInt;
00035 
00036 inline AtomicInt AtomicIncrement(AtomicInt &value)
00037 {
00038    return ::InterlockedIncrement(&value);
00039 }
00040 
00041 inline AtomicInt AtomicDecrement(AtomicInt &value)
00042 {
00043    return ::InterlockedDecrement(&value);
00044 }
00045 
00046 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00047 {
00048    return InterlockedCompareExchangePointer(reinterpret_cast<void **>(&value), newValue, oldValue) == oldValue;
00049 }
00050 
00051 #elif defined __APPLE__
00052 
00053 typedef int32_t AtomicInt;
00054 
00055 inline AtomicInt AtomicIncrement(AtomicInt &value)
00056 {
00057    return OSAtomicIncrement32Barrier(&value);
00058 }
00059 
00060 inline AtomicInt AtomicDecrement(AtomicInt &value)
00061 {
00062    return OSAtomicDecrement32Barrier(&value);
00063 }
00064 
00065 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00066 {
00067    return ::OSAtomicCompareAndSwapPtrBarrier(oldValue, newValue, reinterpret_cast<void **>(&value));
00068 }
00069 
00070 
00071 #elif defined __GNUG__
00072 
00073 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00074 typedef _Atomic_word AtomicInt;
00075 #else
00076 typedef int AtomicInt;
00077 #endif
00078 
00079 inline AtomicInt AtomicIncrement(AtomicInt &value)
00080 {
00081 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00082    return __exchange_and_add(&value, 1) + 1;
00083 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00084    return __gnu_cxx::__exchange_and_add(&value, 1) + 1;
00085 #else
00086    return __sync_add_and_fetch(&value, 1);
00087 #endif
00088 }
00089 
00090 inline AtomicInt AtomicDecrement(AtomicInt &value)
00091 {
00092 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00093    return __exchange_and_add(&value, -1) - 1;
00094 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00095    return __gnu_cxx::__exchange_and_add(&value, -1) - 1;
00096 #else
00097    return __sync_sub_and_fetch(&value, 1);
00098 #endif
00099 }
00100 
00101 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00102 {
00103 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00104    // BUG: Old versions of GCC don't have a CAS
00105    if(value == oldValue)
00106    {
00107       value = newValue;
00108       return true;
00109    }
00110    else
00111       return false;
00112 #else
00113    return __sync_bool_compare_and_swap(&value, oldValue, newValue);
00114 #endif
00115 }
00116 
00117 #else
00118 #error 
00119 #endif
00120 
00121 LT_END_LIDAR_NAMESPACE
00122 #endif // __LIDAR_ATOMIC_H__