Path: blob/main/system/lib/libcxx/src/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 <__assert>9#include <__system_error/throw_system_error.h>10#include <__thread/id.h>11#include <__utility/exception_guard.h>12#include <limits>13#include <mutex>1415#include "include/atomic_support.h"1617#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)18# pragma comment(lib, "pthread")19#endif2021_LIBCPP_PUSH_MACROS22#include <__undef_macros>2324_LIBCPP_BEGIN_NAMESPACE_STD2526// ~mutex is defined elsewhere2728void mutex::lock() {29int ec = __libcpp_mutex_lock(&__m_);30if (ec)31std::__throw_system_error(ec, "mutex lock failed");32}3334bool mutex::try_lock() noexcept { return __libcpp_mutex_trylock(&__m_); }3536void mutex::unlock() noexcept {37int ec = __libcpp_mutex_unlock(&__m_);38(void)ec;39_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(40ec == 0, "call to mutex::unlock failed. A possible reason is that the mutex wasn't locked");41}4243// recursive_mutex4445recursive_mutex::recursive_mutex() {46int ec = __libcpp_recursive_mutex_init(&__m_);47if (ec)48std::__throw_system_error(ec, "recursive_mutex constructor failed");49}5051recursive_mutex::~recursive_mutex() {52int e = __libcpp_recursive_mutex_destroy(&__m_);53(void)e;54_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(e == 0, "call to ~recursive_mutex() failed");55}5657void recursive_mutex::lock() {58int ec = __libcpp_recursive_mutex_lock(&__m_);59if (ec)60std::__throw_system_error(ec, "recursive_mutex lock failed");61}6263void recursive_mutex::unlock() noexcept {64int e = __libcpp_recursive_mutex_unlock(&__m_);65(void)e;66_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(67e == 0, "call to recursive_mutex::unlock() failed. A possible reason is that the mutex wasn't locked");68}6970bool recursive_mutex::try_lock() noexcept { return __libcpp_recursive_mutex_trylock(&__m_); }7172// timed_mutex7374timed_mutex::timed_mutex() : __locked_(false) {}7576timed_mutex::~timed_mutex() { lock_guard<mutex> _(__m_); }7778void timed_mutex::lock() {79unique_lock<mutex> lk(__m_);80while (__locked_)81__cv_.wait(lk);82__locked_ = true;83}8485bool timed_mutex::try_lock() noexcept {86unique_lock<mutex> lk(__m_, try_to_lock);87if (lk.owns_lock() && !__locked_) {88__locked_ = true;89return true;90}91return false;92}9394void timed_mutex::unlock() noexcept {95lock_guard<mutex> _(__m_);96__locked_ = false;97__cv_.notify_one();98}99100// recursive_timed_mutex101102recursive_timed_mutex::recursive_timed_mutex() : __count_(0), __id_{} {}103104recursive_timed_mutex::~recursive_timed_mutex() { lock_guard<mutex> _(__m_); }105106void recursive_timed_mutex::lock() {107__thread_id id = this_thread::get_id();108unique_lock<mutex> lk(__m_);109if (id == __id_) {110if (__count_ == numeric_limits<size_t>::max())111std::__throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached");112++__count_;113return;114}115while (__count_ != 0)116__cv_.wait(lk);117__count_ = 1;118__id_ = id;119}120121bool recursive_timed_mutex::try_lock() noexcept {122__thread_id id = this_thread::get_id();123unique_lock<mutex> lk(__m_, try_to_lock);124if (lk.owns_lock() && (__count_ == 0 || id == __id_)) {125if (__count_ == numeric_limits<size_t>::max())126return false;127++__count_;128__id_ = id;129return true;130}131return false;132}133134void recursive_timed_mutex::unlock() noexcept {135unique_lock<mutex> lk(__m_);136if (--__count_ == 0) {137__id_.__reset();138lk.unlock();139__cv_.notify_one();140}141}142143_LIBCPP_END_NAMESPACE_STD144145_LIBCPP_POP_MACROS146147148