blob: 1d8a0d3c87cb602e78fc83dd4f2598b67e8ef136 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the llvm::sys::Mutex class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_SUPPORT_MUTEX_H
14#define LLVM_SUPPORT_MUTEX_H
15
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010016#include "llvm/Support/Threading.h"
17#include <cassert>
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020018#include <mutex>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010019
20namespace llvm
21{
22 namespace sys
23 {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010024 /// SmartMutex - A mutex with a compile time constant parameter that
25 /// indicates whether this mutex should become a no-op when we're not
26 /// running in multithreaded mode.
27 template<bool mt_only>
28 class SmartMutex {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020029 std::recursive_mutex impl;
30 unsigned acquired = 0;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010031
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020032 public:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010033 bool lock() {
34 if (!mt_only || llvm_is_multithreaded()) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020035 impl.lock();
36 return true;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010037 } else {
38 // Single-threaded debugging code. This would be racy in
39 // multithreaded mode, but provides not sanity checks in single
40 // threaded mode.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010041 ++acquired;
42 return true;
43 }
44 }
45
46 bool unlock() {
47 if (!mt_only || llvm_is_multithreaded()) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020048 impl.unlock();
49 return true;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010050 } else {
51 // Single-threaded debugging code. This would be racy in
52 // multithreaded mode, but provides not sanity checks in single
53 // threaded mode.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020054 assert(acquired && "Lock not acquired before release!");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010055 --acquired;
56 return true;
57 }
58 }
59
60 bool try_lock() {
61 if (!mt_only || llvm_is_multithreaded())
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020062 return impl.try_lock();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063 else return true;
64 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 };
66
67 /// Mutex - A standard, always enforced mutex.
68 typedef SmartMutex<false> Mutex;
69
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020070 template <bool mt_only>
71 using SmartScopedLock = std::lock_guard<SmartMutex<mt_only>>;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010072
73 typedef SmartScopedLock<false> ScopedLock;
74 }
75}
76
77#endif