[flang] Fix length handling in character kind implicit conversion (#74586)
[llvm-project.git] / libcxx / src / mutex.cpp
blobfe7a970ee1c488d7c6352e3c6e5ea5532cb562e4
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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include <__assert>
10 #include <__thread/id.h>
11 #include <__utility/exception_guard.h>
12 #include <limits>
13 #include <mutex>
15 #include "include/atomic_support.h"
17 #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
18 # pragma comment(lib, "pthread")
19 #endif
21 _LIBCPP_PUSH_MACROS
22 #include <__undef_macros>
24 _LIBCPP_BEGIN_NAMESPACE_STD
26 // ~mutex is defined elsewhere
28 void
29 mutex::lock()
31 int ec = __libcpp_mutex_lock(&__m_);
32 if (ec)
33 __throw_system_error(ec, "mutex lock failed");
36 bool
37 mutex::try_lock() noexcept
39 return __libcpp_mutex_trylock(&__m_);
42 void
43 mutex::unlock() noexcept
45 int ec = __libcpp_mutex_unlock(&__m_);
46 (void)ec;
47 _LIBCPP_ASSERT_UNCATEGORIZED(ec == 0, "call to mutex::unlock failed");
50 // recursive_mutex
52 recursive_mutex::recursive_mutex()
54 int ec = __libcpp_recursive_mutex_init(&__m_);
55 if (ec)
56 __throw_system_error(ec, "recursive_mutex constructor failed");
59 recursive_mutex::~recursive_mutex()
61 int e = __libcpp_recursive_mutex_destroy(&__m_);
62 (void)e;
63 _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to ~recursive_mutex() failed");
66 void
67 recursive_mutex::lock()
69 int ec = __libcpp_recursive_mutex_lock(&__m_);
70 if (ec)
71 __throw_system_error(ec, "recursive_mutex lock failed");
74 void
75 recursive_mutex::unlock() noexcept
77 int e = __libcpp_recursive_mutex_unlock(&__m_);
78 (void)e;
79 _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to recursive_mutex::unlock() failed");
82 bool
83 recursive_mutex::try_lock() noexcept
85 return __libcpp_recursive_mutex_trylock(&__m_);
88 // timed_mutex
90 timed_mutex::timed_mutex()
91 : __locked_(false)
95 timed_mutex::~timed_mutex()
97 lock_guard<mutex> _(__m_);
100 void
101 timed_mutex::lock()
103 unique_lock<mutex> lk(__m_);
104 while (__locked_)
105 __cv_.wait(lk);
106 __locked_ = true;
109 bool
110 timed_mutex::try_lock() noexcept
112 unique_lock<mutex> lk(__m_, try_to_lock);
113 if (lk.owns_lock() && !__locked_)
115 __locked_ = true;
116 return true;
118 return false;
121 void
122 timed_mutex::unlock() noexcept
124 lock_guard<mutex> _(__m_);
125 __locked_ = false;
126 __cv_.notify_one();
129 // recursive_timed_mutex
131 recursive_timed_mutex::recursive_timed_mutex()
132 : __count_(0),
133 __id_{}
137 recursive_timed_mutex::~recursive_timed_mutex()
139 lock_guard<mutex> _(__m_);
142 void
143 recursive_timed_mutex::lock()
145 __thread_id id = this_thread::get_id();
146 unique_lock<mutex> lk(__m_);
147 if (id ==__id_)
149 if (__count_ == numeric_limits<size_t>::max())
150 __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached");
151 ++__count_;
152 return;
154 while (__count_ != 0)
155 __cv_.wait(lk);
156 __count_ = 1;
157 __id_ = id;
160 bool
161 recursive_timed_mutex::try_lock() noexcept
163 __thread_id id = this_thread::get_id();
164 unique_lock<mutex> lk(__m_, try_to_lock);
165 if (lk.owns_lock() && (__count_ == 0 || id == __id_))
167 if (__count_ == numeric_limits<size_t>::max())
168 return false;
169 ++__count_;
170 __id_ = id;
171 return true;
173 return false;
176 void
177 recursive_timed_mutex::unlock() noexcept
179 unique_lock<mutex> lk(__m_);
180 if (--__count_ == 0)
182 __id_.__reset();
183 lk.unlock();
184 __cv_.notify_one();
188 _LIBCPP_END_NAMESPACE_STD
190 _LIBCPP_POP_MACROS