diff --git a/include/boost/detail/spinlock_pool.hpp b/include/boost/detail/spinlock_pool.hpp new file mode 100644 index 0000000..b50ccb5 --- /dev/null +++ b/include/boost/detail/spinlock_pool.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED +#define BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/spinlock_pool.hpp +// +// 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) +// +// spinlock_pool<0> is reserved for atomic<>, when/if it arrives +// spinlock_pool<1> is reserved for shared_ptr reference counts +// spinlock_pool<2> is reserved for shared_ptr atomic access +// + +#include + +namespace boost +{ + +namespace detail +{ + +template< int I > class spinlock_pool +{ +private: + + static spinlock pool_[ 41 ]; + +public: + + static spinlock & spinlock_for( void * pv ) + { + size_t i = reinterpret_cast< size_t >( pv ) % 41; + return pool_[ i ]; + } + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( void * pv ): sp_( spinlock_for( pv ) ) + { + sp_.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] = +{ + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT +}; + +} // namespace detail +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5c0a459..0ccc984 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -42,5 +42,6 @@ import testing ; [ run spinlock_test.cpp ] [ run spinlock_try_test.cpp ] [ run spinlock_try_test.cpp : : : multi : spinlock_try_test.mt ] + [ run spinlock_pool_test.cpp ] ; } diff --git a/test/spinlock_pool_test.cpp b/test/spinlock_pool_test.cpp new file mode 100644 index 0000000..00e7558 --- /dev/null +++ b/test/spinlock_pool_test.cpp @@ -0,0 +1,30 @@ +// +// spinlock_pool_test.cpp +// +// Copyright 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 + +// Sanity check only + +int main() +{ + int x = 0; + + { + boost::detail::spinlock_pool<0>::scoped_lock lock( &x ); + ++x; + } + + { + boost::detail::spinlock_pool<1>::scoped_lock lock( &x ); + boost::detail::spinlock_pool<2>::scoped_lock lock2( &x ); + } + + return 0; +}