YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/util/rw_mutex.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
33
#pragma once
34
35
#include <pthread.h>
36
#include <unordered_set>
37
38
#include "yb/gutil/macros.h"
39
#include "yb/gutil/thread_annotations.h"
40
#include "yb/util/locks.h"
41
42
namespace yb {
43
44
// Read/write mutex. Implemented as a thin wrapper around pthread_rwlock_t.
45
//
46
// Although pthread_rwlock_t allows recursive acquisition, this wrapper does
47
// not, and will crash in debug mode if recursive acquisition is detected.
48
class CAPABILITY("mutex") RWMutex {
49
 public:
50
51
  // Possible fairness policies for the RWMutex.
52
  enum class Priority {
53
    // The lock will prioritize readers at the expense of writers.
54
    PREFER_READING,
55
56
    // The lock will prioritize writers at the expense of readers.
57
    //
58
    // Care should be taken when using this fairness policy, as it can lead to
59
    // unexpected deadlocks (e.g. a writer waiting on the lock will prevent
60
    // additional readers from acquiring it).
61
    PREFER_WRITING,
62
  };
63
64
  // Create an RWMutex that prioritizes readers.
65
  RWMutex();
66
67
  // Create an RWMutex with customized priority. This is a best effort; the
68
  // underlying platform may not support custom priorities.
69
  explicit RWMutex(Priority prio);
70
71
  ~RWMutex();
72
73
  void ReadLock() ACQUIRE_SHARED();
74
  void ReadUnlock() RELEASE_SHARED();
75
  bool TryReadLock() TRY_ACQUIRE_SHARED(true);
76
77
  void WriteLock() ACQUIRE();
78
  void WriteUnlock() RELEASE();
79
  bool TryWriteLock() TRY_ACQUIRE(true);
80
81
#ifndef NDEBUG
82
  void AssertAcquiredForReading() const;
83
  void AssertAcquiredForWriting() const;
84
#else
85
  void AssertAcquiredForReading() const {}
86
  void AssertAcquiredForWriting() const {}
87
#endif
88
89
  // Aliases for use with std::lock_guard and yb::shared_lock.
90
15.9M
  void lock() ACQUIRE() { WriteLock(); }
91
15.9M
  void unlock() RELEASE() { WriteUnlock(); }
92
  bool try_lock() TRY_ACQUIRE(true) { return TryWriteLock(); }
93
51.1M
  void lock_shared() ACQUIRE_SHARED() { ReadLock(); }
94
91.2M
  void unlock_shared() RELEASE_SHARED() { ReadUnlock(); }
95
48.0M
  bool try_lock_shared() TRY_ACQUIRE_SHARED(true) { return TryReadLock(); }
96
97
 private:
98
  void Init(Priority prio);
99
100
  enum class LockState {
101
    NEITHER,
102
    READER,
103
    WRITER,
104
  };
105
#ifndef NDEBUG
106
  void CheckLockState(LockState state) const;
107
  void MarkForReading();
108
  void MarkForWriting();
109
  void UnmarkForReading();
110
  void UnmarkForWriting();
111
#else
112
  void CheckLockState(LockState state) const {}
113
  void MarkForReading() {}
114
  void MarkForWriting() {}
115
  void UnmarkForReading() {}
116
  void UnmarkForWriting() {}
117
#endif
118
119
  pthread_rwlock_t native_handle_;
120
121
#ifndef NDEBUG
122
  // Protects reader_tids_ and writer_tid_.
123
  mutable simple_spinlock tid_lock_;
124
125
  // Tracks all current readers by tid.
126
  std::unordered_set<uint64_t> reader_tids_;
127
128
  // Tracks the current writer (if one exists) by tid.
129
  uint64_t writer_tid_;
130
#endif
131
132
  DISALLOW_COPY_AND_ASSIGN(RWMutex);
133
};
134
135
} // namespace yb