diff options
Diffstat (limited to 'boost/smart_ptr')
-rw-r--r-- | boost/smart_ptr/detail/sp_counted_base.hpp | 6 | ||||
-rw-r--r-- | boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp | 150 | ||||
-rw-r--r-- | boost/smart_ptr/detail/spinlock_gcc_arm.hpp | 29 |
3 files changed, 180 insertions, 5 deletions
diff --git a/boost/smart_ptr/detail/sp_counted_base.hpp b/boost/smart_ptr/detail/sp_counted_base.hpp index 8401bfecbc..24adfcc225 100644 --- a/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/boost/smart_ptr/detail/sp_counted_base.hpp @@ -41,6 +41,9 @@ #elif defined(__HP_aCC) && defined(__ia64) # include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp> +#elif defined( __IBMCPP__ ) && defined( __powerpc ) +# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp> + #elif defined( __MWERKS__ ) && defined( __POWERPC__ ) # include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp> @@ -59,9 +62,6 @@ #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) # include <boost/smart_ptr/detail/sp_counted_base_w32.hpp> -#elif defined( _AIX ) -# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp> - #elif !defined( BOOST_HAS_THREADS ) # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> diff --git a/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp new file mode 100644 index 0000000000..842f58f17e --- /dev/null +++ b/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -0,0 +1,150 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED + +// +// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER +// based on: detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2006 Michael van der Westhuizen +// Copyright 2012 IBM Corp. +// +// 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) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include <boost/detail/sp_typeinfo.hpp> + +extern "builtin" void __lwsync(void); +extern "builtin" void __isync(void); +extern "builtin" int __fetch_and_add(volatile int* addr, int val); +extern "builtin" int __compare_and_swap(volatile int*, int*, int); + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int *pw ) +{ + // ++*pw; + __lwsync(); + __fetch_and_add(pw, 1); + __isync(); +} + +inline int atomic_decrement( int *pw ) +{ + // return --*pw; + __lwsync(); + int originalValue = __fetch_and_add(pw, -1); + __isync(); + + return (originalValue - 1); +} + +inline int atomic_conditional_increment( int *pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + __lwsync(); + int v = *const_cast<volatile int*>(pw); + for (;;) + // loop until state is known + { + if (v == 0) return 0; + if (__compare_and_swap(pw, &v, v + 1)) + { + __isync(); return (v + 1); + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + char pad[64] __attribute__((__aligned__(64))); + // pad to prevent false sharing +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return *const_cast<volatile int*>(&use_count_); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED diff --git a/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/boost/smart_ptr/detail/spinlock_gcc_arm.hpp index f58ea44168..f1bbaf66c6 100644 --- a/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +++ b/boost/smart_ptr/detail/spinlock_gcc_arm.hpp @@ -43,13 +43,38 @@ public: { int r; +#if defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) + + __asm__ __volatile__( + "ldrex %0, [%2]; \n" + "cmp %0, %1; \n" + "strexne %0, %1, [%2]; \n" + BOOST_SP_ARM_BARRIER : + "=&r"( r ): // outputs + "r"( 1 ), "r"( &v_ ): // inputs + "memory", "cc" ); + +#else + __asm__ __volatile__( - "swp %0, %1, [%2]\n\t" - BOOST_SP_ARM_BARRIER : + "swp %0, %1, [%2];\n" + BOOST_SP_ARM_BARRIER : "=&r"( r ): // outputs "r"( 1 ), "r"( &v_ ): // inputs "memory", "cc" ); +#endif + return r == 0; } |