1#ifdef MYSQL_TOKUDB_ENGINE
2#include "toku_portability.h"
3#include "toku_pthread.h"
4
5toku_instr_probe_pfs::toku_instr_probe_pfs(const toku_instr_key &key)
6 : mutex(new toku_mutex_t) {
7 toku_mutex_init(key, mutex.get(), nullptr);
8}
9
10toku_instr_probe_pfs::~toku_instr_probe_pfs() {
11 toku_mutex_destroy(mutex.get());
12}
13
14// Thread instrumentation
15
16int toku_pthread_create(const toku_instr_key &key,
17 pthread_t *thread,
18 const pthread_attr_t *attr,
19 void *(*start_routine)(void *),
20 void *arg) {
21#if (MYSQL_VERSION_MAJOR >= 5) && (MYSQL_VERSION_MINOR >= 7)
22 return PSI_THREAD_CALL(spawn_thread)(
23 key.id(), reinterpret_cast<my_thread_handle *>(thread),
24 attr, start_routine, arg);
25#else
26 return PSI_THREAD_CALL(spawn_thread)(
27 key.id(), thread, attr, start_routine, arg);
28#endif
29}
30
31void toku_instr_register_current_thread(const toku_instr_key &key) {
32 struct PSI_thread *psi_thread =
33 PSI_THREAD_CALL(new_thread)(key.id(), nullptr, 0);
34 PSI_THREAD_CALL(set_thread)(psi_thread);
35}
36
37void toku_instr_delete_current_thread() {
38 PSI_THREAD_CALL(delete_current_thread)();
39}
40
41// I/O instrumentation
42
43void toku_instr_file_open_begin(toku_io_instrumentation &io_instr,
44 const toku_instr_key &key,
45 toku_instr_file_op op,
46 const char *name,
47 const char *src_file,
48 int src_line) {
49 io_instr.locker =
50 PSI_FILE_CALL(get_thread_file_name_locker)(
51 &io_instr.state, key.id(), static_cast<PSI_file_operation>(op),
52 name, io_instr.locker);
53 if (io_instr.locker != nullptr) {
54 PSI_FILE_CALL(start_file_open_wait)
55 (io_instr.locker, src_file, src_line);
56 }
57}
58
59void toku_instr_file_stream_open_end(toku_io_instrumentation &io_instr,
60 TOKU_FILE &file) {
61 file.key = nullptr;
62 if (FT_LIKELY(io_instr.locker)) {
63 file.key =
64 PSI_FILE_CALL(end_file_open_wait)(io_instr.locker, file.file);
65 }
66}
67
68void toku_instr_file_open_end(toku_io_instrumentation &io_instr, int fd) {
69 if (FT_LIKELY(io_instr.locker))
70 PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)
71 (io_instr.locker, fd);
72}
73
74void toku_instr_file_name_close_begin(toku_io_instrumentation &io_instr,
75 const toku_instr_key &key,
76 toku_instr_file_op op,
77 const char *name,
78 const char *src_file,
79 int src_line) {
80 io_instr.locker =
81 PSI_FILE_CALL(get_thread_file_name_locker)(
82 &io_instr.state, key.id(), static_cast<PSI_file_operation>(op),
83 name,
84 io_instr.locker);
85 if (FT_LIKELY(io_instr.locker)) {
86 PSI_FILE_CALL(start_file_close_wait)
87 (io_instr.locker, src_file, src_line);
88 }
89}
90
91void toku_instr_file_stream_close_begin(toku_io_instrumentation &io_instr,
92 toku_instr_file_op op,
93 const TOKU_FILE &file,
94 const char *src_file,
95 int src_line) {
96 io_instr.locker = nullptr;
97 if (FT_LIKELY(file.key)) {
98 io_instr.locker = PSI_FILE_CALL(get_thread_file_stream_locker)(
99 &io_instr.state, file.key, (PSI_file_operation)op);
100 if (FT_LIKELY(io_instr.locker)) {
101 PSI_FILE_CALL(start_file_close_wait)
102 (io_instr.locker, src_file, src_line);
103 }
104 }
105}
106
107void toku_instr_file_fd_close_begin(toku_io_instrumentation &io_instr,
108 toku_instr_file_op op,
109 int fd,
110 const char *src_file,
111 int src_line) {
112 io_instr.locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
113 &io_instr.state, fd, (PSI_file_operation)op);
114 if (FT_LIKELY(io_instr.locker)) {
115 PSI_FILE_CALL(start_file_close_wait)
116 (io_instr.locker, src_file, src_line);
117 }
118}
119
120void toku_instr_file_close_end(const toku_io_instrumentation &io_instr,
121 int result) {
122 if (FT_LIKELY(io_instr.locker))
123 PSI_FILE_CALL(end_file_close_wait)
124 (io_instr.locker, result);
125}
126
127void toku_instr_file_io_begin(toku_io_instrumentation &io_instr,
128 toku_instr_file_op op,
129 int fd,
130 ssize_t count,
131 const char *src_file,
132 int src_line) {
133 io_instr.locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
134 &io_instr.state, fd, (PSI_file_operation)op);
135 if (FT_LIKELY(io_instr.locker)) {
136 PSI_FILE_CALL(start_file_wait)
137 (io_instr.locker, count, src_file, src_line);
138 }
139}
140
141void toku_instr_file_name_io_begin(toku_io_instrumentation &io_instr,
142 const toku_instr_key &key,
143 toku_instr_file_op op,
144 const char *name,
145 ssize_t count,
146 const char *src_file,
147 int src_line) {
148 io_instr.locker =
149 PSI_FILE_CALL(get_thread_file_name_locker)(&io_instr.state,
150 key.id(),
151 (PSI_file_operation)op,
152 name,
153 &io_instr.locker);
154 if (FT_LIKELY(io_instr.locker)) {
155 PSI_FILE_CALL(start_file_wait)
156 (io_instr.locker, count, src_file, src_line);
157 }
158}
159
160void toku_instr_file_stream_io_begin(toku_io_instrumentation &io_instr,
161 toku_instr_file_op op,
162 const TOKU_FILE &file,
163 ssize_t count,
164 const char *src_file,
165 int src_line) {
166 io_instr.locker = nullptr;
167 if (FT_LIKELY(file.key)) {
168 io_instr.locker = PSI_FILE_CALL(get_thread_file_stream_locker)(
169 &io_instr.state, file.key, (PSI_file_operation)op);
170 if (FT_LIKELY(io_instr.locker)) {
171 PSI_FILE_CALL(start_file_wait)
172 (io_instr.locker, count, src_file, src_line);
173 }
174 }
175}
176
177void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count) {
178 if (FT_LIKELY(io_instr.locker))
179 PSI_FILE_CALL(end_file_wait)
180 (io_instr.locker, count);
181}
182
183// Mutex instrumentation
184
185void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex) {
186 mutex.psi_mutex = PSI_MUTEX_CALL(init_mutex)(key.id(), &mutex.pmutex);
187#if TOKU_PTHREAD_DEBUG
188 mutex.instr_key_id = key.id();
189#endif
190}
191
192void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr) {
193 if (mutex_instr != nullptr) {
194 PSI_MUTEX_CALL(destroy_mutex)(mutex_instr);
195 mutex_instr = nullptr;
196 }
197}
198
199void toku_instr_mutex_lock_start(toku_mutex_instrumentation &mutex_instr,
200 toku_mutex_t &mutex,
201 const char *src_file,
202 int src_line) {
203 mutex_instr.locker = nullptr;
204 if (mutex.psi_mutex) {
205 mutex_instr.locker =
206 PSI_MUTEX_CALL(start_mutex_wait)(&mutex_instr.state,
207 mutex.psi_mutex,
208 PSI_MUTEX_LOCK,
209 src_file,
210 src_line);
211 }
212}
213
214void toku_instr_mutex_trylock_start(toku_mutex_instrumentation &mutex_instr,
215 toku_mutex_t &mutex,
216 const char *src_file,
217 int src_line) {
218 mutex_instr.locker = nullptr;
219 if (mutex.psi_mutex) {
220 mutex_instr.locker =
221 PSI_MUTEX_CALL(start_mutex_wait)(&mutex_instr.state,
222 mutex.psi_mutex,
223 PSI_MUTEX_TRYLOCK,
224 src_file,
225 src_line);
226 }
227}
228
229void toku_instr_mutex_lock_end(toku_mutex_instrumentation &mutex_instr,
230 int pthread_mutex_lock_result) {
231 if (mutex_instr.locker)
232 PSI_MUTEX_CALL(end_mutex_wait)
233 (mutex_instr.locker, pthread_mutex_lock_result);
234}
235
236void toku_instr_mutex_unlock(PSI_mutex *mutex_instr) {
237 if (mutex_instr)
238 PSI_MUTEX_CALL(unlock_mutex)(mutex_instr);
239}
240
241// Condvar instrumentation
242
243void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond) {
244 cond.psi_cond = PSI_COND_CALL(init_cond)(key.id(), &cond.pcond);
245#if TOKU_PTHREAD_DEBUG
246 cond.instr_key_id = key.id();
247#endif
248}
249
250void toku_instr_cond_destroy(PSI_cond *&cond_instr) {
251 if (cond_instr != nullptr) {
252 PSI_COND_CALL(destroy_cond)(cond_instr);
253 cond_instr = nullptr;
254 }
255}
256
257void toku_instr_cond_wait_start(toku_cond_instrumentation &cond_instr,
258 toku_instr_cond_op op,
259 toku_cond_t &cond,
260 toku_mutex_t &mutex,
261 const char *src_file,
262 int src_line) {
263 cond_instr.locker = nullptr;
264 if (cond.psi_cond) {
265 /* Instrumentation start */
266 cond_instr.locker =
267 PSI_COND_CALL(start_cond_wait)(&cond_instr.state,
268 cond.psi_cond,
269 mutex.psi_mutex,
270 (PSI_cond_operation)op,
271 src_file,
272 src_line);
273 }
274}
275
276void toku_instr_cond_wait_end(toku_cond_instrumentation &cond_instr,
277 int pthread_cond_wait_result) {
278 if (cond_instr.locker)
279 PSI_COND_CALL(end_cond_wait)
280 (cond_instr.locker, pthread_cond_wait_result);
281}
282
283void toku_instr_cond_signal(const toku_cond_t &cond) {
284 if (cond.psi_cond)
285 PSI_COND_CALL(signal_cond)(cond.psi_cond);
286}
287
288void toku_instr_cond_broadcast(const toku_cond_t &cond) {
289 if (cond.psi_cond)
290 PSI_COND_CALL(broadcast_cond)(cond.psi_cond);
291}
292
293// rwlock instrumentation
294
295void toku_instr_rwlock_init(const toku_instr_key &key,
296 toku_pthread_rwlock_t &rwlock) {
297 rwlock.psi_rwlock = PSI_RWLOCK_CALL(init_rwlock)(key.id(), &rwlock.rwlock);
298#if TOKU_PTHREAD_DEBUG
299 rwlock.instr_key_id = key.id();
300#endif
301}
302
303void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr) {
304 if (rwlock_instr != nullptr) {
305 PSI_RWLOCK_CALL(destroy_rwlock)(rwlock_instr);
306 rwlock_instr = nullptr;
307 }
308}
309
310void toku_instr_rwlock_rdlock_wait_start(
311 toku_rwlock_instrumentation &rwlock_instr,
312 toku_pthread_rwlock_t &rwlock,
313 const char *src_file,
314 int src_line) {
315 rwlock_instr.locker = nullptr;
316 if (rwlock.psi_rwlock) {
317 /* Instrumentation start */
318 rwlock_instr.locker =
319 PSI_RWLOCK_CALL(start_rwlock_rdwait)(&rwlock_instr.state,
320 rwlock.psi_rwlock,
321 PSI_RWLOCK_READLOCK,
322 src_file,
323 src_line);
324 }
325}
326
327void toku_instr_rwlock_wrlock_wait_start(
328 toku_rwlock_instrumentation &rwlock_instr,
329 toku_pthread_rwlock_t &rwlock,
330 const char *src_file,
331 int src_line) {
332 rwlock_instr.locker = nullptr;
333 if (rwlock.psi_rwlock) {
334 /* Instrumentation start */
335 rwlock_instr.locker =
336 PSI_RWLOCK_CALL(start_rwlock_wrwait)(&rwlock_instr.state,
337 rwlock.psi_rwlock,
338 PSI_RWLOCK_WRITELOCK,
339 src_file,
340 src_line);
341 }
342}
343
344void toku_instr_rwlock_rdlock_wait_end(
345 toku_rwlock_instrumentation &rwlock_instr,
346 int pthread_rwlock_wait_result) {
347 if (rwlock_instr.locker)
348 PSI_RWLOCK_CALL(end_rwlock_rdwait)
349 (rwlock_instr.locker, pthread_rwlock_wait_result);
350}
351
352void toku_instr_rwlock_wrlock_wait_end(
353 toku_rwlock_instrumentation &rwlock_instr,
354 int pthread_rwlock_wait_result) {
355 if (rwlock_instr.locker)
356 PSI_RWLOCK_CALL(end_rwlock_wrwait)
357 (rwlock_instr.locker, pthread_rwlock_wait_result);
358}
359
360void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock) {
361 if (rwlock.psi_rwlock)
362 PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock);
363}
364
365#endif // MYSQL_TOKUDB_ENGINE
366