diff --git a/include/boost/smart_ptr/detail/interlocked.hpp b/include/boost/smart_ptr/detail/interlocked.hpp deleted file mode 100644 index 1152f71..0000000 --- a/include/boost/smart_ptr/detail/interlocked.hpp +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED -#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED - -// -// boost/detail/interlocked.hpp -// -// Copyright 2005 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// - -#include - -// MS compatible compilers support #pragma once -#ifdef BOOST_HAS_PRAGMA_ONCE -#pragma once -#endif - -#if defined( BOOST_USE_WINDOWS_H ) - -# include - -# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer - -#elif defined( BOOST_USE_INTRIN_H ) - -#include - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd - -# if defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__x86_64) - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer - -# else - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) - -# endif - -#elif defined(_WIN32_WCE) - -#if _WIN32_WCE >= 0x600 - -extern "C" long __cdecl _InterlockedIncrement( long volatile * ); -extern "C" long __cdecl _InterlockedDecrement( long volatile * ); -extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); -extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd - -#else -// under Windows CE we still have old-style Interlocked* functions - -extern "C" long __cdecl InterlockedIncrement( long* ); -extern "C" long __cdecl InterlockedDecrement( long* ); -extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); -extern "C" long __cdecl InterlockedExchange( long*, long ); -extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); - -# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd - -#endif - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long*)(dest),(long)(exchange))) - -#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) - -#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1500 - -#include - -#elif defined( __CLRCALL_PURE_OR_CDECL ) - -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); - -#else - -extern "C" long __cdecl _InterlockedIncrement( long volatile * ); -extern "C" long __cdecl _InterlockedDecrement( long volatile * ); -extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); -extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); - -#endif - -# if defined(_M_IA64) || defined(_M_AMD64) - -extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); -extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer - -# else - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) - -# endif - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd - -// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. -#elif defined(__MINGW64_VERSION_MAJOR) - -// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. -#include - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd -# if defined(__x86_64__) || defined(__x86_64) -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer -# else -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) -# endif - -#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport) - -namespace boost -{ - -namespace detail -{ - -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedIncrement( long volatile * ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedDecrement( long volatile * ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange( long volatile *, long, long ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchange( long volatile *, long ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd( long volatile *, long ); - -# if defined(_M_IA64) || defined(_M_AMD64) -extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); -extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); -# endif - -} // namespace detail - -} // namespace boost - -# define BOOST_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd - -# if defined(_M_IA64) || defined(_M_AMD64) -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::boost::detail::InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER ::boost::detail::InterlockedExchangePointer -# else -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) -# endif - -#else - -# error "Interlocked intrinsics not available" - -#endif - -#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_interlocked.hpp b/include/boost/smart_ptr/detail/sp_interlocked.hpp new file mode 100644 index 0000000..814b0c2 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_interlocked.hpp @@ -0,0 +1,152 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/sp_interlocked.hpp +// +// Copyright 2005, 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +// BOOST_SP_HAS_INTRIN_H + +// VC9 has intrin.h, but it collides with +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 + +# define BOOST_SP_HAS_INTRIN_H + +// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. +#elif defined( __MINGW64_VERSION_MAJOR ) + +// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. +# define BOOST_SP_HAS_INTRIN_H + +// Intel C++ on Windows on VC10+ stdlib +#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520 + +# define BOOST_SP_HAS_INTRIN_H + +#endif + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H ) + +#include + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( _WIN32_WCE ) + +#if _WIN32_WCE >= 0x600 + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#else + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); + +# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +#endif + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +#if defined( __CLRCALL_PURE_OR_CDECL ) + +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); + +#else + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +#endif + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +namespace boost +{ + +namespace detail +{ + +extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); + +} // namespace detail + +} // namespace boost + +# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fc95688..19520c2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -83,6 +83,7 @@ import testing ; [ run shared_ptr_alloc11_test.cpp ] [ run allocate_shared_alloc11_test.cpp ] [ run allocate_shared_construct11_test.cpp ] + [ run sp_interlocked_test.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ] diff --git a/test/sp_interlocked_test.cpp b/test/sp_interlocked_test.cpp new file mode 100644 index 0000000..d02bac7 --- /dev/null +++ b/test/sp_interlocked_test.cpp @@ -0,0 +1,60 @@ +// +// sp_interlocked_test.cpp +// +// Copyright 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +int main() +{ + long x = 0, r; + + r = BOOST_SP_INTERLOCKED_INCREMENT( &x ); + + BOOST_TEST( x == 1 ); + BOOST_TEST( r == 1 ); + + r = BOOST_SP_INTERLOCKED_DECREMENT( &x ); + + BOOST_TEST( x == 0 ); + BOOST_TEST( r == 0 ); + + r = BOOST_SP_INTERLOCKED_EXCHANGE( &x, 3 ); + + BOOST_TEST( x == 3 ); + BOOST_TEST( r == 0 ); + + r = BOOST_SP_INTERLOCKED_EXCHANGE_ADD( &x, 2 ); + + BOOST_TEST( x == 5 ); + BOOST_TEST( r == 3 ); + + r = BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &x, 0, 3 ); + + BOOST_TEST( x == 5 ); + BOOST_TEST( r == 5 ); + + r = BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &x, 0, 5 ); + + BOOST_TEST( x == 0 ); + BOOST_TEST( r == 5 ); + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} + +#endif