1 /* Copyright (c) 2008, 2016, 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 Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 #ifndef MYSQL_THREAD_H
24 #define MYSQL_THREAD_H
25
26 /**
27 @file mysql/psi/mysql_thread.h
28 Instrumentation helpers for mysys threads, mutexes,
29 read write locks and conditions.
30 This header file provides the necessary declarations
31 to use the mysys thread 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 Since the instrumented APIs declared here are wrapper on top
39 of my_pthread / safemutex / etc APIs,
40 including mysql/psi/mysql_thread.h assumes that
41 the dependency on my_pthread and safemutex already exists.
42 */
43 /*
44 Note: there are several orthogonal dimensions here.
45
46 Dimension 1: Instrumentation
47 HAVE_PSI_INTERFACE is defined when the instrumentation is compiled in.
48 This may happen both in debug or production builds.
49
50 Dimension 2: Debug
51 SAFE_MUTEX is defined when debug is compiled in.
52 This may happen both with and without instrumentation.
53
54 Dimension 3: Platform
55 Mutexes are implemented with one of:
56 - the pthread library
57 - fast mutexes
58 - window apis
59 This is implemented by various macro definitions in my_pthread.h
60
61 This causes complexity with '#ifdef'-ery that can't be avoided.
62 */
63
64 #include "mysql/psi/psi.h"
65
66 /**
67 @defgroup Thread_instrumentation Thread Instrumentation
68 @ingroup Instrumentation_interface
69 @{
70 */
71
72 /**
73 An instrumented mutex structure.
74 @sa mysql_mutex_t
75 */
76 struct st_mysql_mutex
77 {
78 /** The real mutex. */
79 #ifdef SAFE_MUTEX
80 safe_mutex_t m_mutex;
81 #elif defined(MY_PTHREAD_FASTMUTEX)
82 my_pthread_fastmutex_t m_mutex;
83 #else
84 pthread_mutex_t m_mutex;
85 #endif
86 /**
87 The instrumentation hook.
88 Note that this hook is not conditionally defined,
89 for binary compatibility of the @c mysql_mutex_t interface.
90 */
91 struct PSI_mutex *m_psi;
92 };
93
94 /**
95 Type of an instrumented mutex.
96 @c mysql_mutex_t is a drop-in replacement for @c pthread_mutex_t.
97 @sa mysql_mutex_assert_owner
98 @sa mysql_mutex_assert_not_owner
99 @sa mysql_mutex_init
100 @sa mysql_mutex_lock
101 @sa mysql_mutex_unlock
102 @sa mysql_mutex_destroy
103 */
104 typedef struct st_mysql_mutex mysql_mutex_t;
105
106 /**
107 An instrumented rwlock structure.
108 @sa mysql_rwlock_t
109 */
110 struct st_mysql_rwlock
111 {
112 /** The real rwlock */
113 rw_lock_t m_rwlock;
114 /**
115 The instrumentation hook.
116 Note that this hook is not conditionally defined,
117 for binary compatibility of the @c mysql_rwlock_t interface.
118 */
119 struct PSI_rwlock *m_psi;
120 };
121
122 /**
123 An instrumented prlock structure.
124 @sa mysql_prlock_t
125 */
126 struct st_mysql_prlock
127 {
128 /** The real prlock */
129 rw_pr_lock_t m_prlock;
130 /**
131 The instrumentation hook.
132 Note that this hook is not conditionally defined,
133 for binary compatibility of the @c mysql_rwlock_t interface.
134 */
135 struct PSI_rwlock *m_psi;
136 };
137
138 /**
139 Type of an instrumented rwlock.
140 @c mysql_rwlock_t is a drop-in replacement for @c pthread_rwlock_t.
141 @sa mysql_rwlock_init
142 @sa mysql_rwlock_rdlock
143 @sa mysql_rwlock_tryrdlock
144 @sa mysql_rwlock_wrlock
145 @sa mysql_rwlock_trywrlock
146 @sa mysql_rwlock_unlock
147 @sa mysql_rwlock_destroy
148 */
149 typedef struct st_mysql_rwlock mysql_rwlock_t;
150
151 /**
152 Type of an instrumented prlock.
153 A prlock is a read write lock that 'prefers readers' (pr).
154 @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
155 @sa mysql_prlock_init
156 @sa mysql_prlock_rdlock
157 @sa mysql_prlock_wrlock
158 @sa mysql_prlock_unlock
159 @sa mysql_prlock_destroy
160 */
161 typedef struct st_mysql_prlock mysql_prlock_t;
162
163 /**
164 An instrumented cond structure.
165 @sa mysql_cond_t
166 */
167 struct st_mysql_cond
168 {
169 /** The real condition */
170 pthread_cond_t m_cond;
171 /**
172 The instrumentation hook.
173 Note that this hook is not conditionally defined,
174 for binary compatibility of the @c mysql_cond_t interface.
175 */
176 struct PSI_cond *m_psi;
177 };
178
179 /**
180 Type of an instrumented condition.
181 @c mysql_cond_t is a drop-in replacement for @c pthread_cond_t.
182 @sa mysql_cond_init
183 @sa mysql_cond_wait
184 @sa mysql_cond_timedwait
185 @sa mysql_cond_signal
186 @sa mysql_cond_broadcast
187 @sa mysql_cond_destroy
188 */
189 typedef struct st_mysql_cond mysql_cond_t;
190
191 /*
192 Consider the following code:
193 static inline void foo() { bar(); }
194 when foo() is never called.
195
196 With gcc, foo() is a local static function, so the dependencies
197 are optimized away at compile time, and there is no dependency on bar().
198 With other compilers (HP, Sun Studio), the function foo() implementation
199 is compiled, and bar() needs to be present to link.
200
201 Due to the existing header dependencies in MySQL code, this header file
202 is sometime used when it is not needed, which in turn cause link failures
203 on some platforms.
204 The proper fix would be to cut these extra dependencies in the calling code.
205 DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
206 DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
207 the prlock wrappers.
208 */
209 #ifndef DISABLE_MYSQL_THREAD_H
210
211 /**
212 @def mysql_mutex_assert_owner(M)
213 Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
214 @c mysql_mutex_assert_owner is a drop-in replacement
215 for @c safe_mutex_assert_owner.
216 */
217 #define mysql_mutex_assert_owner(M) \
218 safe_mutex_assert_owner(&(M)->m_mutex)
219
220 /**
221 @def mysql_mutex_assert_not_owner(M)
222 Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
223 @c mysql_mutex_assert_not_owner is a drop-in replacement
224 for @c safe_mutex_assert_not_owner.
225 */
226 #define mysql_mutex_assert_not_owner(M) \
227 safe_mutex_assert_not_owner(&(M)->m_mutex)
228
229 /** Wrappers for instrumented prlock objects. */
230
231 #define mysql_prlock_assert_write_owner(M) \
232 rw_pr_lock_assert_write_owner(&(M)->m_prlock)
233
234 #define mysql_prlock_assert_not_write_owner(M) \
235 rw_pr_lock_assert_not_write_owner(&(M)->m_prlock)
236
237 /**
238 @def mysql_mutex_register(P1, P2, P3)
239 Mutex registration.
240 */
241 #define mysql_mutex_register(P1, P2, P3) \
242 inline_mysql_mutex_register(P1, P2, P3)
243
244 /**
245 @def mysql_mutex_init(K, M, A)
246 Instrumented mutex_init.
247 @c mysql_mutex_init is a replacement for @c pthread_mutex_init.
248 @param K The PSI_mutex_key for this instrumented mutex
249 @param M The mutex to initialize
250 @param A Mutex attributes
251 */
252
253 #ifdef HAVE_PSI_MUTEX_INTERFACE
254 #ifdef SAFE_MUTEX
255 #define mysql_mutex_init(K, M, A) \
256 inline_mysql_mutex_init(K, M, A, __FILE__, __LINE__)
257 #else
258 #define mysql_mutex_init(K, M, A) \
259 inline_mysql_mutex_init(K, M, A)
260 #endif
261 #else
262 #ifdef SAFE_MUTEX
263 #define mysql_mutex_init(K, M, A) \
264 inline_mysql_mutex_init(M, A, __FILE__, __LINE__)
265 #else
266 #define mysql_mutex_init(K, M, A) \
267 inline_mysql_mutex_init(M, A)
268 #endif
269 #endif
270
271 /**
272 @def mysql_mutex_destroy(M)
273 Instrumented mutex_destroy.
274 @c mysql_mutex_destroy is a drop-in replacement
275 for @c pthread_mutex_destroy.
276 */
277 #ifdef SAFE_MUTEX
278 #define mysql_mutex_destroy(M) \
279 inline_mysql_mutex_destroy(M, __FILE__, __LINE__)
280 #else
281 #define mysql_mutex_destroy(M) \
282 inline_mysql_mutex_destroy(M)
283 #endif
284
285 /**
286 @def mysql_mutex_lock(M)
287 Instrumented mutex_lock.
288 @c mysql_mutex_lock is a drop-in replacement for @c pthread_mutex_lock.
289 @param M The mutex to lock
290 */
291
292 #if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
293 #define mysql_mutex_lock(M) \
294 inline_mysql_mutex_lock(M, __FILE__, __LINE__)
295 #else
296 #define mysql_mutex_lock(M) \
297 inline_mysql_mutex_lock(M)
298 #endif
299
300 /**
301 @def mysql_mutex_trylock(M)
302 Instrumented mutex_lock.
303 @c mysql_mutex_trylock is a drop-in replacement
304 for @c pthread_mutex_trylock.
305 */
306
307 #if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
308 #define mysql_mutex_trylock(M) \
309 inline_mysql_mutex_trylock(M, __FILE__, __LINE__)
310 #else
311 #define mysql_mutex_trylock(M) \
312 inline_mysql_mutex_trylock(M)
313 #endif
314
315 /**
316 @def mysql_mutex_unlock(M)
317 Instrumented mutex_unlock.
318 @c mysql_mutex_unlock is a drop-in replacement for @c pthread_mutex_unlock.
319 */
320 #ifdef SAFE_MUTEX
321 #define mysql_mutex_unlock(M) \
322 inline_mysql_mutex_unlock(M, __FILE__, __LINE__)
323 #else
324 #define mysql_mutex_unlock(M) \
325 inline_mysql_mutex_unlock(M)
326 #endif
327
328 /**
329 @def mysql_rwlock_register(P1, P2, P3)
330 Rwlock registration.
331 */
332 #define mysql_rwlock_register(P1, P2, P3) \
333 inline_mysql_rwlock_register(P1, P2, P3)
334
335 /**
336 @def mysql_rwlock_init(K, RW)
337 Instrumented rwlock_init.
338 @c mysql_rwlock_init is a replacement for @c pthread_rwlock_init.
339 Note that pthread_rwlockattr_t is not supported in MySQL.
340 @param K The PSI_rwlock_key for this instrumented rwlock
341 @param RW The rwlock to initialize
342 */
343 #ifdef HAVE_PSI_RWLOCK_INTERFACE
344 #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(K, RW)
345 #else
346 #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(RW)
347 #endif
348
349 /**
350 @def mysql_prlock_init(K, RW)
351 Instrumented rw_pr_init.
352 @c mysql_prlock_init is a replacement for @c rw_pr_init.
353 @param K The PSI_rwlock_key for this instrumented prlock
354 @param RW The prlock to initialize
355 */
356 #ifdef HAVE_PSI_RWLOCK_INTERFACE
357 #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(K, RW)
358 #else
359 #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(RW)
360 #endif
361
362 /**
363 @def mysql_rwlock_destroy(RW)
364 Instrumented rwlock_destroy.
365 @c mysql_rwlock_destroy is a drop-in replacement
366 for @c pthread_rwlock_destroy.
367 */
368 #define mysql_rwlock_destroy(RW) inline_mysql_rwlock_destroy(RW)
369
370 /**
371 @def mysql_prlock_destroy(RW)
372 Instrumented rw_pr_destroy.
373 @c mysql_prlock_destroy is a drop-in replacement
374 for @c rw_pr_destroy.
375 */
376 #define mysql_prlock_destroy(RW) inline_mysql_prlock_destroy(RW)
377
378 /**
379 @def mysql_rwlock_rdlock(RW)
380 Instrumented rwlock_rdlock.
381 @c mysql_rwlock_rdlock is a drop-in replacement
382 for @c pthread_rwlock_rdlock.
383 */
384 #ifdef HAVE_PSI_RWLOCK_INTERFACE
385 #define mysql_rwlock_rdlock(RW) \
386 inline_mysql_rwlock_rdlock(RW, __FILE__, __LINE__)
387 #else
388 #define mysql_rwlock_rdlock(RW) \
389 inline_mysql_rwlock_rdlock(RW)
390 #endif
391
392 /**
393 @def mysql_prlock_rdlock(RW)
394 Instrumented rw_pr_rdlock.
395 @c mysql_prlock_rdlock is a drop-in replacement
396 for @c rw_pr_rdlock.
397 */
398 #ifdef HAVE_PSI_RWLOCK_INTERFACE
399 #define mysql_prlock_rdlock(RW) \
400 inline_mysql_prlock_rdlock(RW, __FILE__, __LINE__)
401 #else
402 #define mysql_prlock_rdlock(RW) \
403 inline_mysql_prlock_rdlock(RW)
404 #endif
405
406 /**
407 @def mysql_rwlock_wrlock(RW)
408 Instrumented rwlock_wrlock.
409 @c mysql_rwlock_wrlock is a drop-in replacement
410 for @c pthread_rwlock_wrlock.
411 */
412 #ifdef HAVE_PSI_RWLOCK_INTERFACE
413 #define mysql_rwlock_wrlock(RW) \
414 inline_mysql_rwlock_wrlock(RW, __FILE__, __LINE__)
415 #else
416 #define mysql_rwlock_wrlock(RW) \
417 inline_mysql_rwlock_wrlock(RW)
418 #endif
419
420 /**
421 @def mysql_prlock_wrlock(RW)
422 Instrumented rw_pr_wrlock.
423 @c mysql_prlock_wrlock is a drop-in replacement
424 for @c rw_pr_wrlock.
425 */
426 #ifdef HAVE_PSI_RWLOCK_INTERFACE
427 #define mysql_prlock_wrlock(RW) \
428 inline_mysql_prlock_wrlock(RW, __FILE__, __LINE__)
429 #else
430 #define mysql_prlock_wrlock(RW) \
431 inline_mysql_prlock_wrlock(RW)
432 #endif
433
434 /**
435 @def mysql_rwlock_tryrdlock(RW)
436 Instrumented rwlock_tryrdlock.
437 @c mysql_rwlock_tryrdlock is a drop-in replacement
438 for @c pthread_rwlock_tryrdlock.
439 */
440 #ifdef HAVE_PSI_RWLOCK_INTERFACE
441 #define mysql_rwlock_tryrdlock(RW) \
442 inline_mysql_rwlock_tryrdlock(RW, __FILE__, __LINE__)
443 #else
444 #define mysql_rwlock_tryrdlock(RW) \
445 inline_mysql_rwlock_tryrdlock(RW)
446 #endif
447
448 /**
449 @def mysql_rwlock_trywrlock(RW)
450 Instrumented rwlock_trywrlock.
451 @c mysql_rwlock_trywrlock is a drop-in replacement
452 for @c pthread_rwlock_trywrlock.
453 */
454 #ifdef HAVE_PSI_RWLOCK_INTERFACE
455 #define mysql_rwlock_trywrlock(RW) \
456 inline_mysql_rwlock_trywrlock(RW, __FILE__, __LINE__)
457 #else
458 #define mysql_rwlock_trywrlock(RW) \
459 inline_mysql_rwlock_trywrlock(RW)
460 #endif
461
462 /**
463 @def mysql_rwlock_unlock(RW)
464 Instrumented rwlock_unlock.
465 @c mysql_rwlock_unlock is a drop-in replacement
466 for @c pthread_rwlock_unlock.
467 */
468 #define mysql_rwlock_unlock(RW) inline_mysql_rwlock_unlock(RW)
469
470 /**
471 @def mysql_prlock_unlock(RW)
472 Instrumented rw_pr_unlock.
473 @c mysql_prlock_unlock is a drop-in replacement
474 for @c rw_pr_unlock.
475 */
476 #define mysql_prlock_unlock(RW) inline_mysql_prlock_unlock(RW)
477
478 /**
479 @def mysql_cond_register(P1, P2, P3)
480 Cond registration.
481 */
482 #define mysql_cond_register(P1, P2, P3) \
483 inline_mysql_cond_register(P1, P2, P3)
484
485 /**
486 @def mysql_cond_init(K, C, A)
487 Instrumented cond_init.
488 @c mysql_cond_init is a replacement for @c pthread_cond_init.
489 @param C The cond to initialize
490 @param K The PSI_cond_key for this instrumented cond
491 @param A Condition attributes
492 */
493 #ifdef HAVE_PSI_COND_INTERFACE
494 #define mysql_cond_init(K, C, A) inline_mysql_cond_init(K, C, A)
495 #else
496 #define mysql_cond_init(K, C, A) inline_mysql_cond_init(C, A)
497 #endif
498
499 /**
500 @def mysql_cond_destroy(C)
501 Instrumented cond_destroy.
502 @c mysql_cond_destroy is a drop-in replacement for @c pthread_cond_destroy.
503 */
504 #define mysql_cond_destroy(C) inline_mysql_cond_destroy(C)
505
506 /**
507 @def mysql_cond_wait(C)
508 Instrumented cond_wait.
509 @c mysql_cond_wait is a drop-in replacement for @c pthread_cond_wait.
510 */
511 #ifdef HAVE_PSI_COND_INTERFACE
512 #define mysql_cond_wait(C, M) \
513 inline_mysql_cond_wait(C, M, __FILE__, __LINE__)
514 #else
515 #define mysql_cond_wait(C, M) \
516 inline_mysql_cond_wait(C, M)
517 #endif
518
519 /**
520 @def mysql_cond_timedwait(C, M, W)
521 Instrumented cond_timedwait.
522 @c mysql_cond_timedwait is a drop-in replacement
523 for @c pthread_cond_timedwait.
524 */
525 #ifdef HAVE_PSI_COND_INTERFACE
526 #define mysql_cond_timedwait(C, M, W) \
527 inline_mysql_cond_timedwait(C, M, W, __FILE__, __LINE__)
528 #else
529 #define mysql_cond_timedwait(C, M, W) \
530 inline_mysql_cond_timedwait(C, M, W)
531 #endif
532
533 /**
534 @def mysql_cond_signal(C)
535 Instrumented cond_signal.
536 @c mysql_cond_signal is a drop-in replacement for @c pthread_cond_signal.
537 */
538 #define mysql_cond_signal(C) inline_mysql_cond_signal(C)
539
540 /**
541 @def mysql_cond_broadcast(C)
542 Instrumented cond_broadcast.
543 @c mysql_cond_broadcast is a drop-in replacement
544 for @c pthread_cond_broadcast.
545 */
546 #define mysql_cond_broadcast(C) inline_mysql_cond_broadcast(C)
547
548 /**
549 @def mysql_thread_register(P1, P2, P3)
550 Thread registration.
551 */
552 #define mysql_thread_register(P1, P2, P3) \
553 inline_mysql_thread_register(P1, P2, P3)
554
555 /**
556 @def mysql_thread_create(K, P1, P2, P3, P4)
557 Instrumented pthread_create.
558 This function creates both the thread instrumentation and a thread.
559 @c mysql_thread_create is a replacement for @c pthread_create.
560 The parameter P4 (or, if it is NULL, P1) will be used as the
561 instrumented thread "indentity".
562 Providing a P1 / P4 parameter with a different value for each call
563 will on average improve performances, since this thread identity value
564 is used internally to randomize access to data and prevent contention.
565 This is optional, and the improvement is not guaranteed, only statistical.
566 @param K The PSI_thread_key for this instrumented thread
567 @param P1 pthread_create parameter 1
568 @param P2 pthread_create parameter 2
569 @param P3 pthread_create parameter 3
570 @param P4 pthread_create parameter 4
571 */
572 #ifdef HAVE_PSI_THREAD_INTERFACE
573 #define mysql_thread_create(K, P1, P2, P3, P4) \
574 inline_mysql_thread_create(K, P1, P2, P3, P4)
575 #else
576 #define mysql_thread_create(K, P1, P2, P3, P4) \
577 pthread_create(P1, P2, P3, P4)
578 #endif
579
580 /**
581 @def mysql_thread_set_psi_id(I)
582 Set the thread indentifier for the instrumentation.
583 @param I The thread identifier
584 */
585 #ifdef HAVE_PSI_THREAD_INTERFACE
586 #define mysql_thread_set_psi_id(I) inline_mysql_thread_set_psi_id(I)
587 #else
588 #define mysql_thread_set_psi_id(I) do {} while (0)
589 #endif
590
inline_mysql_mutex_register(const char * category,PSI_mutex_info * info,int count)591 static inline void inline_mysql_mutex_register(
592 #ifdef HAVE_PSI_MUTEX_INTERFACE
593 const char *category,
594 PSI_mutex_info *info,
595 int count
596 #else
597 const char *category MY_ATTRIBUTE ((unused)),
598 void *info MY_ATTRIBUTE ((unused)),
599 int count MY_ATTRIBUTE ((unused))
600 #endif
601 )
602 {
603 #ifdef HAVE_PSI_MUTEX_INTERFACE
604 PSI_MUTEX_CALL(register_mutex)(category, info, count);
605 #endif
606 }
607
inline_mysql_mutex_init(PSI_mutex_key key,mysql_mutex_t * that,const pthread_mutexattr_t * attr,const char * src_file,uint src_line)608 static inline int inline_mysql_mutex_init(
609 #ifdef HAVE_PSI_MUTEX_INTERFACE
610 PSI_mutex_key key,
611 #endif
612 mysql_mutex_t *that,
613 const pthread_mutexattr_t *attr
614 #ifdef SAFE_MUTEX
615 , const char *src_file, uint src_line
616 #endif
617 )
618 {
619 #ifdef HAVE_PSI_MUTEX_INTERFACE
620 that->m_psi= PSI_MUTEX_CALL(init_mutex)(key, &that->m_mutex);
621 #else
622 that->m_psi= NULL;
623 #endif
624 #ifdef SAFE_MUTEX
625 return safe_mutex_init(&that->m_mutex, attr, src_file, src_line);
626 #elif defined(MY_PTHREAD_FASTMUTEX)
627 return my_pthread_fastmutex_init(&that->m_mutex, attr);
628 #else
629 return pthread_mutex_init(&that->m_mutex, attr);
630 #endif
631 }
632
inline_mysql_mutex_destroy(mysql_mutex_t * that,const char * src_file,uint src_line)633 static inline int inline_mysql_mutex_destroy(
634 mysql_mutex_t *that
635 #ifdef SAFE_MUTEX
636 , const char *src_file, uint src_line
637 #endif
638 )
639 {
640 #ifdef HAVE_PSI_MUTEX_INTERFACE
641 if (that->m_psi != NULL)
642 {
643 PSI_MUTEX_CALL(destroy_mutex)(that->m_psi);
644 that->m_psi= NULL;
645 }
646 #endif
647 #ifdef SAFE_MUTEX
648 return safe_mutex_destroy(&that->m_mutex, src_file, src_line);
649 #elif defined(MY_PTHREAD_FASTMUTEX)
650 return pthread_mutex_destroy(&that->m_mutex.mutex);
651 #else
652 return pthread_mutex_destroy(&that->m_mutex);
653 #endif
654 }
655
inline_mysql_mutex_lock(mysql_mutex_t * that,const char * src_file,uint src_line)656 static inline int inline_mysql_mutex_lock(
657 mysql_mutex_t *that
658 #if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
659 , const char *src_file, uint src_line
660 #endif
661 )
662 {
663 int result;
664
665 #ifdef HAVE_PSI_MUTEX_INTERFACE
666 if (that->m_psi != NULL)
667 {
668 /* Instrumentation start */
669 PSI_mutex_locker *locker;
670 PSI_mutex_locker_state state;
671 locker= PSI_MUTEX_CALL(start_mutex_wait)(&state, that->m_psi,
672 PSI_MUTEX_LOCK, src_file, src_line);
673
674 /* Instrumented code */
675 #ifdef SAFE_MUTEX
676 result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
677 #elif defined(MY_PTHREAD_FASTMUTEX)
678 result= my_pthread_fastmutex_lock(&that->m_mutex);
679 #else
680 result= pthread_mutex_lock(&that->m_mutex);
681 #endif
682
683 /* Instrumentation end */
684 if (locker != NULL)
685 PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
686
687 return result;
688 }
689 #endif
690
691 /* Non instrumented code */
692 #ifdef SAFE_MUTEX
693 result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
694 #elif defined(MY_PTHREAD_FASTMUTEX)
695 result= my_pthread_fastmutex_lock(&that->m_mutex);
696 #else
697 result= pthread_mutex_lock(&that->m_mutex);
698 #endif
699
700 return result;
701 }
702
inline_mysql_mutex_trylock(mysql_mutex_t * that,const char * src_file,uint src_line)703 static inline int inline_mysql_mutex_trylock(
704 mysql_mutex_t *that
705 #if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
706 , const char *src_file, uint src_line
707 #endif
708 )
709 {
710 int result;
711
712 #ifdef HAVE_PSI_MUTEX_INTERFACE
713 if (that->m_psi != NULL)
714 {
715 /* Instrumentation start */
716 PSI_mutex_locker *locker;
717 PSI_mutex_locker_state state;
718 locker= PSI_MUTEX_CALL(start_mutex_wait)(&state, that->m_psi,
719 PSI_MUTEX_TRYLOCK, src_file, src_line);
720
721 /* Instrumented code */
722 #ifdef SAFE_MUTEX
723 result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
724 #elif defined(MY_PTHREAD_FASTMUTEX)
725 result= pthread_mutex_trylock(&that->m_mutex.mutex);
726 #else
727 result= pthread_mutex_trylock(&that->m_mutex);
728 #endif
729
730 /* Instrumentation end */
731 if (locker != NULL)
732 PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
733
734 return result;
735 }
736 #endif
737
738 /* Non instrumented code */
739 #ifdef SAFE_MUTEX
740 result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
741 #elif defined(MY_PTHREAD_FASTMUTEX)
742 result= pthread_mutex_trylock(&that->m_mutex.mutex);
743 #else
744 result= pthread_mutex_trylock(&that->m_mutex);
745 #endif
746
747 return result;
748 }
749
inline_mysql_mutex_unlock(mysql_mutex_t * that,const char * src_file,uint src_line)750 static inline int inline_mysql_mutex_unlock(
751 mysql_mutex_t *that
752 #ifdef SAFE_MUTEX
753 , const char *src_file, uint src_line
754 #endif
755 )
756 {
757 int result;
758
759 #ifdef HAVE_PSI_MUTEX_INTERFACE
760 if (that->m_psi != NULL)
761 PSI_MUTEX_CALL(unlock_mutex)(that->m_psi);
762 #endif
763
764 #ifdef SAFE_MUTEX
765 result= safe_mutex_unlock(&that->m_mutex, src_file, src_line);
766 #elif defined(MY_PTHREAD_FASTMUTEX)
767 result= pthread_mutex_unlock(&that->m_mutex.mutex);
768 #else
769 result= pthread_mutex_unlock(&that->m_mutex);
770 #endif
771
772 return result;
773 }
774
inline_mysql_rwlock_register(const char * category,PSI_rwlock_info * info,int count)775 static inline void inline_mysql_rwlock_register(
776 #ifdef HAVE_PSI_RWLOCK_INTERFACE
777 const char *category,
778 PSI_rwlock_info *info,
779 int count
780 #else
781 const char *category MY_ATTRIBUTE ((unused)),
782 void *info MY_ATTRIBUTE ((unused)),
783 int count MY_ATTRIBUTE ((unused))
784 #endif
785 )
786 {
787 #ifdef HAVE_PSI_RWLOCK_INTERFACE
788 PSI_RWLOCK_CALL(register_rwlock)(category, info, count);
789 #endif
790 }
791
inline_mysql_rwlock_init(PSI_rwlock_key key,mysql_rwlock_t * that)792 static inline int inline_mysql_rwlock_init(
793 #ifdef HAVE_PSI_RWLOCK_INTERFACE
794 PSI_rwlock_key key,
795 #endif
796 mysql_rwlock_t *that)
797 {
798 #ifdef HAVE_PSI_RWLOCK_INTERFACE
799 that->m_psi= PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_rwlock);
800 #else
801 that->m_psi= NULL;
802 #endif
803 /*
804 pthread_rwlockattr_t is not used in MySQL.
805 */
806 return my_rwlock_init(&that->m_rwlock, NULL);
807 }
808
809 #ifndef DISABLE_MYSQL_PRLOCK_H
inline_mysql_prlock_init(PSI_rwlock_key key,mysql_prlock_t * that)810 static inline int inline_mysql_prlock_init(
811 #ifdef HAVE_PSI_RWLOCK_INTERFACE
812 PSI_rwlock_key key,
813 #endif
814 mysql_prlock_t *that)
815 {
816 #ifdef HAVE_PSI_RWLOCK_INTERFACE
817 that->m_psi= PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_prlock);
818 #else
819 that->m_psi= NULL;
820 #endif
821 return rw_pr_init(&that->m_prlock);
822 }
823 #endif
824
inline_mysql_rwlock_destroy(mysql_rwlock_t * that)825 static inline int inline_mysql_rwlock_destroy(
826 mysql_rwlock_t *that)
827 {
828 #ifdef HAVE_PSI_RWLOCK_INTERFACE
829 if (that->m_psi != NULL)
830 {
831 PSI_RWLOCK_CALL(destroy_rwlock)(that->m_psi);
832 that->m_psi= NULL;
833 }
834 #endif
835 return rwlock_destroy(&that->m_rwlock);
836 }
837
838 #ifndef DISABLE_MYSQL_PRLOCK_H
inline_mysql_prlock_destroy(mysql_prlock_t * that)839 static inline int inline_mysql_prlock_destroy(
840 mysql_prlock_t *that)
841 {
842 #ifdef HAVE_PSI_RWLOCK_INTERFACE
843 if (that->m_psi != NULL)
844 {
845 PSI_RWLOCK_CALL(destroy_rwlock)(that->m_psi);
846 that->m_psi= NULL;
847 }
848 #endif
849 return rw_pr_destroy(&that->m_prlock);
850 }
851 #endif
852
inline_mysql_rwlock_rdlock(mysql_rwlock_t * that,const char * src_file,uint src_line)853 static inline int inline_mysql_rwlock_rdlock(
854 mysql_rwlock_t *that
855 #ifdef HAVE_PSI_RWLOCK_INTERFACE
856 , const char *src_file, uint src_line
857 #endif
858 )
859 {
860 int result;
861
862 #ifdef HAVE_PSI_RWLOCK_INTERFACE
863 if (that->m_psi != NULL)
864 {
865 /* Instrumentation start */
866 PSI_rwlock_locker *locker;
867 PSI_rwlock_locker_state state;
868 locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
869 PSI_RWLOCK_READLOCK, src_file, src_line);
870
871 /* Instrumented code */
872 result= rw_rdlock(&that->m_rwlock);
873
874 /* Instrumentation end */
875 if (locker != NULL)
876 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
877
878 return result;
879 }
880 #endif
881
882 /* Non instrumented code */
883 result= rw_rdlock(&that->m_rwlock);
884
885 return result;
886 }
887
888 #ifndef DISABLE_MYSQL_PRLOCK_H
inline_mysql_prlock_rdlock(mysql_prlock_t * that,const char * src_file,uint src_line)889 static inline int inline_mysql_prlock_rdlock(
890 mysql_prlock_t *that
891 #ifdef HAVE_PSI_RWLOCK_INTERFACE
892 , const char *src_file, uint src_line
893 #endif
894 )
895 {
896 int result;
897
898 #ifdef HAVE_PSI_RWLOCK_INTERFACE
899 if (that->m_psi != NULL)
900 {
901 /* Instrumentation start */
902 PSI_rwlock_locker *locker;
903 PSI_rwlock_locker_state state;
904 locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
905 PSI_RWLOCK_READLOCK, src_file, src_line);
906
907 /* Instrumented code */
908 result= rw_pr_rdlock(&that->m_prlock);
909
910 /* Instrumentation end */
911 if (locker != NULL)
912 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
913
914 return result;
915 }
916 #endif
917
918 /* Non instrumented code */
919 result= rw_pr_rdlock(&that->m_prlock);
920
921 return result;
922 }
923 #endif
924
inline_mysql_rwlock_wrlock(mysql_rwlock_t * that,const char * src_file,uint src_line)925 static inline int inline_mysql_rwlock_wrlock(
926 mysql_rwlock_t *that
927 #ifdef HAVE_PSI_RWLOCK_INTERFACE
928 , const char *src_file, uint src_line
929 #endif
930 )
931 {
932 int result;
933
934 #ifdef HAVE_PSI_RWLOCK_INTERFACE
935 if (that->m_psi != NULL)
936 {
937 /* Instrumentation start */
938 PSI_rwlock_locker *locker;
939 PSI_rwlock_locker_state state;
940 locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
941 PSI_RWLOCK_WRITELOCK, src_file, src_line);
942
943 /* Instrumented code */
944 result= rw_wrlock(&that->m_rwlock);
945
946 /* Instrumentation end */
947 if (locker != NULL)
948 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
949
950 return result;
951 }
952 #endif
953
954 /* Non instrumented code */
955 result= rw_wrlock(&that->m_rwlock);
956
957 return result;
958 }
959
960 #ifndef DISABLE_MYSQL_PRLOCK_H
inline_mysql_prlock_wrlock(mysql_prlock_t * that,const char * src_file,uint src_line)961 static inline int inline_mysql_prlock_wrlock(
962 mysql_prlock_t *that
963 #ifdef HAVE_PSI_RWLOCK_INTERFACE
964 , const char *src_file, uint src_line
965 #endif
966 )
967 {
968 int result;
969
970 #ifdef HAVE_PSI_RWLOCK_INTERFACE
971 if (that->m_psi != NULL)
972 {
973 /* Instrumentation start */
974 PSI_rwlock_locker *locker;
975 PSI_rwlock_locker_state state;
976 locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
977 PSI_RWLOCK_WRITELOCK, src_file, src_line);
978
979 /* Instrumented code */
980 result= rw_pr_wrlock(&that->m_prlock);
981
982 /* Instrumentation end */
983 if (locker != NULL)
984 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
985
986 return result;
987 }
988 #endif
989
990 /* Non instrumented code */
991 result= rw_pr_wrlock(&that->m_prlock);
992
993 return result;
994 }
995 #endif
996
inline_mysql_rwlock_tryrdlock(mysql_rwlock_t * that,const char * src_file,uint src_line)997 static inline int inline_mysql_rwlock_tryrdlock(
998 mysql_rwlock_t *that
999 #ifdef HAVE_PSI_RWLOCK_INTERFACE
1000 , const char *src_file, uint src_line
1001 #endif
1002 )
1003 {
1004 int result;
1005
1006 #ifdef HAVE_PSI_RWLOCK_INTERFACE
1007 if (that->m_psi != NULL)
1008 {
1009 /* Instrumentation start */
1010 PSI_rwlock_locker *locker;
1011 PSI_rwlock_locker_state state;
1012 locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
1013 PSI_RWLOCK_TRYREADLOCK, src_file, src_line);
1014
1015 /* Instrumented code */
1016 result= rw_tryrdlock(&that->m_rwlock);
1017
1018 /* Instrumentation end */
1019 if (locker != NULL)
1020 PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
1021
1022 return result;
1023 }
1024 #endif
1025
1026 /* Non instrumented code */
1027 result= rw_tryrdlock(&that->m_rwlock);
1028
1029 return result;
1030 }
1031
inline_mysql_rwlock_trywrlock(mysql_rwlock_t * that,const char * src_file,uint src_line)1032 static inline int inline_mysql_rwlock_trywrlock(
1033 mysql_rwlock_t *that
1034 #ifdef HAVE_PSI_RWLOCK_INTERFACE
1035 , const char *src_file, uint src_line
1036 #endif
1037 )
1038 {
1039 int result;
1040
1041 #ifdef HAVE_PSI_RWLOCK_INTERFACE
1042 if (that->m_psi != NULL)
1043 {
1044 /* Instrumentation start */
1045 PSI_rwlock_locker *locker;
1046 PSI_rwlock_locker_state state;
1047 locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
1048 PSI_RWLOCK_TRYWRITELOCK, src_file, src_line);
1049
1050 /* Instrumented code */
1051 result= rw_trywrlock(&that->m_rwlock);
1052
1053 /* Instrumentation end */
1054 if (locker != NULL)
1055 PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
1056
1057 return result;
1058 }
1059 #endif
1060
1061 /* Non instrumented code */
1062 result= rw_trywrlock(&that->m_rwlock);
1063
1064 return result;
1065 }
1066
inline_mysql_rwlock_unlock(mysql_rwlock_t * that)1067 static inline int inline_mysql_rwlock_unlock(
1068 mysql_rwlock_t *that)
1069 {
1070 int result;
1071 #ifdef HAVE_PSI_RWLOCK_INTERFACE
1072 if (that->m_psi != NULL)
1073 PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi);
1074 #endif
1075 result= rw_unlock(&that->m_rwlock);
1076 return result;
1077 }
1078
1079 #ifndef DISABLE_MYSQL_PRLOCK_H
inline_mysql_prlock_unlock(mysql_prlock_t * that)1080 static inline int inline_mysql_prlock_unlock(
1081 mysql_prlock_t *that)
1082 {
1083 int result;
1084 #ifdef HAVE_PSI_RWLOCK_INTERFACE
1085 if (that->m_psi != NULL)
1086 PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi);
1087 #endif
1088 result= rw_pr_unlock(&that->m_prlock);
1089 return result;
1090 }
1091 #endif
1092
inline_mysql_cond_register(const char * category,PSI_cond_info * info,int count)1093 static inline void inline_mysql_cond_register(
1094 #ifdef HAVE_PSI_COND_INTERFACE
1095 const char *category,
1096 PSI_cond_info *info,
1097 int count
1098 #else
1099 const char *category MY_ATTRIBUTE ((unused)),
1100 void *info MY_ATTRIBUTE ((unused)),
1101 int count MY_ATTRIBUTE ((unused))
1102 #endif
1103 )
1104 {
1105 #ifdef HAVE_PSI_COND_INTERFACE
1106 PSI_COND_CALL(register_cond)(category, info, count);
1107 #endif
1108 }
1109
inline_mysql_cond_init(PSI_cond_key key,mysql_cond_t * that,const pthread_condattr_t * attr)1110 static inline int inline_mysql_cond_init(
1111 #ifdef HAVE_PSI_COND_INTERFACE
1112 PSI_cond_key key,
1113 #endif
1114 mysql_cond_t *that,
1115 const pthread_condattr_t *attr)
1116 {
1117 #ifdef HAVE_PSI_COND_INTERFACE
1118 that->m_psi= PSI_COND_CALL(init_cond)(key, &that->m_cond);
1119 #else
1120 that->m_psi= NULL;
1121 #endif
1122 return pthread_cond_init(&that->m_cond, attr);
1123 }
1124
inline_mysql_cond_destroy(mysql_cond_t * that)1125 static inline int inline_mysql_cond_destroy(
1126 mysql_cond_t *that)
1127 {
1128 #ifdef HAVE_PSI_COND_INTERFACE
1129 if (that->m_psi != NULL)
1130 {
1131 PSI_COND_CALL(destroy_cond)(that->m_psi);
1132 that->m_psi= NULL;
1133 }
1134 #endif
1135 return pthread_cond_destroy(&that->m_cond);
1136 }
1137
inline_mysql_cond_wait(mysql_cond_t * that,mysql_mutex_t * mutex,const char * src_file,uint src_line)1138 static inline int inline_mysql_cond_wait(
1139 mysql_cond_t *that,
1140 mysql_mutex_t *mutex
1141 #ifdef HAVE_PSI_COND_INTERFACE
1142 , const char *src_file, uint src_line
1143 #endif
1144 )
1145 {
1146 int result;
1147
1148 #ifdef HAVE_PSI_COND_INTERFACE
1149 if (that->m_psi != NULL)
1150 {
1151 /* Instrumentation start */
1152 PSI_cond_locker *locker;
1153 PSI_cond_locker_state state;
1154 locker= PSI_COND_CALL(start_cond_wait)(&state, that->m_psi, mutex->m_psi,
1155 PSI_COND_WAIT, src_file, src_line);
1156
1157 /* Instrumented code */
1158 result= my_cond_wait(&that->m_cond, &mutex->m_mutex);
1159
1160 /* Instrumentation end */
1161 if (locker != NULL)
1162 PSI_COND_CALL(end_cond_wait)(locker, result);
1163
1164 return result;
1165 }
1166 #endif
1167
1168 /* Non instrumented code */
1169 result= my_cond_wait(&that->m_cond, &mutex->m_mutex);
1170
1171 return result;
1172 }
1173
inline_mysql_cond_timedwait(mysql_cond_t * that,mysql_mutex_t * mutex,const struct timespec * abstime,const char * src_file,uint src_line)1174 static inline int inline_mysql_cond_timedwait(
1175 mysql_cond_t *that,
1176 mysql_mutex_t *mutex,
1177 const struct timespec *abstime
1178 #ifdef HAVE_PSI_COND_INTERFACE
1179 , const char *src_file, uint src_line
1180 #endif
1181 )
1182 {
1183 int result;
1184
1185 #ifdef HAVE_PSI_COND_INTERFACE
1186 if (that->m_psi != NULL)
1187 {
1188 /* Instrumentation start */
1189 PSI_cond_locker *locker;
1190 PSI_cond_locker_state state;
1191 locker= PSI_COND_CALL(start_cond_wait)(&state, that->m_psi, mutex->m_psi,
1192 PSI_COND_TIMEDWAIT, src_file, src_line);
1193
1194 /* Instrumented code */
1195 result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
1196
1197 /* Instrumentation end */
1198 if (locker != NULL)
1199 PSI_COND_CALL(end_cond_wait)(locker, result);
1200
1201 return result;
1202 }
1203 #endif
1204
1205 /* Non instrumented code */
1206 result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
1207
1208 return result;
1209 }
1210
inline_mysql_cond_signal(mysql_cond_t * that)1211 static inline int inline_mysql_cond_signal(
1212 mysql_cond_t *that)
1213 {
1214 int result;
1215 #ifdef HAVE_PSI_COND_INTERFACE
1216 if (that->m_psi != NULL)
1217 PSI_COND_CALL(signal_cond)(that->m_psi);
1218 #endif
1219 result= pthread_cond_signal(&that->m_cond);
1220 return result;
1221 }
1222
inline_mysql_cond_broadcast(mysql_cond_t * that)1223 static inline int inline_mysql_cond_broadcast(
1224 mysql_cond_t *that)
1225 {
1226 int result;
1227 #ifdef HAVE_PSI_COND_INTERFACE
1228 if (that->m_psi != NULL)
1229 PSI_COND_CALL(broadcast_cond)(that->m_psi);
1230 #endif
1231 result= pthread_cond_broadcast(&that->m_cond);
1232 return result;
1233 }
1234
inline_mysql_thread_register(const char * category,PSI_thread_info * info,int count)1235 static inline void inline_mysql_thread_register(
1236 #ifdef HAVE_PSI_THREAD_INTERFACE
1237 const char *category,
1238 PSI_thread_info *info,
1239 int count
1240 #else
1241 const char *category MY_ATTRIBUTE ((unused)),
1242 void *info MY_ATTRIBUTE ((unused)),
1243 int count MY_ATTRIBUTE ((unused))
1244 #endif
1245 )
1246 {
1247 #ifdef HAVE_PSI_THREAD_INTERFACE
1248 PSI_THREAD_CALL(register_thread)(category, info, count);
1249 #endif
1250 }
1251
1252 #ifdef HAVE_PSI_THREAD_INTERFACE
inline_mysql_thread_create(PSI_thread_key key,pthread_t * thread,const pthread_attr_t * attr,void * (* start_routine)(void *),void * arg)1253 static inline int inline_mysql_thread_create(
1254 PSI_thread_key key,
1255 pthread_t *thread, const pthread_attr_t *attr,
1256 void *(*start_routine)(void*), void *arg)
1257 {
1258 int result;
1259 result= PSI_THREAD_CALL(spawn_thread)(key, thread, attr, start_routine, arg);
1260 return result;
1261 }
1262
inline_mysql_thread_set_psi_id(ulong id)1263 static inline void inline_mysql_thread_set_psi_id(ulong id)
1264 {
1265 struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
1266 PSI_THREAD_CALL(set_thread_id)(psi, id);
1267 }
1268 #endif
1269
1270 #endif /* DISABLE_MYSQL_THREAD_H */
1271
1272 /** @} (end of group Thread_instrumentation) */
1273
1274 #endif
1275
1276