MySQL 9.1.0
Source Code Documentation
partitioned_rwlock.h
Go to the documentation of this file.
1#ifndef PARTITIONED_RWLOCK_INCLUDED
2#define PARTITIONED_RWLOCK_INCLUDED
3
4/* Copyright (c) 2015, 2024, Oracle and/or its affiliates.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is designed to work with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have either included with
16 the program or referenced in the documentation.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License, version 2.0, for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
26
27#include <new>
28
29#include "my_compiler.h"
30#include "my_psi_config.h"
32
33/**
34 Implementation of read-write lock partitioned by thread id.
35
36 This rwlock provides better scalability in read-heavy environments by
37 employing the following simple trick:
38 *) Read lock is acquired only on one of its partitions. The specific
39 partition is chosen according to thread id.
40 *) Write lock is acquired on all partitions.
41
42 This way concurrent request for read lock made by different threads
43 have a good chance not to disturb each other by doing cache invalidation
44 and atomic operations. As result scalability in this scenario improves.
45 OTOH acquisition of write lock becomes more expensive. So this rwlock
46 is not supposed to be used in cases when number of write requests is
47 significant.
48*/
49
51 public:
52 Partitioned_rwlock() = default;
53
54 /**
55 @param parts Number of partitions.
56 @param psi_key P_S instrumentation key to use for rwlock instances
57 for partitions.
58 */
59 bool init(uint parts
61 ,
62 PSI_rwlock_key psi_key [[maybe_unused]]
63#endif
64 ) {
65 m_parts = parts;
66 if (!(m_locks_array = new (std::nothrow) mysql_rwlock_t[m_parts]))
67 return true;
68 for (uint i = 0; i < m_parts; ++i)
69 mysql_rwlock_init(psi_key, &m_locks_array[i]);
70 return false;
71 }
72 void destroy() {
73 for (uint i = 0; i < m_parts; ++i) mysql_rwlock_destroy(&m_locks_array[i]);
74 delete[] m_locks_array;
75 }
76 void wrlock() {
77 for (uint i = 0; i < m_parts; ++i) mysql_rwlock_wrlock(&m_locks_array[i]);
78 }
79 void wrunlock() {
80 for (uint i = 0; i < m_parts; ++i) mysql_rwlock_unlock(&m_locks_array[i]);
81 }
82 void rdlock(uint thread_id) {
84 }
85 /*
86 One should use the same thread number for releasing read lock
87 as was used for acquiring it,
88 */
89 void rdunlock(uint thread_id) {
91 }
92
93 private:
95 uint m_parts;
96
97 Partitioned_rwlock(const Partitioned_rwlock &); // Non-copyable
99};
100
101/**
102 Read lock guard class for Partitioned_rwlock. Supports early unlocking.
103*/
104
106 public:
107 /**
108 Acquires read lock on partitioned rwlock on behalf of thread.
109 Automatically release lock in destructor.
110 */
112 : m_rwlock(rwlock), m_thread_id(thread_id) {
114 }
115
118 }
119
120 /** Release read lock. Optional method for early unlocking. */
121 void unlock() {
123 m_rwlock = nullptr;
124 }
125
126 private:
127 /**
128 Pointer to partitioned rwlock which was acquired. NULL if lock was
129 released early so destructor should not do anything.
130 */
132 /**
133 Id of thread on which behalf lock was acquired and which is to be used for
134 unlocking.
135 */
137
138 // Non-copyable
142};
143
144/**
145 Write lock guard class for Partitioned_rwlock. Supports early unlocking.
146*/
147
149 public:
150 /**
151 Acquires write lock on partitioned rwlock.
152 Automatically release it in destructor.
153 */
155 : m_rwlock(rwlock) {
156 m_rwlock->wrlock();
157 }
158
160 if (m_rwlock) m_rwlock->wrunlock();
161 }
162
163 /** Release write lock. Optional method for early unlocking. */
164 void unlock() {
166 m_rwlock = nullptr;
167 }
168
169 private:
170 /**
171 Pointer to partitioned rwlock which was acquired. NULL if lock was
172 released early so destructor should not do anything.
173 */
175
176 // Non-copyable
180};
181
182#endif /* PARTITIONED_RWLOCK_INCLUDED */
Read lock guard class for Partitioned_rwlock.
Definition: partitioned_rwlock.h:105
Partitioned_rwlock_read_guard(const Partitioned_rwlock_read_guard &)
Partitioned_rwlock_read_guard(Partitioned_rwlock *rwlock, uint thread_id)
Acquires read lock on partitioned rwlock on behalf of thread.
Definition: partitioned_rwlock.h:111
Partitioned_rwlock * m_rwlock
Pointer to partitioned rwlock which was acquired.
Definition: partitioned_rwlock.h:131
uint m_thread_id
Id of thread on which behalf lock was acquired and which is to be used for unlocking.
Definition: partitioned_rwlock.h:136
~Partitioned_rwlock_read_guard()
Definition: partitioned_rwlock.h:116
Partitioned_rwlock_read_guard & operator=(const Partitioned_rwlock_read_guard &)
void unlock()
Release read lock.
Definition: partitioned_rwlock.h:121
Write lock guard class for Partitioned_rwlock.
Definition: partitioned_rwlock.h:148
Partitioned_rwlock_write_guard(Partitioned_rwlock *rwlock)
Acquires write lock on partitioned rwlock.
Definition: partitioned_rwlock.h:154
~Partitioned_rwlock_write_guard()
Definition: partitioned_rwlock.h:159
Partitioned_rwlock * m_rwlock
Pointer to partitioned rwlock which was acquired.
Definition: partitioned_rwlock.h:174
Partitioned_rwlock_write_guard & operator=(const Partitioned_rwlock_write_guard &)
void unlock()
Release write lock.
Definition: partitioned_rwlock.h:164
Partitioned_rwlock_write_guard(const Partitioned_rwlock_write_guard &)
Implementation of read-write lock partitioned by thread id.
Definition: partitioned_rwlock.h:50
Partitioned_rwlock(const Partitioned_rwlock &)
void wrlock()
Definition: partitioned_rwlock.h:76
bool init(uint parts, PSI_rwlock_key psi_key)
Definition: partitioned_rwlock.h:59
void wrunlock()
Definition: partitioned_rwlock.h:79
mysql_rwlock_t * m_locks_array
Definition: partitioned_rwlock.h:94
uint m_parts
Definition: partitioned_rwlock.h:95
Partitioned_rwlock()=default
void rdunlock(uint thread_id)
Definition: partitioned_rwlock.h:89
void destroy()
Definition: partitioned_rwlock.h:72
Partitioned_rwlock & operator=(const Partitioned_rwlock &)
void rdlock(uint thread_id)
Definition: partitioned_rwlock.h:82
#define mysql_rwlock_rdlock(T)
Definition: mysql_rwlock.h:61
#define mysql_rwlock_unlock(T)
Definition: mysql_rwlock.h:91
#define mysql_rwlock_init(K, T)
Definition: mysql_rwlock.h:41
#define mysql_rwlock_destroy(T)
Definition: mysql_rwlock.h:51
#define mysql_rwlock_wrlock(T)
Definition: mysql_rwlock.h:71
unsigned int PSI_rwlock_key
Instrumented rwlock key.
Definition: psi_rwlock_bits.h:44
Header for compiler-dependent features.
Defines various enable/disable and HAVE_ macros related to the performance schema instrumentation sys...
#define HAVE_PSI_INTERFACE
Definition: my_psi_config.h:39
static my_thread_id thread_id
Definition: my_thr_init.cc:63
Instrumentation helpers for rwlock.
An instrumented rwlock structure.
Definition: mysql_rwlock_bits.h:51