Path: blob/main/system/lib/libcxx/src/shared_mutex.cpp
6175 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <mutex>9#include <shared_mutex>10#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)11# pragma comment(lib, "pthread")12#endif1314_LIBCPP_BEGIN_NAMESPACE_STD1516// Shared Mutex Base17__shared_mutex_base::__shared_mutex_base() : __state_(0) {}1819// Exclusive ownership2021void __shared_mutex_base::lock() {22unique_lock<mutex> lk(__mut_);23while (__state_ & __write_entered_)24__gate1_.wait(lk);25__state_ |= __write_entered_;26while (__state_ & __n_readers_)27__gate2_.wait(lk);28}2930bool __shared_mutex_base::try_lock() {31unique_lock<mutex> lk(__mut_);32if (__state_ == 0) {33__state_ = __write_entered_;34return true;35}36return false;37}3839void __shared_mutex_base::unlock() {40{41lock_guard<mutex> _(__mut_);42__state_ = 0;43}44__gate1_.notify_all();45}4647// Shared ownership4849void __shared_mutex_base::lock_shared() {50unique_lock<mutex> lk(__mut_);51while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)52__gate1_.wait(lk);53unsigned num_readers = (__state_ & __n_readers_) + 1;54__state_ &= ~__n_readers_;55__state_ |= num_readers;56}5758bool __shared_mutex_base::try_lock_shared() {59unique_lock<mutex> lk(__mut_);60unsigned num_readers = __state_ & __n_readers_;61if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {62++num_readers;63__state_ &= ~__n_readers_;64__state_ |= num_readers;65return true;66}67return false;68}6970void __shared_mutex_base::unlock_shared() {71unique_lock<mutex> lk(__mut_);72unsigned num_readers = (__state_ & __n_readers_) - 1;73__state_ &= ~__n_readers_;74__state_ |= num_readers;75if (__state_ & __write_entered_) {76if (num_readers == 0) {77lk.unlock();78__gate2_.notify_one();79}80} else {81if (num_readers == __n_readers_ - 1) {82lk.unlock();83__gate1_.notify_one();84}85}86}8788// Shared Timed Mutex89// These routines are here for ABI stability90shared_timed_mutex::shared_timed_mutex() : __base_() {}91void shared_timed_mutex::lock() { return __base_.lock(); }92bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }93void shared_timed_mutex::unlock() { return __base_.unlock(); }94void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }95bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }96void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }9798_LIBCPP_END_NAMESPACE_STD99100101