1 /* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
2    Copyright (c) 2017, 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_TABLE_H
25 #define MYSQL_TABLE_H
26 
27 /**
28   @file mysql/psi/mysql_table.h
29   Instrumentation helpers for table io.
30 */
31 
32 #include "mysql/psi/psi.h"
33 
34 /**
35   @defgroup Table_instrumentation Table Instrumentation
36   @ingroup Instrumentation_interface
37   @{
38 */
39 
40 #ifdef HAVE_PSI_TABLE_INTERFACE
41 #define MYSQL_UNBIND_TABLE(handler) (handler)->unbind_psi()
42 #define MYSQL_REBIND_TABLE(handler) (handler)->rebind_psi()
43 
44 #define PSI_CALL_unbind_table           PSI_TABLE_CALL(unbind_table)
45 #define PSI_CALL_rebind_table           PSI_TABLE_CALL(rebind_table)
46 #define PSI_CALL_open_table             PSI_TABLE_CALL(open_table)
47 #define PSI_CALL_close_table            PSI_TABLE_CALL(close_table)
48 #define PSI_CALL_get_table_share        PSI_TABLE_CALL(get_table_share)
49 #define PSI_CALL_release_table_share    PSI_TABLE_CALL(release_table_share)
50 #define PSI_CALL_drop_table_share       PSI_TABLE_CALL(drop_table_share)
51 #else
52 #define MYSQL_UNBIND_TABLE(handler)                     do { } while(0)
53 #define MYSQL_REBIND_TABLE(handler)                     do { } while(0)
54 
55 #define PSI_CALL_unbind_table(A1)                       do { } while(0)
56 #define PSI_CALL_rebind_table(A1,A2,A3)                 NULL
57 #define PSI_CALL_close_table(A1)                        do { } while(0)
58 #define PSI_CALL_open_table(A1,A2)                      NULL
59 #define PSI_CALL_get_table_share(A1,A2)                 NULL
60 #define PSI_CALL_release_table_share(A1)                do { } while(0)
61 #define PSI_CALL_drop_table_share(A1,A2,A3,A4,A5)       do { } while(0)
62 #endif
63 
64 /**
65   @def MYSQL_TABLE_WAIT_VARIABLES
66   Instrumentation helper for table waits.
67   This instrumentation declares local variables.
68   Do not use a ';' after this macro
69   @param LOCKER the locker
70   @param STATE the locker state
71   @sa MYSQL_START_TABLE_IO_WAIT.
72   @sa MYSQL_END_TABLE_IO_WAIT.
73   @sa MYSQL_START_TABLE_LOCK_WAIT.
74   @sa MYSQL_END_TABLE_LOCK_WAIT.
75 */
76 #ifdef HAVE_PSI_TABLE_INTERFACE
77   #define MYSQL_TABLE_WAIT_VARIABLES(LOCKER, STATE) \
78     struct PSI_table_locker* LOCKER; \
79     PSI_table_locker_state STATE;
80 #else
81   #define MYSQL_TABLE_WAIT_VARIABLES(LOCKER, STATE)
82 #endif
83 
84 /**
85   @def MYSQL_TABLE_IO_WAIT
86   Instrumentation helper for table io_waits.
87   This instrumentation marks the start of a wait event.
88   @param PSI the instrumented table
89   @param OP the table operation to be performed
90   @param INDEX the table index used if any, or MAY_KEY.
91   @param FLAGS per table operation flags.
92   @sa MYSQL_END_TABLE_WAIT.
93 */
94 #ifdef HAVE_PSI_TABLE_INTERFACE
95   #define MYSQL_TABLE_IO_WAIT(PSI, OP, INDEX, FLAGS, PAYLOAD) \
96     {                                                         \
97       if (psi_likely(PSI != NULL))                            \
98       {                                                       \
99         PSI_table_locker *locker;                             \
100         PSI_table_locker_state state;                         \
101         locker= PSI_TABLE_CALL(start_table_io_wait)           \
102           (& state, PSI, OP, INDEX, __FILE__, __LINE__);      \
103         PAYLOAD                                               \
104         if (locker != NULL)                                   \
105           PSI_TABLE_CALL(end_table_io_wait)(locker);          \
106       }                                                       \
107       else                                                    \
108       {                                                       \
109         PAYLOAD                                               \
110       }                                                       \
111     }
112 #else
113   #define MYSQL_TABLE_IO_WAIT(PSI, OP, INDEX, FLAGS, PAYLOAD) \
114     PAYLOAD
115 #endif
116 
117 /**
118   @def MYSQL_TABLE_LOCK_WAIT
119   Instrumentation helper for table io_waits.
120   This instrumentation marks the start of a wait event.
121   @param PSI the instrumented table
122   @param OP the table operation to be performed
123   @param INDEX the table index used if any, or MAY_KEY.
124   @param FLAGS per table operation flags.
125   @sa MYSQL_END_TABLE_WAIT.
126 */
127 #ifdef HAVE_PSI_TABLE_INTERFACE
128   #define MYSQL_TABLE_LOCK_WAIT(PSI, OP, FLAGS, PAYLOAD) \
129     {                                                    \
130       if (psi_likely(PSI != NULL))                       \
131       {                                                  \
132         PSI_table_locker *locker;                        \
133         PSI_table_locker_state state;                    \
134         locker= PSI_TABLE_CALL(start_table_lock_wait)    \
135           (& state, PSI, OP, FLAGS, __FILE__, __LINE__); \
136         PAYLOAD                                          \
137         if (locker != NULL)                              \
138           PSI_TABLE_CALL(end_table_lock_wait)(locker);   \
139       }                                                  \
140       else                                               \
141       {                                                  \
142         PAYLOAD                                          \
143       }                                                  \
144     }
145 #else
146   #define MYSQL_TABLE_LOCK_WAIT(PSI, OP, FLAGS, PAYLOAD) \
147     PAYLOAD
148 #endif
149 
150 /**
151   @def MYSQL_START_TABLE_LOCK_WAIT
152   Instrumentation helper for table lock waits.
153   This instrumentation marks the start of a wait event.
154   @param LOCKER the locker
155   @param STATE the locker state
156   @param PSI the instrumented table
157   @param OP the table operation to be performed
158   @param FLAGS per table operation flags.
159   @sa MYSQL_END_TABLE_LOCK_WAIT.
160 */
161 #ifdef HAVE_PSI_TABLE_INTERFACE
162   #define MYSQL_START_TABLE_LOCK_WAIT(LOCKER, STATE, PSI, OP, FLAGS) \
163     LOCKER= inline_mysql_start_table_lock_wait(STATE, PSI, \
164                                                OP, FLAGS, __FILE__, __LINE__)
165 #else
166   #define MYSQL_START_TABLE_LOCK_WAIT(LOCKER, STATE, PSI, OP, FLAGS) \
167     do {} while (0)
168 #endif
169 
170 /**
171   @def MYSQL_END_TABLE_LOCK_WAIT
172   Instrumentation helper for table lock waits.
173   This instrumentation marks the end of a wait event.
174   @param LOCKER the locker
175   @sa MYSQL_START_TABLE_LOCK_WAIT.
176 */
177 #ifdef HAVE_PSI_TABLE_INTERFACE
178   #define MYSQL_END_TABLE_LOCK_WAIT(LOCKER) \
179     inline_mysql_end_table_lock_wait(LOCKER)
180 #else
181   #define MYSQL_END_TABLE_LOCK_WAIT(LOCKER) \
182     do {} while (0)
183 #endif
184 
185 #ifdef HAVE_PSI_TABLE_INTERFACE
186 /**
187   Instrumentation calls for MYSQL_START_TABLE_LOCK_WAIT.
188   @sa MYSQL_END_TABLE_LOCK_WAIT.
189 */
190 static inline struct PSI_table_locker *
inline_mysql_start_table_lock_wait(PSI_table_locker_state * state,struct PSI_table * psi,enum PSI_table_lock_operation op,ulong flags,const char * src_file,uint src_line)191 inline_mysql_start_table_lock_wait(PSI_table_locker_state *state,
192                                    struct PSI_table *psi,
193                                    enum PSI_table_lock_operation op,
194                                    ulong flags, const char *src_file, uint src_line)
195 {
196   if (psi_likely(psi != NULL))
197   {
198     struct PSI_table_locker *locker;
199     locker= PSI_TABLE_CALL(start_table_lock_wait)
200       (state, psi, op, flags, src_file, src_line);
201     return locker;
202   }
203   return NULL;
204 }
205 
206 /**
207   Instrumentation calls for MYSQL_END_TABLE_LOCK_WAIT.
208   @sa MYSQL_START_TABLE_LOCK_WAIT.
209 */
210 static inline void
inline_mysql_end_table_lock_wait(struct PSI_table_locker * locker)211 inline_mysql_end_table_lock_wait(struct PSI_table_locker *locker)
212 {
213   if (psi_likely(locker != NULL))
214     PSI_TABLE_CALL(end_table_lock_wait)(locker);
215 }
216 #endif
217 
218 /** @} (end of group Table_instrumentation) */
219 
220 #endif
221 
222