brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 6180833 Raw
100 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <mutex>10#include <shared_mutex>11#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)12#  pragma comment(lib, "pthread")13#endif14 15_LIBCPP_BEGIN_NAMESPACE_STD16 17// Shared Mutex Base18__shared_mutex_base::__shared_mutex_base() : __state_(0) {}19 20// Exclusive ownership21 22void __shared_mutex_base::lock() {23  unique_lock<mutex> lk(__mut_);24  while (__state_ & __write_entered_)25    __gate1_.wait(lk);26  __state_ |= __write_entered_;27  while (__state_ & __n_readers_)28    __gate2_.wait(lk);29}30 31bool __shared_mutex_base::try_lock() {32  unique_lock<mutex> lk(__mut_);33  if (__state_ == 0) {34    __state_ = __write_entered_;35    return true;36  }37  return false;38}39 40void __shared_mutex_base::unlock() {41  {42    lock_guard<mutex> _(__mut_);43    __state_ = 0;44  }45  __gate1_.notify_all();46}47 48// Shared ownership49 50void __shared_mutex_base::lock_shared() {51  unique_lock<mutex> lk(__mut_);52  while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)53    __gate1_.wait(lk);54  unsigned num_readers = (__state_ & __n_readers_) + 1;55  __state_ &= ~__n_readers_;56  __state_ |= num_readers;57}58 59bool __shared_mutex_base::try_lock_shared() {60  unique_lock<mutex> lk(__mut_);61  unsigned num_readers = __state_ & __n_readers_;62  if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {63    ++num_readers;64    __state_ &= ~__n_readers_;65    __state_ |= num_readers;66    return true;67  }68  return false;69}70 71void __shared_mutex_base::unlock_shared() {72  unique_lock<mutex> lk(__mut_);73  unsigned num_readers = (__state_ & __n_readers_) - 1;74  __state_ &= ~__n_readers_;75  __state_ |= num_readers;76  if (__state_ & __write_entered_) {77    if (num_readers == 0) {78      lk.unlock();79      __gate2_.notify_one();80    }81  } else {82    if (num_readers == __n_readers_ - 1) {83      lk.unlock();84      __gate1_.notify_one();85    }86  }87}88 89// Shared Timed Mutex90// These routines are here for ABI stability91shared_timed_mutex::shared_timed_mutex() : __base_() {}92void shared_timed_mutex::lock() { return __base_.lock(); }93bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }94void shared_timed_mutex::unlock() { return __base_.unlock(); }95void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }96bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }97void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }98 99_LIBCPP_END_NAMESPACE_STD100