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