1 //===---------------------- shared_mutex.cpp ------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #define _LIBCPP_BUILDING_SHARED_MUTEX 11 #include "shared_mutex" 12 13 #if !_LIBCPP_SINGLE_THREADED 14 15 _LIBCPP_BEGIN_NAMESPACE_STD 16 shared_timed_mutex()17shared_timed_mutex::shared_timed_mutex() 18 : __state_(0) 19 { 20 } 21 22 // Exclusive ownership 23 24 void lock()25shared_timed_mutex::lock() 26 { 27 unique_lock<mutex> lk(__mut_); 28 while (__state_ & __write_entered_) 29 __gate1_.wait(lk); 30 __state_ |= __write_entered_; 31 while (__state_ & __n_readers_) 32 __gate2_.wait(lk); 33 } 34 35 bool try_lock()36shared_timed_mutex::try_lock() 37 { 38 unique_lock<mutex> lk(__mut_); 39 if (__state_ == 0) 40 { 41 __state_ = __write_entered_; 42 return true; 43 } 44 return false; 45 } 46 47 void unlock()48shared_timed_mutex::unlock() 49 { 50 lock_guard<mutex> _(__mut_); 51 __state_ = 0; 52 __gate1_.notify_all(); 53 } 54 55 // Shared ownership 56 57 void lock_shared()58shared_timed_mutex::lock_shared() 59 { 60 unique_lock<mutex> lk(__mut_); 61 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) 62 __gate1_.wait(lk); 63 unsigned num_readers = (__state_ & __n_readers_) + 1; 64 __state_ &= ~__n_readers_; 65 __state_ |= num_readers; 66 } 67 68 bool try_lock_shared()69shared_timed_mutex::try_lock_shared() 70 { 71 unique_lock<mutex> lk(__mut_); 72 unsigned num_readers = __state_ & __n_readers_; 73 if (!(__state_ & __write_entered_) && num_readers != __n_readers_) 74 { 75 ++num_readers; 76 __state_ &= ~__n_readers_; 77 __state_ |= num_readers; 78 return true; 79 } 80 return false; 81 } 82 83 void unlock_shared()84shared_timed_mutex::unlock_shared() 85 { 86 lock_guard<mutex> _(__mut_); 87 unsigned num_readers = (__state_ & __n_readers_) - 1; 88 __state_ &= ~__n_readers_; 89 __state_ |= num_readers; 90 if (__state_ & __write_entered_) 91 { 92 if (num_readers == 0) 93 __gate2_.notify_one(); 94 } 95 else 96 { 97 if (num_readers == __n_readers_ - 1) 98 __gate1_.notify_one(); 99 } 100 } 101 102 103 _LIBCPP_END_NAMESPACE_STD 104 105 #endif // !_LIBCPP_SINGLE_THREADED 106 107 108