1 //---------------------------------------------------------------------------- 2 /// @file spinlock_t.hpp 3 /// @brief 4 /// 5 /// @author Copyright (c) 2010 2015 Francisco José Tapia (fjtapia@gmail.com )\n 6 /// Distributed under the Boost Software License, Version 1.0.\n 7 /// ( See accompanyingfile LICENSE_1_0.txt or copy at 8 /// http://www.boost.org/LICENSE_1_0.txt ) 9 /// @version 0.1 10 /// 11 /// @remarks 12 //----------------------------------------------------------------------------- 13 #ifndef __BOOST_SORT_PARALLEL_DETAIL_UTIL_SPINLOCK_HPP 14 #define __BOOST_SORT_PARALLEL_DETAIL_UTIL_SPINLOCK_HPP 15 16 #include <atomic> 17 #include <ctime> 18 #include <functional> 19 #include <memory> 20 #include <mutex> 21 #include <thread> 22 23 namespace boost 24 { 25 namespace sort 26 { 27 namespace common 28 { 29 // 30 //--------------------------------------------------------------------------- 31 /// @class spinlock_t 32 /// @brief This class implement, from atomic variables, a spinlock 33 /// @remarks This class meet the BasicLockable requirements ( lock, unlock ) 34 //--------------------------------------------------------------------------- 35 class spinlock_t 36 { 37 private: 38 //------------------------------------------------------------------------ 39 // P R I V A T E V A R I A B L E S 40 //------------------------------------------------------------------------ 41 std::atomic_flag af; 42 43 public: 44 // 45 //------------------------------------------------------------------------- 46 // function : spinlock_t 47 /// @brief class constructor 48 /// @param [in] 49 //------------------------------------------------------------------------- spinlock_t()50 explicit spinlock_t ( ) noexcept { af.clear ( ); }; 51 // 52 //------------------------------------------------------------------------- 53 // function : lock 54 /// @brief Lock the spinlock_t 55 //------------------------------------------------------------------------- lock()56 void lock ( ) noexcept 57 { 58 while (af.test_and_set (std::memory_order_acquire)) 59 { 60 std::this_thread::yield ( ); 61 }; 62 }; 63 // 64 //------------------------------------------------------------------------- 65 // function : try_lock 66 /// @brief Try to lock the spinlock_t, if not, return false 67 /// @return true : locked 68 /// false: not previous locked 69 //------------------------------------------------------------------------- try_lock()70 bool try_lock ( ) noexcept 71 { 72 return not af.test_and_set (std::memory_order_acquire); 73 }; 74 // 75 //------------------------------------------------------------------------- 76 // function : unlock 77 /// @brief unlock the spinlock_t 78 //------------------------------------------------------------------------- unlock()79 void unlock ( ) noexcept { af.clear (std::memory_order_release); }; 80 81 }; // E N D C L A S S S P I N L O C K 82 // 83 //*************************************************************************** 84 }; // end namespace common 85 }; // end namespace sort 86 }; // end namespace boost 87 //*************************************************************************** 88 #endif 89