libqi
1.14.5
|
00001 /* 00002 * Copyright (c) 2012 Aldebaran Robotics. All rights reserved. 00003 * Use of this source code is governed by a BSD-style license that can be 00004 * found in the COPYING file. 00005 */ 00006 00007 #pragma once 00008 00009 #ifndef _LIBQI_QI_ATOMIC_HPP_ 00010 #define _LIBQI_QI_ATOMIC_HPP_ 00011 00012 #ifdef _MSC_VER 00013 # include <windows.h> 00014 # pragma intrinsic(_InterlockedIncrement16) 00015 # pragma intrinsic(_InterlockedDecrement16) 00016 # pragma intrinsic(_InterlockedIncrement) 00017 # pragma intrinsic(_InterlockedDecrement) 00018 00019 extern "C" long __cdecl _InterlockedIncrement(long volatile *); 00020 extern "C" long __cdecl _InterlockedDecrement(long volatile *); 00021 extern "C" short __cdecl _InterlockedIncrement16(short volatile *); 00022 extern "C" short __cdecl _InterlockedDecrement16(short volatile *); 00023 #endif 00024 00025 #include <qi/config.hpp> 00026 00027 namespace qi 00028 { 00029 template <typename T> 00030 class QI_API atomic 00031 { 00032 public: 00033 atomic() 00034 : _value(0) 00035 { 00036 } 00037 00038 atomic(T value) 00039 : _value(value) 00040 { 00041 } 00042 00043 /* prefix operators */ 00044 T operator++(); 00045 T operator--(); 00046 00047 T operator*() 00048 { 00049 return _value; 00050 } 00051 00052 private: 00053 T _value; 00054 }; 00055 00056 #ifdef __GNUC__ 00057 template <typename T> 00058 T atomic<T>::operator++() 00059 { 00060 return __sync_add_and_fetch(&_value, 1); 00061 } 00062 00063 template <typename T> 00064 T atomic<T>::operator--() 00065 { 00066 return __sync_sub_and_fetch(&_value, 1); 00067 } 00068 #endif 00069 00070 #ifdef _MSC_VER 00071 template<> 00072 inline short atomic<short>::operator++() 00073 { 00074 return _InterlockedIncrement16(&_value); 00075 } 00076 00077 template<> 00078 inline short atomic<short>::operator--() 00079 { 00080 return _InterlockedDecrement16(&_value); 00081 } 00082 00083 template <> 00084 inline long atomic<long>::operator++() 00085 { 00086 return _InterlockedIncrement(&_value); 00087 } 00088 00089 template <> 00090 inline long atomic<long>::operator--() 00091 { 00092 return _InterlockedDecrement(&_value); 00093 } 00094 #endif 00095 } 00096 00097 #endif // _LIBQI_QI_ATOMIC_HPP_