1//===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- 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-exception
6//
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
16#include "llvm/Support/Threading.h"
17#include <cassert>
18#include <mutex>
19
20namespace llvm
21{
22  namespace sys
23  {
24    /// 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 {
29      std::recursive_mutex impl;
30      unsigned acquired = 0;
31
32    public:
33      bool lock() {
34        if (!mt_only || llvm_is_multithreaded()) {
35          impl.lock();
36          return true;
37        } else {
38          // Single-threaded debugging code.  This would be racy in
39          // multithreaded mode, but provides not sanity checks in single
40          // threaded mode.
41          ++acquired;
42          return true;
43        }
44      }
45
46      bool unlock() {
47        if (!mt_only || llvm_is_multithreaded()) {
48          impl.unlock();
49          return true;
50        } else {
51          // Single-threaded debugging code.  This would be racy in
52          // multithreaded mode, but provides not sanity checks in single
53          // threaded mode.
54          assert(acquired && "Lock not acquired before release!");
55          --acquired;
56          return true;
57        }
58      }
59
60      bool try_lock() {
61        if (!mt_only || llvm_is_multithreaded())
62          return impl.try_lock();
63        else return true;
64      }
65    };
66
67    /// Mutex - A standard, always enforced mutex.
68    typedef SmartMutex<false> Mutex;
69
70    template <bool mt_only>
71    using SmartScopedLock = std::lock_guard<SmartMutex<mt_only>>;
72
73    typedef SmartScopedLock<false> ScopedLock;
74  }
75}
76
77#endif
78