MrSID Decode SDK for LiDAR Reference Manual  1.1.4.4709
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 __GNUG__
00021 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00022 #include <bits/atomicity.h>
00023 #endif
00024 #else
00025 #error unknown platform
00026 #endif
00027 
00028 LT_BEGIN_LIDAR_NAMESPACE
00029 
00030 #if defined _WIN32
00031 
00032 typedef LONG AtomicInt;
00033 
00034 inline AtomicInt AtomicIncrement(AtomicInt &value)
00035 {
00036    return ::InterlockedIncrement(&value);
00037 }
00038 
00039 inline AtomicInt AtomicDecrement(AtomicInt &value)
00040 {
00041    return ::InterlockedDecrement(&value);
00042 }
00043 
00044 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00045 {
00046    return InterlockedCompareExchangePointer(reinterpret_cast<void **>(&value), newValue, oldValue) == oldValue;
00047 }
00048 
00049 #elif defined __GNUG__
00050 
00051 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00052 typedef _Atomic_word AtomicInt;
00053 #else
00054 typedef int AtomicInt;
00055 #endif
00056 
00057 inline AtomicInt AtomicIncrement(AtomicInt &value)
00058 {
00059 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00060    return __exchange_and_add(&value, 1) + 1;
00061 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00062    return __gnu_cxx::__exchange_and_add(&value, 1) + 1;
00063 #else
00064    return __sync_add_and_fetch(&value, 1);
00065 #endif
00066 }
00067 
00068 inline AtomicInt AtomicDecrement(AtomicInt &value)
00069 {
00070 #if __GNUC__ * 10 + __GNUC_MINOR__ < 34
00071    return __exchange_and_add(&value, -1) - 1;
00072 #elif __GNUC__ * 10 + __GNUC_MINOR__ < 42
00073    return __gnu_cxx::__exchange_and_add(&value, -1) - 1;
00074 #else
00075    return __sync_sub_and_fetch(&value, 1);
00076 #endif
00077 }
00078 
00079 template<typename TYPE> bool AtomicCompareAndSwap(TYPE *&value, TYPE *oldValue, TYPE *newValue)
00080 {
00081 #if __GNUC__ * 10 + __GNUC_MINOR__ < 42
00082    // BUG: Old versions of GCC don't have a CAS
00083    if(value == oldValue)
00084    {
00085       value = newValue;
00086       return true;
00087    }
00088    else
00089       return false;
00090 #else
00091    return __sync_bool_compare_and_swap(&value, oldValue, newValue);
00092 #endif
00093 }
00094 
00095 #else
00096 #error 
00097 #endif
00098 
00099 LT_END_LIDAR_NAMESPACE
00100 #endif // __LIDAR_ATOMIC_H__