diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 1466dd1..26e1b08 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -28,21 +28,19 @@ // #define BOOST_DETAIL_SPINLOCK_INIT // -#include +#include #include +#include #if defined( BOOST_SP_USE_STD_ATOMIC ) -# if !defined( __clang__ ) -# include -# else -// Clang (at least up to 3.4) can't compile spinlock_pool when -// using std::atomic, so substitute the __sync implementation instead. -# include -# endif +# include #elif defined( BOOST_SP_USE_PTHREADS ) # include +#elif defined( BOOST_SP_HAS_GCC_INTRINSICS ) +# include + #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) # include diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp new file mode 100644 index 0000000..c899a59 --- /dev/null +++ b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp @@ -0,0 +1,90 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 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 + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + +#include +BOOST_PRAGMA_MESSAGE("Using __atomic spinlock") + +#endif + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + unsigned char v_; + +public: + + bool try_lock() + { + int r = __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ); + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + __atomic_clear( &v_, __ATOMIC_RELEASE ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED