brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 5b1e7da Raw
147 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 <__assert>10#include <__system_error/throw_system_error.h>11#include <__thread/id.h>12#include <__utility/exception_guard.h>13#include <limits>14#include <mutex>15 16#include "include/atomic_support.h"17 18#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)19#  pragma comment(lib, "pthread")20#endif21 22_LIBCPP_PUSH_MACROS23#include <__undef_macros>24 25_LIBCPP_BEGIN_NAMESPACE_STD26 27// ~mutex is defined elsewhere28 29void mutex::lock() {30  int ec = __libcpp_mutex_lock(&__m_);31  if (ec)32    std::__throw_system_error(ec, "mutex lock failed");33}34 35bool mutex::try_lock() noexcept { return __libcpp_mutex_trylock(&__m_); }36 37void mutex::unlock() noexcept {38  int ec = __libcpp_mutex_unlock(&__m_);39  (void)ec;40  _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(41      ec == 0, "call to mutex::unlock failed. A possible reason is that the mutex wasn't locked");42}43 44// recursive_mutex45 46recursive_mutex::recursive_mutex() {47  int ec = __libcpp_recursive_mutex_init(&__m_);48  if (ec)49    std::__throw_system_error(ec, "recursive_mutex constructor failed");50}51 52recursive_mutex::~recursive_mutex() {53  int e = __libcpp_recursive_mutex_destroy(&__m_);54  (void)e;55  _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(e == 0, "call to ~recursive_mutex() failed");56}57 58void recursive_mutex::lock() {59  int ec = __libcpp_recursive_mutex_lock(&__m_);60  if (ec)61    std::__throw_system_error(ec, "recursive_mutex lock failed");62}63 64void recursive_mutex::unlock() noexcept {65  int e = __libcpp_recursive_mutex_unlock(&__m_);66  (void)e;67  _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(68      e == 0, "call to recursive_mutex::unlock() failed. A possible reason is that the mutex wasn't locked");69}70 71bool recursive_mutex::try_lock() noexcept { return __libcpp_recursive_mutex_trylock(&__m_); }72 73// timed_mutex74 75timed_mutex::timed_mutex() : __locked_(false) {}76 77timed_mutex::~timed_mutex() { lock_guard<mutex> _(__m_); }78 79void timed_mutex::lock() {80  unique_lock<mutex> lk(__m_);81  while (__locked_)82    __cv_.wait(lk);83  __locked_ = true;84}85 86bool timed_mutex::try_lock() noexcept {87  unique_lock<mutex> lk(__m_, try_to_lock);88  if (lk.owns_lock() && !__locked_) {89    __locked_ = true;90    return true;91  }92  return false;93}94 95void timed_mutex::unlock() noexcept {96  lock_guard<mutex> _(__m_);97  __locked_ = false;98  __cv_.notify_one();99}100 101// recursive_timed_mutex102 103recursive_timed_mutex::recursive_timed_mutex() : __count_(0), __id_{} {}104 105recursive_timed_mutex::~recursive_timed_mutex() { lock_guard<mutex> _(__m_); }106 107void recursive_timed_mutex::lock() {108  __thread_id id = this_thread::get_id();109  unique_lock<mutex> lk(__m_);110  if (id == __id_) {111    if (__count_ == numeric_limits<size_t>::max())112      std::__throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached");113    ++__count_;114    return;115  }116  while (__count_ != 0)117    __cv_.wait(lk);118  __count_ = 1;119  __id_    = id;120}121 122bool recursive_timed_mutex::try_lock() noexcept {123  __thread_id id = this_thread::get_id();124  unique_lock<mutex> lk(__m_, try_to_lock);125  if (lk.owns_lock() && (__count_ == 0 || id == __id_)) {126    if (__count_ == numeric_limits<size_t>::max())127      return false;128    ++__count_;129    __id_ = id;130    return true;131  }132  return false;133}134 135void recursive_timed_mutex::unlock() noexcept {136  unique_lock<mutex> lk(__m_);137  if (--__count_ == 0) {138    __id_.__reset();139    lk.unlock();140    __cv_.notify_one();141  }142}143 144_LIBCPP_END_NAMESPACE_STD145 146_LIBCPP_POP_MACROS147