91 lines · c
1//===--- Implementation of a Linux mutex class ------------------*- C++ -*-===//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#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H10#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H11 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"19 20namespace LIBC_NAMESPACE_DECL {21 22// TODO: support shared/recursive/robust mutexes.23class Mutex final : private RawMutex {24 // reserved timed, may be useful when combined with other flags.25 unsigned char timed;26 unsigned char recursive;27 unsigned char robust;28 unsigned char pshared;29 30 // TLS address may not work across forked processes. Use thread id instead.31 pid_t owner;32 unsigned long long lock_count;33 34public:35 LIBC_INLINE constexpr Mutex(bool is_timed, bool is_recursive, bool is_robust,36 bool is_pshared)37 : RawMutex(), timed(is_timed), recursive(is_recursive), robust(is_robust),38 pshared(is_pshared), owner(0), lock_count(0) {}39 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;47 mutex->owner = 0;48 mutex->lock_count = 0;49 return MutexError::NONE;50 }51 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;57 }58 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.62 this->RawMutex::lock(63 /* timeout=*/cpp::nullopt, this->pshared);64 return MutexError::NONE;65 }66 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;72 }73 74 LIBC_INLINE MutexError unlock() {75 if (this->RawMutex::unlock(this->pshared))76 return MutexError::NONE;77 return MutexError::UNLOCK_WITHOUT_LOCK;78 }79 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;85 }86};87 88} // namespace LIBC_NAMESPACE_DECL89 90#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H91