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