Skip to content

Commit 5bd0516

Browse files
committed
MDEV-32537 Name threads to improve debugging experience and diagnostics.
Use SetThreadDescription/pthread_setname_np to give threads a name.
1 parent 584fc85 commit 5bd0516

File tree

14 files changed

+131
-36
lines changed

14 files changed

+131
-36
lines changed

include/mysql/psi/psi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,12 @@ typedef void (*set_thread_os_id_v1_t)(struct PSI_thread *thread);
16241624
*/
16251625
typedef struct PSI_thread* (*get_thread_v1_t)(void);
16261626

1627+
/**
1628+
Get name of the thread, according to the thread class.
1629+
The name is returns without the thread/subsystem prefix.
1630+
*/
1631+
typedef const char* (*get_thread_class_name_v1_t)(void);
1632+
16271633
/**
16281634
Assign a user name to the instrumented thread.
16291635
@param user the user name
@@ -2538,6 +2544,8 @@ struct PSI_v1
25382544
set_thread_os_id_v1_t set_thread_os_id;
25392545
/** @sa get_thread_v1_t. */
25402546
get_thread_v1_t get_thread;
2547+
/** @sa get_thread_name_v1_t. */
2548+
get_thread_class_name_v1_t get_thread_class_name;
25412549
/** @sa set_thread_user_v1_t. */
25422550
set_thread_user_v1_t set_thread_user;
25432551
/** @sa set_thread_account_v1_t. */

include/mysql/psi/psi_abi_v1.h.pp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@
449449
ulonglong id);
450450
typedef void (*set_thread_os_id_v1_t)(struct PSI_thread *thread);
451451
typedef struct PSI_thread* (*get_thread_v1_t)(void);
452+
typedef const char* (*get_thread_class_name_v1_t)(void);
452453
typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
453454
typedef void (*set_thread_account_v1_t)(const char *user, int user_len,
454455
const char *host, int host_len);
@@ -725,6 +726,7 @@
725726
set_thread_THD_v1_t set_thread_THD;
726727
set_thread_os_id_v1_t set_thread_os_id;
727728
get_thread_v1_t get_thread;
729+
get_thread_class_name_v1_t get_thread_class_name;
728730
set_thread_user_v1_t set_thread_user;
729731
set_thread_account_v1_t set_thread_account;
730732
set_thread_db_v1_t set_thread_db;

include/pfs_thread_provider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ void pfs_set_thread_os_id_v1(PSI_thread *thread);
8080
PSI_thread*
8181
pfs_get_thread_v1(void);
8282

83+
const char *pfs_get_thread_class_name_v1(void);
84+
8385
void pfs_set_thread_user_v1(const char *user, int user_len);
8486

8587
void pfs_set_thread_account_v1(const char *user, int user_len,

mysys/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c my_default.c
4646
my_rdtsc.c psi_noop.c
4747
my_atomic_writes.c my_cpu.c my_likely.c my_largepage.c
4848
file_logger.c my_dlerror.c crc32/crc32c.cc
49-
my_timezone.cc)
49+
my_timezone.cc my_thread_name.cc)
5050

5151
IF (WIN32)
5252
SET (MYSYS_SOURCES ${MYSYS_SOURCES}

mysys/my_thr_init.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -172,35 +172,6 @@ my_bool my_thread_global_init(void)
172172
return 0;
173173
}
174174

175-
#ifdef _WIN32
176-
#define MAX_THREAD_NAME 256
177-
#elif defined(__linux__)
178-
#define MAX_THREAD_NAME 16
179-
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
180-
#include <pthread_np.h>
181-
#endif
182-
183-
void my_thread_set_name(const char *name)
184-
{
185-
#ifdef _WIN32
186-
wchar_t wname[MAX_THREAD_NAME];
187-
wname[0]= 0;
188-
MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_THREAD_NAME);
189-
SetThreadDescription(GetCurrentThread(), wname);
190-
#elif defined __linux__
191-
char shortname[MAX_THREAD_NAME];
192-
snprintf(shortname, MAX_THREAD_NAME, "%s", name);
193-
pthread_setname_np(pthread_self(), shortname);
194-
#elif defined __NetBSD__
195-
pthread_setname_np(pthread_self(), "%s", (void *) name);
196-
#elif defined __FreeBSD__ || defined __OpenBSD__
197-
pthread_set_name_np(pthread_self(), name);
198-
#elif defined __APPLE__
199-
pthread_setname_np(name);
200-
#else
201-
(void) name;
202-
#endif
203-
}
204175

205176
/**
206177
End the mysys thread system. Called when ending the last thread

mysys/my_thread_name.cc

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* Copyright 2024, MariaDB.
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 as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
15+
16+
#include <my_global.h>
17+
#include <my_pthread.h>
18+
#include <my_sys.h>
19+
#include "mysql/psi/psi.h"
20+
#include <stdio.h>
21+
22+
#ifdef _WIN32
23+
#define MAX_THREAD_NAME 256
24+
typedef HRESULT (*func_SetThreadDescription)(HANDLE,PCWSTR);
25+
#elif defined(__linux__)
26+
#define MAX_THREAD_NAME 16
27+
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
28+
#include <pthread_np.h>
29+
#endif
30+
31+
#if defined(HAVE_PSI_THREAD_INTERFACE) && !defined DBUG_OFF
32+
/**
33+
Check that the name is consistent with PSI.
34+
Require that the name matches the last part of PSI's class name
35+
(e.g. "thread/sql/main" -> "main").
36+
37+
We drop the namespace prefix, because these thread names are
38+
truncated to 15 characters on Linux, and something like "innodb/" would
39+
already take up about half of that.
40+
*/
41+
static void dbug_verify_thread_name(const char *name)
42+
{
43+
const char *psi_name= NULL;
44+
const char *thread_class_name= PSI_THREAD_CALL(get_thread_class_name)();
45+
if (thread_class_name)
46+
{
47+
/* Remove the path prefix */
48+
const char *last_part= strrchr(thread_class_name, '/');
49+
if (last_part)
50+
psi_name= last_part + 1;
51+
else
52+
psi_name= thread_class_name;
53+
}
54+
if (psi_name && strcmp(psi_name, name))
55+
{
56+
fprintf(stderr, "my_thread_set_name() mismatch: PSI name '%s' != '%s'\n",
57+
psi_name, name);
58+
abort();
59+
}
60+
}
61+
#else
62+
#define dbug_verify_thread_name(name) do {} while (0)
63+
#endif
64+
65+
/* Set current thread name for debugger/profiler and similar tools. */
66+
extern "C" void my_thread_set_name(const char *name)
67+
{
68+
dbug_verify_thread_name(name);
69+
70+
#ifdef _WIN32
71+
/*
72+
SetThreadDescription might not be there on older Windows versions.
73+
Load it dynamically.
74+
*/
75+
static func_SetThreadDescription my_SetThreadDescription=
76+
(func_SetThreadDescription) GetProcAddress(GetModuleHandle("kernel32"),
77+
"SetThreadDescription");
78+
if (!my_SetThreadDescription)
79+
return;
80+
wchar_t wname[MAX_THREAD_NAME];
81+
wname[0]= 0;
82+
MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_THREAD_NAME);
83+
my_SetThreadDescription(GetCurrentThread(), wname);
84+
#elif defined __linux__
85+
char shortname[MAX_THREAD_NAME];
86+
snprintf(shortname, MAX_THREAD_NAME, "%s", name);
87+
pthread_setname_np(pthread_self(), shortname);
88+
#elif defined __NetBSD__
89+
pthread_setname_np(pthread_self(), "%s", (void *) name);
90+
#elif defined __FreeBSD__ || defined __OpenBSD__
91+
pthread_set_name_np(pthread_self(), name);
92+
#elif defined __APPLE__
93+
pthread_setname_np(name);
94+
#else
95+
(void) name;
96+
#endif
97+
}

mysys/psi_noop.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ get_thread_noop(void NNN)
228228
return NULL;
229229
}
230230

231+
static const char* get_thread_class_name_noop(void)
232+
{
233+
return NULL;
234+
}
235+
231236
static void set_thread_user_noop(const char *user NNN, int user_len NNN)
232237
{
233238
return;
@@ -938,6 +943,7 @@ static PSI PSI_noop=
938943
set_thread_THD_noop,
939944
set_thread_os_id_noop,
940945
get_thread_noop,
946+
get_thread_class_name_noop,
941947
set_thread_user_noop,
942948
set_thread_user_host_noop,
943949
set_thread_db_noop,

sql/mysqld.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3219,7 +3219,7 @@ pthread_handler_t signal_hand(void *)
32193219
sigset_t set;
32203220
int sig;
32213221
my_thread_init();// Init new thread
3222-
my_thread_set_name("signal_hand");
3222+
my_thread_set_name("signal_handler");
32233223
signal_thread_in_use= 1;
32243224

32253225
if (test_flags & TEST_SIGINT)

sql/rpl_parallel.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,7 @@ handle_rpl_parallel_thread(void *arg)
12261226
struct rpl_parallel_thread *rpt= (struct rpl_parallel_thread *)arg;
12271227

12281228
my_thread_init();
1229-
my_thread_set_name("rpl_parallel");
1229+
my_thread_set_name("rpl_parallel_thread");
12301230
thd = new THD(next_thread_id());
12311231
thd->thread_stack = (char*)&thd;
12321232
server_threads.insert(thd);

sql/semisync_master_ack_receiver.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pthread_handler_t ack_receive_handler(void *arg)
3333
Ack_receiver *recv= reinterpret_cast<Ack_receiver *>(arg);
3434

3535
my_thread_init();
36-
my_thread_set_name("ack_receive");
36+
my_thread_set_name("Ack_receiver");
3737
recv->run();
3838
my_thread_end();
3939

0 commit comments

Comments
 (0)