OLD | NEW |
(Empty) | |
| 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 _LIBCPP_BEGIN_NAMESPACE_STD |
| 14 |
| 15 shared_mutex::shared_mutex() |
| 16 : __state_(0) |
| 17 { |
| 18 } |
| 19 |
| 20 // Exclusive ownership |
| 21 |
| 22 void |
| 23 shared_mutex::lock() |
| 24 { |
| 25 unique_lock<mutex> lk(__mut_); |
| 26 while (__state_ & __write_entered_) |
| 27 __gate1_.wait(lk); |
| 28 __state_ |= __write_entered_; |
| 29 while (__state_ & __n_readers_) |
| 30 __gate2_.wait(lk); |
| 31 } |
| 32 |
| 33 bool |
| 34 shared_mutex::try_lock() |
| 35 { |
| 36 unique_lock<mutex> lk(__mut_); |
| 37 if (__state_ == 0) |
| 38 { |
| 39 __state_ = __write_entered_; |
| 40 return true; |
| 41 } |
| 42 return false; |
| 43 } |
| 44 |
| 45 void |
| 46 shared_mutex::unlock() |
| 47 { |
| 48 lock_guard<mutex> _(__mut_); |
| 49 __state_ = 0; |
| 50 __gate1_.notify_all(); |
| 51 } |
| 52 |
| 53 // Shared ownership |
| 54 |
| 55 void |
| 56 shared_mutex::lock_shared() |
| 57 { |
| 58 unique_lock<mutex> lk(__mut_); |
| 59 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_rea
ders_) |
| 60 __gate1_.wait(lk); |
| 61 unsigned num_readers = (__state_ & __n_readers_) + 1; |
| 62 __state_ &= ~__n_readers_; |
| 63 __state_ |= num_readers; |
| 64 } |
| 65 |
| 66 bool |
| 67 shared_mutex::try_lock_shared() |
| 68 { |
| 69 unique_lock<mutex> lk(__mut_); |
| 70 unsigned num_readers = __state_ & __n_readers_; |
| 71 if (!(__state_ & __write_entered_) && num_readers != __n_readers_) |
| 72 { |
| 73 ++num_readers; |
| 74 __state_ &= ~__n_readers_; |
| 75 __state_ |= num_readers; |
| 76 return true; |
| 77 } |
| 78 return false; |
| 79 } |
| 80 |
| 81 void |
| 82 shared_mutex::unlock_shared() |
| 83 { |
| 84 lock_guard<mutex> _(__mut_); |
| 85 unsigned num_readers = (__state_ & __n_readers_) - 1; |
| 86 __state_ &= ~__n_readers_; |
| 87 __state_ |= num_readers; |
| 88 if (__state_ & __write_entered_) |
| 89 { |
| 90 if (num_readers == 0) |
| 91 __gate2_.notify_one(); |
| 92 } |
| 93 else |
| 94 { |
| 95 if (num_readers == __n_readers_ - 1) |
| 96 __gate1_.notify_one(); |
| 97 } |
| 98 } |
| 99 |
| 100 |
| 101 _LIBCPP_END_NAMESPACE_STD |
OLD | NEW |