MySQL  8.0.18
Source Code Documentation
mysql_mutex.h
Go to the documentation of this file.
1 /* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
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 
60 #include "mysql/psi/psi_mutex.h"
61 #include "thr_mutex.h"
62 
63 #ifdef MYSQL_SERVER
64 #ifndef MYSQL_DYNAMIC_PLUGIN
65 #include "pfs_mutex_provider.h"
66 #endif
67 #endif
68 
69 #ifndef PSI_MUTEX_CALL
70 #define PSI_MUTEX_CALL(M) psi_mutex_service->M
71 #endif
72 
73 /**
74  @defgroup psi_api_mutex Mutex Instrumentation (API)
75  @ingroup psi_api
76  @{
77 */
78 
79 /*
80  Consider the following code:
81  static inline void foo() { bar(); }
82  when foo() is never called.
83 
84  With gcc, foo() is a local static function, so the dependencies
85  are optimized away at compile time, and there is no dependency on bar().
86  With other compilers (HP, Sun Studio), the function foo() implementation
87  is compiled, and bar() needs to be present to link.
88 
89  Due to the existing header dependencies in MySQL code, this header file
90  is sometime used when it is not needed, which in turn cause link failures
91  on some platforms.
92  The proper fix would be to cut these extra dependencies in the calling code.
93  DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
94  DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
95  the prlock wrappers.
96 */
97 #ifndef DISABLE_MYSQL_THREAD_H
98 
99 /**
100  @def mysql_mutex_assert_owner(M)
101  Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
102  @c mysql_mutex_assert_owner is a drop-in replacement
103  for @c safe_mutex_assert_owner.
104 */
105 #ifdef SAFE_MUTEX
106 #define mysql_mutex_assert_owner(M) \
107  safe_mutex_assert_owner((M)->m_mutex.m_u.m_safe_ptr);
108 #else
109 #define mysql_mutex_assert_owner(M) \
110  {}
111 #endif
112 
113 /**
114  @def mysql_mutex_assert_not_owner(M)
115  Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
116  @c mysql_mutex_assert_not_owner is a drop-in replacement
117  for @c safe_mutex_assert_not_owner.
118 */
119 #ifdef SAFE_MUTEX
120 #define mysql_mutex_assert_not_owner(M) \
121  safe_mutex_assert_not_owner((M)->m_mutex.m_u.m_safe_ptr);
122 #else
123 #define mysql_mutex_assert_not_owner(M) \
124  {}
125 #endif
126 
127 /**
128  @def mysql_mutex_register(P1, P2, P3)
129  Mutex registration.
130 */
131 #define mysql_mutex_register(P1, P2, P3) inline_mysql_mutex_register(P1, P2, P3)
132 
133 /**
134  @def mysql_mutex_init(K, M, A)
135  Instrumented mutex_init.
136  @c mysql_mutex_init is a replacement for @c pthread_mutex_init.
137  @param K The PSI_mutex_key for this instrumented mutex
138  @param M The mutex to initialize
139  @param A Mutex attributes
140 */
141 
142 #define mysql_mutex_init(K, M, A) \
143  mysql_mutex_init_with_src(K, M, A, __FILE__, __LINE__)
144 
145 #define mysql_mutex_init_with_src(K, M, A, F, L) \
146  inline_mysql_mutex_init(K, M, A, F, L)
147 
148 /**
149  @def mysql_mutex_destroy(M)
150  Instrumented mutex_destroy.
151  @c mysql_mutex_destroy is a drop-in replacement
152  for @c pthread_mutex_destroy.
153 */
154 #define mysql_mutex_destroy(M) \
155  mysql_mutex_destroy_with_src(M, __FILE__, __LINE__)
156 
157 #define mysql_mutex_destroy_with_src(M, F, L) \
158  inline_mysql_mutex_destroy(M, F, L)
159 
160 /**
161  @def mysql_mutex_lock(M)
162  Instrumented mutex_lock.
163  @c mysql_mutex_lock is a drop-in replacement for @c pthread_mutex_lock.
164  @param M The mutex to lock
165 */
166 
167 #define mysql_mutex_lock(M) mysql_mutex_lock_with_src(M, __FILE__, __LINE__)
168 
169 #define mysql_mutex_lock_with_src(M, F, L) inline_mysql_mutex_lock(M, F, L)
170 
171 /**
172  @def mysql_mutex_trylock(M)
173  Instrumented mutex_lock.
174  @c mysql_mutex_trylock is a drop-in replacement
175  for @c my_mutex_trylock.
176 */
177 
178 #define mysql_mutex_trylock(M) \
179  mysql_mutex_trylock_with_src(M, __FILE__, __LINE__)
180 
181 #define mysql_mutex_trylock_with_src(M, F, L) \
182  inline_mysql_mutex_trylock(M, F, L)
183 
184 /**
185  @def mysql_mutex_unlock(M)
186  Instrumented mutex_unlock.
187  @c mysql_mutex_unlock is a drop-in replacement for @c pthread_mutex_unlock.
188 */
189 #define mysql_mutex_unlock(M) mysql_mutex_unlock_with_src(M, __FILE__, __LINE__)
190 
191 #define mysql_mutex_unlock_with_src(M, F, L) inline_mysql_mutex_unlock(M, F, L)
192 
193 static inline void inline_mysql_mutex_register(
194  const char *category MY_ATTRIBUTE((unused)),
195  PSI_mutex_info *info MY_ATTRIBUTE((unused)),
196  int count MY_ATTRIBUTE((unused))) {
197 #ifdef HAVE_PSI_MUTEX_INTERFACE
198  PSI_MUTEX_CALL(register_mutex)(category, info, count);
199 #endif
200 }
201 
202 static inline int inline_mysql_mutex_init(
203  PSI_mutex_key key MY_ATTRIBUTE((unused)), mysql_mutex_t *that,
204  const native_mutexattr_t *attr, const char *src_file MY_ATTRIBUTE((unused)),
205  uint src_line MY_ATTRIBUTE((unused))) {
206 #ifdef HAVE_PSI_MUTEX_INTERFACE
207  that->m_psi = PSI_MUTEX_CALL(init_mutex)(key, &that->m_mutex);
208 #else
209  that->m_psi = NULL;
210 #endif
211  return my_mutex_init(&that->m_mutex, attr
212 #ifdef SAFE_MUTEX
213  ,
214  src_file, src_line
215 #endif
216  );
217 }
218 
219 static inline int inline_mysql_mutex_destroy(
220  mysql_mutex_t *that, const char *src_file MY_ATTRIBUTE((unused)),
221  uint src_line MY_ATTRIBUTE((unused))) {
222 #ifdef HAVE_PSI_MUTEX_INTERFACE
223  if (that->m_psi != NULL) {
225  that->m_psi = NULL;
226  }
227 #endif
228  return my_mutex_destroy(&that->m_mutex
229 #ifdef SAFE_MUTEX
230  ,
231  src_file, src_line
232 #endif
233  );
234 }
235 
236 static inline int inline_mysql_mutex_lock(
237  mysql_mutex_t *that, const char *src_file MY_ATTRIBUTE((unused)),
238  uint src_line MY_ATTRIBUTE((unused))) {
239  int result;
240 
241 #ifdef HAVE_PSI_MUTEX_INTERFACE
242  if (that->m_psi != NULL) {
243  /* Instrumentation start */
244  PSI_mutex_locker *locker;
246  locker = PSI_MUTEX_CALL(start_mutex_wait)(
247  &state, that->m_psi, PSI_MUTEX_LOCK, src_file, src_line);
248 
249  /* Instrumented code */
250  result = my_mutex_lock(&that->m_mutex
251 #ifdef SAFE_MUTEX
252  ,
253  src_file, src_line
254 #endif
255  );
256 
257  /* Instrumentation end */
258  if (locker != NULL) {
259  PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
260  }
261 
262  return result;
263  }
264 #endif
265 
266  /* Non instrumented code */
267  result = my_mutex_lock(&that->m_mutex
268 #ifdef SAFE_MUTEX
269  ,
270  src_file, src_line
271 #endif
272  );
273 
274  return result;
275 }
276 
277 static inline int inline_mysql_mutex_trylock(
278  mysql_mutex_t *that, const char *src_file MY_ATTRIBUTE((unused)),
279  uint src_line MY_ATTRIBUTE((unused))) {
280  int result;
281 
282 #ifdef HAVE_PSI_MUTEX_INTERFACE
283  if (that->m_psi != NULL) {
284  /* Instrumentation start */
285  PSI_mutex_locker *locker;
287  locker = PSI_MUTEX_CALL(start_mutex_wait)(
288  &state, that->m_psi, PSI_MUTEX_TRYLOCK, src_file, src_line);
289 
290  /* Instrumented code */
292 #ifdef SAFE_MUTEX
293  ,
294  src_file, src_line
295 #endif
296  );
297 
298  /* Instrumentation end */
299  if (locker != NULL) {
300  PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
301  }
302 
303  return result;
304  }
305 #endif
306 
307  /* Non instrumented code */
309 #ifdef SAFE_MUTEX
310  ,
311  src_file, src_line
312 #endif
313  );
314 
315  return result;
316 }
317 
318 static inline int inline_mysql_mutex_unlock(
319  mysql_mutex_t *that, const char *src_file MY_ATTRIBUTE((unused)),
320  uint src_line MY_ATTRIBUTE((unused))) {
321  int result;
322 
323 #ifdef HAVE_PSI_MUTEX_INTERFACE
324  if (that->m_psi != NULL) {
325  PSI_MUTEX_CALL(unlock_mutex)(that->m_psi);
326  }
327 #endif
328 
330 #ifdef SAFE_MUTEX
331  ,
332  src_file, src_line
333 #endif
334  );
335 
336  return result;
337 }
338 
339 #endif /* DISABLE_MYSQL_THREAD_H */
340 
341 /** @} (end of group psi_api_mutex) */
342 
343 #endif
Definition: result.h:33
static void inline_mysql_mutex_register(const char *category, PSI_mutex_info *info, int count)
Definition: mysql_mutex.h:193
ssize_t count
Definition: memcached.c:386
static int my_mutex_destroy(my_mutex_t *mp)
Definition: thr_mutex.h:223
struct result result
Definition: result.h:37
MySQL mutex implementation.
my_mutex_t m_mutex
The real mutex.
Definition: mysql_mutex_bits.h:51
Lock.
Definition: psi_mutex_bits.h:107
static int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr)
Definition: thr_mutex.h:163
void destroy_mutex(PFS_mutex *pfs)
Destroy instrumentation for a mutex instance.
Definition: pfs_instr.cc:338
static int my_mutex_trylock(my_mutex_t *mp)
Definition: thr_mutex.h:193
#define PSI_MUTEX_CALL(M)
Definition: psi_mutex.h:31
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:202
unsigned int PSI_mutex_key
Instrumented mutex key.
Definition: psi_mutex_bits.h:49
static int my_mutex_unlock(my_mutex_t *mp)
Definition: thr_mutex.h:208
static int inline_mysql_mutex_lock(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:236
native_mutex_t init_mutex
Definition: mysqlimport.cc:54
static int inline_mysql_mutex_unlock(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:318
Performance schema instrumentation (declarations).
static int my_mutex_lock(my_mutex_t *mp)
Definition: thr_mutex.h:178
Performance schema instrumentation interface.
unsigned int uint
Definition: uca-dump.cc:29
Instrumentation helpers for mutexes.
State data storage for start_mutex_wait_v1_t.
Definition: psi_mutex_bits.h:122
struct PSI_mutex_locker PSI_mutex_locker
Definition: psi_mutex_bits.h:102
Mutex information.
Definition: psi_mutex_bits.h:70
static const char * key
Definition: suite_stubs.c:14
enum_state state
Definition: sql_class.h:269
static const char * category
Definition: sha2_password.cc:166
struct PSI_mutex * m_psi
The instrumentation hook.
Definition: mysql_mutex_bits.h:57
static int inline_mysql_mutex_destroy(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:219
Lock attempt.
Definition: psi_mutex_bits.h:109
An instrumented mutex structure.
Definition: mysql_mutex_bits.h:49
ABI for instrumented mutexes.
#define NULL
Definition: types.h:55
static int inline_mysql_mutex_trylock(mysql_mutex_t *that, const char *src_file, uint src_line)
Definition: mysql_mutex.h:277
Log info(cout, "NOTE")
pthread_mutexattr_t native_mutexattr_t
Definition: thr_mutex_bits.h:55