1261272Sdim//===---------------------- shared_mutex.cpp ------------------------------===// 2261272Sdim// 3261272Sdim// The LLVM Compiler Infrastructure 4261272Sdim// 5261272Sdim// This file is dual licensed under the MIT and the University of Illinois Open 6261272Sdim// Source Licenses. See LICENSE.TXT for details. 7261272Sdim// 8261272Sdim//===----------------------------------------------------------------------===// 9261272Sdim 10278724Sdim#include "__config" 11278724Sdim#ifndef _LIBCPP_HAS_NO_THREADS 12278724Sdim 13261272Sdim#define _LIBCPP_BUILDING_SHARED_MUTEX 14261272Sdim#include "shared_mutex" 15261272Sdim 16261272Sdim_LIBCPP_BEGIN_NAMESPACE_STD 17261272Sdim 18278724Sdimshared_timed_mutex::shared_timed_mutex() 19261272Sdim : __state_(0) 20261272Sdim{ 21261272Sdim} 22261272Sdim 23261272Sdim// Exclusive ownership 24261272Sdim 25261272Sdimvoid 26278724Sdimshared_timed_mutex::lock() 27261272Sdim{ 28261272Sdim unique_lock<mutex> lk(__mut_); 29261272Sdim while (__state_ & __write_entered_) 30261272Sdim __gate1_.wait(lk); 31261272Sdim __state_ |= __write_entered_; 32261272Sdim while (__state_ & __n_readers_) 33261272Sdim __gate2_.wait(lk); 34261272Sdim} 35261272Sdim 36261272Sdimbool 37278724Sdimshared_timed_mutex::try_lock() 38261272Sdim{ 39261272Sdim unique_lock<mutex> lk(__mut_); 40261272Sdim if (__state_ == 0) 41261272Sdim { 42261272Sdim __state_ = __write_entered_; 43261272Sdim return true; 44261272Sdim } 45261272Sdim return false; 46261272Sdim} 47261272Sdim 48261272Sdimvoid 49278724Sdimshared_timed_mutex::unlock() 50261272Sdim{ 51261272Sdim lock_guard<mutex> _(__mut_); 52261272Sdim __state_ = 0; 53261272Sdim __gate1_.notify_all(); 54261272Sdim} 55261272Sdim 56261272Sdim// Shared ownership 57261272Sdim 58261272Sdimvoid 59278724Sdimshared_timed_mutex::lock_shared() 60261272Sdim{ 61261272Sdim unique_lock<mutex> lk(__mut_); 62261272Sdim while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) 63261272Sdim __gate1_.wait(lk); 64261272Sdim unsigned num_readers = (__state_ & __n_readers_) + 1; 65261272Sdim __state_ &= ~__n_readers_; 66261272Sdim __state_ |= num_readers; 67261272Sdim} 68261272Sdim 69261272Sdimbool 70278724Sdimshared_timed_mutex::try_lock_shared() 71261272Sdim{ 72261272Sdim unique_lock<mutex> lk(__mut_); 73261272Sdim unsigned num_readers = __state_ & __n_readers_; 74261272Sdim if (!(__state_ & __write_entered_) && num_readers != __n_readers_) 75261272Sdim { 76261272Sdim ++num_readers; 77261272Sdim __state_ &= ~__n_readers_; 78261272Sdim __state_ |= num_readers; 79261272Sdim return true; 80261272Sdim } 81261272Sdim return false; 82261272Sdim} 83261272Sdim 84261272Sdimvoid 85278724Sdimshared_timed_mutex::unlock_shared() 86261272Sdim{ 87261272Sdim lock_guard<mutex> _(__mut_); 88261272Sdim unsigned num_readers = (__state_ & __n_readers_) - 1; 89261272Sdim __state_ &= ~__n_readers_; 90261272Sdim __state_ |= num_readers; 91261272Sdim if (__state_ & __write_entered_) 92261272Sdim { 93261272Sdim if (num_readers == 0) 94261272Sdim __gate2_.notify_one(); 95261272Sdim } 96261272Sdim else 97261272Sdim { 98261272Sdim if (num_readers == __n_readers_ - 1) 99261272Sdim __gate1_.notify_one(); 100261272Sdim } 101261272Sdim} 102261272Sdim 103261272Sdim 104261272Sdim_LIBCPP_END_NAMESPACE_STD 105278724Sdim 106278724Sdim#endif // !_LIBCPP_HAS_NO_THREADS 107