/src/mysql-server/mysys/my_init.cc
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2000, 2025, Oracle and/or its affiliates. |
2 | | |
3 | | This program is free software; you can redistribute it and/or modify |
4 | | it under the terms of the GNU General Public License, version 2.0, |
5 | | as published by the Free Software Foundation. |
6 | | |
7 | | This program is designed to work with certain software (including |
8 | | but not limited to OpenSSL) that is licensed under separate terms, |
9 | | as designated in a particular file or component or in included license |
10 | | documentation. The authors of MySQL hereby grant you an additional |
11 | | permission to link the program and your derivative works with the |
12 | | separately licensed software that they have either included with |
13 | | the program or referenced in the documentation. |
14 | | |
15 | | Without limiting anything contained in the foregoing, this file, |
16 | | which is part of C Driver for MySQL (Connector/C), is also subject to the |
17 | | Universal FOSS Exception, version 1.0, a copy of which can be found at |
18 | | http://oss.oracle.com/licenses/universal-foss-exception. |
19 | | |
20 | | This program is distributed in the hope that it will be useful, |
21 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | | GNU General Public License, version 2.0, for more details. |
24 | | |
25 | | You should have received a copy of the GNU General Public License |
26 | | along with this program; if not, write to the Free Software |
27 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
28 | | |
29 | | /** |
30 | | @file mysys/my_init.cc |
31 | | */ |
32 | | |
33 | | #include "my_config.h" |
34 | | |
35 | | #ifdef MY_MSCRT_DEBUG |
36 | | #include <crtdbg.h> |
37 | | #endif |
38 | | #include <climits> |
39 | | #include <cstdio> |
40 | | #include <cstdlib> |
41 | | #ifdef HAVE_SYS_TIME_H |
42 | | #include <sys/time.h> |
43 | | #endif |
44 | | #include <sys/types.h> |
45 | | #include <unordered_map> |
46 | | |
47 | | #include "my_compiler.h" |
48 | | #include "my_dbug.h" |
49 | | #include "my_inttypes.h" |
50 | | #include "my_macros.h" |
51 | | #include "my_psi_config.h" |
52 | | #include "my_sys.h" |
53 | | #include "my_thread.h" |
54 | | #include "mysql/components/services/bits/psi_bits.h" |
55 | | #include "mysql/psi/mysql_cond.h" |
56 | | #include "mysql/psi/mysql_file.h" |
57 | | #include "mysql/psi/mysql_memory.h" |
58 | | #include "mysql/psi/mysql_mutex.h" |
59 | | #include "mysql/psi/mysql_rwlock.h" |
60 | | #include "mysql/psi/mysql_stage.h" |
61 | | #include "mysql/psi/mysql_thread.h" |
62 | | #include "mysql/psi/psi_cond.h" |
63 | | #include "mysql/psi/psi_file.h" |
64 | | #include "mysql/psi/psi_memory.h" |
65 | | #include "mysql/psi/psi_mutex.h" |
66 | | #include "mysql/psi/psi_rwlock.h" |
67 | | #include "mysql/psi/psi_stage.h" |
68 | | #include "mysql/psi/psi_thread.h" |
69 | | #include "mysql/strings/m_ctype.h" |
70 | | #include "mysys/my_static.h" |
71 | | #include "mysys/mysys_priv.h" |
72 | | #include "mysys_err.h" |
73 | | #include "nulls.h" |
74 | | #include "str2int.h" |
75 | | #include "strxmov.h" |
76 | | #include "template_utils.h" |
77 | | |
78 | | #ifdef HAVE_SYS_RESOURCE_H |
79 | | #include <sys/resource.h> |
80 | | #endif |
81 | | |
82 | | #ifdef _WIN32 |
83 | | #include <crtdbg.h> |
84 | | #include <locale.h> |
85 | | |
86 | | /* WSAStartup needs winsock library*/ |
87 | | #pragma comment(lib, "ws2_32") |
88 | | bool have_tcpip = 0; |
89 | | static void my_win_init(); |
90 | | #endif |
91 | | |
92 | 0 | #define SCALE_SEC 100 |
93 | 0 | #define SCALE_USEC 10000 |
94 | | |
95 | | extern void my_main_thread_end(); |
96 | | |
97 | | bool my_init_done = false; |
98 | | ulong my_thread_stack_size = 65536; |
99 | | |
100 | 0 | static ulong atoi_octal(const char *str) { |
101 | 0 | long int tmp; |
102 | 0 | while (*str && my_isspace(&my_charset_latin1, *str)) str++; |
103 | 0 | str2int(str, (*str == '0' ? 8 : 10), /* Octalt or decimalt */ |
104 | 0 | 0, INT_MAX, &tmp); |
105 | 0 | return (ulong)tmp; |
106 | 0 | } |
107 | | |
108 | | #if defined(MY_MSCRT_DEBUG) |
109 | | int set_crt_report_leaks() { |
110 | | HANDLE hLogFile; |
111 | | |
112 | | _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF // debug allocation on |
113 | | | _CRTDBG_LEAK_CHECK_DF // leak checks on exit |
114 | | | _CRTDBG_CHECK_ALWAYS_DF // memory check (slow) |
115 | | ); |
116 | | |
117 | | return ((NULL == (hLogFile = GetStdHandle(STD_ERROR_HANDLE)) || |
118 | | -1 == _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE) || |
119 | | _CRTDBG_HFILE_ERROR == _CrtSetReportFile(_CRT_WARN, hLogFile) || |
120 | | -1 == _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE) || |
121 | | _CRTDBG_HFILE_ERROR == _CrtSetReportFile(_CRT_ERROR, hLogFile) || |
122 | | -1 == _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE) || |
123 | | _CRTDBG_HFILE_ERROR == _CrtSetReportFile(_CRT_ASSERT, hLogFile)) |
124 | | ? 1 |
125 | | : 0); |
126 | | } |
127 | | #endif |
128 | | |
129 | | /** |
130 | | Initialize my_sys functions, resources and variables |
131 | | |
132 | | @return Initialization result |
133 | | @retval false Success |
134 | | @retval true Error. Couldn't initialize environment |
135 | | */ |
136 | 2 | bool my_init() { |
137 | 2 | char *str; |
138 | | |
139 | 2 | if (my_init_done) return false; |
140 | | |
141 | 2 | my_init_done = true; |
142 | | |
143 | | #if defined(MY_MSCRT_DEBUG) |
144 | | set_crt_report_leaks(); |
145 | | #endif |
146 | | |
147 | 2 | my_umask = 0640; /* Default umask for new files */ |
148 | 2 | my_umask_dir = 0750; /* Default umask for new directories */ |
149 | | |
150 | | /* Default creation of new files */ |
151 | 2 | if ((str = getenv("UMASK")) != nullptr) |
152 | 0 | my_umask = (int)(atoi_octal(str) | 0600); |
153 | | /* Default creation of new dir's */ |
154 | 2 | if ((str = getenv("UMASK_DIR")) != nullptr) |
155 | 0 | my_umask_dir = (int)(atoi_octal(str) | 0700); |
156 | | |
157 | 2 | if (my_thread_global_init()) return true; |
158 | | |
159 | 2 | if (my_thread_init()) return true; |
160 | | |
161 | | /* $HOME is needed early to parse configuration files located in ~/ */ |
162 | 2 | if ((home_dir = getenv("HOME")) != nullptr) |
163 | 2 | home_dir = intern_filename(home_dir_buff, home_dir); |
164 | | |
165 | 2 | { |
166 | 2 | DBUG_TRACE; |
167 | 2 | DBUG_PROCESS(my_progname ? my_progname : "unknown"); |
168 | | #ifdef _WIN32 |
169 | | my_win_init(); |
170 | | #endif |
171 | 2 | MyFileInit(); |
172 | | |
173 | 2 | DBUG_PRINT("exit", ("home: '%s'", home_dir)); |
174 | 2 | return false; |
175 | 2 | } |
176 | 2 | } /* my_init */ |
177 | | |
178 | | /* End my_sys */ |
179 | 0 | void my_end(int infoflag) { |
180 | | /* |
181 | | We do not use DBUG_TRACE here, as after cleanup DBUG is no longer |
182 | | operational, so we cannot use DBUG_RETURN. |
183 | | */ |
184 | |
|
185 | 0 | FILE *info_file = (DBUG_FILE ? DBUG_FILE : stderr); |
186 | |
|
187 | 0 | if (!my_init_done) return; |
188 | | |
189 | 0 | MyFileEnd(); |
190 | | #ifdef _WIN32 |
191 | | MyWinfileEnd(); |
192 | | #endif /* WIN32 */ |
193 | |
|
194 | 0 | if ((infoflag & MY_CHECK_ERROR) || (info_file != stderr)) |
195 | | |
196 | 0 | { /* Test if some file is left open */ |
197 | 0 | if (my_file_opened | my_stream_opened) { |
198 | 0 | char ebuff[512]; |
199 | 0 | snprintf(ebuff, sizeof(ebuff), EE(EE_OPEN_WARNING), my_file_opened, |
200 | 0 | my_stream_opened); |
201 | 0 | my_message_stderr(EE_OPEN_WARNING, ebuff, MYF(0)); |
202 | 0 | DBUG_PRINT("error", ("%s", ebuff)); |
203 | 0 | } |
204 | 0 | } |
205 | 0 | my_error_unregister_all(); |
206 | 0 | charset_uninit(); |
207 | 0 | my_once_free(); |
208 | |
|
209 | 0 | if ((infoflag & MY_GIVE_INFO) || (info_file != stderr)) { |
210 | 0 | #ifdef HAVE_GETRUSAGE |
211 | 0 | struct rusage rus; |
212 | 0 | if (!getrusage(RUSAGE_SELF, &rus)) |
213 | 0 | fprintf(info_file, |
214 | 0 | "\n\ |
215 | 0 | User time %.2f, System time %.2f\n \ |
216 | 0 | Maximum resident set size %ld, Integral resident set size %ld\n\ |
217 | 0 | Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\ |
218 | 0 | Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\ |
219 | 0 | Voluntary context switches %ld, Involuntary context switches %ld\n", |
220 | 0 | (rus.ru_utime.tv_sec * SCALE_SEC + |
221 | 0 | rus.ru_utime.tv_usec / SCALE_USEC) / |
222 | 0 | 100.0, |
223 | 0 | (rus.ru_stime.tv_sec * SCALE_SEC + |
224 | 0 | rus.ru_stime.tv_usec / SCALE_USEC) / |
225 | 0 | 100.0, |
226 | 0 | rus.ru_maxrss, rus.ru_idrss, rus.ru_minflt, rus.ru_majflt, |
227 | 0 | rus.ru_nswap, rus.ru_inblock, rus.ru_oublock, rus.ru_msgsnd, |
228 | 0 | rus.ru_msgrcv, rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw); |
229 | 0 | #endif |
230 | | #ifdef _WIN32 |
231 | | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); |
232 | | _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); |
233 | | _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); |
234 | | _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); |
235 | | _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); |
236 | | _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); |
237 | | #ifdef MY_MSCRT_DEBUG |
238 | | _CrtCheckMemory(); |
239 | | _CrtDumpMemoryLeaks(); |
240 | | #endif /* MY_MSCRT_DEBUG */ |
241 | | #endif /* _WIN32 */ |
242 | 0 | } |
243 | |
|
244 | 0 | if (!(infoflag & MY_DONT_FREE_DBUG)) { |
245 | 0 | DBUG_END(); /* Must be done before my_thread_end */ |
246 | 0 | } |
247 | |
|
248 | | #ifndef NDEBUG |
249 | | if (infoflag & MY_END_PROXY_MAIN_THD) my_main_thread_end(); |
250 | | #endif |
251 | 0 | my_thread_end(); |
252 | 0 | my_thread_global_end(); |
253 | |
|
254 | | #ifdef _WIN32 |
255 | | if (have_tcpip) WSACleanup(); |
256 | | #endif /* _WIN32 */ |
257 | |
|
258 | 0 | my_init_done = false; |
259 | 0 | } /* my_end */ |
260 | | |
261 | | /** |
262 | | Pointer to function that handles abort. It is the std's abort() by default. |
263 | | */ |
264 | | static void (*my_abort_func)() = abort; |
265 | | |
266 | 0 | [[noreturn]] void my_abort() { |
267 | 0 | my_abort_func(); |
268 | | /* |
269 | | We should not reach here, it is required only because my_abort_func() is |
270 | | not [[noreturn]]. |
271 | | */ |
272 | 0 | abort(); |
273 | 0 | } |
274 | | |
275 | 0 | void set_my_abort(void (*new_my_abort_func)()) { |
276 | 0 | my_abort_func = new_my_abort_func; |
277 | 0 | } |
278 | | |
279 | | #ifdef _WIN32 |
280 | | /* |
281 | | my_parameter_handler |
282 | | |
283 | | Invalid parameter handler we will use instead of the one "baked" |
284 | | into the CRT for Visual Studio. |
285 | | The assert will catch things typically *not* caught by sanitizers, |
286 | | e.g. iterator out-of-range, but pointing to valid memory. |
287 | | */ |
288 | | |
289 | | void my_parameter_handler(const wchar_t *expression [[maybe_unused]], |
290 | | const wchar_t *function [[maybe_unused]], |
291 | | const wchar_t *file [[maybe_unused]], |
292 | | unsigned int line [[maybe_unused]], |
293 | | uintptr_t pReserved [[maybe_unused]]) { |
294 | | #ifndef NDEBUG |
295 | | fprintf(stderr, |
296 | | "my_parameter_handler errno %d " |
297 | | "expression: %ws function: %ws file: %ws, line: %d\n", |
298 | | errno, expression, function, file, line); |
299 | | fflush(stderr); |
300 | | // We have tests which do this kind of failure injection: |
301 | | // DBUG_EXECUTE_IF("ib_export_io_write_failure_1", close(fileno(file));); |
302 | | // So ignore EBADF |
303 | | if (errno != EBADF) { |
304 | | assert(false); |
305 | | } |
306 | | #endif |
307 | | } |
308 | | |
309 | | #ifdef __MSVC_RUNTIME_CHECKS |
310 | | #include <rtcapi.h> |
311 | | |
312 | | /* Turn off runtime checks for 'handle_rtc_failure' */ |
313 | | #pragma runtime_checks("", off) |
314 | | |
315 | | /* |
316 | | handle_rtc_failure |
317 | | Windows: run-time error checks are reported to ... |
318 | | */ |
319 | | |
320 | | int handle_rtc_failure(int err_type, const char *file, int line, |
321 | | const char *module, const char *format, ...) { |
322 | | va_list args; |
323 | | char buff[2048]; |
324 | | size_t len; |
325 | | |
326 | | len = snprintf(buff, sizeof(buff), "At %s:%d: ", file, line); |
327 | | |
328 | | va_start(args, format); |
329 | | vsnprintf(buff + len, sizeof(buff) - len, format, args); |
330 | | va_end(args); |
331 | | |
332 | | my_message_local(ERROR_LEVEL, EE_WIN_RUN_TIME_ERROR_CHECK, buff); |
333 | | |
334 | | return 0; /* Error is handled */ |
335 | | } |
336 | | #pragma runtime_checks("", restore) |
337 | | #endif |
338 | | |
339 | | /* |
340 | | Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found |
341 | | there as environment variables |
342 | | */ |
343 | | static void win_init_registry() { |
344 | | HKEY key_handle; |
345 | | |
346 | | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) "SOFTWARE\\MySQL", 0, KEY_READ, |
347 | | &key_handle) == ERROR_SUCCESS) { |
348 | | LONG ret; |
349 | | DWORD index = 0; |
350 | | DWORD type; |
351 | | char key_name[256], key_data[1024]; |
352 | | DWORD key_name_len = sizeof(key_name) - 1; |
353 | | DWORD key_data_len = sizeof(key_data) - 1; |
354 | | |
355 | | while ((ret = RegEnumValue(key_handle, index++, key_name, &key_name_len, |
356 | | nullptr, &type, (LPBYTE)&key_data, |
357 | | &key_data_len)) != ERROR_NO_MORE_ITEMS) { |
358 | | char env_string[sizeof(key_name) + sizeof(key_data) + 2]; |
359 | | |
360 | | if (ret == ERROR_MORE_DATA) { |
361 | | /* Registry value larger than 'key_data', skip it */ |
362 | | DBUG_PRINT("error", ("Skipped registry value that was too large")); |
363 | | } else if (ret == ERROR_SUCCESS) { |
364 | | if (type == REG_SZ) { |
365 | | strxmov(env_string, key_name, "=", key_data, NullS); |
366 | | |
367 | | /* variable for putenv must be allocated ! */ |
368 | | putenv(strdup(env_string)); |
369 | | } |
370 | | } else { |
371 | | /* Unhandled error, break out of loop */ |
372 | | break; |
373 | | } |
374 | | |
375 | | key_name_len = sizeof(key_name) - 1; |
376 | | key_data_len = sizeof(key_data) - 1; |
377 | | } |
378 | | |
379 | | RegCloseKey(key_handle); |
380 | | } |
381 | | } |
382 | | |
383 | | /*------------------------------------------------------------------ |
384 | | Name: CheckForTcpip| Desc: checks if tcpip has been installed on system |
385 | | According to Microsoft Developers documentation the first registry |
386 | | entry should be enough to check if TCP/IP is installed, but as expected |
387 | | this doesn't work on all Win32 machines :( |
388 | | ------------------------------------------------------------------*/ |
389 | | |
390 | | #define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" |
391 | | #define WINSOCK2KEY "SYSTEM\\CurrentControlSet\\Services\\Winsock2\\Parameters" |
392 | | #define WINSOCKKEY "SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters" |
393 | | |
394 | | static bool win32_have_tcpip() { |
395 | | HKEY hTcpipRegKey; |
396 | | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCPIPKEY, 0, KEY_READ, &hTcpipRegKey) != |
397 | | ERROR_SUCCESS) { |
398 | | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINSOCK2KEY, 0, KEY_READ, |
399 | | &hTcpipRegKey) != ERROR_SUCCESS) { |
400 | | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINSOCKKEY, 0, KEY_READ, |
401 | | &hTcpipRegKey) != ERROR_SUCCESS) |
402 | | if (!getenv("HAVE_TCPIP") || have_tcpip) /* Provide a workaround */ |
403 | | return (false); |
404 | | } |
405 | | } |
406 | | RegCloseKey(hTcpipRegKey); |
407 | | return (true); |
408 | | } |
409 | | |
410 | | static bool win32_init_tcp_ip() { |
411 | | if (win32_have_tcpip()) { |
412 | | const WORD wVersionRequested = MAKEWORD(2, 2); |
413 | | WSADATA wsaData; |
414 | | /* Be a good citizen: maybe another lib has already initialised |
415 | | sockets, so dont clobber them unless necessary */ |
416 | | if (WSAStartup(wVersionRequested, &wsaData)) { |
417 | | /* Load failed, maybe because of previously loaded |
418 | | incompatible version; try again */ |
419 | | WSACleanup(); |
420 | | if (!WSAStartup(wVersionRequested, &wsaData)) have_tcpip = 1; |
421 | | } else { |
422 | | if (wsaData.wVersion != wVersionRequested) { |
423 | | /* Version is no good, try again */ |
424 | | WSACleanup(); |
425 | | if (!WSAStartup(wVersionRequested, &wsaData)) have_tcpip = 1; |
426 | | } else |
427 | | have_tcpip = 1; |
428 | | } |
429 | | } |
430 | | return (0); |
431 | | } |
432 | | |
433 | | /** |
434 | | Windows specific initialization of my_sys functions, resources and variables |
435 | | */ |
436 | | static void my_win_init() { |
437 | | DBUG_TRACE; |
438 | | |
439 | | /* this is required to make crt functions return -1 appropriately */ |
440 | | _set_invalid_parameter_handler(my_parameter_handler); |
441 | | |
442 | | #ifdef __MSVC_RUNTIME_CHECKS |
443 | | /* |
444 | | Install handler to send RTC (Runtime Error Check) warnings |
445 | | to log file |
446 | | */ |
447 | | _RTC_SetErrorFunc(handle_rtc_failure); |
448 | | #endif |
449 | | |
450 | | _tzset(); |
451 | | |
452 | | win_init_registry(); |
453 | | win32_init_tcp_ip(); |
454 | | |
455 | | MyWinfileInit(); |
456 | | } |
457 | | #endif /* _WIN32 */ |
458 | | |
459 | | PSI_stage_info stage_waiting_for_table_level_lock = { |
460 | | 0, "Waiting for table level lock", 0, PSI_DOCUMENT_ME}; |
461 | | |
462 | | PSI_stage_info stage_waiting_for_disk_space = {0, "Waiting for disk space", 0, |
463 | | PSI_DOCUMENT_ME}; |
464 | | |
465 | | PSI_mutex_key key_IO_CACHE_append_buffer_lock, key_IO_CACHE_SHARE_mutex, |
466 | | key_KEY_CACHE_cache_lock, key_THR_LOCK_heap, key_THR_LOCK_lock, |
467 | | key_THR_LOCK_malloc, key_THR_LOCK_mutex, key_THR_LOCK_myisam, |
468 | | key_THR_LOCK_net, key_THR_LOCK_open, key_THR_LOCK_threads, key_TMPDIR_mutex, |
469 | | key_THR_LOCK_myisam_mmap; |
470 | | |
471 | | #ifdef HAVE_PSI_MUTEX_INTERFACE |
472 | | |
473 | | static PSI_mutex_info all_mysys_mutexes[] = { |
474 | | {&key_IO_CACHE_append_buffer_lock, "IO_CACHE::append_buffer_lock", 0, 0, |
475 | | PSI_DOCUMENT_ME}, |
476 | | {&key_IO_CACHE_SHARE_mutex, "IO_CACHE::SHARE_mutex", 0, 0, PSI_DOCUMENT_ME}, |
477 | | {&key_KEY_CACHE_cache_lock, "KEY_CACHE::cache_lock", 0, 0, PSI_DOCUMENT_ME}, |
478 | | {&key_THR_LOCK_heap, "THR_LOCK_heap", PSI_FLAG_SINGLETON, 0, |
479 | | PSI_DOCUMENT_ME}, |
480 | | {&key_THR_LOCK_lock, "THR_LOCK_lock", PSI_FLAG_SINGLETON, 0, |
481 | | PSI_DOCUMENT_ME}, |
482 | | {&key_THR_LOCK_malloc, "THR_LOCK_malloc", PSI_FLAG_SINGLETON, 0, |
483 | | PSI_DOCUMENT_ME}, |
484 | | {&key_THR_LOCK_mutex, "THR_LOCK::mutex", 0, 0, PSI_DOCUMENT_ME}, |
485 | | {&key_THR_LOCK_myisam, "THR_LOCK_myisam", PSI_FLAG_SINGLETON, 0, |
486 | | PSI_DOCUMENT_ME}, |
487 | | {&key_THR_LOCK_net, "THR_LOCK_net", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, |
488 | | {&key_THR_LOCK_open, "THR_LOCK_open", PSI_FLAG_SINGLETON, 0, |
489 | | PSI_DOCUMENT_ME}, |
490 | | {&key_THR_LOCK_threads, "THR_LOCK_threads", PSI_FLAG_SINGLETON, 0, |
491 | | PSI_DOCUMENT_ME}, |
492 | | {&key_TMPDIR_mutex, "TMPDIR_mutex", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, |
493 | | {&key_THR_LOCK_myisam_mmap, "THR_LOCK_myisam_mmap", PSI_FLAG_SINGLETON, 0, |
494 | | PSI_DOCUMENT_ME}}; |
495 | | #endif /* HAVE_PSI_MUTEX_INTERFACE */ |
496 | | |
497 | | PSI_rwlock_key key_SAFE_HASH_lock; |
498 | | |
499 | | #ifdef HAVE_PSI_RWLOCK_INTERFACE |
500 | | static PSI_rwlock_info all_mysys_rwlocks[] = { |
501 | | {&key_SAFE_HASH_lock, "SAFE_HASH::lock", 0, 0, PSI_DOCUMENT_ME}}; |
502 | | #endif /* HAVE_PSI_RWLOCK_INTERFACE */ |
503 | | |
504 | | PSI_cond_key key_IO_CACHE_SHARE_cond, key_IO_CACHE_SHARE_cond_writer, |
505 | | key_THR_COND_threads; |
506 | | |
507 | | #ifdef HAVE_PSI_COND_INTERFACE |
508 | | |
509 | | static PSI_cond_info all_mysys_conds[] = { |
510 | | {&key_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond", 0, 0, PSI_DOCUMENT_ME}, |
511 | | {&key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer", 0, 0, |
512 | | PSI_DOCUMENT_ME}, |
513 | | {&key_THR_COND_threads, "THR_COND_threads", 0, 0, PSI_DOCUMENT_ME}}; |
514 | | #endif /* HAVE_PSI_COND_INTERFACE */ |
515 | | |
516 | | #ifdef HAVE_PSI_FILE_INTERFACE |
517 | | #ifdef HAVE_LINUX_LARGE_PAGES |
518 | | PSI_file_key key_file_proc_meminfo; |
519 | | #endif /* HAVE_LINUX_LARGE_PAGES */ |
520 | | PSI_file_key key_file_charset, key_file_cnf; |
521 | | |
522 | | static PSI_file_info all_mysys_files[] = { |
523 | | #ifdef HAVE_LINUX_LARGE_PAGES |
524 | | {&key_file_proc_meminfo, "proc_meminfo", 0, 0, PSI_DOCUMENT_ME}, |
525 | | #endif /* HAVE_LINUX_LARGE_PAGES */ |
526 | | {&key_file_charset, "charset", 0, 0, PSI_DOCUMENT_ME}, |
527 | | {&key_file_cnf, "cnf", 0, 0, PSI_DOCUMENT_ME}}; |
528 | | #endif /* HAVE_PSI_FILE_INTERFACE */ |
529 | | |
530 | | #ifdef HAVE_PSI_STAGE_INTERFACE |
531 | | PSI_stage_info *all_mysys_stages[] = {&stage_waiting_for_table_level_lock}; |
532 | | #endif /* HAVE_PSI_STAGE_INTERFACE */ |
533 | | |
534 | | #ifdef HAVE_PSI_MEMORY_INTERFACE |
535 | | static PSI_memory_info all_mysys_memory[] = { |
536 | | #ifdef _WIN32 |
537 | | {&key_memory_win_SECURITY_ATTRIBUTES, "win_SECURITY_ATTRIBUTES", 0, 0, |
538 | | PSI_DOCUMENT_ME}, |
539 | | {&key_memory_win_PACL, "win_PACL", 0, 0, PSI_DOCUMENT_ME}, |
540 | | {&key_memory_win_IP_ADAPTER_ADDRESSES, "win_IP_ADAPTER_ADDRESSES", 0, 0, |
541 | | PSI_DOCUMENT_ME}, |
542 | | {&key_memory_win_handle_info, "win_handle_to_fd_mapping", 0, 0, |
543 | | PSI_DOCUMENT_ME}, |
544 | | #endif |
545 | | |
546 | | {&key_memory_max_alloca, "max_alloca", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
547 | | PSI_DOCUMENT_ME}, |
548 | | {&key_memory_charset_loader, "charset_loader", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
549 | | PSI_DOCUMENT_ME}, |
550 | | {&key_memory_lf_node, "lf_node", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
551 | | PSI_DOCUMENT_ME}, |
552 | | {&key_memory_lf_dynarray, "lf_dynarray", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
553 | | PSI_DOCUMENT_ME}, |
554 | | {&key_memory_lf_slist, "lf_slist", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
555 | | PSI_DOCUMENT_ME}, |
556 | | {&key_memory_LIST, "LIST", 0, 0, PSI_DOCUMENT_ME}, |
557 | | {&key_memory_IO_CACHE, "IO_CACHE", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
558 | | PSI_DOCUMENT_ME}, |
559 | | {&key_memory_KEY_CACHE, "KEY_CACHE", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
560 | | PSI_DOCUMENT_ME}, |
561 | | {&key_memory_SAFE_HASH_ENTRY, "SAFE_HASH_ENTRY", 0, 0, PSI_DOCUMENT_ME}, |
562 | | {&key_memory_MY_TMPDIR_full_list, "MY_TMPDIR::full_list", 0, 0, |
563 | | PSI_DOCUMENT_ME}, |
564 | | {&key_memory_MY_BITMAP_bitmap, "MY_BITMAP::bitmap", 0, 0, PSI_DOCUMENT_ME}, |
565 | | {&key_memory_my_compress_alloc, "my_compress_alloc", 0, 0, PSI_DOCUMENT_ME}, |
566 | | {&key_memory_my_err_head, "my_err_head", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
567 | | PSI_DOCUMENT_ME}, |
568 | | {&key_memory_my_file_info, "my_file_info", PSI_FLAG_ONLY_GLOBAL_STAT, 0, |
569 | | PSI_DOCUMENT_ME}, |
570 | | {&key_memory_MY_DIR, "MY_DIR", 0, 0, PSI_DOCUMENT_ME}, |
571 | | {&key_memory_DYNAMIC_STRING, "DYNAMIC_STRING", 0, 0, PSI_DOCUMENT_ME}, |
572 | | {&key_memory_TREE, "TREE", 0, 0, PSI_DOCUMENT_ME}}; |
573 | | #endif /* HAVE_PSI_MEMORY_INTERFACE */ |
574 | | |
575 | | #ifdef HAVE_PSI_THREAD_INTERFACE |
576 | | static PSI_thread_info all_mysys_thread[] = { |
577 | | {&key_thread_timer_notifier, "thread_timer_notifier", "timer_notifier", |
578 | | PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}}; |
579 | | #endif /* HAVE_PSI_THREAD_INTERFACE */ |
580 | | |
581 | | #ifdef HAVE_PSI_INTERFACE |
582 | 0 | void my_init_mysys_psi_keys() { |
583 | 0 | const char *category [[maybe_unused]] = "mysys"; |
584 | 0 | int count [[maybe_unused]]; |
585 | |
|
586 | 0 | #ifdef HAVE_PSI_MUTEX_INTERFACE |
587 | 0 | count = sizeof(all_mysys_mutexes) / sizeof(all_mysys_mutexes[0]); |
588 | 0 | mysql_mutex_register(category, all_mysys_mutexes, count); |
589 | 0 | #endif /* HAVE_PSI_MUTEX_INTERFACE */ |
590 | |
|
591 | 0 | #ifdef HAVE_PSI_RWLOCK_INTERFACE |
592 | 0 | count = sizeof(all_mysys_rwlocks) / sizeof(all_mysys_rwlocks[0]); |
593 | 0 | mysql_rwlock_register(category, all_mysys_rwlocks, count); |
594 | 0 | #endif /* HAVE_PSI_RWLOCK_INTERFACE */ |
595 | |
|
596 | 0 | #ifdef HAVE_PSI_COND_INTERFACE |
597 | 0 | count = sizeof(all_mysys_conds) / sizeof(all_mysys_conds[0]); |
598 | 0 | mysql_cond_register(category, all_mysys_conds, count); |
599 | 0 | #endif /* HAVE_PSI_COND_INTERFACE */ |
600 | |
|
601 | 0 | #ifdef HAVE_PSI_FILE_INTERFACE |
602 | 0 | count = sizeof(all_mysys_files) / sizeof(all_mysys_files[0]); |
603 | 0 | mysql_file_register(category, all_mysys_files, count); |
604 | 0 | #endif /* HAVE_PSI_FILE_INTERFACE */ |
605 | |
|
606 | 0 | #ifdef HAVE_PSI_STAGE_INTERFACE |
607 | 0 | count = array_elements(all_mysys_stages); |
608 | 0 | mysql_stage_register(category, all_mysys_stages, count); |
609 | 0 | #endif /* HAVE_PSI_STAGE_INTERFACE */ |
610 | |
|
611 | 0 | #ifdef HAVE_PSI_MEMORY_INTERFACE |
612 | 0 | count = array_elements(all_mysys_memory); |
613 | 0 | mysql_memory_register(category, all_mysys_memory, count); |
614 | 0 | #endif /* HAVE_PSI_MEMORY_INTERFACE */ |
615 | |
|
616 | 0 | #ifdef HAVE_PSI_THREAD_INTERFACE |
617 | 0 | count = array_elements(all_mysys_thread); |
618 | 0 | mysql_thread_register(category, all_mysys_thread, count); |
619 | 0 | #endif /* HAVE_PSI_THREAD_INTERFACE */ |
620 | 0 | } |
621 | | #endif /* HAVE_PSI_INTERFACE */ |