Add pthread_getname_np and pthread_setname_np for Hurd

We use thread_get_name and thread_set_name to get and set the thread
name, so nothing is stored in the thread structure since these functions
are supposed to be called sparingly.

One notable difference with Linux is that the thread name is up to 32
chars, whereas Linux's is 16.

Also added a mach_RPC_CHECK to check for the existing of gnumach RPCs.
This commit is contained in:
Flavio Cruz 2024-07-11 23:37:35 +01:00 committed by Samuel Thibault
parent a11e15ea0a
commit 2dcc908538
10 changed files with 239 additions and 13 deletions

View File

@ -159,6 +159,12 @@
/* Mach specific: define if the `host_page_size' RPC is available. */ /* Mach specific: define if the `host_page_size' RPC is available. */
#undef HAVE_HOST_PAGE_SIZE #undef HAVE_HOST_PAGE_SIZE
/* Mach specific: define if the `thread_set_name' RPC is available. */
#undef HAVE_MACH_THREAD_SET_NAME
/* Mach specific: define if the `thread_get_name' RPC is available. */
#undef HAVE_MACH_THREAD_GET_NAME
/* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */ /* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */
#undef HAVE_I386_IO_PERM_MODIFY #undef HAVE_I386_IO_PERM_MODIFY

View File

@ -145,6 +145,8 @@ libpthread-routines := \
pt-getcpuclockid \ pt-getcpuclockid \
pt-setschedprio \ pt-setschedprio \
pt-yield \ pt-yield \
pt-getname-np \
pt-setname-np \
sem_close \ sem_close \
sem-destroy \ sem-destroy \
sem-getvalue \ sem-getvalue \

View File

@ -169,6 +169,11 @@ libpthread {
sem_clockwait; sem_clockwait;
} }
GLIBC_2.40 {
pthread_getname_np;
pthread_setname_np;
}
GLIBC_PRIVATE { GLIBC_PRIVATE {
__pthread_initialize_minimal; __pthread_initialize_minimal;

View File

@ -891,6 +891,17 @@ extern int pthread_setschedparam (pthread_t __thr, int __policy,
/* Set thread THREAD's scheduling priority. */ /* Set thread THREAD's scheduling priority. */
extern int pthread_setschedprio (pthread_t __thr, int __prio) __THROW; extern int pthread_setschedprio (pthread_t __thr, int __prio) __THROW;
#ifdef __USE_GNU
/* Get thread name visible in the kernel and its interfaces. */
extern int pthread_getname_np (pthread_t __target_thread, char *__buf,
size_t __buflen)
__THROW __nonnull ((2)) __attr_access ((__write_only__, 2));
/* Set thread name visible in the kernel and its interfaces. */
extern int pthread_setname_np (pthread_t __target_thread, const char *__name)
__THROW __nonnull ((2)) __attr_access ((__read_only__, 2));
#endif
#ifdef __USE_GNU #ifdef __USE_GNU
/* Yield the processor to another thread or process. /* Yield the processor to another thread or process.
This function is similar to the POSIX `sched_yield' function but This function is similar to the POSIX `sched_yield' function but

View File

@ -293,6 +293,9 @@ if test "x$mach_interface_list" = x; then
as_fn_error $? "what manner of Mach is this?" "$LINENO" 5 as_fn_error $? "what manner of Mach is this?" "$LINENO" 5
fi fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep -e" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep -e" >&5
printf %s "checking for egrep -e... " >&6; } printf %s "checking for egrep -e... " >&6; }
if test ${ac_cv_path_EGREP_TRADITIONAL+y} if test ${ac_cv_path_EGREP_TRADITIONAL+y}
@ -429,7 +432,7 @@ printf "%s\n" "$ac_cv_path_EGREP_TRADITIONAL" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for host_page_size in mach_host.defs" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for host_page_size in mach_host.defs" >&5
printf %s "checking for host_page_size in mach_host.defs... " >&6; } printf %s "checking for host_page_size in mach_host.defs... " >&6; }
if test ${libc_cv_mach_host_page_size+y} if test ${libc_cv_mach_rpc_host_page_size+y}
then : then :
printf %s "(cached) " >&6 printf %s "(cached) " >&6
else case e in #( else case e in #(
@ -441,22 +444,83 @@ _ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP_TRADITIONAL "host_page_size" >/dev/null 2>&1 $EGREP_TRADITIONAL "host_page_size" >/dev/null 2>&1
then : then :
libc_cv_mach_host_page_size=yes libc_cv_mach_rpc_host_page_size=yes
else case e in #( else case e in #(
e) libc_cv_mach_host_page_size=no ;; e) libc_cv_mach_rpc_host_page_size=no ;;
esac esac
fi fi
rm -rf conftest* rm -rf conftest*
;; ;;
esac esac
fi fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_host_page_size" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_host_page_size" >&5
printf "%s\n" "$libc_cv_mach_host_page_size" >&6; } printf "%s\n" "$libc_cv_mach_rpc_host_page_size" >&6; }
if test $libc_cv_mach_host_page_size = yes; then if test $libc_cv_mach_rpc_host_page_size = yes; then
printf "%s\n" "#define HAVE_HOST_PAGE_SIZE 1" >>confdefs.h printf "%s\n" "#define HAVE_HOST_PAGE_SIZE 1" >>confdefs.h
fi fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for thread_set_name in gnumach.defs" >&5
printf %s "checking for thread_set_name in gnumach.defs... " >&6; }
if test ${libc_cv_mach_rpc_thread_set_name+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <mach/gnumach.defs>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP_TRADITIONAL "thread_set_name" >/dev/null 2>&1
then :
libc_cv_mach_rpc_thread_set_name=yes
else case e in #(
e) libc_cv_mach_rpc_thread_set_name=no ;;
esac
fi
rm -rf conftest*
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_thread_set_name" >&5
printf "%s\n" "$libc_cv_mach_rpc_thread_set_name" >&6; }
if test $libc_cv_mach_rpc_thread_set_name = yes; then
printf "%s\n" "#define HAVE_MACH_THREAD_SET_NAME 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for thread_get_name in gnumach.defs" >&5
printf %s "checking for thread_get_name in gnumach.defs... " >&6; }
if test ${libc_cv_mach_rpc_thread_get_name+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <mach/gnumach.defs>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP_TRADITIONAL "thread_get_name" >/dev/null 2>&1
then :
libc_cv_mach_rpc_thread_get_name=yes
else case e in #(
e) libc_cv_mach_rpc_thread_get_name=no ;;
esac
fi
rm -rf conftest*
;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_thread_get_name" >&5
printf "%s\n" "$libc_cv_mach_rpc_thread_get_name" >&6; }
if test $libc_cv_mach_rpc_thread_get_name = yes; then
printf "%s\n" "#define HAVE_MACH_THREAD_GET_NAME 1" >>confdefs.h
fi
ac_fn_c_check_header_preproc "$LINENO" "mach/machine/ndr_def.h" "ac_cv_header_mach_machine_ndr_def_h" ac_fn_c_check_header_preproc "$LINENO" "mach/machine/ndr_def.h" "ac_cv_header_mach_machine_ndr_def_h"
if test "x$ac_cv_header_mach_machine_ndr_def_h" = xyes if test "x$ac_cv_header_mach_machine_ndr_def_h" = xyes
then : then :

View File

@ -72,14 +72,29 @@ if test "x$mach_interface_list" = x; then
AC_MSG_ERROR([what manner of Mach is this?]) AC_MSG_ERROR([what manner of Mach is this?])
fi fi
AC_CACHE_CHECK(for host_page_size in mach_host.defs, dnl
libc_cv_mach_host_page_size, [dnl dnl mach_RPC_CHECK(interface.defs, rpc_method, define)
AC_EGREP_HEADER(host_page_size, mach/mach_host.defs, dnl
libc_cv_mach_host_page_size=yes, dnl Check if rpc_method RPC is defined by interface.defs
libc_cv_mach_host_page_size=no)]) dnl and define `define`.
if test $libc_cv_mach_host_page_size = yes; then dnl
AC_DEFINE([HAVE_HOST_PAGE_SIZE]) AC_DEFUN([mach_RPC_CHECK], [dnl
AC_CACHE_CHECK(for $2 in $1, libc_cv_mach_rpc_$2, [dnl
AC_EGREP_HEADER($2, mach/$1,
libc_cv_mach_rpc_$2=yes,
libc_cv_mach_rpc_$2=no)])
if test $libc_cv_mach_rpc_$2 = yes; then
AC_DEFINE([$3])
fi fi
])
mach_RPC_CHECK(mach_host.defs, host_page_size,
HAVE_HOST_PAGE_SIZE)
mach_RPC_CHECK(gnumach.defs, thread_set_name,
HAVE_MACH_THREAD_SET_NAME)
mach_RPC_CHECK(gnumach.defs, thread_get_name,
HAVE_MACH_THREAD_GET_NAME)
AC_CHECK_HEADER(mach/machine/ndr_def.h, [dnl AC_CHECK_HEADER(mach/machine/ndr_def.h, [dnl
DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"], [dnl DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"], [dnl

View File

@ -0,0 +1,67 @@
/* pthread_getname_np.
Copyright (C) 2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <hurd.h>
#include <mach_debug/mach_debug_types.h>
#include <pthread.h>
#include <pthreadP.h>
#include <string.h>
#include <pt-internal.h>
int
__pthread_getname_np (pthread_t thread, char *buf, size_t len)
{
#ifdef HAVE_MACH_THREAD_GET_NAME
/* GNU Mach doesn't export this so we have to define it ourselves. */
#define MACH_THREAD_NAME_MAX 32
struct __pthread *pthread;
error_t err;
kernel_debug_name_t tmp;
/* Note that we don't check for len to be MACH_THREAD_NAME_MAX
* since we want to be more compatible with the Linux API which
* requires that the buffer is at least 16 bytes long.
*
* We check for at least 1 byte since we truncate the result below. */
if (len < 1)
return ERANGE;
if (len > MACH_THREAD_NAME_MAX)
len = MACH_THREAD_NAME_MAX;
/* Lookup the thread structure for THREAD. */
pthread = __pthread_getid (thread);
if (pthread == NULL)
return ESRCH;
/* __thread_get_name expects a buffer of size sizeof (kernel_debug_name_t)
* and anything smaller will overflow. */
err = __thread_get_name (pthread->kernel_thread, tmp);
if (err != KERN_SUCCESS)
return __hurd_fail (err);
/* Truncate the source name to fit in the destination buffer. */
tmp[len - 1] = '\0';
memcpy (buf, tmp, len);
return 0;
#else
return ENOTSUP;
#endif
}
weak_alias (__pthread_getname_np, pthread_getname_np)

View File

@ -0,0 +1,52 @@
/* pthread_setname_np. Mach version.
Copyright (C) 2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <hurd.h>
#include <pthread.h>
#include <pthreadP.h>
#include <string.h>
#include <pt-internal.h>
int
__pthread_setname_np (pthread_t thread, const char *name)
{
#ifdef HAVE_MACH_THREAD_SET_NAME
/* GNU Mach doesn't export this so we have to define it ourselves. */
#define MACH_THREAD_NAME_MAX 32
struct __pthread *pthread;
error_t err;
/* Lookup the thread structure for THREAD. */
pthread = __pthread_getid (thread);
if (pthread == NULL)
return ESRCH;
if (strlen (name) >= MACH_THREAD_NAME_MAX)
return ERANGE;
err = __thread_set_name (pthread->kernel_thread, name);
if (err != KERN_SUCCESS)
return __hurd_fail (err);
return 0;
#else
return ENOTSUP;
#endif
}
weak_alias (__pthread_setname_np, pthread_setname_np)

View File

@ -164,3 +164,5 @@ GLIBC_2.32 tss_create F
GLIBC_2.32 tss_delete F GLIBC_2.32 tss_delete F
GLIBC_2.32 tss_get F GLIBC_2.32 tss_get F
GLIBC_2.32 tss_set F GLIBC_2.32 tss_set F
GLIBC_2.40 pthread_getname_np F
GLIBC_2.40 pthread_setname_np F

View File

@ -163,3 +163,5 @@ GLIBC_2.38 tss_create F
GLIBC_2.38 tss_delete F GLIBC_2.38 tss_delete F
GLIBC_2.38 tss_get F GLIBC_2.38 tss_get F
GLIBC_2.38 tss_set F GLIBC_2.38 tss_set F
GLIBC_2.40 pthread_getname_np F
GLIBC_2.40 pthread_setname_np F