1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include <__thread/id.h>
11 #include <__utility/exception_guard.h>
15 #include "include/atomic_support.h"
17 #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
18 # pragma comment(lib, "pthread")
22 #include <__undef_macros>
24 _LIBCPP_BEGIN_NAMESPACE_STD
26 // ~mutex is defined elsewhere
31 int ec
= __libcpp_mutex_lock(&__m_
);
33 __throw_system_error(ec
, "mutex lock failed");
37 mutex::try_lock() noexcept
39 return __libcpp_mutex_trylock(&__m_
);
43 mutex::unlock() noexcept
45 int ec
= __libcpp_mutex_unlock(&__m_
);
47 _LIBCPP_ASSERT_UNCATEGORIZED(ec
== 0, "call to mutex::unlock failed");
52 recursive_mutex::recursive_mutex()
54 int ec
= __libcpp_recursive_mutex_init(&__m_
);
56 __throw_system_error(ec
, "recursive_mutex constructor failed");
59 recursive_mutex::~recursive_mutex()
61 int e
= __libcpp_recursive_mutex_destroy(&__m_
);
63 _LIBCPP_ASSERT_UNCATEGORIZED(e
== 0, "call to ~recursive_mutex() failed");
67 recursive_mutex::lock()
69 int ec
= __libcpp_recursive_mutex_lock(&__m_
);
71 __throw_system_error(ec
, "recursive_mutex lock failed");
75 recursive_mutex::unlock() noexcept
77 int e
= __libcpp_recursive_mutex_unlock(&__m_
);
79 _LIBCPP_ASSERT_UNCATEGORIZED(e
== 0, "call to recursive_mutex::unlock() failed");
83 recursive_mutex::try_lock() noexcept
85 return __libcpp_recursive_mutex_trylock(&__m_
);
90 timed_mutex::timed_mutex()
95 timed_mutex::~timed_mutex()
97 lock_guard
<mutex
> _(__m_
);
103 unique_lock
<mutex
> lk(__m_
);
110 timed_mutex::try_lock() noexcept
112 unique_lock
<mutex
> lk(__m_
, try_to_lock
);
113 if (lk
.owns_lock() && !__locked_
)
122 timed_mutex::unlock() noexcept
124 lock_guard
<mutex
> _(__m_
);
129 // recursive_timed_mutex
131 recursive_timed_mutex::recursive_timed_mutex()
137 recursive_timed_mutex::~recursive_timed_mutex()
139 lock_guard
<mutex
> _(__m_
);
143 recursive_timed_mutex::lock()
145 __thread_id id
= this_thread::get_id();
146 unique_lock
<mutex
> lk(__m_
);
149 if (__count_
== numeric_limits
<size_t>::max())
150 __throw_system_error(EAGAIN
, "recursive_timed_mutex lock limit reached");
154 while (__count_
!= 0)
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())
177 recursive_timed_mutex::unlock() noexcept
179 unique_lock
<mutex
> lk(__m_
);
188 _LIBCPP_END_NAMESPACE_STD