1 // (C) Copyright 2008 Anthony Williams 2 // Copyright (c) 2015 Hartmut Kaiser 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See 5 // accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 8 #if !defined(HPX_TEST_SHARED_MUTEX_LOCKING_THREAD_AUG_03_2015_0927PM) 9 #define HPX_TEST_SHARED_MUTEX_LOCKING_THREAD_AUG_03_2015_0927PM 10 11 #include <hpx/config.hpp> 12 #include <hpx/lcos/local/mutex.hpp> 13 #include <hpx/lcos/local/condition_variable.hpp> 14 #include <hpx/lcos/local/shared_mutex.hpp> 15 16 #include <boost/thread/locks.hpp> 17 18 #include <mutex> 19 20 namespace test 21 { 22 template <typename Lock> 23 class locking_thread 24 { 25 private: 26 hpx::lcos::local::shared_mutex& rw_mutex; 27 unsigned& unblocked_count; 28 hpx::lcos::local::condition_variable& unblocked_condition; 29 unsigned& simultaneous_running_count; 30 unsigned& max_simultaneous_running; 31 hpx::lcos::local::mutex& unblocked_count_mutex; 32 hpx::lcos::local::mutex& finish_mutex; 33 34 public: locking_thread(hpx::lcos::local::shared_mutex & rw_mutex_,unsigned & unblocked_count_,hpx::lcos::local::mutex & unblocked_count_mutex_,hpx::lcos::local::condition_variable & unblocked_condition_,hpx::lcos::local::mutex & finish_mutex_,unsigned & simultaneous_running_count_,unsigned & max_simultaneous_running_)35 locking_thread( 36 hpx::lcos::local::shared_mutex& rw_mutex_, 37 unsigned& unblocked_count_, 38 hpx::lcos::local::mutex& unblocked_count_mutex_, 39 hpx::lcos::local::condition_variable& unblocked_condition_, 40 hpx::lcos::local::mutex& finish_mutex_, 41 unsigned& simultaneous_running_count_, 42 unsigned& max_simultaneous_running_) 43 : rw_mutex(rw_mutex_), 44 unblocked_count(unblocked_count_), 45 unblocked_condition(unblocked_condition_), 46 simultaneous_running_count(simultaneous_running_count_), 47 max_simultaneous_running(max_simultaneous_running_), 48 unblocked_count_mutex(unblocked_count_mutex_), 49 finish_mutex(finish_mutex_) 50 {} 51 operator ()()52 void operator()() 53 { 54 // acquire lock 55 Lock lock(rw_mutex); 56 57 // increment count to show we're unblocked 58 { 59 std::unique_lock<hpx::lcos::local::mutex> ublock( 60 unblocked_count_mutex); 61 62 ++unblocked_count; 63 unblocked_condition.notify_one(); 64 ++simultaneous_running_count; 65 if (simultaneous_running_count > max_simultaneous_running) 66 { 67 max_simultaneous_running = simultaneous_running_count; 68 } 69 } 70 71 // wait to finish 72 std::unique_lock<hpx::lcos::local::mutex> finish_lock(finish_mutex); 73 { 74 std::unique_lock<hpx::lcos::local::mutex> ublock( 75 unblocked_count_mutex); 76 77 --simultaneous_running_count; 78 } 79 } 80 }; 81 82 /////////////////////////////////////////////////////////////////////////// 83 class simple_writing_thread 84 { 85 private: 86 hpx::lcos::local::shared_mutex& rwm; 87 hpx::lcos::local::mutex& finish_mutex; 88 hpx::lcos::local::mutex& unblocked_mutex; 89 unsigned& unblocked_count; 90 91 public: simple_writing_thread(hpx::lcos::local::shared_mutex & rwm_,hpx::lcos::local::mutex & finish_mutex_,hpx::lcos::local::mutex & unblocked_mutex_,unsigned & unblocked_count_)92 simple_writing_thread( 93 hpx::lcos::local::shared_mutex& rwm_, 94 hpx::lcos::local::mutex& finish_mutex_, 95 hpx::lcos::local::mutex& unblocked_mutex_, 96 unsigned& unblocked_count_) 97 : rwm(rwm_), 98 finish_mutex(finish_mutex_), 99 unblocked_mutex(unblocked_mutex_), 100 unblocked_count(unblocked_count_) 101 {} 102 operator ()()103 void operator()() 104 { 105 std::unique_lock<hpx::lcos::local::shared_mutex> lk(rwm); 106 { 107 std::unique_lock<hpx::lcos::local::mutex> ulk(unblocked_mutex); 108 ++unblocked_count; 109 } 110 std::unique_lock<hpx::lcos::local::mutex> flk(finish_mutex); 111 } 112 }; 113 114 /////////////////////////////////////////////////////////////////////////// 115 class simple_reading_thread 116 { 117 private: 118 hpx::lcos::local::shared_mutex& rwm; 119 hpx::lcos::local::mutex& finish_mutex; 120 hpx::lcos::local::mutex& unblocked_mutex; 121 unsigned& unblocked_count; 122 123 public: simple_reading_thread(hpx::lcos::local::shared_mutex & rwm_,hpx::lcos::local::mutex & finish_mutex_,hpx::lcos::local::mutex & unblocked_mutex_,unsigned & unblocked_count_)124 simple_reading_thread( 125 hpx::lcos::local::shared_mutex& rwm_, 126 hpx::lcos::local::mutex& finish_mutex_, 127 hpx::lcos::local::mutex& unblocked_mutex_, 128 unsigned& unblocked_count_) 129 : rwm(rwm_), 130 finish_mutex(finish_mutex_), 131 unblocked_mutex(unblocked_mutex_), 132 unblocked_count(unblocked_count_) 133 {} 134 operator ()()135 void operator()() 136 { 137 boost::shared_lock<hpx::lcos::local::shared_mutex> lk(rwm); 138 { 139 std::unique_lock<hpx::lcos::local::mutex> ulk(unblocked_mutex); 140 ++unblocked_count; 141 } 142 std::unique_lock<hpx::lcos::local::mutex> flk(finish_mutex); 143 } 144 }; 145 146 /////////////////////////////////////////////////////////////////////////// 147 class simple_upgrade_thread 148 { 149 private: 150 hpx::lcos::local::shared_mutex& rwm; 151 hpx::lcos::local::mutex& finish_mutex; 152 hpx::lcos::local::mutex& unblocked_mutex; 153 unsigned& unblocked_count; 154 155 public: simple_upgrade_thread(hpx::lcos::local::shared_mutex & rwm_,hpx::lcos::local::mutex & finish_mutex_,hpx::lcos::local::mutex & unblocked_mutex_,unsigned & unblocked_count_)156 simple_upgrade_thread( 157 hpx::lcos::local::shared_mutex& rwm_, 158 hpx::lcos::local::mutex& finish_mutex_, 159 hpx::lcos::local::mutex& unblocked_mutex_, 160 unsigned& unblocked_count_) 161 : rwm(rwm_), 162 finish_mutex(finish_mutex_), 163 unblocked_mutex(unblocked_mutex_), 164 unblocked_count(unblocked_count_) 165 {} 166 operator ()()167 void operator()() 168 { 169 boost::upgrade_lock<hpx::lcos::local::shared_mutex> lk(rwm); 170 { 171 std::unique_lock<hpx::lcos::local::mutex> ulk(unblocked_mutex); 172 ++unblocked_count; 173 } 174 std::unique_lock<hpx::lcos::local::mutex> flk(finish_mutex); 175 } 176 }; 177 } 178 179 #endif 180