1 /*======
2 This file is part of PerconaFT.
3
4 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
5
6 PerconaFT is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2,
8 as published by the Free Software Foundation.
9
10 PerconaFT is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
17
18 ----------------------------------------
19
20 PerconaFT is free software: you can redistribute it and/or modify
21 it under the terms of the GNU Affero General Public License, version 3,
22 as published by the Free Software Foundation.
23
24 PerconaFT is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU Affero General Public License for more details.
28
29 You should have received a copy of the GNU Affero General Public License
30 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
31
32 ----------------------------------------
33
34 Licensed under the Apache License, Version 2.0 (the "License");
35 you may not use this file except in compliance with the License.
36 You may obtain a copy of the License at
37
38 http://www.apache.org/licenses/LICENSE-2.0
39
40 Unless required by applicable law or agreed to in writing, software
41 distributed under the License is distributed on an "AS IS" BASIS,
42 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43 See the License for the specific language governing permissions and
44 limitations under the License.
45 ======= */
46
47 #pragma once
48
49 #include <stdio.h> // FILE
50
51 // Performance instrumentation object identifier type
52 typedef unsigned int pfs_key_t;
53
54 enum class toku_instr_object_type { mutex, rwlock, cond, thread, file };
55
56 struct PSI_file;
57
58 struct TOKU_FILE {
59 /** The real file. */
60 FILE *file;
61 struct PSI_file *key;
TOKU_FILETOKU_FILE62 TOKU_FILE() : file(nullptr), key(nullptr) {}
63 };
64
65 struct PSI_mutex;
66 struct PSI_cond;
67 struct PSI_rwlock;
68
69 struct toku_mutex_t;
70 struct toku_cond_t;
71 struct toku_pthread_rwlock_t;
72
73 class toku_instr_key;
74
75 class toku_instr_probe_empty {
76 public:
toku_instr_probe_empty(UU (const toku_instr_key & key))77 explicit toku_instr_probe_empty(UU(const toku_instr_key &key)) {}
78
start_with_source_location(UU (const char * src_file),UU (int src_line))79 void start_with_source_location(UU(const char *src_file),
80 UU(int src_line)) {}
81
stop()82 void stop() {}
83 };
84
85 #define TOKU_PROBE_START(p) p->start_with_source_location(__FILE__, __LINE__)
86 #define TOKU_PROBE_STOP(p) p->stop
87
88 extern toku_instr_key toku_uninstrumented;
89
90 #ifndef TOKU_MYSQL_WITH_PFS
91
92 #include <pthread.h>
93
94 class toku_instr_key {
95 public:
toku_instr_key(UU (toku_instr_object_type type),UU (const char * group),UU (const char * name))96 toku_instr_key(UU(toku_instr_object_type type),
97 UU(const char *group),
98 UU(const char *name)) {}
99
toku_instr_key(UU (pfs_key_t key_id))100 explicit toku_instr_key(UU(pfs_key_t key_id)) {}
101
~toku_instr_key()102 ~toku_instr_key() {}
103 };
104
105 typedef toku_instr_probe_empty toku_instr_probe;
106
107 enum class toku_instr_file_op {
108 file_stream_open,
109 file_create,
110 file_open,
111 file_delete,
112 file_rename,
113 file_read,
114 file_write,
115 file_sync,
116 file_stream_close,
117 file_close,
118 file_stat
119 };
120
121 struct PSI_file {};
122 struct PSI_mutex {};
123
124 struct toku_io_instrumentation {};
125
toku_pthread_create(UU (const toku_instr_key & key),pthread_t * thread,const pthread_attr_t * attr,void * (* start_routine)(void *),void * arg)126 inline int toku_pthread_create(UU(const toku_instr_key &key),
127 pthread_t *thread,
128 const pthread_attr_t *attr,
129 void *(*start_routine)(void *),
130 void *arg) {
131 return pthread_create(thread, attr, start_routine, arg);
132 }
133
toku_instr_register_current_thread()134 inline void toku_instr_register_current_thread() {}
135
toku_instr_delete_current_thread()136 inline void toku_instr_delete_current_thread() {}
137
138 // Instrument file creation, opening, closing, and renaming
toku_instr_file_open_begin(UU (toku_io_instrumentation & io_instr),UU (const toku_instr_key & key),UU (toku_instr_file_op op),UU (const char * name),UU (const char * src_file),UU (int src_line))139 inline void toku_instr_file_open_begin(UU(toku_io_instrumentation &io_instr),
140 UU(const toku_instr_key &key),
141 UU(toku_instr_file_op op),
142 UU(const char *name),
143 UU(const char *src_file),
144 UU(int src_line)) {}
145
toku_instr_file_stream_open_end(UU (toku_io_instrumentation & io_instr),UU (TOKU_FILE & file))146 inline void toku_instr_file_stream_open_end(
147 UU(toku_io_instrumentation &io_instr),
148 UU(TOKU_FILE &file)) {}
149
toku_instr_file_open_end(UU (toku_io_instrumentation & io_instr),UU (int fd))150 inline void toku_instr_file_open_end(UU(toku_io_instrumentation &io_instr),
151 UU(int fd)) {}
152
toku_instr_file_name_close_begin(UU (toku_io_instrumentation & io_instr),UU (const toku_instr_key & key),UU (toku_instr_file_op op),UU (const char * name),UU (const char * src_file),UU (int src_line))153 inline void toku_instr_file_name_close_begin(
154 UU(toku_io_instrumentation &io_instr),
155 UU(const toku_instr_key &key),
156 UU(toku_instr_file_op op),
157 UU(const char *name),
158 UU(const char *src_file),
159 UU(int src_line)) {}
160
toku_instr_file_stream_close_begin(UU (toku_io_instrumentation & io_instr),UU (toku_instr_file_op op),UU (TOKU_FILE & file),UU (const char * src_file),UU (int src_line))161 inline void toku_instr_file_stream_close_begin(
162 UU(toku_io_instrumentation &io_instr),
163 UU(toku_instr_file_op op),
164 UU(TOKU_FILE &file),
165 UU(const char *src_file),
166 UU(int src_line)) {}
167
toku_instr_file_fd_close_begin(UU (toku_io_instrumentation & io_instr),UU (toku_instr_file_op op),UU (int fd),UU (const char * src_file),UU (int src_line))168 inline void toku_instr_file_fd_close_begin(
169 UU(toku_io_instrumentation &io_instr),
170 UU(toku_instr_file_op op),
171 UU(int fd),
172 UU(const char *src_file),
173 UU(int src_line)) {}
174
toku_instr_file_close_end(UU (toku_io_instrumentation & io_instr),UU (int result))175 inline void toku_instr_file_close_end(UU(toku_io_instrumentation &io_instr),
176 UU(int result)) {}
177
toku_instr_file_io_begin(UU (toku_io_instrumentation & io_instr),UU (toku_instr_file_op op),UU (int fd),UU (unsigned int count),UU (const char * src_file),UU (int src_line))178 inline void toku_instr_file_io_begin(UU(toku_io_instrumentation &io_instr),
179 UU(toku_instr_file_op op),
180 UU(int fd),
181 UU(unsigned int count),
182 UU(const char *src_file),
183 UU(int src_line)) {}
184
toku_instr_file_name_io_begin(UU (toku_io_instrumentation & io_instr),UU (const toku_instr_key & key),UU (toku_instr_file_op op),UU (const char * name),UU (unsigned int count),UU (const char * src_file),UU (int src_line))185 inline void toku_instr_file_name_io_begin(UU(toku_io_instrumentation &io_instr),
186 UU(const toku_instr_key &key),
187 UU(toku_instr_file_op op),
188 UU(const char *name),
189 UU(unsigned int count),
190 UU(const char *src_file),
191 UU(int src_line)) {}
192
toku_instr_file_stream_io_begin(UU (toku_io_instrumentation & io_instr),UU (toku_instr_file_op op),UU (TOKU_FILE & file),UU (unsigned int count),UU (const char * src_file),UU (int src_line))193 inline void toku_instr_file_stream_io_begin(
194 UU(toku_io_instrumentation &io_instr),
195 UU(toku_instr_file_op op),
196 UU(TOKU_FILE &file),
197 UU(unsigned int count),
198 UU(const char *src_file),
199 UU(int src_line)) {}
200
toku_instr_file_io_end(UU (toku_io_instrumentation & io_instr),UU (unsigned int count))201 inline void toku_instr_file_io_end(UU(toku_io_instrumentation &io_instr),
202 UU(unsigned int count)) {}
203
204 struct toku_mutex_t;
205
206 struct toku_mutex_instrumentation {};
207
toku_instr_mutex_init(UU (const toku_instr_key & key),UU (toku_mutex_t & mutex))208 inline PSI_mutex *toku_instr_mutex_init(UU(const toku_instr_key &key),
209 UU(toku_mutex_t &mutex)) {
210 return nullptr;
211 }
212
toku_instr_mutex_destroy(UU (PSI_mutex * & mutex_instr))213 inline void toku_instr_mutex_destroy(UU(PSI_mutex *&mutex_instr)) {}
214
toku_instr_mutex_lock_start(UU (toku_mutex_instrumentation & mutex_instr),UU (toku_mutex_t & mutex),UU (const char * src_file),UU (int src_line))215 inline void toku_instr_mutex_lock_start(
216 UU(toku_mutex_instrumentation &mutex_instr),
217 UU(toku_mutex_t &mutex),
218 UU(const char *src_file),
219 UU(int src_line)) {}
220
toku_instr_mutex_trylock_start(UU (toku_mutex_instrumentation & mutex_instr),UU (toku_mutex_t & mutex),UU (const char * src_file),UU (int src_line))221 inline void toku_instr_mutex_trylock_start(
222 UU(toku_mutex_instrumentation &mutex_instr),
223 UU(toku_mutex_t &mutex),
224 UU(const char *src_file),
225 UU(int src_line)) {}
226
toku_instr_mutex_lock_end(UU (toku_mutex_instrumentation & mutex_instr),UU (int pthread_mutex_lock_result))227 inline void toku_instr_mutex_lock_end(
228 UU(toku_mutex_instrumentation &mutex_instr),
229 UU(int pthread_mutex_lock_result)) {}
230
toku_instr_mutex_unlock(UU (PSI_mutex * mutex_instr))231 inline void toku_instr_mutex_unlock(UU(PSI_mutex *mutex_instr)) {}
232
233 struct toku_cond_instrumentation {};
234
235 enum class toku_instr_cond_op {
236 cond_wait,
237 cond_timedwait,
238 };
239
toku_instr_cond_init(UU (const toku_instr_key & key),UU (toku_cond_t & cond))240 inline PSI_cond *toku_instr_cond_init(UU(const toku_instr_key &key),
241 UU(toku_cond_t &cond)) {
242 return nullptr;
243 }
244
toku_instr_cond_destroy(UU (PSI_cond * & cond_instr))245 inline void toku_instr_cond_destroy(UU(PSI_cond *&cond_instr)) {}
246
toku_instr_cond_wait_start(UU (toku_cond_instrumentation & cond_instr),UU (toku_instr_cond_op op),UU (toku_cond_t & cond),UU (toku_mutex_t & mutex),UU (const char * src_file),UU (int src_line))247 inline void toku_instr_cond_wait_start(
248 UU(toku_cond_instrumentation &cond_instr),
249 UU(toku_instr_cond_op op),
250 UU(toku_cond_t &cond),
251 UU(toku_mutex_t &mutex),
252 UU(const char *src_file),
253 UU(int src_line)) {}
254
toku_instr_cond_wait_end(UU (toku_cond_instrumentation & cond_instr),UU (int pthread_cond_wait_result))255 inline void toku_instr_cond_wait_end(UU(toku_cond_instrumentation &cond_instr),
256 UU(int pthread_cond_wait_result)) {}
257
toku_instr_cond_signal(UU (toku_cond_t & cond))258 inline void toku_instr_cond_signal(UU(toku_cond_t &cond)) {}
259
toku_instr_cond_broadcast(UU (toku_cond_t & cond))260 inline void toku_instr_cond_broadcast(UU(toku_cond_t &cond)) {}
261
262 // rwlock instrumentation
263 struct toku_rwlock_instrumentation {};
264
toku_instr_rwlock_init(UU (const toku_instr_key & key),UU (toku_pthread_rwlock_t & rwlock))265 inline PSI_rwlock *toku_instr_rwlock_init(UU(const toku_instr_key &key),
266 UU(toku_pthread_rwlock_t &rwlock)) {
267 return nullptr;
268 }
269
toku_instr_rwlock_destroy(UU (PSI_rwlock * & rwlock_instr))270 inline void toku_instr_rwlock_destroy(UU(PSI_rwlock *&rwlock_instr)) {}
271
toku_instr_rwlock_rdlock_wait_start(UU (toku_rwlock_instrumentation & rwlock_instr),UU (toku_pthread_rwlock_t & rwlock),UU (const char * src_file),UU (int src_line))272 inline void toku_instr_rwlock_rdlock_wait_start(
273 UU(toku_rwlock_instrumentation &rwlock_instr),
274 UU(toku_pthread_rwlock_t &rwlock),
275 UU(const char *src_file),
276 UU(int src_line)) {}
277
toku_instr_rwlock_wrlock_wait_start(UU (toku_rwlock_instrumentation & rwlock_instr),UU (toku_pthread_rwlock_t & rwlock),UU (const char * src_file),UU (int src_line))278 inline void toku_instr_rwlock_wrlock_wait_start(
279 UU(toku_rwlock_instrumentation &rwlock_instr),
280 UU(toku_pthread_rwlock_t &rwlock),
281 UU(const char *src_file),
282 UU(int src_line)) {}
283
toku_instr_rwlock_rdlock_wait_end(UU (toku_rwlock_instrumentation & rwlock_instr),UU (int pthread_rwlock_wait_result))284 inline void toku_instr_rwlock_rdlock_wait_end(
285 UU(toku_rwlock_instrumentation &rwlock_instr),
286 UU(int pthread_rwlock_wait_result)) {}
287
toku_instr_rwlock_wrlock_wait_end(UU (toku_rwlock_instrumentation & rwlock_instr),UU (int pthread_rwlock_wait_result))288 inline void toku_instr_rwlock_wrlock_wait_end(
289 UU(toku_rwlock_instrumentation &rwlock_instr),
290 UU(int pthread_rwlock_wait_result)) {}
291
toku_instr_rwlock_unlock(UU (toku_pthread_rwlock_t & rwlock))292 inline void toku_instr_rwlock_unlock(UU(toku_pthread_rwlock_t &rwlock)) {}
293
294 #else // TOKU_MYSQL_WITH_PFS
295 // There can be not only mysql but also mongodb or any other PFS stuff
296 #include <toku_instr_mysql.h>
297 #endif // TOKU_MYSQL_WITH_PFS
298
299 extern toku_instr_key toku_uninstrumented;
300
301 extern toku_instr_probe *toku_instr_probe_1;
302
303 // threads
304 extern toku_instr_key *extractor_thread_key;
305 extern toku_instr_key *fractal_thread_key;
306 extern toku_instr_key *io_thread_key;
307 extern toku_instr_key *eviction_thread_key;
308 extern toku_instr_key *kibbutz_thread_key;
309 extern toku_instr_key *minicron_thread_key;
310 extern toku_instr_key *tp_internal_thread_key;
311
312 // Files
313 extern toku_instr_key *tokudb_file_data_key;
314 extern toku_instr_key *tokudb_file_load_key;
315 extern toku_instr_key *tokudb_file_tmp_key;
316 extern toku_instr_key *tokudb_file_log_key;
317
318 // Mutexes
319 extern toku_instr_key *kibbutz_mutex_key;
320 extern toku_instr_key *minicron_p_mutex_key;
321 extern toku_instr_key *queue_result_mutex_key;
322 extern toku_instr_key *tpool_lock_mutex_key;
323 extern toku_instr_key *workset_lock_mutex_key;
324 extern toku_instr_key *bjm_jobs_lock_mutex_key;
325 extern toku_instr_key *log_internal_lock_mutex_key;
326 extern toku_instr_key *cachetable_ev_thread_lock_mutex_key;
327 extern toku_instr_key *cachetable_disk_nb_mutex_key;
328 extern toku_instr_key *cachetable_m_mutex_key;
329 extern toku_instr_key *safe_file_size_lock_mutex_key;
330 extern toku_instr_key *checkpoint_safe_mutex_key;
331 extern toku_instr_key *ft_ref_lock_mutex_key;
332 extern toku_instr_key *loader_error_mutex_key;
333 extern toku_instr_key *bfs_mutex_key;
334 extern toku_instr_key *loader_bl_mutex_key;
335 extern toku_instr_key *loader_fi_lock_mutex_key;
336 extern toku_instr_key *loader_out_mutex_key;
337 extern toku_instr_key *result_output_condition_lock_mutex_key;
338 extern toku_instr_key *block_table_mutex_key;
339 extern toku_instr_key *rollback_log_node_cache_mutex_key;
340 extern toku_instr_key *txn_lock_mutex_key;
341 extern toku_instr_key *txn_state_lock_mutex_key;
342 extern toku_instr_key *txn_child_manager_mutex_key;
343 extern toku_instr_key *txn_manager_lock_mutex_key;
344 extern toku_instr_key *treenode_mutex_key;
345 extern toku_instr_key *manager_mutex_key;
346 extern toku_instr_key *manager_escalation_mutex_key;
347 extern toku_instr_key *manager_escalator_mutex_key;
348 extern toku_instr_key *db_txn_struct_i_txn_mutex_key;
349 extern toku_instr_key *indexer_i_indexer_lock_mutex_key;
350 extern toku_instr_key *indexer_i_indexer_estimate_lock_mutex_key;
351 extern toku_instr_key *locktree_request_info_mutex_key;
352 extern toku_instr_key *locktree_request_info_retry_mutex_key;
353
354 // condition vars
355 extern toku_instr_key *result_state_cond_key;
356 extern toku_instr_key *bjm_jobs_wait_key;
357 extern toku_instr_key *cachetable_p_refcount_wait_key;
358 extern toku_instr_key *cachetable_m_flow_control_cond_key;
359 extern toku_instr_key *cachetable_m_ev_thread_cond_key;
360 extern toku_instr_key *bfs_cond_key;
361 extern toku_instr_key *result_output_condition_key;
362 extern toku_instr_key *manager_m_escalator_done_key;
363 extern toku_instr_key *lock_request_m_wait_cond_key;
364 extern toku_instr_key *queue_result_cond_key;
365 extern toku_instr_key *ws_worker_wait_key;
366 extern toku_instr_key *rwlock_wait_read_key;
367 extern toku_instr_key *rwlock_wait_write_key;
368 extern toku_instr_key *rwlock_cond_key;
369 extern toku_instr_key *tp_thread_wait_key;
370 extern toku_instr_key *tp_pool_wait_free_key;
371 extern toku_instr_key *frwlock_m_wait_read_key;
372 extern toku_instr_key *kibbutz_k_cond_key;
373 extern toku_instr_key *minicron_p_condvar_key;
374 extern toku_instr_key *locktree_request_info_retry_cv_key;
375
376 // rwlocks
377 extern toku_instr_key *multi_operation_lock_key;
378 extern toku_instr_key *low_priority_multi_operation_lock_key;
379 extern toku_instr_key *cachetable_m_list_lock_key;
380 extern toku_instr_key *cachetable_m_pending_lock_expensive_key;
381 extern toku_instr_key *cachetable_m_pending_lock_cheap_key;
382 extern toku_instr_key *cachetable_m_lock_key;
383 extern toku_instr_key *result_i_open_dbs_rwlock_key;
384 extern toku_instr_key *checkpoint_safe_rwlock_key;
385 extern toku_instr_key *cachetable_value_key;
386 extern toku_instr_key *safe_file_size_lock_rwlock_key;
387 extern toku_instr_key *cachetable_disk_nb_rwlock_key;
388