1 //===--- Implementation of a Linux mutex class ------------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H
10 #define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H
12 #include "hdr/types/pid_t.h"
13 #include "src/__support/CPP/optional.h"
14 #include "src/__support/libc_assert.h"
15 #include "src/__support/macros/config.h"
16 #include "src/__support/threads/linux/futex_utils.h"
17 #include "src/__support/threads/linux/raw_mutex.h"
18 #include "src/__support/threads/mutex_common.h"
20 namespace LIBC_NAMESPACE_DECL
{
22 // TODO: support shared/recursive/robust mutexes.
23 class Mutex final
: private RawMutex
{
24 // reserved timed, may be useful when combined with other flags.
26 unsigned char recursive
;
28 unsigned char pshared
;
30 // TLS address may not work across forked processes. Use thread id instead.
32 unsigned long long lock_count
;
35 LIBC_INLINE
constexpr Mutex(bool is_timed
, bool is_recursive
, bool is_robust
,
37 : RawMutex(), timed(is_timed
), recursive(is_recursive
), robust(is_robust
),
38 pshared(is_pshared
), owner(0), lock_count(0) {}
40 LIBC_INLINE
static MutexError
init(Mutex
*mutex
, bool is_timed
, bool isrecur
,
41 bool isrobust
, bool is_pshared
) {
42 RawMutex::init(mutex
);
43 mutex
->timed
= is_timed
;
44 mutex
->recursive
= isrecur
;
45 mutex
->robust
= isrobust
;
46 mutex
->pshared
= is_pshared
;
48 mutex
->lock_count
= 0;
49 return MutexError::NONE
;
52 LIBC_INLINE
static MutexError
destroy(Mutex
*lock
) {
53 LIBC_ASSERT(lock
->owner
== 0 && lock
->lock_count
== 0 &&
54 "Mutex destroyed while being locked.");
55 RawMutex::destroy(lock
);
56 return MutexError::NONE
;
59 // TODO: record owner and lock count.
60 LIBC_INLINE MutexError
lock() {
61 // Since timeout is not specified, we do not need to check the return value.
63 /* timeout=*/cpp::nullopt
, this->pshared
);
64 return MutexError::NONE
;
67 // TODO: record owner and lock count.
68 LIBC_INLINE MutexError
timed_lock(internal::AbsTimeout abs_time
) {
69 if (this->RawMutex::lock(abs_time
, this->pshared
))
70 return MutexError::NONE
;
71 return MutexError::TIMEOUT
;
74 LIBC_INLINE MutexError
unlock() {
75 if (this->RawMutex::unlock(this->pshared
))
76 return MutexError::NONE
;
77 return MutexError::UNLOCK_WITHOUT_LOCK
;
80 // TODO: record owner and lock count.
81 LIBC_INLINE MutexError
try_lock() {
82 if (this->RawMutex::try_lock())
83 return MutexError::NONE
;
84 return MutexError::BUSY
;
88 } // namespace LIBC_NAMESPACE_DECL
90 #endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H