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