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