1 | /* |
2 | Copyright (c) 2000, 2012, Oracle and/or its affiliates |
3 | Copyright (c) 2009, 2011, Monty Program Ab |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by |
7 | the Free Software Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
17 | |
18 | #include "mysys_priv.h" |
19 | #include "my_static.h" |
20 | #include "mysys_err.h" |
21 | #include <m_string.h> |
22 | #include <m_ctype.h> |
23 | #include <signal.h> |
24 | #include <mysql/psi/mysql_stage.h> |
25 | #ifdef __WIN__ |
26 | #ifdef _MSC_VER |
27 | #include <locale.h> |
28 | #include <crtdbg.h> |
29 | /* WSAStartup needs winsock library*/ |
30 | #pragma comment(lib, "ws2_32") |
31 | #endif |
32 | my_bool have_tcpip=0; |
33 | static void my_win_init(void); |
34 | static my_bool win32_init_tcp_ip(); |
35 | #else |
36 | #define my_win_init() |
37 | #endif |
38 | |
39 | extern pthread_key(struct st_my_thread_var*, THR_KEY_mysys); |
40 | |
41 | #define SCALE_SEC 100 |
42 | #define SCALE_USEC 10000 |
43 | |
44 | my_bool my_init_done= 0; |
45 | uint mysys_usage_id= 0; /* Incremented for each my_init() */ |
46 | |
47 | ulonglong my_thread_stack_size= (sizeof(void*) <= 4)? 65536: ((256-16)*1024); |
48 | |
49 | static ulong atoi_octal(const char *str) |
50 | { |
51 | long int tmp; |
52 | while (*str && my_isspace(&my_charset_latin1, *str)) |
53 | str++; |
54 | str2int(str, |
55 | (*str == '0' ? 8 : 10), /* Octalt or decimalt */ |
56 | 0, INT_MAX, &tmp); |
57 | return (ulong) tmp; |
58 | } |
59 | |
60 | MYSQL_FILE *mysql_stdin= NULL; |
61 | static MYSQL_FILE instrumented_stdin; |
62 | |
63 | |
64 | /** |
65 | Initialize my_sys functions, resources and variables |
66 | |
67 | @return Initialization result |
68 | @retval 0 Success |
69 | @retval 1 Error. Couldn't initialize environment |
70 | */ |
71 | my_bool my_init(void) |
72 | { |
73 | char *str; |
74 | |
75 | if (my_init_done) |
76 | return 0; |
77 | |
78 | my_init_done= 1; |
79 | |
80 | mysys_usage_id++; |
81 | my_umask= 0660; /* Default umask for new files */ |
82 | my_umask_dir= 0700; /* Default umask for new directories */ |
83 | my_global_flags= 0; |
84 | |
85 | /* Default creation of new files */ |
86 | if ((str= getenv("UMASK" )) != 0) |
87 | my_umask= (int) (atoi_octal(str) | 0600); |
88 | /* Default creation of new dir's */ |
89 | if ((str= getenv("UMASK_DIR" )) != 0) |
90 | my_umask_dir= (int) (atoi_octal(str) | 0700); |
91 | |
92 | init_glob_errs(); |
93 | |
94 | instrumented_stdin.m_file= stdin; |
95 | instrumented_stdin.m_psi= NULL; /* not yet instrumented */ |
96 | mysql_stdin= & instrumented_stdin; |
97 | |
98 | my_progname_short= "unknown" ; |
99 | if (my_progname) |
100 | my_progname_short= my_progname + dirname_length(my_progname); |
101 | |
102 | /* Initialize our mutex handling */ |
103 | my_mutex_init(); |
104 | |
105 | if (my_thread_global_init()) |
106 | return 1; |
107 | |
108 | #if defined(SAFEMALLOC) && !defined(DBUG_OFF) |
109 | dbug_sanity= sf_sanity; |
110 | #endif |
111 | |
112 | /* $HOME is needed early to parse configuration files located in ~/ */ |
113 | if ((home_dir= getenv("HOME" )) != 0) |
114 | home_dir= intern_filename(home_dir_buff, home_dir); |
115 | |
116 | { |
117 | DBUG_ENTER("my_init" ); |
118 | DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown" )); |
119 | my_time_init(); |
120 | my_win_init(); |
121 | DBUG_PRINT("exit" , ("home: '%s'" , home_dir)); |
122 | #ifdef __WIN__ |
123 | win32_init_tcp_ip(); |
124 | #endif |
125 | #ifdef CHECK_UNLIKELY |
126 | init_my_likely(); |
127 | #endif |
128 | DBUG_RETURN(0); |
129 | } |
130 | } /* my_init */ |
131 | |
132 | |
133 | /* End my_sys */ |
134 | |
135 | void my_end(int infoflag) |
136 | { |
137 | /* |
138 | this code is suboptimal to workaround a bug in |
139 | Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be |
140 | optimized until this compiler is not in use anymore |
141 | */ |
142 | FILE *info_file= DBUG_FILE; |
143 | my_bool print_info= (info_file != stderr); |
144 | |
145 | if (!my_init_done) |
146 | return; |
147 | |
148 | /* |
149 | We do not use DBUG_ENTER here, as after cleanup DBUG is no longer |
150 | operational, so we cannot use DBUG_RETURN. |
151 | */ |
152 | DBUG_PRINT("info" ,("Shutting down: infoflag: %d print_info: %d" , |
153 | infoflag, print_info)); |
154 | if (!info_file) |
155 | { |
156 | info_file= stderr; |
157 | print_info= 0; |
158 | } |
159 | |
160 | if ((infoflag & MY_CHECK_ERROR) || print_info) |
161 | { /* Test if some file is left open */ |
162 | char ebuff[512]; |
163 | uint i, open_files, open_streams; |
164 | |
165 | for (open_streams= open_files= i= 0 ; i < my_file_limit ; i++) |
166 | { |
167 | if (my_file_info[i].type == UNOPEN) |
168 | continue; |
169 | if (my_file_info[i].type == STREAM_BY_FOPEN || |
170 | my_file_info[i].type == STREAM_BY_FDOPEN) |
171 | open_streams++; |
172 | else |
173 | open_files++; |
174 | |
175 | #ifdef EXTRA_DEBUG |
176 | fprintf(stderr, EE(EE_FILE_NOT_CLOSED), my_file_info[i].name, i); |
177 | fputc('\n', stderr); |
178 | #endif |
179 | } |
180 | if (open_files || open_streams) |
181 | { |
182 | my_snprintf(ebuff, sizeof(ebuff), EE(EE_OPEN_WARNING), |
183 | open_files, open_streams); |
184 | my_message_stderr(EE_OPEN_WARNING, ebuff, ME_BELL); |
185 | DBUG_PRINT("error" , ("%s" , ebuff)); |
186 | } |
187 | |
188 | #ifdef CHECK_UNLIKELY |
189 | end_my_likely(info_file); |
190 | #endif |
191 | } |
192 | free_charsets(); |
193 | my_error_unregister_all(); |
194 | my_once_free(); |
195 | |
196 | if ((infoflag & MY_GIVE_INFO) || print_info) |
197 | { |
198 | #ifdef HAVE_GETRUSAGE |
199 | struct rusage rus; |
200 | #ifdef HAVE_valgrind |
201 | /* Purify assumes that rus is uninitialized after getrusage call */ |
202 | bzero((char*) &rus, sizeof(rus)); |
203 | #endif |
204 | if (!getrusage(RUSAGE_SELF, &rus)) |
205 | fprintf(info_file,"\n\ |
206 | User time %.2f, System time %.2f\n\ |
207 | Maximum resident set size %ld, Integral resident set size %ld\n\ |
208 | Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\ |
209 | Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\ |
210 | Voluntary context switches %ld, Involuntary context switches %ld\n" , |
211 | (rus.ru_utime.tv_sec * SCALE_SEC + |
212 | rus.ru_utime.tv_usec / SCALE_USEC) / 100.0, |
213 | (rus.ru_stime.tv_sec * SCALE_SEC + |
214 | rus.ru_stime.tv_usec / SCALE_USEC) / 100.0, |
215 | rus.ru_maxrss, rus.ru_idrss, |
216 | rus.ru_minflt, rus.ru_majflt, |
217 | rus.ru_nswap, rus.ru_inblock, rus.ru_oublock, |
218 | rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals, |
219 | rus.ru_nvcsw, rus.ru_nivcsw); |
220 | #endif |
221 | #if defined(__WIN__) && defined(_MSC_VER) |
222 | _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); |
223 | _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR ); |
224 | _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE ); |
225 | _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR ); |
226 | _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); |
227 | _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR ); |
228 | _CrtCheckMemory(); |
229 | #endif |
230 | } |
231 | |
232 | my_thread_end(); |
233 | my_thread_global_end(); |
234 | |
235 | if (!(infoflag & MY_DONT_FREE_DBUG)) |
236 | DBUG_END(); /* Must be done as late as possible */ |
237 | |
238 | my_mutex_end(); |
239 | #if defined(SAFE_MUTEX) |
240 | /* |
241 | Check on destroying of mutexes. A few may be left that will get cleaned |
242 | up by C++ destructors |
243 | */ |
244 | safe_mutex_end((infoflag & (MY_GIVE_INFO | MY_CHECK_ERROR)) ? stderr : |
245 | (FILE *) 0); |
246 | #endif /* defined(SAFE_MUTEX) */ |
247 | |
248 | #ifdef __WIN__ |
249 | if (have_tcpip) |
250 | WSACleanup(); |
251 | #endif /* __WIN__ */ |
252 | |
253 | /* At very last, delete mysys key, it is used everywhere including DBUG */ |
254 | pthread_key_delete(THR_KEY_mysys); |
255 | my_init_done= my_thr_key_mysys_exists= 0; |
256 | } /* my_end */ |
257 | |
258 | #ifdef DBUG_ASSERT_EXISTS |
259 | /* Dummy tag function for debugging */ |
260 | |
261 | void my_debug_put_break_here(void) |
262 | { |
263 | } |
264 | #endif |
265 | |
266 | #ifdef __WIN__ |
267 | |
268 | |
269 | /* |
270 | my_parameter_handler |
271 | |
272 | Invalid parameter handler we will use instead of the one "baked" |
273 | into the CRT for MSC v8. This one just prints out what invalid |
274 | parameter was encountered. By providing this routine, routines like |
275 | lseek will return -1 when we expect them to instead of crash. |
276 | */ |
277 | |
278 | void my_parameter_handler(const wchar_t * expression, const wchar_t * function, |
279 | const wchar_t * file, unsigned int line, |
280 | uintptr_t pReserved) |
281 | { |
282 | __debugbreak(); |
283 | } |
284 | |
285 | |
286 | #ifdef __MSVC_RUNTIME_CHECKS |
287 | #include <rtcapi.h> |
288 | |
289 | /* Turn off runtime checks for 'handle_rtc_failure' */ |
290 | #pragma runtime_checks("", off) |
291 | |
292 | /* |
293 | handle_rtc_failure |
294 | Catch the RTC error and dump it to stderr |
295 | */ |
296 | |
297 | int handle_rtc_failure(int err_type, const char *file, int line, |
298 | const char* module, const char *format, ...) |
299 | { |
300 | va_list args; |
301 | va_start(args, format); |
302 | fprintf(stderr, "Error:" ); |
303 | vfprintf(stderr, format, args); |
304 | fprintf(stderr, " At %s:%d\n" , file, line); |
305 | va_end(args); |
306 | (void) fflush(stderr); |
307 | __debugbreak(); |
308 | |
309 | return 0; /* Error is handled */ |
310 | } |
311 | #pragma runtime_checks("", restore) |
312 | #endif |
313 | |
314 | /* |
315 | Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found |
316 | there as environment variables |
317 | */ |
318 | static void win_init_registry(void) |
319 | { |
320 | HKEY key_handle; |
321 | |
322 | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL" , |
323 | 0, KEY_READ, &key_handle) == ERROR_SUCCESS) |
324 | { |
325 | LONG ret; |
326 | DWORD index= 0; |
327 | DWORD type; |
328 | char key_name[256], key_data[1024]; |
329 | DWORD key_name_len= sizeof(key_name) - 1; |
330 | DWORD key_data_len= sizeof(key_data) - 1; |
331 | |
332 | while ((ret= RegEnumValue(key_handle, index++, |
333 | key_name, &key_name_len, |
334 | NULL, &type, (LPBYTE)&key_data, |
335 | &key_data_len)) != ERROR_NO_MORE_ITEMS) |
336 | { |
337 | char env_string[sizeof(key_name) + sizeof(key_data) + 2]; |
338 | |
339 | if (ret == ERROR_MORE_DATA) |
340 | { |
341 | /* Registry value larger than 'key_data', skip it */ |
342 | DBUG_PRINT("error" , ("Skipped registry value that was too large" )); |
343 | } |
344 | else if (ret == ERROR_SUCCESS) |
345 | { |
346 | if (type == REG_SZ) |
347 | { |
348 | strxmov(env_string, key_name, "=" , key_data, NullS); |
349 | |
350 | /* variable for putenv must be allocated ! */ |
351 | putenv(strdup(env_string)) ; |
352 | } |
353 | } |
354 | else |
355 | { |
356 | /* Unhandled error, break out of loop */ |
357 | break; |
358 | } |
359 | |
360 | key_name_len= sizeof(key_name) - 1; |
361 | key_data_len= sizeof(key_data) - 1; |
362 | } |
363 | |
364 | RegCloseKey(key_handle); |
365 | } |
366 | } |
367 | |
368 | |
369 | static void my_win_init(void) |
370 | { |
371 | DBUG_ENTER("my_win_init" ); |
372 | |
373 | #if defined(_MSC_VER) |
374 | #if _MSC_VER < 1300 |
375 | /* |
376 | Clear the OS system variable TZ and avoid the 100% CPU usage |
377 | Only for old versions of Visual C++ |
378 | */ |
379 | _putenv("TZ=" ); |
380 | #endif |
381 | #if _MSC_VER >= 1400 |
382 | /* this is required to make crt functions return -1 appropriately */ |
383 | _set_invalid_parameter_handler(my_parameter_handler); |
384 | #endif |
385 | #endif |
386 | |
387 | #ifdef __MSVC_RUNTIME_CHECKS |
388 | /* |
389 | Install handler to send RTC (Runtime Error Check) warnings |
390 | to log file |
391 | */ |
392 | _RTC_SetErrorFunc(handle_rtc_failure); |
393 | #endif |
394 | |
395 | _tzset(); |
396 | |
397 | win_init_registry(); |
398 | |
399 | DBUG_VOID_RETURN; |
400 | } |
401 | |
402 | |
403 | /*------------------------------------------------------------------ |
404 | Name: CheckForTcpip| Desc: checks if tcpip has been installed on system |
405 | According to Microsoft Developers documentation the first registry |
406 | entry should be enough to check if TCP/IP is installed, but as expected |
407 | this doesn't work on all Win32 machines :( |
408 | ------------------------------------------------------------------*/ |
409 | |
410 | #define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" |
411 | #define WINSOCK2KEY "SYSTEM\\CurrentControlSet\\Services\\Winsock2\\Parameters" |
412 | #define WINSOCKKEY "SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters" |
413 | |
414 | static my_bool win32_have_tcpip(void) |
415 | { |
416 | HKEY hTcpipRegKey; |
417 | if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, TCPIPKEY, 0, KEY_READ, |
418 | &hTcpipRegKey) != ERROR_SUCCESS) |
419 | { |
420 | if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCK2KEY, 0, KEY_READ, |
421 | &hTcpipRegKey) != ERROR_SUCCESS) |
422 | { |
423 | if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCKKEY, 0, KEY_READ, |
424 | &hTcpipRegKey) != ERROR_SUCCESS) |
425 | if (!getenv("HAVE_TCPIP" ) || have_tcpip) /* Provide a workaround */ |
426 | return (FALSE); |
427 | } |
428 | } |
429 | RegCloseKey ( hTcpipRegKey); |
430 | return (TRUE); |
431 | } |
432 | |
433 | |
434 | static my_bool win32_init_tcp_ip() |
435 | { |
436 | if (win32_have_tcpip()) |
437 | { |
438 | WORD wVersionRequested = MAKEWORD( 2, 2 ); |
439 | WSADATA wsaData; |
440 | /* Be a good citizen: maybe another lib has already initialised |
441 | sockets, so don't clobber them unless necessary */ |
442 | if (WSAStartup( wVersionRequested, &wsaData )) |
443 | { |
444 | /* Load failed, maybe because of previously loaded |
445 | incompatible version; try again */ |
446 | WSACleanup( ); |
447 | if (!WSAStartup( wVersionRequested, &wsaData )) |
448 | have_tcpip=1; |
449 | } |
450 | else |
451 | { |
452 | if (wsaData.wVersion != wVersionRequested) |
453 | { |
454 | /* Version is no good, try again */ |
455 | WSACleanup( ); |
456 | if (!WSAStartup( wVersionRequested, &wsaData )) |
457 | have_tcpip=1; |
458 | } |
459 | else |
460 | have_tcpip=1; |
461 | } |
462 | } |
463 | return(0); |
464 | } |
465 | #endif /* __WIN__ */ |
466 | |
467 | PSI_stage_info stage_waiting_for_table_level_lock= |
468 | {0, "Waiting for table level lock" , 0}; |
469 | |
470 | #ifdef HAVE_PSI_INTERFACE |
471 | #if !defined(HAVE_PREAD) && !defined(_WIN32) |
472 | PSI_mutex_key key_my_file_info_mutex; |
473 | #endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */ |
474 | |
475 | #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) |
476 | PSI_mutex_key key_LOCK_localtime_r; |
477 | #endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */ |
478 | |
479 | PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock, |
480 | key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, |
481 | key_LOCK_alarm, key_LOCK_timer, |
482 | key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap, |
483 | key_THR_LOCK_lock, key_THR_LOCK_malloc, |
484 | key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net, |
485 | key_THR_LOCK_open, key_THR_LOCK_threads, |
486 | key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap, key_LOCK_uuid_generator; |
487 | |
488 | static PSI_mutex_info all_mysys_mutexes[]= |
489 | { |
490 | #if !defined(HAVE_PREAD) && !defined(_WIN32) |
491 | { &key_my_file_info_mutex, "st_my_file_info:mutex" , 0}, |
492 | #endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */ |
493 | #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) |
494 | { &key_LOCK_localtime_r, "LOCK_localtime_r" , PSI_FLAG_GLOBAL}, |
495 | #endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */ |
496 | { &key_BITMAP_mutex, "BITMAP::mutex" , 0}, |
497 | { &key_IO_CACHE_append_buffer_lock, "IO_CACHE::append_buffer_lock" , 0}, |
498 | { &key_IO_CACHE_SHARE_mutex, "IO_CACHE::SHARE_mutex" , 0}, |
499 | { &key_KEY_CACHE_cache_lock, "KEY_CACHE::cache_lock" , 0}, |
500 | { &key_LOCK_alarm, "LOCK_alarm" , PSI_FLAG_GLOBAL}, |
501 | { &key_LOCK_timer, "LOCK_timer" , PSI_FLAG_GLOBAL}, |
502 | { &key_my_thread_var_mutex, "my_thread_var::mutex" , 0}, |
503 | { &key_THR_LOCK_charset, "THR_LOCK_charset" , PSI_FLAG_GLOBAL}, |
504 | { &key_THR_LOCK_heap, "THR_LOCK_heap" , PSI_FLAG_GLOBAL}, |
505 | { &key_THR_LOCK_lock, "THR_LOCK_lock" , PSI_FLAG_GLOBAL}, |
506 | { &key_THR_LOCK_malloc, "THR_LOCK_malloc" , PSI_FLAG_GLOBAL}, |
507 | { &key_THR_LOCK_mutex, "THR_LOCK::mutex" , 0}, |
508 | { &key_THR_LOCK_myisam, "THR_LOCK_myisam" , PSI_FLAG_GLOBAL}, |
509 | { &key_THR_LOCK_net, "THR_LOCK_net" , PSI_FLAG_GLOBAL}, |
510 | { &key_THR_LOCK_open, "THR_LOCK_open" , PSI_FLAG_GLOBAL}, |
511 | { &key_THR_LOCK_threads, "THR_LOCK_threads" , PSI_FLAG_GLOBAL}, |
512 | { &key_TMPDIR_mutex, "TMPDIR_mutex" , PSI_FLAG_GLOBAL}, |
513 | { &key_THR_LOCK_myisam_mmap, "THR_LOCK_myisam_mmap" , PSI_FLAG_GLOBAL}, |
514 | { &key_LOCK_uuid_generator, "LOCK_uuid_generator" , PSI_FLAG_GLOBAL } |
515 | }; |
516 | |
517 | PSI_cond_key key_COND_alarm, key_COND_timer, key_IO_CACHE_SHARE_cond, |
518 | key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend, |
519 | key_THR_COND_threads, key_WT_RESOURCE_cond; |
520 | |
521 | static PSI_cond_info all_mysys_conds[]= |
522 | { |
523 | { &key_COND_alarm, "COND_alarm" , PSI_FLAG_GLOBAL}, |
524 | { &key_COND_timer, "COND_timer" , PSI_FLAG_GLOBAL}, |
525 | { &key_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond" , 0}, |
526 | { &key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer" , 0}, |
527 | { &key_my_thread_var_suspend, "my_thread_var::suspend" , 0}, |
528 | { &key_THR_COND_threads, "THR_COND_threads" , PSI_FLAG_GLOBAL}, |
529 | { &key_WT_RESOURCE_cond, "WT_RESOURCE::cond" , 0} |
530 | }; |
531 | |
532 | PSI_rwlock_key key_SAFEHASH_mutex; |
533 | |
534 | static PSI_rwlock_info all_mysys_rwlocks[]= |
535 | { |
536 | { &key_SAFEHASH_mutex, "SAFE_HASH::mutex" , 0} |
537 | }; |
538 | |
539 | #ifdef USE_ALARM_THREAD |
540 | PSI_thread_key key_thread_alarm; |
541 | #endif |
542 | PSI_thread_key key_thread_timer; |
543 | |
544 | static PSI_thread_info all_mysys_threads[]= |
545 | { |
546 | #ifdef USE_ALARM_THREAD |
547 | { &key_thread_alarm, "alarm" , PSI_FLAG_GLOBAL}, |
548 | #endif |
549 | { &key_thread_timer, "statement_timer" , PSI_FLAG_GLOBAL} |
550 | }; |
551 | |
552 | |
553 | #ifdef HUGETLB_USE_PROC_MEMINFO |
554 | PSI_file_key key_file_proc_meminfo; |
555 | #endif /* HUGETLB_USE_PROC_MEMINFO */ |
556 | PSI_file_key key_file_charset, key_file_cnf; |
557 | |
558 | static PSI_file_info all_mysys_files[]= |
559 | { |
560 | #ifdef HUGETLB_USE_PROC_MEMINFO |
561 | { &key_file_proc_meminfo, "proc_meminfo" , 0}, |
562 | #endif /* HUGETLB_USE_PROC_MEMINFO */ |
563 | { &key_file_charset, "charset" , 0}, |
564 | { &key_file_cnf, "cnf" , 0} |
565 | }; |
566 | |
567 | PSI_stage_info *all_mysys_stages[]= |
568 | { |
569 | & stage_waiting_for_table_level_lock |
570 | }; |
571 | |
572 | void my_init_mysys_psi_keys() |
573 | { |
574 | const char* category= "mysys" ; |
575 | int count; |
576 | |
577 | count= sizeof(all_mysys_mutexes)/sizeof(all_mysys_mutexes[0]); |
578 | mysql_mutex_register(category, all_mysys_mutexes, count); |
579 | |
580 | count= sizeof(all_mysys_conds)/sizeof(all_mysys_conds[0]); |
581 | mysql_cond_register(category, all_mysys_conds, count); |
582 | |
583 | count= sizeof(all_mysys_rwlocks)/sizeof(all_mysys_rwlocks[0]); |
584 | mysql_rwlock_register(category, all_mysys_rwlocks, count); |
585 | |
586 | count= sizeof(all_mysys_threads)/sizeof(all_mysys_threads[0]); |
587 | mysql_thread_register(category, all_mysys_threads, count); |
588 | |
589 | count= sizeof(all_mysys_files)/sizeof(all_mysys_files[0]); |
590 | mysql_file_register(category, all_mysys_files, count); |
591 | |
592 | count= array_elements(all_mysys_stages); |
593 | mysql_stage_register(category, all_mysys_stages, count); |
594 | } |
595 | #endif /* HAVE_PSI_INTERFACE */ |
596 | |
597 | |