diff --git a/config.h.in b/config.h.in index 9a83b774fa..f495f11244 100644 --- a/config.h.in +++ b/config.h.in @@ -159,6 +159,12 @@ /* Mach specific: define if the `host_page_size' RPC is available. */ #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. */ #undef HAVE_I386_IO_PERM_MODIFY diff --git a/htl/Makefile b/htl/Makefile index 4028e5a240..c5d1c473a0 100644 --- a/htl/Makefile +++ b/htl/Makefile @@ -145,6 +145,8 @@ libpthread-routines := \ pt-getcpuclockid \ pt-setschedprio \ pt-yield \ + pt-getname-np \ + pt-setname-np \ sem_close \ sem-destroy \ sem-getvalue \ diff --git a/htl/Versions b/htl/Versions index 710051756a..e1524117a0 100644 --- a/htl/Versions +++ b/htl/Versions @@ -169,6 +169,11 @@ libpthread { sem_clockwait; } + GLIBC_2.40 { + pthread_getname_np; + pthread_setname_np; + } + GLIBC_PRIVATE { __pthread_initialize_minimal; diff --git a/sysdeps/htl/pthread.h b/sysdeps/htl/pthread.h index fa626ebc82..65837d10cf 100644 --- a/sysdeps/htl/pthread.h +++ b/sysdeps/htl/pthread.h @@ -891,6 +891,17 @@ extern int pthread_setschedparam (pthread_t __thr, int __policy, /* Set thread THREAD's scheduling priority. */ 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 /* Yield the processor to another thread or process. This function is similar to the POSIX `sched_yield' function but diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure index 5779efd1ef..cd21b26df4 100644 --- a/sysdeps/mach/configure +++ b/sysdeps/mach/configure @@ -293,6 +293,9 @@ if test "x$mach_interface_list" = x; then as_fn_error $? "what manner of Mach is this?" "$LINENO" 5 fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep -e" >&5 printf %s "checking for egrep -e... " >&6; } 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 "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 : printf %s "(cached) " >&6 else case e in #( @@ -441,22 +444,83 @@ _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP_TRADITIONAL "host_page_size" >/dev/null 2>&1 then : - libc_cv_mach_host_page_size=yes + libc_cv_mach_rpc_host_page_size=yes else case e in #( - e) libc_cv_mach_host_page_size=no ;; + e) libc_cv_mach_rpc_host_page_size=no ;; esac fi rm -rf conftest* ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_host_page_size" >&5 -printf "%s\n" "$libc_cv_mach_host_page_size" >&6; } -if test $libc_cv_mach_host_page_size = yes; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_host_page_size" >&5 +printf "%s\n" "$libc_cv_mach_rpc_host_page_size" >&6; } +if test $libc_cv_mach_rpc_host_page_size = yes; then printf "%s\n" "#define HAVE_HOST_PAGE_SIZE 1" >>confdefs.h 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 + +_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 + +_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" if test "x$ac_cv_header_mach_machine_ndr_def_h" = xyes then : diff --git a/sysdeps/mach/configure.ac b/sysdeps/mach/configure.ac index 730fb25d50..648035e832 100644 --- a/sysdeps/mach/configure.ac +++ b/sysdeps/mach/configure.ac @@ -72,14 +72,29 @@ if test "x$mach_interface_list" = x; then AC_MSG_ERROR([what manner of Mach is this?]) fi -AC_CACHE_CHECK(for host_page_size in mach_host.defs, - libc_cv_mach_host_page_size, [dnl -AC_EGREP_HEADER(host_page_size, mach/mach_host.defs, - libc_cv_mach_host_page_size=yes, - libc_cv_mach_host_page_size=no)]) -if test $libc_cv_mach_host_page_size = yes; then - AC_DEFINE([HAVE_HOST_PAGE_SIZE]) +dnl +dnl mach_RPC_CHECK(interface.defs, rpc_method, define) +dnl +dnl Check if rpc_method RPC is defined by interface.defs +dnl and define `define`. +dnl +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 +]) + + +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 DEFINES="$DEFINES -DNDR_DEF_HEADER=''"], [dnl diff --git a/sysdeps/mach/htl/pt-getname-np.c b/sysdeps/mach/htl/pt-getname-np.c new file mode 100644 index 0000000000..8943474b3d --- /dev/null +++ b/sysdeps/mach/htl/pt-getname-np.c @@ -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 + . */ + +#include +#include +#include +#include +#include + +#include + +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) diff --git a/sysdeps/mach/htl/pt-setname-np.c b/sysdeps/mach/htl/pt-setname-np.c new file mode 100644 index 0000000000..2fd66730e9 --- /dev/null +++ b/sysdeps/mach/htl/pt-setname-np.c @@ -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 + . */ + +#include +#include +#include +#include + +#include + +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) diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist index fa90cc6597..3ea7cb41fa 100644 --- a/sysdeps/mach/hurd/i386/libpthread.abilist +++ b/sysdeps/mach/hurd/i386/libpthread.abilist @@ -164,3 +164,5 @@ GLIBC_2.32 tss_create F GLIBC_2.32 tss_delete F GLIBC_2.32 tss_get F GLIBC_2.32 tss_set F +GLIBC_2.40 pthread_getname_np F +GLIBC_2.40 pthread_setname_np F diff --git a/sysdeps/mach/hurd/x86_64/libpthread.abilist b/sysdeps/mach/hurd/x86_64/libpthread.abilist index 80615d16ee..69999df5bb 100644 --- a/sysdeps/mach/hurd/x86_64/libpthread.abilist +++ b/sysdeps/mach/hurd/x86_64/libpthread.abilist @@ -163,3 +163,5 @@ GLIBC_2.38 tss_create F GLIBC_2.38 tss_delete F GLIBC_2.38 tss_get F GLIBC_2.38 tss_set F +GLIBC_2.40 pthread_getname_np F +GLIBC_2.40 pthread_setname_np F