1 //////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2011 Bryce Lelbach 3 // Copyright (c) 2011-2012 Hartmut Kaiser 4 // Copyright (c) 2008 Peter Dimov 5 // 6 // Distributed under the Boost Software License, Version 1.0. (See accompanying 7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 //////////////////////////////////////////////////////////////////////////////// 9 10 #if !defined(HPX_LCOS_LOCAL_SPINLOCK_NO_BACKOFF) 11 #define HPX_LCOS_LOCAL_SPINLOCK_NO_BACKOFF 12 13 #include <hpx/config.hpp> 14 #include <hpx/runtime/threads/thread_helpers.hpp> 15 #include <hpx/util/itt_notify.hpp> 16 #include <hpx/util/register_locks.hpp> 17 18 #if defined(HPX_WINDOWS) 19 # include <boost/smart_ptr/detail/spinlock.hpp> 20 # if !defined( BOOST_SP_HAS_SYNC ) 21 # include <hpx/config/compiler_fence.hpp> 22 # include <boost/detail/interlocked.hpp> 23 # endif 24 #else 25 # if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__arm__) 26 # include <boost/smart_ptr/detail/spinlock.hpp> 27 # if defined( __ia64__ ) && defined( __INTEL_COMPILER ) 28 # include <ia64intrin.h> 29 # endif 30 # endif 31 #endif 32 33 #include <cstddef> 34 #include <cstdint> 35 36 /////////////////////////////////////////////////////////////////////////////// 37 namespace hpx { namespace lcos { namespace local 38 { 39 /// boost::mutex-compatible spinlock class 40 struct spinlock_no_backoff 41 { 42 public: 43 HPX_NON_COPYABLE(spinlock_no_backoff); 44 45 private: 46 std::uint64_t v_; 47 48 public: spinlock_no_backoffhpx::lcos::local::spinlock_no_backoff49 spinlock_no_backoff() : v_(0) 50 { 51 HPX_ITT_SYNC_CREATE(this, "hpx::lcos::local::spinlock_no_backoff", ""); 52 } 53 ~spinlock_no_backoffhpx::lcos::local::spinlock_no_backoff54 ~spinlock_no_backoff() 55 { 56 HPX_ITT_SYNC_DESTROY(this); 57 } 58 lockhpx::lcos::local::spinlock_no_backoff59 void lock() 60 { 61 HPX_ITT_SYNC_PREPARE(this); 62 63 for (std::size_t k = 0; !try_lock(); ++k) 64 { 65 } 66 67 HPX_ITT_SYNC_ACQUIRED(this); 68 util::register_lock(this); 69 } 70 try_lockhpx::lcos::local::spinlock_no_backoff71 bool try_lock() 72 { 73 HPX_ITT_SYNC_PREPARE(this); 74 75 #if !defined( BOOST_SP_HAS_SYNC ) 76 std::uint64_t r = BOOST_INTERLOCKED_EXCHANGE(&v_, 1); 77 HPX_COMPILER_FENCE; 78 #else 79 std::uint64_t r = __sync_lock_test_and_set(&v_, 1); 80 #endif 81 82 if (r == 0) { 83 HPX_ITT_SYNC_ACQUIRED(this); 84 util::register_lock(this); 85 return true; 86 } 87 88 HPX_ITT_SYNC_CANCEL(this); 89 return false; 90 } 91 unlockhpx::lcos::local::spinlock_no_backoff92 void unlock() 93 { 94 HPX_ITT_SYNC_RELEASING(this); 95 96 #if !defined( BOOST_SP_HAS_SYNC ) 97 HPX_COMPILER_FENCE; 98 *const_cast<std::uint64_t volatile*>(&v_) = 0; 99 #else 100 __sync_lock_release(&v_); 101 #endif 102 103 HPX_ITT_SYNC_RELEASED(this); 104 util::unregister_lock(this); 105 } 106 }; 107 }}} 108 109 #endif // HPX_B3A83B49_92E0_4150_A551_488F9F5E1113 110