Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/RWMutex.h
Line
Count
Source (jump to first uncovered line)
1
//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- 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::RWMutex class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_SUPPORT_RWMUTEX_H
14
#define LLVM_SUPPORT_RWMUTEX_H
15
16
#include "llvm/Config/llvm-config.h"
17
#include "llvm/Support/Threading.h"
18
#include <cassert>
19
20
namespace llvm {
21
namespace sys {
22
23
    /// Platform agnostic RWMutex class.
24
    class RWMutexImpl
25
    {
26
    /// @name Constructors
27
    /// @{
28
    public:
29
30
      /// Initializes the lock but doesn't acquire it.
31
      /// Default Constructor.
32
      explicit RWMutexImpl();
33
34
    /// @}
35
    /// @name Do Not Implement
36
    /// @{
37
      RWMutexImpl(const RWMutexImpl & original) = delete;
38
      RWMutexImpl &operator=(const RWMutexImpl &) = delete;
39
    /// @}
40
41
      /// Releases and removes the lock
42
      /// Destructor
43
      ~RWMutexImpl();
44
45
    /// @}
46
    /// @name Methods
47
    /// @{
48
    public:
49
50
      /// Attempts to unconditionally acquire the lock in reader mode. If the
51
      /// lock is held by a writer, this method will wait until it can acquire
52
      /// the lock.
53
      /// @returns false if any kind of error occurs, true otherwise.
54
      /// Unconditionally acquire the lock in reader mode.
55
      bool reader_acquire();
56
57
      /// Attempts to release the lock in reader mode.
58
      /// @returns false if any kind of error occurs, true otherwise.
59
      /// Unconditionally release the lock in reader mode.
60
      bool reader_release();
61
62
      /// Attempts to unconditionally acquire the lock in reader mode. If the
63
      /// lock is held by any readers, this method will wait until it can
64
      /// acquire the lock.
65
      /// @returns false if any kind of error occurs, true otherwise.
66
      /// Unconditionally acquire the lock in writer mode.
67
      bool writer_acquire();
68
69
      /// Attempts to release the lock in writer mode.
70
      /// @returns false if any kind of error occurs, true otherwise.
71
      /// Unconditionally release the lock in write mode.
72
      bool writer_release();
73
74
    //@}
75
    /// @name Platform Dependent Data
76
    /// @{
77
    private:
78
#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
79
      void* data_ = nullptr; ///< We don't know what the data will be
80
#endif
81
    };
82
83
    /// SmartMutex - An R/W mutex with a compile time constant parameter that
84
    /// indicates whether this mutex should become a no-op when we're not
85
    /// running in multithreaded mode.
86
    template<bool mt_only>
87
    class SmartRWMutex {
88
      RWMutexImpl impl;
89
      unsigned readers = 0;
90
      unsigned writers = 0;
91
92
    public:
93
120k
      explicit SmartRWMutex() = default;
94
      SmartRWMutex(const SmartRWMutex<mt_only> & original) = delete;
95
      SmartRWMutex<mt_only> &operator=(const SmartRWMutex<mt_only> &) = delete;
96
97
167M
      bool lock_shared() {
98
167M
        if (
!mt_only167M
|| llvm_is_multithreaded())
99
167M
          return impl.reader_acquire();
100
18.4E
101
18.4E
        // Single-threaded debugging code.  This would be racy in multithreaded
102
18.4E
        // mode, but provides not sanity checks in single threaded mode.
103
18.4E
        ++readers;
104
18.4E
        return true;
105
18.4E
      }
106
107
167M
      bool unlock_shared() {
108
167M
        if (
!mt_only167M
|| llvm_is_multithreaded())
109
167M
          return impl.reader_release();
110
18.4E
111
18.4E
        // Single-threaded debugging code.  This would be racy in multithreaded
112
18.4E
        // mode, but provides not sanity checks in single threaded mode.
113
18.4E
        assert(readers > 0 && "Reader lock not acquired before release!");
114
18.4E
        --readers;
115
18.4E
        return true;
116
18.4E
      }
117
118
33.0M
      bool lock() {
119
33.0M
        if (!mt_only || llvm_is_multithreaded())
120
33.0M
          return impl.writer_acquire();
121
0
122
0
        // Single-threaded debugging code.  This would be racy in multithreaded
123
0
        // mode, but provides not sanity checks in single threaded mode.
124
0
        assert(writers == 0 && "Writer lock already acquired!");
125
0
        ++writers;
126
0
        return true;
127
0
      }
128
129
33.0M
      bool unlock() {
130
33.0M
        if (!mt_only || llvm_is_multithreaded())
131
33.0M
          return impl.writer_release();
132
0
133
0
        // Single-threaded debugging code.  This would be racy in multithreaded
134
0
        // mode, but provides not sanity checks in single threaded mode.
135
0
        assert(writers == 1 && "Writer lock not acquired before release!");
136
0
        --writers;
137
0
        return true;
138
0
      }
139
    };
140
141
    typedef SmartRWMutex<false> RWMutex;
142
143
    /// ScopedReader - RAII acquisition of a reader lock
144
    template<bool mt_only>
145
    struct SmartScopedReader {
146
      SmartRWMutex<mt_only>& mutex;
147
148
167M
      explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
149
167M
        mutex.lock_shared();
150
167M
      }
151
152
167M
      ~SmartScopedReader() {
153
167M
        mutex.unlock_shared();
154
167M
      }
155
    };
156
157
    typedef SmartScopedReader<false> ScopedReader;
158
159
    /// ScopedWriter - RAII acquisition of a writer lock
160
    template<bool mt_only>
161
    struct SmartScopedWriter {
162
      SmartRWMutex<mt_only>& mutex;
163
164
33.0M
      explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
165
33.0M
        mutex.lock();
166
33.0M
      }
167
168
33.0M
      ~SmartScopedWriter() {
169
33.0M
        mutex.unlock();
170
33.0M
      }
171
    };
172
173
    typedef SmartScopedWriter<false> ScopedWriter;
174
175
} // end namespace sys
176
} // end namespace llvm
177
178
#endif // LLVM_SUPPORT_RWMUTEX_H