1 | #ifdef MYSQL_TOKUDB_ENGINE |
2 | #include "toku_portability.h" |
3 | #include "toku_pthread.h" |
4 | |
5 | toku_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 | |
10 | toku_instr_probe_pfs::~toku_instr_probe_pfs() { |
11 | toku_mutex_destroy(mutex.get()); |
12 | } |
13 | |
14 | // Thread instrumentation |
15 | |
16 | int 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 | |
31 | void 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 | |
37 | void toku_instr_delete_current_thread() { |
38 | PSI_THREAD_CALL(delete_current_thread)(); |
39 | } |
40 | |
41 | // I/O instrumentation |
42 | |
43 | void 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 | |
59 | void 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 | |
68 | void 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 | |
74 | void 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 | |
91 | void 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 | |
107 | void 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 | |
120 | void 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 | |
127 | void 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 | |
141 | void 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 | |
160 | void 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 | |
177 | void 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 | |
185 | void 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 | |
192 | void 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 | |
199 | void 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 | |
214 | void 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 | |
229 | void 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 | |
236 | void 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 | |
243 | void 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 | |
250 | void 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 | |
257 | void 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 | |
276 | void 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 | |
283 | void 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 | |
288 | void 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 | |
295 | void 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 | |
303 | void 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 | |
310 | void 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 | |
327 | void 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 | |
344 | void 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 | |
352 | void 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 | |
360 | void 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 | |