MySQL 8.3.0
Source Code Documentation
mysql_rwlock.h
Go to the documentation of this file.
1/* Copyright (c) 2008, 2023, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef MYSQL_RWLOCK_H
24#define MYSQL_RWLOCK_H
25
26/**
27 @file include/mysql/psi/mysql_rwlock.h
28 Instrumentation helpers for rwlock.
29*/
30
31/* HAVE_PSI_*_INTERFACE */
32#include "my_psi_config.h" // IWYU pragma: keep
33
36#include "thr_rwlock.h"
37
38#if defined(MYSQL_SERVER) || defined(PFS_DIRECT_CALL)
39/* PSI_RWLOCK_CALL() as direct call. */
40#include "pfs_rwlock_provider.h" // IWYU pragma: keep
41#endif
42
43#ifndef PSI_RWLOCK_CALL
44#define PSI_RWLOCK_CALL(M) psi_rwlock_service->M
45#endif
46
47/**
48 @defgroup psi_api_rwlock Rwlock Instrumentation (API)
49 @ingroup psi_api
50 @{
51*/
52
53/**
54 @def mysql_prlock_assert_write_owner(M)
55 Drop-in replacement
56 for @c rw_pr_lock_assert_write_owner.
57*/
58#ifdef SAFE_MUTEX
59#define mysql_prlock_assert_write_owner(M) \
60 rw_pr_lock_assert_write_owner(&(M)->m_prlock)
61#else
62#define mysql_prlock_assert_write_owner(M) \
63 {}
64#endif
65
66/**
67 @def mysql_prlock_assert_not_write_owner(M)
68 Drop-in replacement
69 for @c rw_pr_lock_assert_not_write_owner.
70*/
71#ifdef SAFE_MUTEX
72#define mysql_prlock_assert_not_write_owner(M) \
73 rw_pr_lock_assert_not_write_owner(&(M)->m_prlock)
74#else
75#define mysql_prlock_assert_not_write_owner(M) \
76 {}
77#endif
78
79#ifndef DISABLE_MYSQL_THREAD_H
80
81/**
82 @def mysql_rwlock_register(P1, P2, P3)
83 Rwlock registration.
84*/
85#define mysql_rwlock_register(P1, P2, P3) \
86 inline_mysql_rwlock_register(P1, P2, P3)
87
88/**
89 @def mysql_rwlock_init(K, T)
90 Instrumented rwlock_init.
91 @c mysql_rwlock_init is a replacement for @c pthread_rwlock_init.
92 Note that pthread_rwlockattr_t is not supported in MySQL.
93 @param K The PSI_rwlock_key for this instrumented rwlock
94 @param T The rwlock to initialize
95*/
96
97#define mysql_rwlock_init(K, T) \
98 mysql_rwlock_init_with_src(K, T, __FILE__, __LINE__)
99
100#define mysql_rwlock_init_with_src(K, T, F, L) \
101 inline_mysql_rwlock_init(K, T, F, L)
102
103/**
104 @def mysql_prlock_init(K, T)
105 Instrumented rw_pr_init.
106 @c mysql_prlock_init is a replacement for @c rw_pr_init.
107 @param K The PSI_rwlock_key for this instrumented prlock
108 @param T The prlock to initialize
109*/
110
111#define mysql_prlock_init(K, T) \
112 mysql_prlock_init_with_src(K, T, __FILE__, __LINE__)
113
114#define mysql_prlock_init_with_src(K, T, F, L) \
115 inline_mysql_prlock_init(K, T, F, L)
116
117/**
118 @def mysql_rwlock_destroy(T)
119 Instrumented rwlock_destroy.
120 @c mysql_rwlock_destroy is a drop-in replacement
121 for @c pthread_rwlock_destroy.
122*/
123
124#define mysql_rwlock_destroy(T) \
125 mysql_rwlock_destroy_with_src(T, __FILE__, __LINE__)
126
127#define mysql_rwlock_destroy_with_src(T, F, L) \
128 inline_mysql_rwlock_destroy(T, F, L)
129
130/**
131 @def mysql_prlock_destroy(T)
132 Instrumented rw_pr_destroy.
133 @c mysql_prlock_destroy is a drop-in replacement
134 for @c rw_pr_destroy.
135*/
136#define mysql_prlock_destroy(T) \
137 mysql_prlock_destroy_with_src(T, __FILE__, __LINE__)
138
139#define mysql_prlock_destroy_with_src(T, F, L) \
140 inline_mysql_prlock_destroy(T, F, L)
141
142/**
143 @def mysql_rwlock_rdlock(T)
144 Instrumented rwlock_rdlock.
145 @c mysql_rwlock_rdlock is a drop-in replacement
146 for @c pthread_rwlock_rdlock.
147*/
148
149#define mysql_rwlock_rdlock(T) \
150 mysql_rwlock_rdlock_with_src(T, __FILE__, __LINE__)
151
152#define mysql_rwlock_rdlock_with_src(T, F, L) \
153 inline_mysql_rwlock_rdlock(T, F, L)
154
155/**
156 @def mysql_prlock_rdlock(T)
157 Instrumented rw_pr_rdlock.
158 @c mysql_prlock_rdlock is a drop-in replacement
159 for @c rw_pr_rdlock.
160*/
161
162#define mysql_prlock_rdlock(T) \
163 mysql_prlock_rdlock_with_src(T, __FILE__, __LINE__)
164
165#define mysql_prlock_rdlock_with_src(T, F, L) \
166 inline_mysql_prlock_rdlock(T, F, L)
167
168/**
169 @def mysql_rwlock_wrlock(T)
170 Instrumented rwlock_wrlock.
171 @c mysql_rwlock_wrlock is a drop-in replacement
172 for @c pthread_rwlock_wrlock.
173*/
174
175#define mysql_rwlock_wrlock(T) \
176 mysql_rwlock_wrlock_with_src(T, __FILE__, __LINE__)
177
178#define mysql_rwlock_wrlock_with_src(T, F, L) \
179 inline_mysql_rwlock_wrlock(T, F, L)
180
181/**
182 @def mysql_prlock_wrlock(T)
183 Instrumented rw_pr_wrlock.
184 @c mysql_prlock_wrlock is a drop-in replacement
185 for @c rw_pr_wrlock.
186*/
187
188#define mysql_prlock_wrlock(T) \
189 mysql_prlock_wrlock_with_src(T, __FILE__, __LINE__)
190
191#define mysql_prlock_wrlock_with_src(T, F, L) \
192 inline_mysql_prlock_wrlock(T, F, L)
193
194/**
195 @def mysql_rwlock_tryrdlock(T)
196 Instrumented rwlock_tryrdlock.
197 @c mysql_rwlock_tryrdlock is a drop-in replacement
198 for @c pthread_rwlock_tryrdlock.
199*/
200
201#define mysql_rwlock_tryrdlock(T) \
202 mysql_rwlock_tryrdlock_with_src(T, __FILE__, __LINE__)
203
204#define mysql_rwlock_tryrdlock_with_src(T, F, L) \
205 inline_mysql_rwlock_tryrdlock(T, F, L)
206
207/**
208 @def mysql_rwlock_trywrlock(T)
209 Instrumented rwlock_trywrlock.
210 @c mysql_rwlock_trywrlock is a drop-in replacement
211 for @c pthread_rwlock_trywrlock.
212*/
213
214#define mysql_rwlock_trywrlock(T) \
215 mysql_rwlock_trywrlock_with_src(T, __FILE__, __LINE__)
216
217#define mysql_rwlock_trywrlock_with_src(T, F, L) \
218 inline_mysql_rwlock_trywrlock(T, F, L)
219
220/**
221 @def mysql_rwlock_unlock(T)
222 Instrumented rwlock_unlock.
223 @c mysql_rwlock_unlock is a drop-in replacement
224 for @c pthread_rwlock_unlock.
225*/
226#define mysql_rwlock_unlock(T) \
227 mysql_rwlock_unlock_with_src(T, __FILE__, __LINE__)
228
229#define mysql_rwlock_unlock_with_src(T, F, L) \
230 inline_mysql_rwlock_unlock(T, F, L)
231
232/**
233 @def mysql_prlock_unlock(T)
234 Instrumented rw_pr_unlock.
235 @c mysql_prlock_unlock is a drop-in replacement
236 for @c rw_pr_unlock.
237*/
238
239#define mysql_prlock_unlock(T) \
240 mysql_prlock_unlock_with_src(T, __FILE__, __LINE__)
241
242#define mysql_prlock_unlock_with_src(T, F, L) \
243 inline_mysql_prlock_unlock(T, F, L)
244
245static inline void inline_mysql_rwlock_register(const char *category
246 [[maybe_unused]],
248 [[maybe_unused]],
249 int count [[maybe_unused]]) {
250#ifdef HAVE_PSI_RWLOCK_INTERFACE
251 PSI_RWLOCK_CALL(register_rwlock)(category, info, count);
252#endif
253}
254
255static inline int inline_mysql_rwlock_init(PSI_rwlock_key key [[maybe_unused]],
256 mysql_rwlock_t *that,
257 const char *src_file
258 [[maybe_unused]],
259 int src_line [[maybe_unused]]) {
260#ifdef HAVE_PSI_RWLOCK_INTERFACE
261 that->m_psi = PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_rwlock);
262#else
263 that->m_psi = nullptr;
264#endif
265 return native_rw_init(&that->m_rwlock);
266}
267
268#ifndef DISABLE_MYSQL_PRLOCK_H
269static inline int inline_mysql_prlock_init(PSI_rwlock_key key [[maybe_unused]],
270 mysql_prlock_t *that,
271 const char *src_file
272 [[maybe_unused]],
273 int src_line [[maybe_unused]]) {
274#ifdef HAVE_PSI_RWLOCK_INTERFACE
275 that->m_psi = PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_prlock);
276#else
277 that->m_psi = nullptr;
278#endif
279 return rw_pr_init(&that->m_prlock);
280}
281#endif
282
284 const char *src_file
285 [[maybe_unused]],
286 int src_line [[maybe_unused]]) {
287#ifdef HAVE_PSI_RWLOCK_INTERFACE
288 if (that->m_psi != nullptr) {
290 that->m_psi = nullptr;
291 }
292#endif
293 return native_rw_destroy(&that->m_rwlock);
294}
295
296#ifndef DISABLE_MYSQL_PRLOCK_H
298 const char *src_file
299 [[maybe_unused]],
300 int src_line [[maybe_unused]]) {
301#ifdef HAVE_PSI_RWLOCK_INTERFACE
302 if (that->m_psi != nullptr) {
304 that->m_psi = nullptr;
305 }
306#endif
307 return rw_pr_destroy(&that->m_prlock);
308}
309#endif
310
312 const char *src_file
313 [[maybe_unused]],
314 int src_line [[maybe_unused]]) {
315 int result;
316
317#ifdef HAVE_PSI_RWLOCK_INTERFACE
318 if (that->m_psi != nullptr) {
319 if (that->m_psi->m_enabled) {
320 /* Instrumentation start */
321 PSI_rwlock_locker *locker;
323 locker = PSI_RWLOCK_CALL(start_rwlock_rdwait)(
324 &state, that->m_psi, PSI_RWLOCK_READLOCK, src_file, src_line);
325
326 /* Instrumented code */
328
329 /* Instrumentation end */
330 if (locker != nullptr) {
331 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
332 }
333
334 return result;
335 }
336 }
337#endif
338
339 /* Non instrumented code */
341
342 return result;
343}
344
345#ifndef DISABLE_MYSQL_PRLOCK_H
347 const char *src_file
348 [[maybe_unused]],
349 int src_line [[maybe_unused]]) {
350 int result;
351
352#ifdef HAVE_PSI_RWLOCK_INTERFACE
353 if (that->m_psi != nullptr) {
354 if (that->m_psi->m_enabled) {
355 /* Instrumentation start */
356 PSI_rwlock_locker *locker;
358 locker = PSI_RWLOCK_CALL(start_rwlock_rdwait)(
359 &state, that->m_psi, PSI_RWLOCK_READLOCK, src_file, src_line);
360
361 /* Instrumented code */
362 result = rw_pr_rdlock(&that->m_prlock);
363
364 /* Instrumentation end */
365 if (locker != nullptr) {
366 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
367 }
368
369 return result;
370 }
371 }
372#endif
373
374 /* Non instrumented code */
375 result = rw_pr_rdlock(&that->m_prlock);
376
377 return result;
378}
379#endif
380
382 const char *src_file
383 [[maybe_unused]],
384 int src_line [[maybe_unused]]) {
385 int result;
386
387#ifdef HAVE_PSI_RWLOCK_INTERFACE
388 if (that->m_psi != nullptr) {
389 if (that->m_psi->m_enabled) {
390 /* Instrumentation start */
391 PSI_rwlock_locker *locker;
393 locker = PSI_RWLOCK_CALL(start_rwlock_wrwait)(
394 &state, that->m_psi, PSI_RWLOCK_WRITELOCK, src_file, src_line);
395
396 /* Instrumented code */
398
399 /* Instrumentation end */
400 if (locker != nullptr) {
401 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
402 }
403
404 return result;
405 }
406 }
407#endif
408
409 /* Non instrumented code */
411
412 return result;
413}
414
415#ifndef DISABLE_MYSQL_PRLOCK_H
417 const char *src_file
418 [[maybe_unused]],
419 int src_line [[maybe_unused]]) {
420 int result;
421
422#ifdef HAVE_PSI_RWLOCK_INTERFACE
423 if (that->m_psi != nullptr) {
424 if (that->m_psi->m_enabled) {
425 /* Instrumentation start */
426 PSI_rwlock_locker *locker;
428 locker = PSI_RWLOCK_CALL(start_rwlock_wrwait)(
429 &state, that->m_psi, PSI_RWLOCK_WRITELOCK, src_file, src_line);
430
431 /* Instrumented code */
432 result = rw_pr_wrlock(&that->m_prlock);
433
434 /* Instrumentation end */
435 if (locker != nullptr) {
436 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
437 }
438
439 return result;
440 }
441 }
442#endif
443
444 /* Non instrumented code */
445 result = rw_pr_wrlock(&that->m_prlock);
446
447 return result;
448}
449#endif
450
452 const char *src_file
453 [[maybe_unused]],
454 int src_line [[maybe_unused]]) {
455 int result;
456
457#ifdef HAVE_PSI_RWLOCK_INTERFACE
458 if (that->m_psi != nullptr) {
459 if (that->m_psi->m_enabled) {
460 /* Instrumentation start */
461 PSI_rwlock_locker *locker;
463 locker = PSI_RWLOCK_CALL(start_rwlock_rdwait)(
464 &state, that->m_psi, PSI_RWLOCK_TRYREADLOCK, src_file, src_line);
465
466 /* Instrumented code */
468
469 /* Instrumentation end */
470 if (locker != nullptr) {
471 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
472 }
473
474 return result;
475 }
476 }
477#endif
478
479 /* Non instrumented code */
481
482 return result;
483}
484
486 const char *src_file
487 [[maybe_unused]],
488 int src_line [[maybe_unused]]) {
489 int result;
490
491#ifdef HAVE_PSI_RWLOCK_INTERFACE
492 if (that->m_psi != nullptr) {
493 if (that->m_psi->m_enabled) {
494 /* Instrumentation start */
495 PSI_rwlock_locker *locker;
497 locker = PSI_RWLOCK_CALL(start_rwlock_wrwait)(
498 &state, that->m_psi, PSI_RWLOCK_TRYWRITELOCK, src_file, src_line);
499
500 /* Instrumented code */
502
503 /* Instrumentation end */
504 if (locker != nullptr) {
505 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
506 }
507
508 return result;
509 }
510 }
511#endif
512
513 /* Non instrumented code */
515
516 return result;
517}
518
520 const char *src_file
521 [[maybe_unused]],
522 int src_line [[maybe_unused]]) {
523 int result;
524#ifdef HAVE_PSI_RWLOCK_INTERFACE
525 if (that->m_psi != nullptr) {
526 if (that->m_psi->m_enabled) {
527 PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi, PSI_RWLOCK_UNLOCK);
528 }
529 }
530#endif
532 return result;
533}
534
535#ifndef DISABLE_MYSQL_PRLOCK_H
537 const char *src_file
538 [[maybe_unused]],
539 int src_line [[maybe_unused]]) {
540 int result;
541#ifdef HAVE_PSI_RWLOCK_INTERFACE
542 if (that->m_psi != nullptr) {
543 if (that->m_psi->m_enabled) {
544 PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi, PSI_RWLOCK_UNLOCK);
545 }
546 }
547#endif
548 result = rw_pr_unlock(&that->m_prlock);
549 return result;
550}
551#endif
552
553#endif /* DISABLE_MYSQL_THREAD_H */
554
555/** @} (end of group psi_api_rwlock) */
556
557#endif
#define PSI_RWLOCK_CALL(M)
Definition: psi_rwlock.h:35
void destroy_rwlock(PFS_rwlock *pfs)
Destroy instrumentation for a rwlock instance.
Definition: pfs_instr.cc:429
unsigned int PSI_rwlock_key
Instrumented rwlock key.
Definition: psi_rwlock_bits.h:43
struct PSI_rwlock_locker PSI_rwlock_locker
Definition: psi_rwlock_bits.h:78
@ PSI_RWLOCK_TRYWRITELOCK
Write lock attempt.
Definition: psi_rwlock_bits.h:131
@ PSI_RWLOCK_WRITELOCK
Write lock.
Definition: psi_rwlock_bits.h:127
@ PSI_RWLOCK_UNLOCK
Unlock (Read or Write).
Definition: psi_rwlock_bits.h:133
@ PSI_RWLOCK_TRYREADLOCK
Read lock attempt.
Definition: psi_rwlock_bits.h:129
@ PSI_RWLOCK_READLOCK
Read lock.
Definition: psi_rwlock_bits.h:125
static int inline_mysql_rwlock_init(PSI_rwlock_key key, mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:255
static int inline_mysql_prlock_wrlock(mysql_prlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:416
static int inline_mysql_prlock_unlock(mysql_prlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:536
static int inline_mysql_prlock_init(PSI_rwlock_key key, mysql_prlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:269
static int inline_mysql_rwlock_unlock(mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:519
static int inline_mysql_prlock_destroy(mysql_prlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:297
static int inline_mysql_rwlock_trywrlock(mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:485
static int inline_mysql_rwlock_destroy(mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:283
static int inline_mysql_rwlock_rdlock(mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:311
static int inline_mysql_rwlock_wrlock(mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:381
static int inline_mysql_rwlock_tryrdlock(mysql_rwlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:451
static void inline_mysql_rwlock_register(const char *category, PSI_rwlock_info *info, int count)
Definition: mysql_rwlock.h:245
static int inline_mysql_prlock_rdlock(mysql_prlock_t *that, const char *src_file, int src_line)
Definition: mysql_rwlock.h:346
Defines various enable/disable and HAVE_ macros related to the performance schema instrumentation sys...
static int count
Definition: myisam_ftdump.cc:44
Instrumentation helpers for rwlock.
static const char * category
Definition: sha2_password.cc:169
Performance schema instrumentation (declarations).
struct result result
Definition: result.h:33
Performance schema instrumentation interface.
required string key
Definition: replication_asynchronous_connection_failover.proto:59
bool m_enabled
Instrumentation is enabled.
Definition: psi_bits.h:190
Rwlock information.
Definition: psi_rwlock_bits.h:161
State data storage for start_rwlock_rdwait_v1_t, start_rwlock_wrwait_v1_t.
Definition: psi_rwlock_bits.h:193
An instrumented prlock structure.
Definition: mysql_rwlock_bits.h:71
struct PSI_rwlock * m_psi
The instrumentation hook.
Definition: mysql_rwlock_bits.h:79
rw_pr_lock_t m_prlock
The real prlock.
Definition: mysql_rwlock_bits.h:73
An instrumented rwlock structure.
Definition: mysql_rwlock_bits.h:50
struct PSI_rwlock * m_psi
The instrumentation hook.
Definition: mysql_rwlock_bits.h:58
native_rw_lock_t m_rwlock
The real rwlock.
Definition: mysql_rwlock_bits.h:52
Definition: result.h:29
MySQL rwlock implementation.
static int native_rw_init(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:58
int rw_pr_wrlock(rw_pr_lock_t *)
Definition: thr_rwlock.cc:66
int rw_pr_destroy(rw_pr_lock_t *)
Definition: thr_rwlock.cc:47
static int native_rw_trywrlock(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:105
int rw_pr_rdlock(rw_pr_lock_t *)
Definition: thr_rwlock.cc:53
static int native_rw_tryrdlock(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:86
static int native_rw_destroy(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:69
int rw_pr_unlock(rw_pr_lock_t *)
Definition: thr_rwlock.cc:99
static int native_rw_rdlock(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:77
static int native_rw_unlock(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:115
static int native_rw_wrlock(native_rw_lock_t *rwp)
Definition: thr_rwlock.h:95
int rw_pr_init(rw_pr_lock_t *)
Definition: thr_rwlock.cc:35