Coverage Report

Created: 2025-07-23 06:50

/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 */