Skip to content

Commit 73fd8a4

Browse files
committed
Fix BSD and macOS builds w.r.t. pthread_setname_np (bug#38632)
pthread_setname_np takes only a single argument on BSD and macOS, and affects the current thread only. * configure.ac: Add check for single-argument pthread_setname_np * src/systhread.c (sys_thread_set_name): New (w32 and pthread versions). (sys_thread_create): Remove name argument and name-setting. (w32_beginthread_wrapper): Remove name-setting. * src/systhread.h (sys_thread_create, sys_thread_set_name): Update prototypes. * src/thread.c (run_thread): Call sys_thread_set_name. (Fmake_thread): Adapt call to sys_thread_create. * src/thread.h (struct thread_state): Adjust comment.
1 parent f54b243 commit 73fd8a4

File tree

5 files changed

+55
-33
lines changed

5 files changed

+55
-33
lines changed

configure.ac

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4183,6 +4183,23 @@ getpwent endpwent getgrent endgrent \
41834183
cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np)
41844184
LIBS=$OLD_LIBS
41854185

4186+
if test "$ac_cv_func_pthread_setname_np" = "yes"; then
4187+
AC_CACHE_CHECK(
4188+
[whether pthread_setname_np takes a single argument],
4189+
[emacs_cv_pthread_setname_np_1arg],
4190+
[AC_COMPILE_IFELSE(
4191+
[AC_LANG_PROGRAM(
4192+
[[#include <pthread.h>]],
4193+
[[pthread_setname_np ("a");]])],
4194+
[emacs_cv_pthread_setname_np_1arg=yes],
4195+
[emacs_cv_pthread_setname_np_1arg=no])])
4196+
if test "$emacs_cv_pthread_setname_np_1arg" = "yes"; then
4197+
AC_DEFINE(
4198+
HAVE_PTHREAD_SETNAME_NP_1ARG, 1,
4199+
[Define to 1 if pthread_setname_np takes a single argument.])
4200+
fi
4201+
fi
4202+
41864203
dnl No need to check for posix_memalign if aligned_alloc works.
41874204
AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
41884205
AC_CHECK_DECLS([aligned_alloc], [], [], [[#include <stdlib.h>]])

src/systhread.c

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,28 @@ sys_thread_equal (sys_thread_t t, sys_thread_t u)
200200
return pthread_equal (t, u);
201201
}
202202

203+
void
204+
sys_thread_set_name (const char *name)
205+
{
206+
#ifdef HAVE_PTHREAD_SETNAME_NP
207+
/* We need to truncate here otherwise pthread_setname_np
208+
fails to set the name. TASK_COMM_LEN is what the length
209+
is called in the Linux kernel headers (Bug#38632). */
210+
#define TASK_COMM_LEN 16
211+
char p_name[TASK_COMM_LEN];
212+
strncpy (p_name, name, TASK_COMM_LEN - 1);
213+
p_name[TASK_COMM_LEN - 1] = '\0';
214+
#ifdef HAVE_PTHREAD_SETNAME_NP_1ARG
215+
pthread_setname_np (p_name);
216+
#else
217+
pthread_setname_np (pthread_self (), p_name);
218+
#endif
219+
#endif
220+
}
221+
203222
bool
204-
sys_thread_create (sys_thread_t *thread_ptr, const char *name,
205-
thread_creation_function *func, void *arg)
223+
sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func,
224+
void *arg)
206225
{
207226
pthread_attr_t attr;
208227
bool result = false;
@@ -221,22 +240,7 @@ sys_thread_create (sys_thread_t *thread_ptr, const char *name,
221240
}
222241

223242
if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED))
224-
{
225-
result = pthread_create (thread_ptr, &attr, func, arg) == 0;
226-
#ifdef HAVE_PTHREAD_SETNAME_NP
227-
if (result && name != NULL)
228-
{
229-
/* We need to truncate here otherwise pthread_setname_np
230-
fails to set the name. TASK_COMM_LEN is what the length
231-
is called in the Linux kernel headers (Bug#38632). */
232-
#define TASK_COMM_LEN 16
233-
char p_name[TASK_COMM_LEN];
234-
strncpy (p_name, name, TASK_COMM_LEN - 1);
235-
p_name[TASK_COMM_LEN - 1] = '\0';
236-
pthread_setname_np (*thread_ptr, p_name);
237-
}
238-
#endif
239-
}
243+
result = pthread_create (thread_ptr, &attr, func, arg) == 0;
240244

241245
out: ;
242246
int error = pthread_attr_destroy (&attr);
@@ -457,26 +461,24 @@ w32_set_thread_name (DWORD thread_id, const char *name)
457461

458462
static thread_creation_function *thread_start_address;
459463

464+
void
465+
sys_thread_set_name (const char *name)
466+
{
467+
w32_set_thread_name (GetCurrentThreadId (), name);
468+
}
469+
460470
/* _beginthread wants a void function, while we are passed a function
461471
that returns a pointer. So we use a wrapper. See the command in
462472
w32term.h about the need for ALIGN_STACK attribute. */
463473
static void ALIGN_STACK
464474
w32_beginthread_wrapper (void *arg)
465475
{
466-
/* FIXME: This isn't very clean: systhread.c is not supposed to know
467-
that ARG is a pointer to a thread_state object, or be familiar
468-
with thread_state object's structure in general. */
469-
struct thread_state *this_thread = arg;
470-
471-
if (this_thread->thread_name)
472-
w32_set_thread_name (GetCurrentThreadId (), this_thread->thread_name);
473-
474476
(void)thread_start_address (arg);
475477
}
476478

477479
bool
478-
sys_thread_create (sys_thread_t *thread_ptr, const char *name,
479-
thread_creation_function *func, void *arg)
480+
sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func,
481+
void *arg)
480482
{
481483
/* FIXME: Do threads that run Lisp require some minimum amount of
482484
stack? Zero here means each thread will get the same amount as

src/systhread.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,11 @@ extern sys_thread_t sys_thread_self (void)
112112
extern bool sys_thread_equal (sys_thread_t, sys_thread_t)
113113
ATTRIBUTE_WARN_UNUSED_RESULT;
114114

115-
extern bool sys_thread_create (sys_thread_t *, const char *,
116-
thread_creation_function *, void *)
115+
extern bool sys_thread_create (sys_thread_t *, thread_creation_function *,
116+
void *)
117117
ATTRIBUTE_WARN_UNUSED_RESULT;
118118

119119
extern void sys_thread_yield (void);
120+
extern void sys_thread_set_name (const char *);
120121

121122
#endif /* SYSTHREAD_H */

src/thread.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,9 @@ run_thread (void *state)
725725
self->m_stack_bottom = self->stack_top = (char *) &stack_pos;
726726
self->thread_id = sys_thread_self ();
727727

728+
if (self->thread_name)
729+
sys_thread_set_name (self->thread_name);
730+
728731
acquire_global_lock (self);
729732

730733
/* Put a dummy catcher at top-level so that handlerlist is never NULL.
@@ -832,7 +835,7 @@ If NAME is given, it must be a string; it names the new thread. */)
832835
else
833836
new_thread->thread_name = NULL;
834837
sys_thread_t thr;
835-
if (! sys_thread_create (&thr, c_name, run_thread, new_thread))
838+
if (! sys_thread_create (&thr, run_thread, new_thread))
836839
{
837840
/* Restore the previous situation. */
838841
all_threads = all_threads->next_thread;

src/thread.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,7 @@ struct thread_state
169169
interrupter should broadcast to this condition. */
170170
sys_cond_t *wait_condvar;
171171

172-
/* Thread's name in the locale encoding. Actually used only on
173-
WINDOWSNT. */
172+
/* Thread's name in the locale encoding. */
174173
char *thread_name;
175174

176175
/* This thread might have released the global lock. If so, this is

0 commit comments

Comments
 (0)