MySQL 9.0.0
Source Code Documentation
mysql_mutex.h
Go to the documentation of this file.
1/* Copyright (c) 2008, 2024, 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 designed to work 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 either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef MYSQL_MUTEX_H
25#define MYSQL_MUTEX_H
26
27/**
28 @file include/mysql/psi/mysql_mutex.h
29 Instrumentation helpers for mutexes.
30 This header file provides the necessary declarations
31 to use the mutex API with the performance schema instrumentation.
32 In some compilers (SunStudio), 'static inline' functions, when declared
33 but not used, are not optimized away (because they are unused) by default,
34 so that including a static inline function from a header file does
35 create unwanted dependencies, causing unresolved symbols at link time.
36 Other compilers, like gcc, optimize these dependencies by default.
37*/
38/*
39 Note: there are several orthogonal dimensions here.
40
41 Dimension 1: Instrumentation
42 HAVE_PSI_MUTEX_INTERFACE is defined when the instrumentation is compiled in.
43 This may happen both in debug or production builds.
44
45 Dimension 2: Debug
46 SAFE_MUTEX is defined when debug is compiled in.
47 This may happen both with and without instrumentation.
48
49 Dimension 3: Platform
50 Mutexes are implemented with one of:
51 - the pthread library
52 - fast mutexes
53 - window apis
54 This is implemented by various macro definitions in my_thread.h
55
56 This causes complexity with '#ifdef'-ery that can't be avoided.
57*/
58
59/* HAVE_PSI_*_INTERFACE */
60#include "my_psi_config.h" // IWYU pragma: keep
61
64#include "mysql/psi/psi_mutex.h"
65#include "thr_mutex.h"
66
67#if defined(MYSQL_SERVER) || defined(PFS_DIRECT_CALL)
68/* PSI_MUTEX_CALL() as direct call. */
69#include "pfs_mutex_provider.h" // IWYU pragma: keep
70#endif
71
72#ifndef PSI_MUTEX_CALL
73#define PSI_MUTEX_CALL(M) psi_mutex_service->M
74#endif
75
76/**
77 @defgroup psi_api_mutex Mutex Instrumentation (API)
78 @ingroup psi_api
79 @{
80*/
81
82/*
83 Consider the following code:
84 static inline void foo() { bar(); }
85 when foo() is never called.
86
87 With gcc, foo() is a local static function, so the dependencies
88 are optimized away at compile time, and there is no dependency on bar().
89 With other compilers (HP, Sun Studio), the function foo() implementation
90 is compiled, and bar() needs to be present to link.
91
92 Due to the existing header dependencies in MySQL code, this header file
93 is sometime used when it is not needed, which in turn cause link failures
94 on some platforms.
95 The proper fix would be to cut these extra dependencies in the calling code.
96 DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
97 DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
98 the prlock wrappers.
99*/
100#ifndef DISABLE_MYSQL_THREAD_H
101
102/**
103 @def mysql_mutex_assert_owner(M)
104 Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
105 @c mysql_mutex_assert_owner is a drop-in replacement
106 for @c safe_mutex_assert_owner.
107*/
108#ifdef SAFE_MUTEX
109#define mysql_mutex_assert_owner(M) \
110 safe_mutex_assert_owner((M)->m_mutex.m_u.m_safe_ptr);
111#else
112#define mysql_mutex_assert_owner(M) \
113 {}
114#endif
115
116/**
117 @def mysql_mutex_assert_not_owner(M)
118 Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
119 @c mysql_mutex_assert_not_owner is a drop-in replacement
120 for @c safe_mutex_assert_not_owner.
121*/
122#ifdef SAFE_MUTEX
123#define mysql_mutex_assert_not_owner(M) \
124 safe_mutex_assert_not_owner((M)->m_mutex.m_u.m_safe_ptr);
125#else
126#define mysql_mutex_assert_not_owner(M) \
127 {}
128#endif
129
130/**
131 @def mysql_mutex_register(P1, P2, P3)
132 Mutex registration.
133*/
134#define mysql_mutex_register(P1, P2, P3) inline_mysql_mutex_register(P1, P2, P3)
135
136/**
137 @def mysql_mutex_init(K, M, A)
138 Instrumented mutex_init.
139 @c mysql_mutex_init is a replacement for @c pthread_mutex_init.
140 @param K The PSI_mutex_key for this instrumented mutex
141 @param M The mutex to initialize
142 @param A Mutex attributes
143*/
144
145#define mysql_mutex_init(K, M, A) \
146 mysql_mutex_init_with_src(K, M, A, __FILE__, __LINE__)
147
148#define mysql_mutex_init_with_src(K, M, A, F, L) \
149 inline_mysql_mutex_init(K, M, A, F, L)
150
151/**
152 @def mysql_mutex_destroy(M)
153 Instrumented mutex_destroy.
154 @c mysql_mutex_destroy is a drop-in replacement
155 for @c pthread_mutex_destroy.
156*/
157#define mysql_mutex_destroy(M) \
158 mysql_mutex_destroy_with_src(M, __FILE__, __LINE__)
159
160#define mysql_mutex_destroy_with_src(M, F, L) \
161 inline_mysql_mutex_destroy(M, F, L)
162
163/**
164 @def mysql_mutex_lock(M)
165 Instrumented mutex_lock.
166 @c mysql_mutex_lock is a drop-in replacement for @c pthread_mutex_lock.
167 @param M The mutex to lock
168*/
169
170#define mysql_mutex_lock(M) mysql_mutex_lock_with_src(M, __FILE__, __LINE__)
171
172#define mysql_mutex_lock_with_src(M, F, L) inline_mysql_mutex_lock(M, F, L)
173
174/**
175 @def mysql_mutex_trylock(M)
176 Instrumented mutex_lock.
177 @c mysql_mutex_trylock is a drop-in replacement
178 for @c my_mutex_trylock.
179*/
180
181#define mysql_mutex_trylock(M) \
182 mysql_mutex_trylock_with_src(M, __FILE__, __LINE__)
183
184#define mysql_mutex_trylock_with_src(M, F, L) \
185 inline_mysql_mutex_trylock(M, F, L)
186
187/**
188 @def mysql_mutex_unlock(M)
189 Instrumented mutex_unlock.
190 @c mysql_mutex_unlock is a drop-in replacement for @c pthread_mutex_unlock.
191*/
192#define mysql_mutex_unlock(M) mysql_mutex_unlock_with_src(M, __FILE__, __LINE__)
193
194#define mysql_mutex_unlock_with_src(M, F, L) inline_mysql_mutex_unlock(M, F, L)
195
196static inline void inline_mysql_mutex_register(const char *category
197 [[maybe_unused]],
198 PSI_mutex_info *info
199 [[maybe_unused]],
200 int count [[maybe_unused]]) {
201#ifdef HAVE_PSI_MUTEX_INTERFACE
202 PSI_MUTEX_CALL(register_mutex)(category, info, count);
203#endif
204}
205
206static inline int inline_mysql_mutex_init(PSI_mutex_key key [[maybe_unused]],
207 mysql_mutex_t *that,
208 const native_mutexattr_t *attr,
209 const char *src_file [[maybe_unused]],
210 uint src_line [[maybe_unused]]) {
211#ifdef HAVE_PSI_MUTEX_INTERFACE
212 that->m_psi = PSI_MUTEX_CALL(init_mutex)(key, &that->m_mutex);
213#else
214 that->m_psi = nullptr;
215#endif
216 return my_mutex_init(&that->m_mutex, attr
217#ifdef SAFE_MUTEX
218 ,
219 src_file, src_line
220#endif
221 );
222}
223
225 const char *src_file
226 [[maybe_unused]],
227 uint src_line [[maybe_unused]]) {
228#ifdef HAVE_PSI_MUTEX_INTERFACE
229 if (that->m_psi != nullptr) {
231 that->m_psi = nullptr;
232 }
233#endif
234 return my_mutex_destroy(&that->m_mutex
235#ifdef SAFE_MUTEX
236 ,
237 src_file, src_line
238#endif
239 );
240}
241
243 const char *src_file [[maybe_unused]],
244 uint src_line [[maybe_unused]]) {
245 int result;
246
247#ifdef HAVE_PSI_MUTEX_INTERFACE
248 if (that->m_psi != nullptr) {
249 if (that->m_psi->m_enabled) {
250 /* Instrumentation start */
251 PSI_mutex_locker *locker;
253 locker = PSI_MUTEX_CALL(start_mutex_wait)(
254 &state, that->m_psi, PSI_MUTEX_LOCK, src_file, src_line);
255
256 /* Instrumented code */
258#ifdef SAFE_MUTEX
259 ,
260 src_file, src_line
261#endif
262 );
263
264 /* Instrumentation end */
265 if (locker != nullptr) {
266 PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
267 }
268
269 return result;
270 }
271 }
272#endif
273
274 /* Non instrumented code */
276#ifdef SAFE_MUTEX
277 ,
278 src_file, src_line
279#endif
280 );
281
282 return result;
283}
284
286 const char *src_file
287 [[maybe_unused]],
288 uint src_line [[maybe_unused]]) {
289 int result;
290
291#ifdef HAVE_PSI_MUTEX_INTERFACE
292 if (that->m_psi != nullptr) {
293 if (that->m_psi->m_enabled) {
294 /* Instrumentation start */
295 PSI_mutex_locker *locker;
297 locker = PSI_MUTEX_CALL(start_mutex_wait)(
298 &state, that->m_psi, PSI_MUTEX_TRYLOCK, src_file, src_line);
299
300 /* Instrumented code */
302#ifdef SAFE_MUTEX
303 ,
304 src_file, src_line
305#endif
306 );
307
308 /* Instrumentation end */
309 if (locker != nullptr) {
310 PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
311 }
312
313 return result;
314 }
315 }
316#endif
317
318 /* Non instrumented code */
320#ifdef SAFE_MUTEX
321 ,
322 src_file, src_line
323#endif
324 );
325
326 return result;
327}
328
330 const char *src_file
331 [[maybe_unused]],
332 uint src_line [[maybe_unused]]) {
333 int result;
334
335#ifdef HAVE_PSI_MUTEX_INTERFACE
336 if (that->m_psi != nullptr) {
337 PSI_MUTEX_CALL(unlock_mutex)(that->m_psi);
338 }
339#endif
340
342#ifdef SAFE_MUTEX
343 ,
344 src_file, src_line
345#endif
346 );
347
348 return result;
349}
350
351#endif /* DISABLE_MYSQL_THREAD_H */
352
353/** @} (end of group psi_api_mutex) */
354
355#endif
#define PSI_MUTEX_CALL(M)
Definition: psi_mutex.h:36
void destroy_mutex(PFS_mutex *pfs)
Destroy instrumentation for a mutex instance.
Definition: pfs_instr.cc:381
struct PSI_mutex_locker PSI_mutex_locker
Definition: psi_mutex_bits.h:105
unsigned int PSI_mutex_key
Instrumented mutex key.
Definition: psi_mutex_bits.h:52
@ PSI_MUTEX_TRYLOCK
Lock attempt.
Definition: psi_mutex_bits.h:112
@ PSI_MUTEX_LOCK
Lock.
Definition: psi_mutex_bits.h:110
static void inline_mysql_mutex_register(const char *category, PSI_mutex_info *info, int count)
Definition: mysql_mutex.h:196
static int inline_mysql_mutex_destroy(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:224
static int inline_mysql_mutex_init(PSI_mutex_key key, mysql_mutex_t *that, const native_mutexattr_t *attr, const char *src_file, uint src_line)
Definition: mysql_mutex.h:206
static int inline_mysql_mutex_unlock(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:329
static int inline_mysql_mutex_lock(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:242
static int inline_mysql_mutex_trylock(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:285
Defines various enable/disable and HAVE_ macros related to the performance schema instrumentation sys...
static int count
Definition: myisam_ftdump.cc:45
ABI for instrumented mutexes.
native_mutex_t init_mutex
Definition: mysqlimport.cc:59
static const char * category
Definition: sha2_password.cc:170
Performance schema instrumentation (declarations).
struct result result
Definition: result.h:34
Performance schema instrumentation interface.
Instrumentation helpers for mutexes.
required string key
Definition: replication_asynchronous_connection_failover.proto:60
bool m_enabled
Instrumentation is enabled.
Definition: psi_bits.h:191
Mutex information.
Definition: psi_mutex_bits.h:73
State data storage for start_mutex_wait_v1_t.
Definition: psi_mutex_bits.h:125
An instrumented mutex structure.
Definition: mysql_mutex_bits.h:50
struct PSI_mutex * m_psi
The instrumentation hook.
Definition: mysql_mutex_bits.h:58
my_mutex_t m_mutex
The real mutex.
Definition: mysql_mutex_bits.h:52
Definition: result.h:30
MySQL mutex implementation.
static int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr)
Definition: thr_mutex.h:165
static int my_mutex_destroy(my_mutex_t *mp)
Definition: thr_mutex.h:225
static int my_mutex_lock(my_mutex_t *mp)
Definition: thr_mutex.h:180
static int my_mutex_trylock(my_mutex_t *mp)
Definition: thr_mutex.h:195
static int my_mutex_unlock(my_mutex_t *mp)
Definition: thr_mutex.h:210
pthread_mutexattr_t native_mutexattr_t
Definition: thr_mutex_bits.h:56