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.
This commit is contained in:
parent
f54b24304d
commit
73fd8a4b53
5 changed files with 55 additions and 33 deletions
17
configure.ac
17
configure.ac
|
@ -4183,6 +4183,23 @@ getpwent endpwent getgrent endgrent \
|
|||
cfmakeraw cfsetspeed __executable_start log2 pthread_setname_np)
|
||||
LIBS=$OLD_LIBS
|
||||
|
||||
if test "$ac_cv_func_pthread_setname_np" = "yes"; then
|
||||
AC_CACHE_CHECK(
|
||||
[whether pthread_setname_np takes a single argument],
|
||||
[emacs_cv_pthread_setname_np_1arg],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <pthread.h>]],
|
||||
[[pthread_setname_np ("a");]])],
|
||||
[emacs_cv_pthread_setname_np_1arg=yes],
|
||||
[emacs_cv_pthread_setname_np_1arg=no])])
|
||||
if test "$emacs_cv_pthread_setname_np_1arg" = "yes"; then
|
||||
AC_DEFINE(
|
||||
HAVE_PTHREAD_SETNAME_NP_1ARG, 1,
|
||||
[Define to 1 if pthread_setname_np takes a single argument.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl No need to check for posix_memalign if aligned_alloc works.
|
||||
AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
|
||||
AC_CHECK_DECLS([aligned_alloc], [], [], [[#include <stdlib.h>]])
|
||||
|
|
|
@ -200,9 +200,28 @@ sys_thread_equal (sys_thread_t t, sys_thread_t u)
|
|||
return pthread_equal (t, u);
|
||||
}
|
||||
|
||||
void
|
||||
sys_thread_set_name (const char *name)
|
||||
{
|
||||
#ifdef HAVE_PTHREAD_SETNAME_NP
|
||||
/* We need to truncate here otherwise pthread_setname_np
|
||||
fails to set the name. TASK_COMM_LEN is what the length
|
||||
is called in the Linux kernel headers (Bug#38632). */
|
||||
#define TASK_COMM_LEN 16
|
||||
char p_name[TASK_COMM_LEN];
|
||||
strncpy (p_name, name, TASK_COMM_LEN - 1);
|
||||
p_name[TASK_COMM_LEN - 1] = '\0';
|
||||
#ifdef HAVE_PTHREAD_SETNAME_NP_1ARG
|
||||
pthread_setname_np (p_name);
|
||||
#else
|
||||
pthread_setname_np (pthread_self (), p_name);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
sys_thread_create (sys_thread_t *thread_ptr, const char *name,
|
||||
thread_creation_function *func, void *arg)
|
||||
sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func,
|
||||
void *arg)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
bool result = false;
|
||||
|
@ -221,22 +240,7 @@ sys_thread_create (sys_thread_t *thread_ptr, const char *name,
|
|||
}
|
||||
|
||||
if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED))
|
||||
{
|
||||
result = pthread_create (thread_ptr, &attr, func, arg) == 0;
|
||||
#ifdef HAVE_PTHREAD_SETNAME_NP
|
||||
if (result && name != NULL)
|
||||
{
|
||||
/* We need to truncate here otherwise pthread_setname_np
|
||||
fails to set the name. TASK_COMM_LEN is what the length
|
||||
is called in the Linux kernel headers (Bug#38632). */
|
||||
#define TASK_COMM_LEN 16
|
||||
char p_name[TASK_COMM_LEN];
|
||||
strncpy (p_name, name, TASK_COMM_LEN - 1);
|
||||
p_name[TASK_COMM_LEN - 1] = '\0';
|
||||
pthread_setname_np (*thread_ptr, p_name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
result = pthread_create (thread_ptr, &attr, func, arg) == 0;
|
||||
|
||||
out: ;
|
||||
int error = pthread_attr_destroy (&attr);
|
||||
|
@ -457,26 +461,24 @@ w32_set_thread_name (DWORD thread_id, const char *name)
|
|||
|
||||
static thread_creation_function *thread_start_address;
|
||||
|
||||
void
|
||||
sys_thread_set_name (const char *name)
|
||||
{
|
||||
w32_set_thread_name (GetCurrentThreadId (), name);
|
||||
}
|
||||
|
||||
/* _beginthread wants a void function, while we are passed a function
|
||||
that returns a pointer. So we use a wrapper. See the command in
|
||||
w32term.h about the need for ALIGN_STACK attribute. */
|
||||
static void ALIGN_STACK
|
||||
w32_beginthread_wrapper (void *arg)
|
||||
{
|
||||
/* FIXME: This isn't very clean: systhread.c is not supposed to know
|
||||
that ARG is a pointer to a thread_state object, or be familiar
|
||||
with thread_state object's structure in general. */
|
||||
struct thread_state *this_thread = arg;
|
||||
|
||||
if (this_thread->thread_name)
|
||||
w32_set_thread_name (GetCurrentThreadId (), this_thread->thread_name);
|
||||
|
||||
(void)thread_start_address (arg);
|
||||
}
|
||||
|
||||
bool
|
||||
sys_thread_create (sys_thread_t *thread_ptr, const char *name,
|
||||
thread_creation_function *func, void *arg)
|
||||
sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func,
|
||||
void *arg)
|
||||
{
|
||||
/* FIXME: Do threads that run Lisp require some minimum amount of
|
||||
stack? Zero here means each thread will get the same amount as
|
||||
|
|
|
@ -112,10 +112,11 @@ extern sys_thread_t sys_thread_self (void)
|
|||
extern bool sys_thread_equal (sys_thread_t, sys_thread_t)
|
||||
ATTRIBUTE_WARN_UNUSED_RESULT;
|
||||
|
||||
extern bool sys_thread_create (sys_thread_t *, const char *,
|
||||
thread_creation_function *, void *)
|
||||
extern bool sys_thread_create (sys_thread_t *, thread_creation_function *,
|
||||
void *)
|
||||
ATTRIBUTE_WARN_UNUSED_RESULT;
|
||||
|
||||
extern void sys_thread_yield (void);
|
||||
extern void sys_thread_set_name (const char *);
|
||||
|
||||
#endif /* SYSTHREAD_H */
|
||||
|
|
|
@ -725,6 +725,9 @@ run_thread (void *state)
|
|||
self->m_stack_bottom = self->stack_top = (char *) &stack_pos;
|
||||
self->thread_id = sys_thread_self ();
|
||||
|
||||
if (self->thread_name)
|
||||
sys_thread_set_name (self->thread_name);
|
||||
|
||||
acquire_global_lock (self);
|
||||
|
||||
/* 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. */)
|
|||
else
|
||||
new_thread->thread_name = NULL;
|
||||
sys_thread_t thr;
|
||||
if (! sys_thread_create (&thr, c_name, run_thread, new_thread))
|
||||
if (! sys_thread_create (&thr, run_thread, new_thread))
|
||||
{
|
||||
/* Restore the previous situation. */
|
||||
all_threads = all_threads->next_thread;
|
||||
|
|
|
@ -169,8 +169,7 @@ struct thread_state
|
|||
interrupter should broadcast to this condition. */
|
||||
sys_cond_t *wait_condvar;
|
||||
|
||||
/* Thread's name in the locale encoding. Actually used only on
|
||||
WINDOWSNT. */
|
||||
/* Thread's name in the locale encoding. */
|
||||
char *thread_name;
|
||||
|
||||
/* This thread might have released the global lock. If so, this is
|
||||
|
|
Loading…
Add table
Reference in a new issue