diff options
Diffstat (limited to 'nptl')
288 files changed, 1711 insertions, 897 deletions
diff --git a/nptl/Makefile b/nptl/Makefile index c4c27e0..e6481d5 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2024 Free Software Foundation, Inc. +# Copyright (C) 2002-2025 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 @@ -63,7 +63,6 @@ routines = \ old_pthread_cond_signal \ old_pthread_cond_timedwait \ old_pthread_cond_wait \ - pthread_atfork \ pthread_attr_copy \ pthread_attr_destroy \ pthread_attr_extension \ @@ -124,6 +123,7 @@ routines = \ pthread_getname \ pthread_getschedparam \ pthread_getspecific \ + pthread_gettid_np \ pthread_join \ pthread_join_common \ pthread_key_create \ @@ -204,12 +204,12 @@ routines = \ sem_timedwait \ sem_unlink \ sem_wait \ + syscall_cancel \ tpp \ unwind \ vars \ # routines -static-only-routines = pthread_atfork libpthread-routines = libpthread-compat libpthread-shared-only-routines = libpthread-compat @@ -235,7 +235,8 @@ CFLAGS-pthread_setcanceltype.c += -fexceptions -fasynchronous-unwind-tables # These are internal functions which similar functionality as setcancelstate # and setcanceltype. -CFLAGS-cancellation.c += -fasynchronous-unwind-tables +CFLAGS-cancellation.c += -fexceptions -fasynchronous-unwind-tables +CFLAGS-syscall_cancel.c += -fexceptions -fasynchronous-unwind-tables # Calling pthread_exit() must cause the registered cancel handlers to # be executed. Therefore exceptions have to be thrown through this @@ -274,17 +275,20 @@ LDLIBS-tst-minstack-throw = -lstdc++ tests = \ tst-attr2 \ tst-attr3 \ + tst-attr4 \ tst-cancel4_1 \ tst-cancel4_2 \ tst-cancel7 \ tst-cancel17 \ tst-cancel24 \ + tst-cancel31 \ tst-cond26 \ tst-context1 \ tst-default-attr \ tst-dlsym1 \ tst-exec4 \ tst-exec5 \ + tst-guard1 \ tst-initializers1 \ tst-initializers1-c11 \ tst-initializers1-c89 \ @@ -309,16 +313,19 @@ tests = \ tst-mutexpi11 \ tst-mutexpi12 \ tst-once5 \ + tst-pthread-affinity-inheritance \ tst-pthread-attr-affinity \ tst-pthread-attr-affinity-fail \ tst-pthread-attr-sigmask \ tst-pthread-defaultattr-free \ tst-pthread-gdb-attach \ tst-pthread-gdb-attach-static \ + tst-pthread-getcpuclockid-invalid \ tst-pthread-key1-static \ tst-pthread-timedlock-lockloop \ tst-pthread_exit-nothreads \ tst-pthread_exit-nothreads-static \ + tst-pthread_gettid_np \ tst-robust-fork \ tst-robustpi1 \ tst-robustpi2 \ @@ -404,7 +411,10 @@ xtests += tst-eintr1 test-srcs = tst-oddstacklimit -gen-as-const-headers = unwindbuf.sym +gen-as-const-headers = \ + descr-const.sym \ + unwindbuf.sym \ + # gen-as-const-headers gen-py-const-headers := nptl_lock_constants.pysym pretty-printers := nptl-printers.py @@ -466,7 +476,7 @@ tests-internal += \ tst-tls3-malloc \ tst-tls5 \ # tests-internal -ifeq ($(have-z-execstack),yes) +ifeq ($(have-z-execstack)$(have-test-cc-trampoline),yesyes) tests += tst-execstack-threads endif endif @@ -475,7 +485,6 @@ modules-names = \ tst-audit-threads-mod1 \ tst-audit-threads-mod2 \ tst-compat-forwarder-mod \ - tst-execstack-threads-mod \ tst-stack4mod \ tst-tls3mod \ tst-tls5mod \ @@ -496,6 +505,12 @@ test-extras += \ tst-cleanupx4aux \ # test-extras +ifneq ($(have-test-clang),yes) +modules-names += \ + tst-execstack-threads-mod \ + # modules-names +endif + # This test exercises compat symbols removed in glibc 2.34. ifdef have-GLIBC_2.33 tests += tst-cleanup4 @@ -687,6 +702,9 @@ $(objpfx)tst-execstack-threads.out: $(objpfx)tst-execstack-threads-mod.so LDFLAGS-tst-execstack-threads = -Wl,-z,noexecstack LDFLAGS-tst-execstack-threads-mod.so = -Wl,-z,execstack CFLAGS-tst-execstack-threads-mod.c += -Wno-trampolines +ifeq ($(have-no-error-execstack),yes) +LDFLAGS-tst-execstack-threads-mod.so += -Wl,--no-error-execstack +endif tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child" tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" diff --git a/nptl/TODO-testing b/nptl/TODO-testing index e076e56..46ebf3b 100644 --- a/nptl/TODO-testing +++ b/nptl/TODO-testing @@ -1,7 +1,3 @@ -pthread_attr_setguardsize - - test effectiveness - pthread_attr_[sg]etschedparam what to test? @@ -10,10 +6,6 @@ pthread_attr_[sg]etstack some more tests needed -pthread_getcpuclockid - - check that value is reset -> rt subdir - pthread_getschedparam pthread_setschedparam diff --git a/nptl/Versions b/nptl/Versions index 3221de8..ef55376 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -378,6 +378,9 @@ libc { tss_get; tss_set; } + GLIBC_2.42 { + pthread_gettid_np; + } GLIBC_PRIVATE { __libc_alloca_cutoff; __lll_lock_wake_private; diff --git a/nptl/alloca_cutoff.c b/nptl/alloca_cutoff.c index 811687b..276f75a 100644 --- a/nptl/alloca_cutoff.c +++ b/nptl/alloca_cutoff.c @@ -1,5 +1,5 @@ /* Determine whether block of given size can be allocated on the stack or not. - Copyright (C) 2002-2024 Free Software Foundation, Inc. + Copyright (C) 2002-2025 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 diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 2cb562f..800ca89 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -132,6 +132,8 @@ get_cached_stack (size_t *sizep, void **memp) __libc_lock_init (result->exit_lock); memset (&result->tls_state, 0, sizeof result->tls_state); + result->getrandom_buf = NULL; + /* Clear the DTV. */ dtv_t *dtv = GET_DTV (TLS_TPADJ (result)); for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt) @@ -144,10 +146,37 @@ get_cached_stack (size_t *sizep, void **memp) return result; } +/* Assume support for MADV_ADVISE_GUARD, setup_stack_prot will disable it + and fallback to ALLOCATE_GUARD_PROT_NONE if the madvise call fails. */ +static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD; + +static inline int stack_prot (void) +{ + return (PROT_READ | PROT_WRITE + | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)); +} + +static void * +allocate_thread_stack (size_t size, size_t guardsize) +{ + /* MADV_ADVISE_GUARD does not require an additional PROT_NONE mapping. */ + int prot = stack_prot (); + + if (atomic_load_relaxed (&allocate_stack_mode) == ALLOCATE_GUARD_PROT_NONE) + /* If a guard page is required, avoid committing memory by first allocate + with PROT_NONE and then reserve with required permission excluding the + guard page. */ + prot = guardsize == 0 ? prot : PROT_NONE; + + return __mmap (NULL, size, prot, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, + 0); +} + + /* Return the guard page position on allocated stack. */ static inline char * __attribute ((always_inline)) -guard_position (void *mem, size_t size, size_t guardsize, struct pthread *pd, +guard_position (void *mem, size_t size, size_t guardsize, const struct pthread *pd, size_t pagesize_m1) { #if _STACK_GROWS_DOWN @@ -157,27 +186,131 @@ guard_position (void *mem, size_t size, size_t guardsize, struct pthread *pd, #endif } -/* Based on stack allocated with PROT_NONE, setup the required portions with - 'prot' flags based on the guard page position. */ -static inline int -setup_stack_prot (char *mem, size_t size, char *guard, size_t guardsize, - const int prot) +/* Setup the MEM thread stack of SIZE bytes with the required protection flags + along with a guard area of GUARDSIZE size. It first tries with + MADV_GUARD_INSTALL, and then fallback to setup the guard area using the + extra PROT_NONE mapping. Update PD with the type of guard area setup. */ +static inline bool +setup_stack_prot (char *mem, size_t size, struct pthread *pd, + size_t guardsize, size_t pagesize_m1) { - char *guardend = guard + guardsize; + if (__glibc_unlikely (guardsize == 0)) + return true; + + char *guard = guard_position (mem, size, guardsize, pd, pagesize_m1); + if (atomic_load_relaxed (&allocate_stack_mode) == ALLOCATE_GUARD_MADV_GUARD) + { + if (__madvise (guard, guardsize, MADV_GUARD_INSTALL) == 0) + { + pd->stack_mode = ALLOCATE_GUARD_MADV_GUARD; + return true; + } + + /* If madvise fails it means the kernel does not support the guard + advise (we assume that the syscall is available, guard is page-aligned + and length is non negative). The stack has already the expected + protection flags, so it just need to PROT_NONE the guard area. */ + atomic_store_relaxed (&allocate_stack_mode, ALLOCATE_GUARD_PROT_NONE); + if (__mprotect (guard, guardsize, PROT_NONE) != 0) + return false; + } + else + { + const int prot = stack_prot (); + char *guardend = guard + guardsize; #if _STACK_GROWS_DOWN - /* As defined at guard_position, for architectures with downward stack - the guard page is always at start of the allocated area. */ - if (__mprotect (guardend, size - guardsize, prot) != 0) - return errno; + /* As defined at guard_position, for architectures with downward stack + the guard page is always at start of the allocated area. */ + if (__mprotect (guardend, size - guardsize, prot) != 0) + return false; #else - size_t mprots1 = (uintptr_t) guard - (uintptr_t) mem; - if (__mprotect (mem, mprots1, prot) != 0) - return errno; - size_t mprots2 = ((uintptr_t) mem + size) - (uintptr_t) guardend; - if (__mprotect (guardend, mprots2, prot) != 0) - return errno; + size_t mprots1 = (uintptr_t) guard - (uintptr_t) mem; + if (__mprotect (mem, mprots1, prot) != 0) + return false; + size_t mprots2 = ((uintptr_t) mem + size) - (uintptr_t) guardend; + if (__mprotect (guardend, mprots2, prot) != 0) + return false; #endif - return 0; + } + + pd->stack_mode = ALLOCATE_GUARD_PROT_NONE; + return true; +} + +/* Update the guard area of the thread stack MEM of size SIZE with the new + GUARDISZE. It uses the method defined by PD stack_mode. */ +static inline bool +adjust_stack_prot (char *mem, size_t size, const struct pthread *pd, + size_t guardsize, size_t pagesize_m1) +{ + /* The required guard area is larger than the current one. For + _STACK_GROWS_DOWN it means the guard should increase as: + + |guard|---------------------------------stack| + |new guard--|---------------------------stack| + + while for _STACK_GROWS_UP: + + |stack---------------------------|guard|-----| + |stack--------------------|new guard---|-----| + + Both madvise and mprotect allows overlap the required region, + so use the new guard placement with the new size. */ + if (guardsize > pd->guardsize) + { + char *guard = guard_position (mem, size, guardsize, pd, pagesize_m1); + if (pd->stack_mode == ALLOCATE_GUARD_MADV_GUARD) + return __madvise (guard, guardsize, MADV_GUARD_INSTALL) == 0; + else if (pd->stack_mode == ALLOCATE_GUARD_PROT_NONE) + return __mprotect (guard, guardsize, PROT_NONE) == 0; + } + /* The current guard area is larger than the required one. For + _STACK_GROWS_DOWN is means change the guard as: + + |guard-------|-------------------------stack| + |new guard|----------------------------stack| + + And for _STACK_GROWS_UP: + + |stack---------------------|guard-------|---| + |stack------------------------|new guard|---| + + For ALLOCATE_GUARD_MADV_GUARD it means remove the slack area + (disjointed region of guard and new guard), while for + ALLOCATE_GUARD_PROT_NONE it requires to mprotect it with the stack + protection flags. */ + else if (pd->guardsize > guardsize) + { + size_t slacksize = pd->guardsize - guardsize; + if (pd->stack_mode == ALLOCATE_GUARD_MADV_GUARD) + { + void *slack = +#if _STACK_GROWS_DOWN + mem + guardsize; +#else + guard_position (mem, size, pd->guardsize, pd, pagesize_m1); +#endif + return __madvise (slack, slacksize, MADV_GUARD_REMOVE) == 0; + } + else if (pd->stack_mode == ALLOCATE_GUARD_PROT_NONE) + { + const int prot = stack_prot (); +#if _STACK_GROWS_DOWN + return __mprotect (mem + guardsize, slacksize, prot) == 0; +#else + char *new_guard = (char *)(((uintptr_t) pd - guardsize) + & ~pagesize_m1); + char *old_guard = (char *)(((uintptr_t) pd - pd->guardsize) + & ~pagesize_m1); + /* The guard size difference might be > 0, but once rounded + to the nearest page the size difference might be zero. */ + if (new_guard > old_guard + && __mprotect (old_guard, new_guard - old_guard, prot) != 0) + return false; +#endif + } + } + return true; } /* Mark the memory of the stack as usable to the kernel. It frees everything @@ -289,7 +422,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* This is a user-provided stack. It will not be queued in the stack cache nor will the memory (except the TLS memory) be freed. */ - pd->user_stack = true; + pd->stack_mode = ALLOCATE_GUARD_USER; /* This is at least the second thread. */ pd->header.multiple_threads = 1; @@ -323,10 +456,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* Allocate some anonymous memory. If possible use the cache. */ size_t guardsize; size_t reported_guardsize; - size_t reqsize; void *mem; - const int prot = (PROT_READ | PROT_WRITE - | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)); /* Adjust the stack size for alignment. */ size &= ~tls_static_align_m1; @@ -356,16 +486,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, return EINVAL; /* Try to get a stack from the cache. */ - reqsize = size; pd = get_cached_stack (&size, &mem); if (pd == NULL) { - /* If a guard page is required, avoid committing memory by first - allocate with PROT_NONE and then reserve with required permission - excluding the guard page. */ - mem = __mmap (NULL, size, (guardsize == 0) ? prot : PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - + mem = allocate_thread_stack (size, guardsize); if (__glibc_unlikely (mem == MAP_FAILED)) return errno; @@ -392,15 +516,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, #endif /* Now mprotect the required region excluding the guard area. */ - if (__glibc_likely (guardsize > 0)) + if (!setup_stack_prot (mem, size, pd, guardsize, pagesize_m1)) { - char *guard = guard_position (mem, size, guardsize, pd, - pagesize_m1); - if (setup_stack_prot (mem, size, guard, guardsize, prot) != 0) - { - __munmap (mem, size); - return errno; - } + __munmap (mem, size); + return errno; } /* Remember the stack-related values. */ @@ -446,25 +565,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); - - /* There might have been a race. Another thread might have - caused the stacks to get exec permission while this new - stack was prepared. Detect if this was possible and - change the permission if necessary. */ - if (__builtin_expect ((GL(dl_stack_flags) & PF_X) != 0 - && (prot & PROT_EXEC) == 0, 0)) - { - int err = __nptl_change_stack_perm (pd); - if (err != 0) - { - /* Free the stack memory we just allocated. */ - (void) __munmap (mem, size); - - return err; - } - } - - /* Note that all of the stack and the thread descriptor is zeroed. This means we do not have to initialize fields with initial value zero. This is specifically true for @@ -473,59 +573,31 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, which will be read next. */ } - /* Create or resize the guard area if necessary. */ - if (__glibc_unlikely (guardsize > pd->guardsize)) + /* Create or resize the guard area if necessary on an already + allocated stack. */ + if (!adjust_stack_prot (mem, size, pd, guardsize, pagesize_m1)) { - char *guard = guard_position (mem, size, guardsize, pd, - pagesize_m1); - if (__mprotect (guard, guardsize, PROT_NONE) != 0) - { - mprot_error: - lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE); + lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE); - /* Remove the thread from the list. */ - __nptl_stack_list_del (&pd->list); + /* Remove the thread from the list. */ + __nptl_stack_list_del (&pd->list); - lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); + lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); - /* Get rid of the TLS block we allocated. */ - _dl_deallocate_tls (TLS_TPADJ (pd), false); + /* Get rid of the TLS block we allocated. */ + _dl_deallocate_tls (TLS_TPADJ (pd), false); - /* Free the stack memory regardless of whether the size - of the cache is over the limit or not. If this piece - of memory caused problems we better do not use it - anymore. Uh, and we ignore possible errors. There - is nothing we could do. */ - (void) __munmap (mem, size); + /* Free the stack memory regardless of whether the size + of the cache is over the limit or not. If this piece + of memory caused problems we better do not use it + anymore. Uh, and we ignore possible errors. There + is nothing we could do. */ + (void) __munmap (mem, size); - return errno; - } - - pd->guardsize = guardsize; + return errno; } - else if (__builtin_expect (pd->guardsize - guardsize > size - reqsize, - 0)) - { - /* The old guard area is too large. */ - -#if _STACK_GROWS_DOWN - if (__mprotect ((char *) mem + guardsize, pd->guardsize - guardsize, - prot) != 0) - goto mprot_error; -#elif _STACK_GROWS_UP - char *new_guard = (char *)(((uintptr_t) pd - guardsize) - & ~pagesize_m1); - char *old_guard = (char *)(((uintptr_t) pd - pd->guardsize) - & ~pagesize_m1); - /* The guard size difference might be > 0, but once rounded - to the nearest page the size difference might be zero. */ - if (new_guard > old_guard - && __mprotect (old_guard, new_guard - old_guard, prot) != 0) - goto mprot_error; -#endif - pd->guardsize = guardsize; - } + pd->guardsize = guardsize; /* The pthread_getattr_np() calls need to get passed the size requested in the attribute, regardless of how large the actually used guardsize is. */ @@ -566,10 +638,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, return 0; } -/* Maximum supported name from initial kernel support, not exported - by user API. */ -#define ANON_VMA_NAME_MAX_LEN 80 - #define SET_STACK_NAME(__prefix, __stack, __stacksize, __tid) \ ({ \ char __stack_name[sizeof (__prefix) + \ @@ -585,19 +653,21 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, static void name_stack_maps (struct pthread *pd, bool set) { + size_t adjust = pd->stack_mode == ALLOCATE_GUARD_PROT_NONE ? + pd->guardsize : 0; #if _STACK_GROWS_DOWN - void *stack = pd->stackblock + pd->guardsize; + void *stack = pd->stackblock + adjust; #else void *stack = pd->stackblock; #endif - size_t stacksize = pd->stackblock_size - pd->guardsize; + size_t stacksize = pd->stackblock_size - adjust; if (!set) - __set_vma_name (stack, stacksize, NULL); + __set_vma_name (stack, stacksize, " glibc: unused stack"); else { unsigned int tid = pd->tid; - if (pd->user_stack) + if (pd->stack_mode == ALLOCATE_GUARD_USER) SET_STACK_NAME (" glibc: pthread user stack: ", stack, stacksize, tid); else SET_STACK_NAME (" glibc: pthread stack: ", stack, stacksize, tid); diff --git a/nptl/cancellation.c b/nptl/cancellation.c index 7ce60e7..156e63d 100644 --- a/nptl/cancellation.c +++ b/nptl/cancellation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -18,74 +18,93 @@ #include <setjmp.h> #include <stdlib.h> #include "pthreadP.h" -#include <futex-internal.h> - -/* The next two functions are similar to pthread_setcanceltype() but - more specialized for the use in the cancelable functions like write(). - They do not need to check parameters etc. These functions must be - AS-safe, with the exception of the actual cancellation, because they - are called by wrappers around AS-safe functions like write().*/ -int -__pthread_enable_asynccancel (void) +/* Called by the INTERNAL_SYSCALL_CANCEL macro, check for cancellation and + returns the syscall value or its negative error code. */ +long int +__internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2, + __syscall_arg_t a3, __syscall_arg_t a4, + __syscall_arg_t a5, __syscall_arg_t a6, + __SYSCALL_CANCEL7_ARG_DEF + __syscall_arg_t nr) { - struct pthread *self = THREAD_SELF; - int oldval = atomic_load_relaxed (&self->cancelhandling); + long int result; + struct pthread *pd = THREAD_SELF; - while (1) + /* If cancellation is not enabled, call the syscall directly and also + for thread terminatation to avoid call __syscall_do_cancel while + executing cleanup handlers. */ + int ch = atomic_load_relaxed (&pd->cancelhandling); + if (SINGLE_THREAD_P || !cancel_enabled (ch) || cancel_exiting (ch)) { - int newval = oldval | CANCELTYPE_BITMASK; - - if (newval == oldval) - break; + result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6 + __SYSCALL_CANCEL7_ARCH_ARG7); + if (INTERNAL_SYSCALL_ERROR_P (result)) + return -INTERNAL_SYSCALL_ERRNO (result); + return result; + } - if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, - &oldval, newval)) - { - if (cancel_enabled_and_canceled_and_async (newval)) - { - self->result = PTHREAD_CANCELED; - __do_cancel (); - } + /* Call the arch-specific entry points that contains the globals markers + to be checked by SIGCANCEL handler. */ + result = __syscall_cancel_arch (&pd->cancelhandling, nr, a1, a2, a3, a4, a5, + a6 __SYSCALL_CANCEL7_ARCH_ARG7); - break; - } - } + /* If the cancellable syscall was interrupted by SIGCANCEL and it has no + side-effect, cancel the thread if cancellation is enabled. */ + ch = atomic_load_relaxed (&pd->cancelhandling); + /* The behaviour here assumes that EINTR is returned only if there are no + visible side effects. POSIX Issue 7 has not yet provided any stronger + language for close, and in theory the close syscall could return EINTR + and leave the file descriptor open (conforming and leaks). It expects + that no such kernel is used with glibc. */ + if (result == -EINTR && cancel_enabled_and_canceled (ch)) + __syscall_do_cancel (); - return oldval; + return result; } -libc_hidden_def (__pthread_enable_asynccancel) -/* See the comment for __pthread_enable_asynccancel regarding - the AS-safety of this function. */ -void -__pthread_disable_asynccancel (int oldtype) +/* Called by the SYSCALL_CANCEL macro, check for cancellation and return the + syscall expected success value (usually 0) or, in case of failure, -1 and + sets errno to syscall return value. */ +long int +__syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2, + __syscall_arg_t a3, __syscall_arg_t a4, + __syscall_arg_t a5, __syscall_arg_t a6, + __SYSCALL_CANCEL7_ARG_DEF __syscall_arg_t nr) { - /* If asynchronous cancellation was enabled before we do not have - anything to do. */ - if (oldtype & CANCELTYPE_BITMASK) - return; + int r = __internal_syscall_cancel (a1, a2, a3, a4, a5, a6, + __SYSCALL_CANCEL7_ARG nr); + return __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (r)) + ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (r)) + : r; +} +/* Called by __syscall_cancel_arch or function above start the thread + cancellation. */ +_Noreturn void +__syscall_do_cancel (void) +{ struct pthread *self = THREAD_SELF; - int newval; + + /* Disable thread cancellation to avoid cancellable entrypoints calling + __syscall_do_cancel recursively. We atomic load relaxed to check the + state of cancelhandling, there is no particular ordering requirement + between the syscall call and the other thread setting our cancelhandling + with a atomic store acquire. + + POSIX Issue 7 notes that the cancellation occurs asynchronously on the + target thread, that implies there is no ordering requirements. It does + not need a MO release store here. */ int oldval = atomic_load_relaxed (&self->cancelhandling); - do + while (1) { - newval = oldval & ~CANCELTYPE_BITMASK; + int newval = oldval | CANCELSTATE_BITMASK; + if (oldval == newval) + break; + if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, + &oldval, newval)) + break; } - while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling, - &oldval, newval)); - /* We cannot return when we are being canceled. Upon return the - thread might be things which would have to be undone. The - following loop should loop until the cancellation signal is - delivered. */ - while (__glibc_unlikely ((newval & (CANCELING_BITMASK | CANCELED_BITMASK)) - == CANCELING_BITMASK)) - { - futex_wait_simple ((unsigned int *) &self->cancelhandling, newval, - FUTEX_PRIVATE); - newval = atomic_load_relaxed (&self->cancelhandling); - } + __do_cancel (PTHREAD_CANCELED); } -libc_hidden_def (__pthread_disable_asynccancel) diff --git a/nptl/cleanup.c b/nptl/cleanup.c index b0c403b..724481c 100644 --- a/nptl/cleanup.c +++ b/nptl/cleanup.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/cleanup_compat.c b/nptl/cleanup_compat.c index a47d220..a386501 100644 --- a/nptl/cleanup_compat.c +++ b/nptl/cleanup_compat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c index dc08eda..98fbf4a 100644 --- a/nptl/cleanup_defer.c +++ b/nptl/cleanup_defer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -82,10 +82,7 @@ ___pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf) &cancelhandling, newval)); if (cancel_enabled_and_canceled (cancelhandling)) - { - self->result = PTHREAD_CANCELED; - __do_cancel (); - } + __do_cancel (PTHREAD_CANCELED); } } versioned_symbol (libc, ___pthread_unregister_cancel_restore, diff --git a/nptl/cleanup_defer_compat.c b/nptl/cleanup_defer_compat.c index d139d58..23c94d5 100644 --- a/nptl/cleanup_defer_compat.c +++ b/nptl/cleanup_defer_compat.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/cleanup_routine.c b/nptl/cleanup_routine.c index 32a61a7..40096d6 100644 --- a/nptl/cleanup_routine.c +++ b/nptl/cleanup_routine.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/default-sched.h b/nptl/default-sched.h index 4062980..e07597b 100644 --- a/nptl/default-sched.h +++ b/nptl/default-sched.h @@ -1,5 +1,5 @@ /* Determine calling thread's scheduling parameters. Stub version. - Copyright (C) 2014-2024 Free Software Foundation, Inc. + Copyright (C) 2014-2025 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 diff --git a/nptl/descr-const.sym b/nptl/descr-const.sym new file mode 100644 index 0000000..8608248 --- /dev/null +++ b/nptl/descr-const.sym @@ -0,0 +1,6 @@ +#include <tls.h> + +-- Not strictly offsets, these values are using thread cancellation by arch +-- specific cancel entrypoint. +TCB_CANCELED_BIT CANCELED_BIT +TCB_CANCELED_BITMASK CANCELED_BITMASK diff --git a/nptl/descr.h b/nptl/descr.h index 8cef958..ada6867 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -125,6 +125,12 @@ struct priority_protection_data unsigned int priomap[]; }; +enum allocate_stack_mode_t +{ + ALLOCATE_GUARD_MADV_GUARD = 0, + ALLOCATE_GUARD_PROT_NONE = 1, + ALLOCATE_GUARD_USER = 2, +}; /* Thread descriptor data structure. */ struct pthread @@ -324,7 +330,7 @@ struct pthread bool report_events; /* True if the user provided the stack. */ - bool user_stack; + enum allocate_stack_mode_t stack_mode; /* True if thread must stop at startup time. */ bool stopped_start; @@ -404,28 +410,35 @@ struct pthread /* Used on strsignal. */ struct tls_internal_t tls_state; - /* rseq area registered with the kernel. Use a custom definition - here to isolate from kernel struct rseq changes. The - implementation of sched_getcpu needs acccess to the cpu_id field; - the other fields are unused and not included here. */ - union - { - struct - { - uint32_t cpu_id_start; - uint32_t cpu_id; - }; - char pad[32]; /* Original rseq area size. */ - } rseq_area __attribute__ ((aligned (32))); + /* getrandom vDSO per-thread opaque state. */ + void *getrandom_buf; /* Amount of end padding, if any, in this structure. - This definition relies on rseq_area being last. */ + This definition relies on getrandom_buf being last. */ #define PTHREAD_STRUCT_END_PADDING \ - (sizeof (struct pthread) - offsetof (struct pthread, rseq_area) \ - + sizeof ((struct pthread) {}.rseq_area)) + (sizeof (struct pthread) - offsetof (struct pthread, getrandom_buf) \ + + sizeof ((struct pthread) {}.getrandom_buf)) } __attribute ((aligned (TCB_ALIGNMENT))); static inline bool +cancel_enabled (int value) +{ + return (value & CANCELSTATE_BITMASK) == 0; +} + +static inline bool +cancel_async_enabled (int value) +{ + return (value & CANCELTYPE_BITMASK) != 0; +} + +static inline bool +cancel_exiting (int value) +{ + return (value & EXITING_BITMASK) != 0; +} + +static inline bool cancel_enabled_and_canceled (int value) { return (value & (CANCELSTATE_BITMASK | CANCELED_BITMASK | EXITING_BITMASK diff --git a/nptl/elision-conf.c b/nptl/elision-conf.c index ca80b7f..a4230b5 100644 --- a/nptl/elision-conf.c +++ b/nptl/elision-conf.c @@ -1,5 +1,5 @@ /* elision-conf.c: Lock elision tunable parameters. Stub version. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/elision-lock.c b/nptl/elision-lock.c index 96ff868..7bed73a 100644 --- a/nptl/elision-lock.c +++ b/nptl/elision-lock.c @@ -1,5 +1,5 @@ /* elision-lock.c: Lock elision locking. Stub version. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/elision-timed.c b/nptl/elision-timed.c index c705cef..9845497 100644 --- a/nptl/elision-timed.c +++ b/nptl/elision-timed.c @@ -1,5 +1,5 @@ /* elision-lock.c: Lock elision timed locking. Stub version. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/elision-trylock.c b/nptl/elision-trylock.c index b72aac5..392bf7b 100644 --- a/nptl/elision-trylock.c +++ b/nptl/elision-trylock.c @@ -1,5 +1,5 @@ /* elision-lock.c: Lock elision locking attempts. Stub version. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/elision-unlock.c b/nptl/elision-unlock.c index 764139f..a3a1088 100644 --- a/nptl/elision-unlock.c +++ b/nptl/elision-unlock.c @@ -1,5 +1,5 @@ /* elision-lock.c: Lock elision unlocking support. Stub version. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/events.c b/nptl/events.c index f1600f0..80fe04d 100644 --- a/nptl/events.c +++ b/nptl/events.c @@ -1,5 +1,5 @@ /* Event functions used while debugging. - Copyright (C) 1999-2024 Free Software Foundation, Inc. + Copyright (C) 1999-2025 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 diff --git a/nptl/futex-internal.c b/nptl/futex-internal.c index 0bb1dd5..b81ca07 100644 --- a/nptl/futex-internal.c +++ b/nptl/futex-internal.c @@ -1,5 +1,5 @@ /* futex helper functions for glibc-internal use. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/libc-cleanup.c b/nptl/libc-cleanup.c index fe042c8..26c358b 100644 --- a/nptl/libc-cleanup.c +++ b/nptl/libc-cleanup.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -69,10 +69,7 @@ __libc_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer) &cancelhandling, newval)); if (cancel_enabled_and_canceled (cancelhandling)) - { - self->result = PTHREAD_CANCELED; - __do_cancel (); - } + __do_cancel (PTHREAD_CANCELED); } } libc_hidden_def (__libc_cleanup_pop_restore) diff --git a/nptl/libpthread-compat.c b/nptl/libpthread-compat.c index 1978bea..c531410 100644 --- a/nptl/libpthread-compat.c +++ b/nptl/libpthread-compat.c @@ -1,5 +1,5 @@ /* Placeholder definitions to pull in removed symbol versions. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/lowlevellock.c b/nptl/lowlevellock.c index 4f9d75c..dd6ab15 100644 --- a/nptl/lowlevellock.c +++ b/nptl/lowlevellock.c @@ -1,5 +1,5 @@ /* low level locking for pthread library. Generic futex-using version. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/nptl-printers.py b/nptl/nptl-printers.py index fc9d39d..93aec34 100644 --- a/nptl/nptl-printers.py +++ b/nptl/nptl-printers.py @@ -1,6 +1,6 @@ # Pretty printers for the NPTL lock types. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/nptl-stack.c b/nptl/nptl-stack.c index 396f226..c049c51 100644 --- a/nptl/nptl-stack.c +++ b/nptl/nptl-stack.c @@ -1,5 +1,5 @@ /* Stack cache management for NPTL. - Copyright (C) 2002-2024 Free Software Foundation, Inc. + Copyright (C) 2002-2025 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 @@ -120,7 +120,7 @@ __nptl_deallocate_stack (struct pthread *pd) not reset the 'used' flag in the 'tid' field. This is done by the kernel. If no thread has been created yet this field is still zero. */ - if (__glibc_likely (! pd->user_stack)) + if (__glibc_likely (pd->stack_mode != ALLOCATE_GUARD_USER)) (void) queue_stack (pd); else /* Free the memory associated with the ELF TLS. */ diff --git a/nptl/nptl-stack.h b/nptl/nptl-stack.h index 6f34b34..ac672e1 100644 --- a/nptl/nptl-stack.h +++ b/nptl/nptl-stack.h @@ -1,5 +1,5 @@ /* Stack cache management for NPTL. - Copyright (C) 2002-2024 Free Software Foundation, Inc. + Copyright (C) 2002-2025 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 diff --git a/nptl/nptl_free_tcb.c b/nptl/nptl_free_tcb.c index 8aa7fc5..0c168a2 100644 --- a/nptl/nptl_free_tcb.c +++ b/nptl/nptl_free_tcb.c @@ -1,5 +1,5 @@ /* TCB deallocation for NPTL. - Copyright (C) 2002-2024 Free Software Foundation, Inc. + Copyright (C) 2002-2025 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 diff --git a/nptl/nptl_nthreads.c b/nptl/nptl_nthreads.c index 0ad6310..91f97b7 100644 --- a/nptl/nptl_nthreads.c +++ b/nptl/nptl_nthreads.c @@ -1,5 +1,5 @@ /* Thread counter variable. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/nptl_setxid.c b/nptl/nptl_setxid.c index 718a479..3da0d19 100644 --- a/nptl/nptl_setxid.c +++ b/nptl/nptl_setxid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/nptlfreeres.c b/nptl/nptlfreeres.c index 42e923a..17d48d7 100644 --- a/nptl/nptlfreeres.c +++ b/nptl/nptlfreeres.c @@ -1,5 +1,5 @@ /* Clean up allocated libpthread memory on demand. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/old_pthread_cond_broadcast.c b/nptl/old_pthread_cond_broadcast.c index 4611ac5..6b7289e 100644 --- a/nptl/old_pthread_cond_broadcast.c +++ b/nptl/old_pthread_cond_broadcast.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/old_pthread_cond_destroy.c b/nptl/old_pthread_cond_destroy.c index 020f68a..7e2ef61 100644 --- a/nptl/old_pthread_cond_destroy.c +++ b/nptl/old_pthread_cond_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/old_pthread_cond_init.c b/nptl/old_pthread_cond_init.c index 47a593d..e75d56f 100644 --- a/nptl/old_pthread_cond_init.c +++ b/nptl/old_pthread_cond_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/old_pthread_cond_signal.c b/nptl/old_pthread_cond_signal.c index b69db75..9226990 100644 --- a/nptl/old_pthread_cond_signal.c +++ b/nptl/old_pthread_cond_signal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/old_pthread_cond_timedwait.c b/nptl/old_pthread_cond_timedwait.c index c59a766..3950d8b 100644 --- a/nptl/old_pthread_cond_timedwait.c +++ b/nptl/old_pthread_cond_timedwait.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/old_pthread_cond_wait.c b/nptl/old_pthread_cond_wait.c index 40343fc..e597cb1 100644 --- a/nptl/old_pthread_cond_wait.c +++ b/nptl/old_pthread_cond_wait.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/perf.c b/nptl/perf.c index b587211..5defd62 100644 --- a/nptl/perf.c +++ b/nptl/perf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_copy.c b/nptl/pthread_attr_copy.c index 4fe02a2..4d894d6 100644 --- a/nptl/pthread_attr_copy.c +++ b/nptl/pthread_attr_copy.c @@ -1,5 +1,5 @@ /* Deep copy of a pthread_attr_t object. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/pthread_attr_destroy.c b/nptl/pthread_attr_destroy.c index 94e7419..bc01b15 100644 --- a/nptl/pthread_attr_destroy.c +++ b/nptl/pthread_attr_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_extension.c b/nptl/pthread_attr_extension.c index 385ff44..7cf3b9b 100644 --- a/nptl/pthread_attr_extension.c +++ b/nptl/pthread_attr_extension.c @@ -1,5 +1,5 @@ /* Allocate the extension space for struct pthread_attr. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/pthread_attr_getaffinity.c b/nptl/pthread_attr_getaffinity.c index a91eec8..ce39e70 100644 --- a/nptl/pthread_attr_getaffinity.c +++ b/nptl/pthread_attr_getaffinity.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_attr_getdetachstate.c b/nptl/pthread_attr_getdetachstate.c index 2da62d1..9286d6f 100644 --- a/nptl/pthread_attr_getdetachstate.c +++ b/nptl/pthread_attr_getdetachstate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getguardsize.c b/nptl/pthread_attr_getguardsize.c index cd6fbbb..c6643db 100644 --- a/nptl/pthread_attr_getguardsize.c +++ b/nptl/pthread_attr_getguardsize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getinheritsched.c b/nptl/pthread_attr_getinheritsched.c index 7bae98f..8c03004 100644 --- a/nptl/pthread_attr_getinheritsched.c +++ b/nptl/pthread_attr_getinheritsched.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getschedparam.c b/nptl/pthread_attr_getschedparam.c index 2c287cc..4fbb51e 100644 --- a/nptl/pthread_attr_getschedparam.c +++ b/nptl/pthread_attr_getschedparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getschedpolicy.c b/nptl/pthread_attr_getschedpolicy.c index 859d287..8fd26fa 100644 --- a/nptl/pthread_attr_getschedpolicy.c +++ b/nptl/pthread_attr_getschedpolicy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getscope.c b/nptl/pthread_attr_getscope.c index ca078e9..aa7e3b2 100644 --- a/nptl/pthread_attr_getscope.c +++ b/nptl/pthread_attr_getscope.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getsigmask.c b/nptl/pthread_attr_getsigmask.c index a2a66e6..6a43357 100644 --- a/nptl/pthread_attr_getsigmask.c +++ b/nptl/pthread_attr_getsigmask.c @@ -1,5 +1,5 @@ /* Obtain the configured signal mask from a POSIX thread attribute. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/pthread_attr_getstack.c b/nptl/pthread_attr_getstack.c index 6109566..77c41dc 100644 --- a/nptl/pthread_attr_getstack.c +++ b/nptl/pthread_attr_getstack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getstackaddr.c b/nptl/pthread_attr_getstackaddr.c index 1ff2e9b..05e87f8 100644 --- a/nptl/pthread_attr_getstackaddr.c +++ b/nptl/pthread_attr_getstackaddr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_getstacksize.c b/nptl/pthread_attr_getstacksize.c index 52f607b..544e9a7 100644 --- a/nptl/pthread_attr_getstacksize.c +++ b/nptl/pthread_attr_getstacksize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_init.c b/nptl/pthread_attr_init.c index 35188b0..9af4e87 100644 --- a/nptl/pthread_attr_init.c +++ b/nptl/pthread_attr_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setaffinity.c b/nptl/pthread_attr_setaffinity.c index ae259c4..0867037 100644 --- a/nptl/pthread_attr_setaffinity.c +++ b/nptl/pthread_attr_setaffinity.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_attr_setdetachstate.c b/nptl/pthread_attr_setdetachstate.c index 28a990c..e42a89a 100644 --- a/nptl/pthread_attr_setdetachstate.c +++ b/nptl/pthread_attr_setdetachstate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setguardsize.c b/nptl/pthread_attr_setguardsize.c index 75686f0..203f658 100644 --- a/nptl/pthread_attr_setguardsize.c +++ b/nptl/pthread_attr_setguardsize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setinheritsched.c b/nptl/pthread_attr_setinheritsched.c index 8834765..5ef6cc1 100644 --- a/nptl/pthread_attr_setinheritsched.c +++ b/nptl/pthread_attr_setinheritsched.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setschedparam.c b/nptl/pthread_attr_setschedparam.c index bd6718b..5eb927b 100644 --- a/nptl/pthread_attr_setschedparam.c +++ b/nptl/pthread_attr_setschedparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setschedpolicy.c b/nptl/pthread_attr_setschedpolicy.c index d793721..aae1cdd 100644 --- a/nptl/pthread_attr_setschedpolicy.c +++ b/nptl/pthread_attr_setschedpolicy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setscope.c b/nptl/pthread_attr_setscope.c index ee3f952..7631c93 100644 --- a/nptl/pthread_attr_setscope.c +++ b/nptl/pthread_attr_setscope.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setsigmask.c b/nptl/pthread_attr_setsigmask.c index 96527af..a90ae7f 100644 --- a/nptl/pthread_attr_setsigmask.c +++ b/nptl/pthread_attr_setsigmask.c @@ -1,5 +1,5 @@ /* Set the signal mask in a POSIX thread attribute. Public variant. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/pthread_attr_setsigmask_internal.c b/nptl/pthread_attr_setsigmask_internal.c index 0617224..8f86c57 100644 --- a/nptl/pthread_attr_setsigmask_internal.c +++ b/nptl/pthread_attr_setsigmask_internal.c @@ -1,5 +1,5 @@ /* Set the signal mask in a POSIX thread attribute. Internal variant. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/pthread_attr_setstack.c b/nptl/pthread_attr_setstack.c index 362ed50..6efbbfe 100644 --- a/nptl/pthread_attr_setstack.c +++ b/nptl/pthread_attr_setstack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setstackaddr.c b/nptl/pthread_attr_setstackaddr.c index 2d40748..feba0e0 100644 --- a/nptl/pthread_attr_setstackaddr.c +++ b/nptl/pthread_attr_setstackaddr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_attr_setstacksize.c b/nptl/pthread_attr_setstacksize.c index c5aeba1..e7812d2 100644 --- a/nptl/pthread_attr_setstacksize.c +++ b/nptl/pthread_attr_setstacksize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_barrier_destroy.c b/nptl/pthread_barrier_destroy.c index b9c6f94..079965d 100644 --- a/nptl/pthread_barrier_destroy.c +++ b/nptl/pthread_barrier_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_barrier_init.c b/nptl/pthread_barrier_init.c index 5f0069e..c911834 100644 --- a/nptl/pthread_barrier_init.c +++ b/nptl/pthread_barrier_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_barrier_wait.c b/nptl/pthread_barrier_wait.c index ff3a1ff..fb6475b 100644 --- a/nptl/pthread_barrier_wait.c +++ b/nptl/pthread_barrier_wait.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_barrierattr_destroy.c b/nptl/pthread_barrierattr_destroy.c index 43e225e..93866b6 100644 --- a/nptl/pthread_barrierattr_destroy.c +++ b/nptl/pthread_barrierattr_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_barrierattr_getpshared.c b/nptl/pthread_barrierattr_getpshared.c index 8631ee2..37729f3 100644 --- a/nptl/pthread_barrierattr_getpshared.c +++ b/nptl/pthread_barrierattr_getpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_barrierattr_init.c b/nptl/pthread_barrierattr_init.c index ae27b59..0d4c384 100644 --- a/nptl/pthread_barrierattr_init.c +++ b/nptl/pthread_barrierattr_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_barrierattr_setpshared.c b/nptl/pthread_barrierattr_setpshared.c index 4bfe33f..ae58a2b 100644 --- a/nptl/pthread_barrierattr_setpshared.c +++ b/nptl/pthread_barrierattr_setpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index 69701db..b838273 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -23,6 +23,7 @@ #include <sysdep.h> #include <unistd.h> #include <unwind-link.h> +#include <cancellation-pc-check.h> #include <stdio.h> #include <gnu/lib-names.h> #include <sys/single_threaded.h> @@ -40,31 +41,18 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx) || si->si_code != SI_TKILL) return; + /* Check if asynchronous cancellation mode is set and cancellation is not + already in progress, or if interrupted instruction pointer falls within + the cancellable syscall bridge. + For interruptable syscalls with external side-effects (i.e. partial + reads), the kernel will set the IP to after __syscall_cancel_arch_end, + thus disabling the cancellation and allowing the process to handle such + conditions. */ struct pthread *self = THREAD_SELF; - int oldval = atomic_load_relaxed (&self->cancelhandling); - while (1) - { - /* We are canceled now. When canceled by another thread this flag - is already set but if the signal is directly send (internally or - from another process) is has to be done here. */ - int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; - - if (oldval == newval || (oldval & EXITING_BITMASK) != 0) - /* Already canceled or exiting. */ - break; - - if (atomic_compare_exchange_weak_acquire (&self->cancelhandling, - &oldval, newval)) - { - self->result = PTHREAD_CANCELED; - - /* Make sure asynchronous cancellation is still enabled. */ - if ((oldval & CANCELTYPE_BITMASK) != 0) - /* Run the registered destructors and terminate the thread. */ - __do_cancel (); - } - } + if (cancel_enabled_and_canceled_and_async (oldval) + || cancellation_pc_check (ctx)) + __syscall_do_cancel (); } int @@ -106,15 +94,13 @@ __pthread_cancel (pthread_t th) /* Some syscalls are never restarted after being interrupted by a signal handler, regardless of the use of SA_RESTART (they always fail with EINTR). So pthread_cancel cannot send SIGCANCEL unless the cancellation - is enabled and set as asynchronous (in this case the cancellation will - be acted in the cancellation handler instead by the syscall wrapper). - Otherwise the target thread is set as 'cancelling' (CANCELING_BITMASK) + is enabled. + In this case the target thread is set as 'cancelled' (CANCELED_BITMASK) by atomically setting 'cancelhandling' and the cancelation will be acted upon on next cancellation entrypoing in the target thread. - It also requires to atomically check if cancellation is enabled and - asynchronous, so both cancellation state and type are tracked on - 'cancelhandling'. */ + It also requires to atomically check if cancellation is enabled, so the + state are also tracked on 'cancelhandling'. */ int result = 0; int oldval = atomic_load_relaxed (&pd->cancelhandling); @@ -122,19 +108,17 @@ __pthread_cancel (pthread_t th) do { again: - newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; + newval = oldval | CANCELED_BITMASK; if (oldval == newval) break; - /* If the cancellation is handled asynchronously just send a - signal. We avoid this if possible since it's more - expensive. */ - if (cancel_enabled_and_canceled_and_async (newval)) + /* Only send the SIGANCEL signal if cancellation is enabled, since some + syscalls are never restarted even with SA_RESTART. The signal + will act iff async cancellation is enabled. */ + if (cancel_enabled (newval)) { - /* Mark the cancellation as "in progress". */ - int newval2 = oldval | CANCELING_BITMASK; if (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, - &oldval, newval2)) + &oldval, newval)) goto again; if (pd == THREAD_SELF) @@ -143,9 +127,8 @@ __pthread_cancel (pthread_t th) pthread_create, so the signal handler may not have been set up for a self-cancel. */ { - pd->result = PTHREAD_CANCELED; - if ((newval & CANCELTYPE_BITMASK) != 0) - __do_cancel (); + if (cancel_async_enabled (newval)) + __do_cancel (PTHREAD_CANCELED); } else /* The cancellation handler will take care of marking the @@ -154,19 +137,18 @@ __pthread_cancel (pthread_t th) break; } - - /* A single-threaded process should be able to kill itself, since - there is nothing in the POSIX specification that says that it - cannot. So we set multiple_threads to true so that cancellation - points get executed. */ - THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); -#ifndef TLS_MULTIPLE_THREADS_IN_TCB - __libc_single_threaded_internal = 0; -#endif } while (!atomic_compare_exchange_weak_acquire (&pd->cancelhandling, &oldval, newval)); + /* A single-threaded process should be able to kill itself, since there is + nothing in the POSIX specification that says that it cannot. So we set + multiple_threads to true so that cancellation points get executed. */ + THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); +#ifndef TLS_MULTIPLE_THREADS_IN_TCB + __libc_single_threaded_internal = 0; +#endif + return result; } versioned_symbol (libc, __pthread_cancel, pthread_cancel, GLIBC_2_34); diff --git a/nptl/pthread_cleanup_upto.c b/nptl/pthread_cleanup_upto.c index 4f7fa9a..898b2ac 100644 --- a/nptl/pthread_cleanup_upto.c +++ b/nptl/pthread_cleanup_upto.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_clockjoin.c b/nptl/pthread_clockjoin.c index 73e1b81..53944fb 100644 --- a/nptl/pthread_clockjoin.c +++ b/nptl/pthread_clockjoin.c @@ -1,5 +1,5 @@ /* Join with a terminated thread using an specific clock. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c index aada916..12e2687 100644 --- a/nptl/pthread_cond_broadcast.c +++ b/nptl/pthread_cond_broadcast.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 @@ -57,10 +57,10 @@ ___pthread_cond_broadcast (pthread_cond_t *cond) { /* Add as many signals as the remaining size of the group. */ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, - cond->__data.__g_size[g1] << 1); + cond->__data.__g_size[g1]); cond->__data.__g_size[g1] = 0; - /* We need to wake G1 waiters before we quiesce G1 below. */ + /* We need to wake G1 waiters before we switch G1 below. */ /* TODO Only set it if there are indeed futex waiters. We could also try to move this out of the critical section in cases when G2 is empty (and we don't need to quiesce). */ @@ -69,11 +69,11 @@ ___pthread_cond_broadcast (pthread_cond_t *cond) /* G1 is complete. Step (2) is next unless there are no waiters in G2, in which case we can stop. */ - if (__condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private)) + if (__condvar_switch_g1 (cond, wseq, &g1, private)) { /* Step (3): Send signals to all waiters in the old G2 / new G1. */ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, - cond->__data.__g_size[g1] << 1); + cond->__data.__g_size[g1]); cond->__data.__g_size[g1] = 0; /* TODO Only set it if there are indeed futex waiters. */ do_futex_wake = true; diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c index 3487557..2708d26 100644 --- a/nptl/pthread_cond_common.c +++ b/nptl/pthread_cond_common.c @@ -1,5 +1,5 @@ /* pthread_cond_common -- shared code for condition variable. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 @@ -189,19 +189,17 @@ __condvar_get_private (int flags) return FUTEX_SHARED; } -/* This closes G1 (whose index is in G1INDEX), waits for all futex waiters to - leave G1, converts G1 into a fresh G2, and then switches group roles so that - the former G2 becomes the new G1 ending at the current __wseq value when we - eventually make the switch (WSEQ is just an observation of __wseq by the - signaler). +/* This closes G1 (whose index is in G1INDEX), converts G1 into a fresh G2, + and then switches group roles so that the former G2 becomes the new G1 + ending at the current __wseq value when we eventually make the switch + (WSEQ is just an observation of __wseq by the signaler). If G2 is empty, it will not switch groups because then it would create an empty G1 which would require switching groups again on the next signal. Returns false iff groups were not switched because G2 was empty. */ static bool __attribute__ ((unused)) -__condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq, +__condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq, unsigned int *g1index, int private) { - const unsigned int maxspin = 0; unsigned int g1 = *g1index; /* If there is no waiter in G2, we don't do anything. The expression may @@ -210,96 +208,23 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq, behavior. Note that this works correctly for a zero-initialized condvar too. */ unsigned int old_orig_size = __condvar_get_orig_size (cond); - uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond) >> 1; - if (((unsigned) (wseq - old_g1_start - old_orig_size) - + cond->__data.__g_size[g1 ^ 1]) == 0) + uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond); + uint64_t new_g1_start = old_g1_start + old_orig_size; + if (((unsigned) (wseq - new_g1_start) + cond->__data.__g_size[g1 ^ 1]) == 0) return false; - /* Now try to close and quiesce G1. We have to consider the following kinds - of waiters: + /* We have to consider the following kinds of waiters: * Waiters from less recent groups than G1 are not affected because nothing will change for them apart from __g1_start getting larger. * New waiters arriving concurrently with the group switching will all go into G2 until we atomically make the switch. Waiters existing in G2 are not affected. - * Waiters in G1 will be closed out immediately by setting a flag in - __g_signals, which will prevent waiters from blocking using a futex on - __g_signals and also notifies them that the group is closed. As a - result, they will eventually remove their group reference, allowing us - to close switch group roles. */ + * Waiters in G1 have already received a signal and been woken. */ - /* First, set the closed flag on __g_signals. This tells waiters that are - about to wait that they shouldn't do that anymore. This basically - serves as an advance notification of the upcoming change to __g1_start; - waiters interpret it as if __g1_start was larger than their waiter - sequence position. This allows us to change __g1_start after waiting - for all existing waiters with group references to leave, which in turn - makes recovery after stealing a signal simpler because it then can be - skipped if __g1_start indicates that the group is closed (otherwise, - we would have to recover always because waiters don't know how big their - groups are). Relaxed MO is fine. */ - atomic_fetch_or_relaxed (cond->__data.__g_signals + g1, 1); - - /* Wait until there are no group references anymore. The fetch-or operation - injects us into the modification order of __g_refs; release MO ensures - that waiters incrementing __g_refs after our fetch-or see the previous - changes to __g_signals and to __g1_start that had to happen before we can - switch this G1 and alias with an older group (we have two groups, so - aliasing requires switching group roles twice). Note that nobody else - can have set the wake-request flag, so we do not have to act upon it. - - Also note that it is harmless if older waiters or waiters from this G1 - get a group reference after we have quiesced the group because it will - remain closed for them either because of the closed flag in __g_signals - or the later update to __g1_start. New waiters will never arrive here - but instead continue to go into the still current G2. */ - unsigned r = atomic_fetch_or_release (cond->__data.__g_refs + g1, 0); - while ((r >> 1) > 0) - { - for (unsigned int spin = maxspin; ((r >> 1) > 0) && (spin > 0); spin--) - { - /* TODO Back off. */ - r = atomic_load_relaxed (cond->__data.__g_refs + g1); - } - if ((r >> 1) > 0) - { - /* There is still a waiter after spinning. Set the wake-request - flag and block. Relaxed MO is fine because this is just about - this futex word. - - Update r to include the set wake-request flag so that the upcoming - futex_wait only blocks if the flag is still set (otherwise, we'd - violate the basic client-side futex protocol). */ - r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1; - - if ((r >> 1) > 0) - futex_wait_simple (cond->__data.__g_refs + g1, r, private); - /* Reload here so we eventually see the most recent value even if we - do not spin. */ - r = atomic_load_relaxed (cond->__data.__g_refs + g1); - } - } - /* Acquire MO so that we synchronize with the release operation that waiters - use to decrement __g_refs and thus happen after the waiters we waited - for. */ - atomic_thread_fence_acquire (); - - /* Update __g1_start, which finishes closing this group. The value we add - will never be negative because old_orig_size can only be zero when we - switch groups the first time after a condvar was initialized, in which - case G1 will be at index 1 and we will add a value of 1. See above for - why this takes place after waiting for quiescence of the group. - Relaxed MO is fine because the change comes with no additional - constraints that others would have to observe. */ - __condvar_add_g1_start_relaxed (cond, - (old_orig_size << 1) + (g1 == 1 ? 1 : - 1)); - - /* Now reopen the group, thus enabling waiters to again block using the - futex controlled by __g_signals. Release MO so that observers that see - no signals (and thus can block) also see the write __g1_start and thus - that this is now a new group (see __pthread_cond_wait_common for the - matching acquire MO loads). */ - atomic_store_release (cond->__data.__g_signals + g1, 0); + /* Update __g1_start, which closes this group. Relaxed MO is fine because + the change comes with no additional constraints that others would have + to observe. */ + __condvar_add_g1_start_relaxed (cond, old_orig_size); /* At this point, the old G1 is now a valid new G2 (but not in use yet). No old waiter can neither grab a signal nor acquire a reference without @@ -311,9 +236,13 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq, g1 ^= 1; *g1index ^= 1; + /* Now advance the new G1 g_signals to the new g1_start, giving it + an effective signal count of 0 to start. */ + atomic_store_release (cond->__data.__g_signals + g1, (unsigned)new_g1_start); + /* These values are just observed by signalers, and thus protected by the lock. */ - unsigned int orig_size = wseq - (old_g1_start + old_orig_size); + unsigned int orig_size = wseq - new_g1_start; __condvar_set_orig_size (cond, orig_size); /* Use and addition to not loose track of cancellations in what was previously G2. */ diff --git a/nptl/pthread_cond_destroy.c b/nptl/pthread_cond_destroy.c index 0bbe406..c504a96 100644 --- a/nptl/pthread_cond_destroy.c +++ b/nptl/pthread_cond_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_cond_init.c b/nptl/pthread_cond_init.c index 59b38bc..d3285b1 100644 --- a/nptl/pthread_cond_init.c +++ b/nptl/pthread_cond_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c index 43d6286..f327d42 100644 --- a/nptl/pthread_cond_signal.c +++ b/nptl/pthread_cond_signal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 @@ -69,19 +69,18 @@ ___pthread_cond_signal (pthread_cond_t *cond) bool do_futex_wake = false; /* If G1 is still receiving signals, we put the signal there. If not, we - check if G2 has waiters, and if so, quiesce and switch G1 to the former - G2; if this results in a new G1 with waiters (G2 might have cancellations - already, see __condvar_quiesce_and_switch_g1), we put the signal in the - new G1. */ + check if G2 has waiters, and if so, switch G1 to the former G2; if this + results in a new G1 with waiters (G2 might have cancellations already, + see __condvar_switch_g1), we put the signal in the new G1. */ if ((cond->__data.__g_size[g1] != 0) - || __condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private)) + || __condvar_switch_g1 (cond, wseq, &g1, private)) { /* Add a signal. Relaxed MO is fine because signaling does not need to - establish a happens-before relation (see above). We do not mask the - release-MO store when initializing a group in - __condvar_quiesce_and_switch_g1 because we use an atomic - read-modify-write and thus extend that store's release sequence. */ - atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2); + establish a happens-before relation (see above). We do not mask the + release-MO store when initializing a group in __condvar_switch_g1 + because we use an atomic read-modify-write and thus extend that + store's release sequence. */ + atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 1); cond->__data.__g_size[g1]--; /* TODO Only set it if there are indeed futex waiters. */ do_futex_wake = true; diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c index 66786c7..c6461bd 100644 --- a/nptl/pthread_cond_wait.c +++ b/nptl/pthread_cond_wait.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 @@ -84,7 +84,7 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g, not hold a reference on the group. */ __condvar_acquire_lock (cond, private); - uint64_t g1_start = __condvar_load_g1_start_relaxed (cond) >> 1; + uint64_t g1_start = __condvar_load_g1_start_relaxed (cond); if (g1_start > seq) { /* Our group is closed, so someone provided enough signals for it. @@ -143,23 +143,6 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g, } } -/* Wake up any signalers that might be waiting. */ -static void -__condvar_dec_grefs (pthread_cond_t *cond, unsigned int g, int private) -{ - /* Release MO to synchronize-with the acquire load in - __condvar_quiesce_and_switch_g1. */ - if (atomic_fetch_add_release (cond->__data.__g_refs + g, -2) == 3) - { - /* Clear the wake-up request flag before waking up. We do not need more - than relaxed MO and it doesn't matter if we apply this for an aliased - group because we wake all futex waiters right after clearing the - flag. */ - atomic_fetch_and_relaxed (cond->__data.__g_refs + g, ~(unsigned int) 1); - futex_wake (cond->__data.__g_refs + g, INT_MAX, private); - } -} - /* Clean-up for cancellation of waiters waiting for normal signals. We cancel our registration as a waiter, confirm we have woken up, and re-acquire the mutex. */ @@ -171,8 +154,6 @@ __condvar_cleanup_waiting (void *arg) pthread_cond_t *cond = cbuffer->cond; unsigned g = cbuffer->wseq & 1; - __condvar_dec_grefs (cond, g, cbuffer->private); - __condvar_cancel_waiting (cond, cbuffer->wseq >> 1, g, cbuffer->private); /* FIXME With the current cancellation implementation, it is possible that a thread is cancelled after it has returned from a syscall. This could @@ -238,9 +219,7 @@ __condvar_cleanup_waiting (void *arg) signaled), and a reference count. The group reference count is used to maintain the number of waiters that - are using the group's futex. Before a group can change its role, the - reference count must show that no waiters are using the futex anymore; this - prevents ABA issues on the futex word. + are using the group's futex. To represent which intervals in the waiter sequence the groups cover (and thus also which group slot contains G1 or G2), we use a 64b counter to @@ -251,7 +230,7 @@ __condvar_cleanup_waiting (void *arg) figure out whether they are in a group that has already been completely signaled (i.e., if the current G1 starts at a later position that the waiter's position). Waiters cannot determine whether they are currently - in G2 or G1 -- but they do not have too because all they are interested in + in G2 or G1 -- but they do not have to because all they are interested in is whether there are available signals, and they always start in G2 (whose group slot they know because of the bit in the waiter sequence. Signalers will simply fill the right group until it is completely signaled and can @@ -280,7 +259,6 @@ __condvar_cleanup_waiting (void *arg) * Waiters fetch-add while having acquire the mutex associated with the condvar. Signalers load it and fetch-xor it concurrently. __g1_start: Starting position of G1 (inclusive) - * LSB is index of current G2. * Modified by signalers while having acquired the condvar-internal lock and observed concurrently by waiters. __g1_orig_size: Initial size of G1 @@ -295,16 +273,10 @@ __condvar_cleanup_waiting (void *arg) (If the format of __wrefs is changed, update nptl_lock_constants.pysym and the pretty printers.) For each of the two groups, we have: - __g_refs: Futex waiter reference count. - * LSB is true if waiters should run futex_wake when they remove the - last reference. - * Reference count used by waiters concurrently with signalers that have - acquired the condvar-internal lock. - __g_signals: The number of signals that can still be consumed. + __g_signals: The number of signals that can still be consumed, relative to + the current g1_start. (i.e. g1_start with the signal count added) * Used as a futex word by waiters. Used concurrently by waiters and signalers. - * LSB is true iff this group has been completely signaled (i.e., it is - closed). __g_size: Waiters remaining in this group (i.e., which have not been signaled yet. * Accessed by signalers and waiters that cancel waiting (both do so only @@ -328,27 +300,6 @@ __condvar_cleanup_waiting (void *arg) sufficient because if a waiter can see a sufficiently large value, it could have also consume a signal in the waiters group. - Waiters try to grab a signal from __g_signals without holding a reference - count, which can lead to stealing a signal from a more recent group after - their own group was already closed. They cannot always detect whether they - in fact did because they do not know when they stole, but they can - conservatively add a signal back to the group they stole from; if they - did so unnecessarily, all that happens is a spurious wake-up. To make this - even less likely, __g1_start contains the index of the current g2 too, - which allows waiters to check if there aliasing on the group slots; if - there wasn't, they didn't steal from the current G1, which means that the - G1 they stole from must have been already closed and they do not need to - fix anything. - - It is essential that the last field in pthread_cond_t is __g_signals[1]: - The previous condvar used a pointer-sized field in pthread_cond_t, so a - PTHREAD_COND_INITIALIZER from that condvar implementation might only - initialize 4 bytes to zero instead of the 8 bytes we need (i.e., 44 bytes - in total instead of the 48 we need). __g_signals[1] is not accessed before - the first group switch (G2 starts at index 0), which will set its value to - zero after a harmless fetch-or whose return value is ignored. This - effectively completes initialization. - Limitations: * This condvar isn't designed to allow for more than @@ -379,7 +330,6 @@ static __always_inline int __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex, clockid_t clockid, const struct __timespec64 *abstime) { - const int maxspin = 0; int err; int result = 0; @@ -396,8 +346,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex, because we do not need to establish any happens-before relation with signalers (see __pthread_cond_signal); modification order alone establishes a total order of waiters/signals. We do need acquire MO - to synchronize with group reinitialization in - __condvar_quiesce_and_switch_g1. */ + to synchronize with group reinitialization in __condvar_switch_g1. */ uint64_t wseq = __condvar_fetch_add_wseq_acquire (cond, 2); /* Find our group's index. We always go into what was G2 when we acquired our position. */ @@ -424,178 +373,64 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex, return err; } - /* Now wait until a signal is available in our group or it is closed. - Acquire MO so that if we observe a value of zero written after group - switching in __condvar_quiesce_and_switch_g1, we synchronize with that - store and will see the prior update of __g1_start done while switching - groups too. */ - unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g); - do + while (1) { - while (1) - { - /* Spin-wait first. - Note that spinning first without checking whether a timeout - passed might lead to what looks like a spurious wake-up even - though we should return ETIMEDOUT (e.g., if the caller provides - an absolute timeout that is clearly in the past). However, - (1) spurious wake-ups are allowed, (2) it seems unlikely that a - user will (ab)use pthread_cond_wait as a check for whether a - point in time is in the past, and (3) spinning first without - having to compare against the current time seems to be the right - choice from a performance perspective for most use cases. */ - unsigned int spin = maxspin; - while (signals == 0 && spin > 0) - { - /* Check that we are not spinning on a group that's already - closed. */ - if (seq < (__condvar_load_g1_start_relaxed (cond) >> 1)) - goto done; - - /* TODO Back off. */ - - /* Reload signals. See above for MO. */ - signals = atomic_load_acquire (cond->__data.__g_signals + g); - spin--; - } - - /* If our group will be closed as indicated by the flag on signals, - don't bother grabbing a signal. */ - if (signals & 1) - goto done; - - /* If there is an available signal, don't block. */ - if (signals != 0) - break; - - /* No signals available after spinning, so prepare to block. - We first acquire a group reference and use acquire MO for that so - that we synchronize with the dummy read-modify-write in - __condvar_quiesce_and_switch_g1 if we read from that. In turn, - in this case this will make us see the closed flag on __g_signals - that designates a concurrent attempt to reuse the group's slot. - We use acquire MO for the __g_signals check to make the - __g1_start check work (see spinning above). - Note that the group reference acquisition will not mask the - release MO when decrementing the reference count because we use - an atomic read-modify-write operation and thus extend the release - sequence. */ - atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2); - if (((atomic_load_acquire (cond->__data.__g_signals + g) & 1) != 0) - || (seq < (__condvar_load_g1_start_relaxed (cond) >> 1))) - { - /* Our group is closed. Wake up any signalers that might be - waiting. */ - __condvar_dec_grefs (cond, g, private); - goto done; - } - - // Now block. - struct _pthread_cleanup_buffer buffer; - struct _condvar_cleanup_buffer cbuffer; - cbuffer.wseq = wseq; - cbuffer.cond = cond; - cbuffer.mutex = mutex; - cbuffer.private = private; - __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer); - - err = __futex_abstimed_wait_cancelable64 ( - cond->__data.__g_signals + g, 0, clockid, abstime, private); - - __pthread_cleanup_pop (&buffer, 0); - - if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW)) - { - __condvar_dec_grefs (cond, g, private); - /* If we timed out, we effectively cancel waiting. Note that - we have decremented __g_refs before cancellation, so that a - deadlock between waiting for quiescence of our group in - __condvar_quiesce_and_switch_g1 and us trying to acquire - the lock during cancellation is not possible. */ - __condvar_cancel_waiting (cond, seq, g, private); - result = err; - goto done; - } - else - __condvar_dec_grefs (cond, g, private); - - /* Reload signals. See above for MO. */ - signals = atomic_load_acquire (cond->__data.__g_signals + g); + /* Now wait until a signal is available in our group or it is closed. + Acquire MO so that if we observe (signals == lowseq) after group + switching in __condvar_switch_g1, we synchronize with that store and + will see the prior update of __g1_start done while switching groups + too. */ + unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g); + uint64_t g1_start = __condvar_load_g1_start_relaxed (cond); + + if (seq < g1_start) + { + /* If the group is closed already, + then this waiter originally had enough extra signals to + consume, up until the time its group was closed. */ + break; + } + + /* If there is an available signal, don't block. + If __g1_start has advanced at all, then we must be in G1 + by now, perhaps in the process of switching back to an older + G2, but in either case we're allowed to consume the available + signal and should not block anymore. */ + if ((int)(signals - (unsigned int)g1_start) > 0) + { + /* Try to grab a signal. See above for MO. (if we do another loop + iteration we need to see the correct value of g1_start) */ + if (atomic_compare_exchange_weak_acquire ( + cond->__data.__g_signals + g, + &signals, signals - 1)) + break; + else + continue; } + // Now block. + struct _pthread_cleanup_buffer buffer; + struct _condvar_cleanup_buffer cbuffer; + cbuffer.wseq = wseq; + cbuffer.cond = cond; + cbuffer.mutex = mutex; + cbuffer.private = private; + __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer); + + err = __futex_abstimed_wait_cancelable64 ( + cond->__data.__g_signals + g, signals, clockid, abstime, private); + + __pthread_cleanup_pop (&buffer, 0); + + if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW)) + { + /* If we timed out, we effectively cancel waiting. */ + __condvar_cancel_waiting (cond, seq, g, private); + result = err; + break; + } } - /* Try to grab a signal. Use acquire MO so that we see an up-to-date value - of __g1_start below (see spinning above for a similar case). In - particular, if we steal from a more recent group, we will also see a - more recent __g1_start below. */ - while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g, - &signals, signals - 2)); - - /* We consumed a signal but we could have consumed from a more recent group - that aliased with ours due to being in the same group slot. If this - might be the case our group must be closed as visible through - __g1_start. */ - uint64_t g1_start = __condvar_load_g1_start_relaxed (cond); - if (seq < (g1_start >> 1)) - { - /* We potentially stole a signal from a more recent group but we do not - know which group we really consumed from. - We do not care about groups older than current G1 because they are - closed; we could have stolen from these, but then we just add a - spurious wake-up for the current groups. - We will never steal a signal from current G2 that was really intended - for G2 because G2 never receives signals (until it becomes G1). We - could have stolen a signal from G2 that was conservatively added by a - previous waiter that also thought it stole a signal -- but given that - that signal was added unnecessarily, it's not a problem if we steal - it. - Thus, the remaining case is that we could have stolen from the current - G1, where "current" means the __g1_start value we observed. However, - if the current G1 does not have the same slot index as we do, we did - not steal from it and do not need to undo that. This is the reason - for putting a bit with G2's index into__g1_start as well. */ - if (((g1_start & 1) ^ 1) == g) - { - /* We have to conservatively undo our potential mistake of stealing - a signal. We can stop trying to do that when the current G1 - changes because other spinning waiters will notice this too and - __condvar_quiesce_and_switch_g1 has checked that there are no - futex waiters anymore before switching G1. - Relaxed MO is fine for the __g1_start load because we need to - merely be able to observe this fact and not have to observe - something else as well. - ??? Would it help to spin for a little while to see whether the - current G1 gets closed? This might be worthwhile if the group is - small or close to being closed. */ - unsigned int s = atomic_load_relaxed (cond->__data.__g_signals + g); - while (__condvar_load_g1_start_relaxed (cond) == g1_start) - { - /* Try to add a signal. We don't need to acquire the lock - because at worst we can cause a spurious wake-up. If the - group is in the process of being closed (LSB is true), this - has an effect similar to us adding a signal. */ - if (((s & 1) != 0) - || atomic_compare_exchange_weak_relaxed - (cond->__data.__g_signals + g, &s, s + 2)) - { - /* If we added a signal, we also need to add a wake-up on - the futex. We also need to do that if we skipped adding - a signal because the group is being closed because - while __condvar_quiesce_and_switch_g1 could have closed - the group, it might still be waiting for futex waiters to - leave (and one of those waiters might be the one we stole - the signal from, which cause it to block using the - futex). */ - futex_wake (cond->__data.__g_signals + g, 1, private); - break; - } - /* TODO Back off. */ - } - } - } - - done: /* Confirm that we have been woken. We do that before acquiring the mutex to allow for execution of pthread_cond_destroy while having acquired the diff --git a/nptl/pthread_condattr_destroy.c b/nptl/pthread_condattr_destroy.c index 4a26820..b8cc9e7 100644 --- a/nptl/pthread_condattr_destroy.c +++ b/nptl/pthread_condattr_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_condattr_getclock.c b/nptl/pthread_condattr_getclock.c index 6fecf82..057e214 100644 --- a/nptl/pthread_condattr_getclock.c +++ b/nptl/pthread_condattr_getclock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_condattr_getpshared.c b/nptl/pthread_condattr_getpshared.c index d8c8cc8..21d1c4c 100644 --- a/nptl/pthread_condattr_getpshared.c +++ b/nptl/pthread_condattr_getpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_condattr_init.c b/nptl/pthread_condattr_init.c index 77f868b..1b9db9b 100644 --- a/nptl/pthread_condattr_init.c +++ b/nptl/pthread_condattr_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_condattr_setclock.c b/nptl/pthread_condattr_setclock.c index df29893..27dddee 100644 --- a/nptl/pthread_condattr_setclock.c +++ b/nptl/pthread_condattr_setclock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_condattr_setpshared.c b/nptl/pthread_condattr_setpshared.c index 7debf70..13e6f78 100644 --- a/nptl/pthread_condattr_setpshared.c +++ b/nptl/pthread_condattr_setpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 1d3665d..e1033d4 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -38,6 +38,7 @@ #include <version.h> #include <clone_internal.h> #include <futex-internal.h> +#include <getrandom-internal.h> #include <shlib-compat.h> @@ -238,7 +239,7 @@ static int create_thread (struct pthread *pd, const struct pthread_attr *attr, stopped since we have to set the scheduling parameters or set the affinity. */ bool need_setaffinity = (attr != NULL && attr->extension != NULL - && attr->extension->cpuset != 0); + && attr->extension->cpuset != NULL); if (attr != NULL && (__glibc_unlikely (need_setaffinity) || __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))) @@ -549,7 +550,11 @@ start_thread (void *arg) } #endif - if (!pd->user_stack) + /* Release the vDSO getrandom per-thread buffer with all signal blocked, + to avoid creating a new free-state block during thread release. */ + __getrandom_vdso_release (pd); + + if (pd->stack_mode != ALLOCATE_GUARD_USER) advise_stack_range (pd->stackblock, pd->stackblock_size, (uintptr_t) pd, pd->guardsize); @@ -691,7 +696,7 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, /* Inherit rseq registration state. Without seccomp filters, rseq registration will either always fail or always succeed. */ - if ((int) THREAD_GETMEM_VOLATILE (self, rseq_area.cpu_id) >= 0) + if ((int) RSEQ_GETMEM_ONCE (cpu_id) >= 0) pd->flags |= ATTR_FLAG_DO_RSEQ; /* Initialize the field for the ID of the thread which is waiting diff --git a/nptl/pthread_detach.c b/nptl/pthread_detach.c index 25eea52..3bbc037 100644 --- a/nptl/pthread_detach.c +++ b/nptl/pthread_detach.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_equal.c b/nptl/pthread_equal.c index 9317306..56ca33b 100644 --- a/nptl/pthread_equal.c +++ b/nptl/pthread_equal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_exit.c b/nptl/pthread_exit.c index dc2635f..b8b723c 100644 --- a/nptl/pthread_exit.c +++ b/nptl/pthread_exit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -31,9 +31,7 @@ __pthread_exit (void *value) " must be installed for pthread_exit to work\n"); } - THREAD_SETMEM (THREAD_SELF, result, value); - - __do_cancel (); + __do_cancel (value); } libc_hidden_def (__pthread_exit) weak_alias (__pthread_exit, pthread_exit) diff --git a/nptl/pthread_getaffinity.c b/nptl/pthread_getaffinity.c index 823c4d6..0828185 100644 --- a/nptl/pthread_getaffinity.c +++ b/nptl/pthread_getaffinity.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_getattr_default_np.c b/nptl/pthread_getattr_default_np.c index 0c9c953..4a66c95 100644 --- a/nptl/pthread_getattr_default_np.c +++ b/nptl/pthread_getattr_default_np.c @@ -1,5 +1,5 @@ /* Get the default attributes used by pthread_create in the process. - Copyright (C) 2013-2024 Free Software Foundation, Inc. + Copyright (C) 2013-2025 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 diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c index 1e91874..43dd16d 100644 --- a/nptl/pthread_getattr_np.c +++ b/nptl/pthread_getattr_np.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -145,9 +145,9 @@ __pthread_getattr_np (pthread_t thread_id, pthread_attr_t *attr) > (size_t) iattr->stackaddr - last_to) iattr->stacksize = (size_t) iattr->stackaddr - last_to; #else - /* The limit might be too high. */ + /* The limit might be too low. */ if ((size_t) iattr->stacksize - > to - (size_t) iattr->stackaddr) + < to - (size_t) iattr->stackaddr) iattr->stacksize = to - (size_t) iattr->stackaddr; #endif /* We succeed and no need to look further. */ diff --git a/nptl/pthread_getconcurrency.c b/nptl/pthread_getconcurrency.c index 04fd324..28118af 100644 --- a/nptl/pthread_getconcurrency.c +++ b/nptl/pthread_getconcurrency.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_getcpuclockid.c b/nptl/pthread_getcpuclockid.c index ed464ba..0cd9f77 100644 --- a/nptl/pthread_getcpuclockid.c +++ b/nptl/pthread_getcpuclockid.c @@ -1,5 +1,5 @@ /* pthread_getcpuclockid -- Get POSIX clockid_t for a pthread_t. Linux version - Copyright (C) 2000-2024 Free Software Foundation, Inc. + Copyright (C) 2000-2025 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 diff --git a/nptl/pthread_getname.c b/nptl/pthread_getname.c index 070ebd9..535932b 100644 --- a/nptl/pthread_getname.c +++ b/nptl/pthread_getname.c @@ -1,5 +1,5 @@ /* pthread_getname_np -- Get thread name. Linux version - Copyright (C) 2010-2024 Free Software Foundation, Inc. + Copyright (C) 2010-2025 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 diff --git a/nptl/pthread_getschedparam.c b/nptl/pthread_getschedparam.c index 1aba822..bb74ed9 100644 --- a/nptl/pthread_getschedparam.c +++ b/nptl/pthread_getschedparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_getspecific.c b/nptl/pthread_getspecific.c index a51e1de..ea3c7e4 100644 --- a/nptl/pthread_getspecific.c +++ b/nptl/pthread_getspecific.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_gettid_np.c b/nptl/pthread_gettid_np.c new file mode 100644 index 0000000..bf3a12c --- /dev/null +++ b/nptl/pthread_gettid_np.c @@ -0,0 +1,30 @@ +/* Get the Linux TID from a pthread_t handle. + Copyright (C) 2025 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; see the file COPYING.LIB. If + not, see <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthreadP.h> + +pid_t +pthread_gettid_np (pthread_t threadid) +{ + /* The kernel may concurrently set this field. */ + pid_t tid = atomic_load_relaxed (&((struct pthread *) threadid)->tid); + if (tid <= 0) + return -1; + return tid; +} diff --git a/nptl/pthread_join.c b/nptl/pthread_join.c index 31f8036..cf8e56c8 100644 --- a/nptl/pthread_join.c +++ b/nptl/pthread_join.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c index 9c685c7..ff389bf 100644 --- a/nptl/pthread_join_common.c +++ b/nptl/pthread_join_common.c @@ -1,5 +1,5 @@ /* Common definition for pthread_{timed,try}join{_np}. - Copyright (C) 2017-2024 Free Software Foundation, Inc. + Copyright (C) 2017-2025 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 @@ -49,6 +49,12 @@ __pthread_clockjoin_ex (pthread_t threadid, void **thread_return, /* We cannot wait for the thread. */ return EINVAL; + /* Make sure the clock and time specified are valid. */ + if (abstime + && __glibc_unlikely (!futex_abstimed_supported_clockid (clockid) + || ! valid_nanoseconds (abstime->tv_nsec))) + return EINVAL; + struct pthread *self = THREAD_SELF; int result = 0; diff --git a/nptl/pthread_key_create.c b/nptl/pthread_key_create.c index a759bdd..486db9a 100644 --- a/nptl/pthread_key_create.c +++ b/nptl/pthread_key_create.c @@ -1,4 +1,4 @@ - /* Copyright (C) 2002-2024 Free Software Foundation, Inc. + /* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_key_delete.c b/nptl/pthread_key_delete.c index 3ec3701..28fd5df 100644 --- a/nptl/pthread_key_delete.c +++ b/nptl/pthread_key_delete.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_keys.c b/nptl/pthread_keys.c index 8a686f8..c43edc6 100644 --- a/nptl/pthread_keys.c +++ b/nptl/pthread_keys.c @@ -1,5 +1,5 @@ /* Table of pthread_key_create keys and their destructors. - Copyright (C) 2004-2024 Free Software Foundation, Inc. + Copyright (C) 2004-2025 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 diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c index 71e5a7b..3938e3f 100644 --- a/nptl/pthread_kill.c +++ b/nptl/pthread_kill.c @@ -1,5 +1,5 @@ /* Send a signal to a specific pthread. Stub version. - Copyright (C) 2014-2024 Free Software Foundation, Inc. + Copyright (C) 2014-2025 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 @@ -69,6 +69,17 @@ __pthread_kill_implementation (pthread_t threadid, int signo, int no_tid) return ret; } +/* Send the signal SIGNO to the caller. Used by abort and called where the + signals are being already blocked and there is no need to synchronize with + exit_lock. */ +int +__pthread_raise_internal (int signo) +{ + /* Use the gettid syscall so it works after vfork. */ + int ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), __gettid(), signo); + return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; +} + int __pthread_kill_internal (pthread_t threadid, int signo) { diff --git a/nptl/pthread_kill_other_threads.c b/nptl/pthread_kill_other_threads.c index 43034ec..9ce02eb 100644 --- a/nptl/pthread_kill_other_threads.c +++ b/nptl/pthread_kill_other_threads.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutex_conf.c b/nptl/pthread_mutex_conf.c index 8aac5f2..9f29740 100644 --- a/nptl/pthread_mutex_conf.c +++ b/nptl/pthread_mutex_conf.c @@ -1,5 +1,5 @@ /* Pthread mutex tunable parameters. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c index 2a9c4c7..4529419 100644 --- a/nptl/pthread_mutex_consistent.c +++ b/nptl/pthread_mutex_consistent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2024 Free Software Foundation, Inc. +/* Copyright (C) 2005-2025 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 diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c index f866dda..94f50ac 100644 --- a/nptl/pthread_mutex_destroy.c +++ b/nptl/pthread_mutex_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutex_getprioceiling.c b/nptl/pthread_mutex_getprioceiling.c index df3d3e4..16d9ee9 100644 --- a/nptl/pthread_mutex_getprioceiling.c +++ b/nptl/pthread_mutex_getprioceiling.c @@ -1,5 +1,5 @@ /* Get current priority ceiling of pthread_mutex_t. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c index 260bae3..1639935 100644 --- a/nptl/pthread_mutex_init.c +++ b/nptl/pthread_mutex_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c index befa31c..604941c 100644 --- a/nptl/pthread_mutex_lock.c +++ b/nptl/pthread_mutex_lock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c index 30053c5..a02d1a2 100644 --- a/nptl/pthread_mutex_setprioceiling.c +++ b/nptl/pthread_mutex_setprioceiling.c @@ -1,5 +1,5 @@ /* Set current priority ceiling of pthread_mutex_t. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 53851fe..138cdcc 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c index 720c103..dbb8fcc 100644 --- a/nptl/pthread_mutex_trylock.c +++ b/nptl/pthread_mutex_trylock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c index 2240d2c..60bea80 100644 --- a/nptl/pthread_mutex_unlock.c +++ b/nptl/pthread_mutex_unlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutexattr_destroy.c b/nptl/pthread_mutexattr_destroy.c index cdb3602..90b51ec 100644 --- a/nptl/pthread_mutexattr_destroy.c +++ b/nptl/pthread_mutexattr_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutexattr_getprioceiling.c b/nptl/pthread_mutexattr_getprioceiling.c index 493ad82..02c22d4 100644 --- a/nptl/pthread_mutexattr_getprioceiling.c +++ b/nptl/pthread_mutexattr_getprioceiling.c @@ -1,5 +1,5 @@ /* Get priority ceiling setting from pthread_mutexattr_t. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/pthread_mutexattr_getprotocol.c b/nptl/pthread_mutexattr_getprotocol.c index c3d61dc..f63c10f 100644 --- a/nptl/pthread_mutexattr_getprotocol.c +++ b/nptl/pthread_mutexattr_getprotocol.c @@ -1,5 +1,5 @@ /* Get priority protocol setting from pthread_mutexattr_t. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/pthread_mutexattr_getpshared.c b/nptl/pthread_mutexattr_getpshared.c index eed43f0..8f26003 100644 --- a/nptl/pthread_mutexattr_getpshared.c +++ b/nptl/pthread_mutexattr_getpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutexattr_getrobust.c b/nptl/pthread_mutexattr_getrobust.c index 887ec3e..e6738f0 100644 --- a/nptl/pthread_mutexattr_getrobust.c +++ b/nptl/pthread_mutexattr_getrobust.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2024 Free Software Foundation, Inc. +/* Copyright (C) 2005-2025 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 diff --git a/nptl/pthread_mutexattr_gettype.c b/nptl/pthread_mutexattr_gettype.c index 688e2d5..5448cbe 100644 --- a/nptl/pthread_mutexattr_gettype.c +++ b/nptl/pthread_mutexattr_gettype.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutexattr_init.c b/nptl/pthread_mutexattr_init.c index a3498ea..2ca5237 100644 --- a/nptl/pthread_mutexattr_init.c +++ b/nptl/pthread_mutexattr_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutexattr_setprioceiling.c b/nptl/pthread_mutexattr_setprioceiling.c index 95ae2fd..faf1ec8 100644 --- a/nptl/pthread_mutexattr_setprioceiling.c +++ b/nptl/pthread_mutexattr_setprioceiling.c @@ -1,5 +1,5 @@ /* Change priority ceiling setting in pthread_mutexattr_t. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/pthread_mutexattr_setprotocol.c b/nptl/pthread_mutexattr_setprotocol.c index 9e26cd6..c1fcbf9 100644 --- a/nptl/pthread_mutexattr_setprotocol.c +++ b/nptl/pthread_mutexattr_setprotocol.c @@ -1,5 +1,5 @@ /* Change priority protocol setting in pthread_mutexattr_t. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/pthread_mutexattr_setpshared.c b/nptl/pthread_mutexattr_setpshared.c index b10de7a..fea8ee6 100644 --- a/nptl/pthread_mutexattr_setpshared.c +++ b/nptl/pthread_mutexattr_setpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_mutexattr_setrobust.c b/nptl/pthread_mutexattr_setrobust.c index 807d247..ee768a6 100644 --- a/nptl/pthread_mutexattr_setrobust.c +++ b/nptl/pthread_mutexattr_setrobust.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2024 Free Software Foundation, Inc. +/* Copyright (C) 2005-2025 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 diff --git a/nptl/pthread_mutexattr_settype.c b/nptl/pthread_mutexattr_settype.c index 3de8536..7536800 100644 --- a/nptl/pthread_mutexattr_settype.c +++ b/nptl/pthread_mutexattr_settype.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c index 397ad12..efeb174 100644 --- a/nptl/pthread_once.c +++ b/nptl/pthread_once.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_rwlock_clockrdlock.c b/nptl/pthread_rwlock_clockrdlock.c index 573ecd4..26b4206 100644 --- a/nptl/pthread_rwlock_clockrdlock.c +++ b/nptl/pthread_rwlock_clockrdlock.c @@ -1,6 +1,6 @@ /* Implement pthread_rwlock_clockrdlock. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/pthread_rwlock_clockwrlock.c b/nptl/pthread_rwlock_clockwrlock.c index cf94089..c7a0638 100644 --- a/nptl/pthread_rwlock_clockwrlock.c +++ b/nptl/pthread_rwlock_clockwrlock.c @@ -1,6 +1,6 @@ /* Implement pthread_rwlock_clockwrlock. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c index 5673ab2..d49ea25 100644 --- a/nptl/pthread_rwlock_common.c +++ b/nptl/pthread_rwlock_common.c @@ -1,5 +1,5 @@ /* POSIX reader--writer lock: core parts. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/pthread_rwlock_destroy.c b/nptl/pthread_rwlock_destroy.c index a2b1b8f..078e109 100644 --- a/nptl/pthread_rwlock_destroy.c +++ b/nptl/pthread_rwlock_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlock_init.c b/nptl/pthread_rwlock_init.c index 22f93fd..da7bcae 100644 --- a/nptl/pthread_rwlock_init.c +++ b/nptl/pthread_rwlock_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlock_rdlock.c b/nptl/pthread_rwlock_rdlock.c index 04d2f1b..7324ded 100644 --- a/nptl/pthread_rwlock_rdlock.c +++ b/nptl/pthread_rwlock_rdlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c index cf14e63..46ec8da 100644 --- a/nptl/pthread_rwlock_timedrdlock.c +++ b/nptl/pthread_rwlock_timedrdlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c index b0c7b2a..ca3a27c 100644 --- a/nptl/pthread_rwlock_timedwrlock.c +++ b/nptl/pthread_rwlock_timedwrlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c index 5a01553..f036acc 100644 --- a/nptl/pthread_rwlock_tryrdlock.c +++ b/nptl/pthread_rwlock_tryrdlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c index a89d4ef..ec66263 100644 --- a/nptl/pthread_rwlock_trywrlock.c +++ b/nptl/pthread_rwlock_trywrlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlock_unlock.c b/nptl/pthread_rwlock_unlock.c index c172c97..988e5a9 100644 --- a/nptl/pthread_rwlock_unlock.c +++ b/nptl/pthread_rwlock_unlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_rwlock_wrlock.c b/nptl/pthread_rwlock_wrlock.c index 35707fc..c1f8fb9 100644 --- a/nptl/pthread_rwlock_wrlock.c +++ b/nptl/pthread_rwlock_wrlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_rwlockattr_destroy.c b/nptl/pthread_rwlockattr_destroy.c index 4cc1943..114b43a 100644 --- a/nptl/pthread_rwlockattr_destroy.c +++ b/nptl/pthread_rwlockattr_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlockattr_getkind_np.c b/nptl/pthread_rwlockattr_getkind_np.c index 084ba6c..1c5c3a6 100644 --- a/nptl/pthread_rwlockattr_getkind_np.c +++ b/nptl/pthread_rwlockattr_getkind_np.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlockattr_getpshared.c b/nptl/pthread_rwlockattr_getpshared.c index b093a40..babb308 100644 --- a/nptl/pthread_rwlockattr_getpshared.c +++ b/nptl/pthread_rwlockattr_getpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlockattr_init.c b/nptl/pthread_rwlockattr_init.c index 95405dc..095dce7 100644 --- a/nptl/pthread_rwlockattr_init.c +++ b/nptl/pthread_rwlockattr_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlockattr_setkind_np.c b/nptl/pthread_rwlockattr_setkind_np.c index cef22f9..bf1f252 100644 --- a/nptl/pthread_rwlockattr_setkind_np.c +++ b/nptl/pthread_rwlockattr_setkind_np.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_rwlockattr_setpshared.c b/nptl/pthread_rwlockattr_setpshared.c index d008f95..c32d995 100644 --- a/nptl/pthread_rwlockattr_setpshared.c +++ b/nptl/pthread_rwlockattr_setpshared.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_self.c b/nptl/pthread_self.c index 930a29d..0565843 100644 --- a/nptl/pthread_self.c +++ b/nptl/pthread_self.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_setaffinity.c b/nptl/pthread_setaffinity.c index 2dec8f2..711d826 100644 --- a/nptl/pthread_setaffinity.c +++ b/nptl/pthread_setaffinity.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_setattr_default_np.c b/nptl/pthread_setattr_default_np.c index 0c6d479..75df868 100644 --- a/nptl/pthread_setattr_default_np.c +++ b/nptl/pthread_setattr_default_np.c @@ -1,5 +1,5 @@ /* Set the default attributes to be used by pthread_create in the process. - Copyright (C) 2013-2024 Free Software Foundation, Inc. + Copyright (C) 2013-2025 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 diff --git a/nptl/pthread_setcancelstate.c b/nptl/pthread_setcancelstate.c index 18fb42a..1b57caa 100644 --- a/nptl/pthread_setcancelstate.c +++ b/nptl/pthread_setcancelstate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -48,7 +48,7 @@ __pthread_setcancelstate (int state, int *oldstate) &oldval, newval)) { if (cancel_enabled_and_canceled_and_async (newval)) - __do_cancel (); + __do_cancel (PTHREAD_CANCELED); break; } diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c index cf441ce..e23e3d1 100644 --- a/nptl/pthread_setcanceltype.c +++ b/nptl/pthread_setcanceltype.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -48,7 +48,7 @@ __pthread_setcanceltype (int type, int *oldtype) if (cancel_enabled_and_canceled_and_async (newval)) { THREAD_SETMEM (self, result, PTHREAD_CANCELED); - __do_cancel (); + __do_cancel (PTHREAD_CANCELED); } break; diff --git a/nptl/pthread_setconcurrency.c b/nptl/pthread_setconcurrency.c index a2c4333..7d5611a 100644 --- a/nptl/pthread_setconcurrency.c +++ b/nptl/pthread_setconcurrency.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_setname.c b/nptl/pthread_setname.c index a97740e..356d2e0 100644 --- a/nptl/pthread_setname.c +++ b/nptl/pthread_setname.c @@ -1,5 +1,5 @@ /* pthread_setname_np -- Set thread name. Linux version - Copyright (C) 2010-2024 Free Software Foundation, Inc. + Copyright (C) 2010-2025 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 diff --git a/nptl/pthread_setschedparam.c b/nptl/pthread_setschedparam.c index 8e4f334..1b43eb1 100644 --- a/nptl/pthread_setschedparam.c +++ b/nptl/pthread_setschedparam.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_setschedprio.c b/nptl/pthread_setschedprio.c index d6c5a96..c355716 100644 --- a/nptl/pthread_setschedprio.c +++ b/nptl/pthread_setschedprio.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_setspecific.c b/nptl/pthread_setspecific.c index ae1d79c..f98d1c5 100644 --- a/nptl/pthread_setspecific.c +++ b/nptl/pthread_setspecific.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c index a39f3ca..752fd17 100644 --- a/nptl/pthread_sigmask.c +++ b/nptl/pthread_sigmask.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_sigqueue.c b/nptl/pthread_sigqueue.c index 9873ca1..cd7d8cc 100644 --- a/nptl/pthread_sigqueue.c +++ b/nptl/pthread_sigqueue.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2009-2024 Free Software Foundation, Inc. +/* Copyright (C) 2009-2025 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 diff --git a/nptl/pthread_spin_destroy.c b/nptl/pthread_spin_destroy.c index 42f1b83..cc098e9 100644 --- a/nptl/pthread_spin_destroy.c +++ b/nptl/pthread_spin_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_spin_init.c b/nptl/pthread_spin_init.c index 01a3d26..4dc53cc 100644 --- a/nptl/pthread_spin_init.c +++ b/nptl/pthread_spin_init.c @@ -1,5 +1,5 @@ /* pthread_spin_init -- initialize a spin lock. Generic version. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_spin_lock.c b/nptl/pthread_spin_lock.c index 4366fa3..0e49e3b 100644 --- a/nptl/pthread_spin_lock.c +++ b/nptl/pthread_spin_lock.c @@ -1,5 +1,5 @@ /* pthread_spin_lock -- lock a spin lock. Generic version. - Copyright (C) 2012-2024 Free Software Foundation, Inc. + Copyright (C) 2012-2025 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 diff --git a/nptl/pthread_spin_trylock.c b/nptl/pthread_spin_trylock.c index 5085e37..cb828e1 100644 --- a/nptl/pthread_spin_trylock.c +++ b/nptl/pthread_spin_trylock.c @@ -1,5 +1,5 @@ /* pthread_spin_trylock -- trylock a spin lock. Generic version. - Copyright (C) 2012-2024 Free Software Foundation, Inc. + Copyright (C) 2012-2025 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 diff --git a/nptl/pthread_spin_unlock.c b/nptl/pthread_spin_unlock.c index 65ca2f3..467b4f2 100644 --- a/nptl/pthread_spin_unlock.c +++ b/nptl/pthread_spin_unlock.c @@ -1,5 +1,5 @@ /* pthread_spin_unlock -- unlock a spin lock. Generic version. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/pthread_testcancel.c b/nptl/pthread_testcancel.c index a0197b5..a4e7199 100644 --- a/nptl/pthread_testcancel.c +++ b/nptl/pthread_testcancel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -25,10 +25,7 @@ ___pthread_testcancel (void) struct pthread *self = THREAD_SELF; int cancelhandling = atomic_load_relaxed (&self->cancelhandling); if (cancel_enabled_and_canceled (cancelhandling)) - { - self->result = PTHREAD_CANCELED; - __do_cancel (); - } + __do_cancel (PTHREAD_CANCELED); } versioned_symbol (libc, ___pthread_testcancel, pthread_testcancel, GLIBC_2_34); libc_hidden_ver (___pthread_testcancel, __pthread_testcancel) diff --git a/nptl/pthread_timedjoin.c b/nptl/pthread_timedjoin.c index 30c1402..691b69a 100644 --- a/nptl/pthread_timedjoin.c +++ b/nptl/pthread_timedjoin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_tryjoin.c b/nptl/pthread_tryjoin.c index 7e4ad5a..54b528f 100644 --- a/nptl/pthread_tryjoin.c +++ b/nptl/pthread_tryjoin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/pthread_yield.c b/nptl/pthread_yield.c index 3bd45e4..539e521 100644 --- a/nptl/pthread_yield.c +++ b/nptl/pthread_yield.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/sem_clockwait.c b/nptl/sem_clockwait.c index 39c8d1f..2756cc8 100644 --- a/nptl/sem_clockwait.c +++ b/nptl/sem_clockwait.c @@ -1,7 +1,7 @@ /* sem_clockwait -- wait on a semaphore with timeout using the specified clock. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/sem_destroy.c b/nptl/sem_destroy.c index 4a04b09..16a36d6 100644 --- a/nptl/sem_destroy.c +++ b/nptl/sem_destroy.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/sem_getvalue.c b/nptl/sem_getvalue.c index b2ccacf..53012f7 100644 --- a/nptl/sem_getvalue.c +++ b/nptl/sem_getvalue.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/sem_init.c b/nptl/sem_init.c index f9e7f2c..cf17411 100644 --- a/nptl/sem_init.c +++ b/nptl/sem_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/sem_post.c b/nptl/sem_post.c index 93228c2..659e931 100644 --- a/nptl/sem_post.c +++ b/nptl/sem_post.c @@ -1,5 +1,5 @@ /* sem_post -- post to a POSIX semaphore. Generic futex-using version. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c index ee59468..1ab1bec 100644 --- a/nptl/sem_timedwait.c +++ b/nptl/sem_timedwait.c @@ -1,5 +1,5 @@ /* sem_timedwait -- wait on a semaphore with timeout. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c index ddf9fe4..bc75ff1 100644 --- a/nptl/sem_wait.c +++ b/nptl/sem_wait.c @@ -1,5 +1,5 @@ /* sem_wait -- wait on a semaphore. Generic futex-using version. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c index 75fb26b..95450ee 100644 --- a/nptl/sem_waitcommon.c +++ b/nptl/sem_waitcommon.c @@ -1,5 +1,5 @@ /* sem_waitcommon -- wait on a semaphore, shared code. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/semaphoreP.h b/nptl/semaphoreP.h index 5fe32bd..39e0d15 100644 --- a/nptl/semaphoreP.h +++ b/nptl/semaphoreP.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. Ulrich Drepper <drepper@redhat.com>, 2002. diff --git a/nptl/test-cond-printers.c b/nptl/test-cond-printers.c index 7a6ebc0..147b5d9 100644 --- a/nptl/test-cond-printers.c +++ b/nptl/test-cond-printers.c @@ -1,6 +1,6 @@ /* Helper program for testing the pthread_cond_t pretty printer. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/test-cond-printers.py b/nptl/test-cond-printers.py index 6f740c5..b49600d 100644 --- a/nptl/test-cond-printers.py +++ b/nptl/test-cond-printers.py @@ -1,6 +1,6 @@ # Common tests for the ConditionVariablePrinter class. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/test-condattr-printers.c b/nptl/test-condattr-printers.c index d48feeb..bf9926a 100644 --- a/nptl/test-condattr-printers.c +++ b/nptl/test-condattr-printers.c @@ -1,7 +1,7 @@ /* Helper program for testing the pthread_cond_t and pthread_condattr_t pretty printers. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/test-condattr-printers.py b/nptl/test-condattr-printers.py index 66f4788..4b86346 100644 --- a/nptl/test-condattr-printers.py +++ b/nptl/test-condattr-printers.py @@ -1,7 +1,7 @@ # Common tests for the ConditionVariablePrinter and # ConditionVariableAttributesPrinter classes. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/test-mutex-printers.c b/nptl/test-mutex-printers.c index 55a4aba..7965ac0 100644 --- a/nptl/test-mutex-printers.c +++ b/nptl/test-mutex-printers.c @@ -1,6 +1,6 @@ /* Helper program for testing the pthread_mutex_t pretty printer. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/test-mutex-printers.py b/nptl/test-mutex-printers.py index fbbf7d9..1d38dfe 100644 --- a/nptl/test-mutex-printers.py +++ b/nptl/test-mutex-printers.py @@ -1,6 +1,6 @@ # Tests for the MutexPrinter class. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/test-mutexattr-printers.c b/nptl/test-mutexattr-printers.c index 2876d4c..e5985d7 100644 --- a/nptl/test-mutexattr-printers.c +++ b/nptl/test-mutexattr-printers.c @@ -1,7 +1,7 @@ /* Helper program for testing the pthread_mutex_t and pthread_mutexattr_t pretty printers. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/test-mutexattr-printers.py b/nptl/test-mutexattr-printers.py index cf64970..a5a636b 100644 --- a/nptl/test-mutexattr-printers.py +++ b/nptl/test-mutexattr-printers.py @@ -1,6 +1,6 @@ # Common tests for the MutexPrinter and MutexAttributesPrinter classes. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/test-rwlock-printers.c b/nptl/test-rwlock-printers.c index cfc6edb..96f61d4 100644 --- a/nptl/test-rwlock-printers.c +++ b/nptl/test-rwlock-printers.c @@ -1,6 +1,6 @@ /* Helper program for testing the pthread_rwlock_t pretty printer. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/test-rwlock-printers.py b/nptl/test-rwlock-printers.py index c47f3e2..51df7a9 100644 --- a/nptl/test-rwlock-printers.py +++ b/nptl/test-rwlock-printers.py @@ -1,6 +1,6 @@ # Common tests for the RWLockPrinter class. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/test-rwlockattr-printers.c b/nptl/test-rwlockattr-printers.c index c2787cb..9db73bb 100644 --- a/nptl/test-rwlockattr-printers.c +++ b/nptl/test-rwlockattr-printers.c @@ -1,7 +1,7 @@ /* Helper program for testing the pthread_rwlock_t and pthread_rwlockattr_t pretty printers. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/test-rwlockattr-printers.py b/nptl/test-rwlockattr-printers.py index 08d13c9..144b9f7 100644 --- a/nptl/test-rwlockattr-printers.py +++ b/nptl/test-rwlockattr-printers.py @@ -1,6 +1,6 @@ # Common tests for the RWLockPrinter and RWLockAttributesPrinter classes. # -# Copyright (C) 2016-2024 Free Software Foundation, Inc. +# Copyright (C) 2016-2025 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 diff --git a/nptl/thrd_current.c b/nptl/thrd_current.c index 9911ae9..1d2ea69 100644 --- a/nptl/thrd_current.c +++ b/nptl/thrd_current.c @@ -1,5 +1,5 @@ /* C11 threads current thread implementation. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/thrd_yield.c b/nptl/thrd_yield.c index 000e0ae..e74cf3b 100644 --- a/nptl/thrd_yield.c +++ b/nptl/thrd_yield.c @@ -1,5 +1,5 @@ /* C11 threads thread yield implementation. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 @@ -1,5 +1,5 @@ /* Thread Priority Protect helpers. - Copyright (C) 2006-2024 Free Software Foundation, Inc. + Copyright (C) 2006-2025 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 diff --git a/nptl/tst-attr2.c b/nptl/tst-attr2.c index 828a95a..475add1 100644 --- a/nptl/tst-attr2.c +++ b/nptl/tst-attr2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-attr3.c b/nptl/tst-attr3.c index 498b4f5..aec10b3 100644 --- a/nptl/tst-attr3.c +++ b/nptl/tst-attr3.c @@ -1,5 +1,5 @@ /* pthread_getattr_np test. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/tst-attr4.c b/nptl/tst-attr4.c new file mode 100644 index 0000000..9def411 --- /dev/null +++ b/nptl/tst-attr4.c @@ -0,0 +1,62 @@ +/* Test initial values of pthread attributes. + Copyright (C) 2024-2025 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 <sched.h> +#include <stdio.h> +#include <stdint.h> + +#include <support/check.h> +#include <support/test-driver.h> +#include <support/xthread.h> + + +int +do_test (void) +{ + pthread_attr_t a; + int ret; + + xpthread_attr_init (&a); + + size_t stacksize = 0; + verbose_printf ("testing default stack size\n"); + ret = pthread_attr_getstacksize (&a, &stacksize); + TEST_VERIFY_EXIT (ret == 0); + TEST_VERIFY (stacksize >= PTHREAD_STACK_MIN); + TEST_VERIFY (stacksize <= SIZE_MAX / 2); + + int policy; + verbose_printf ("testing default scheduler parameters\n"); + ret = pthread_attr_getschedpolicy (&a, &policy); + TEST_VERIFY_EXIT (ret == 0); + struct sched_param param; + ret = pthread_attr_getschedparam (&a, ¶m); + TEST_VERIFY_EXIT (ret == 0); + int min = sched_get_priority_min (policy); + TEST_VERIFY (min != -1); + int max = sched_get_priority_max (policy); + TEST_VERIFY (max != -1); + TEST_VERIFY (param.sched_priority >= min); + TEST_VERIFY (param.sched_priority <= max); + + xpthread_attr_destroy (&a); + + return 0; +} + +#include <support/test-driver.c> diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c index a962654..961b24b 100644 --- a/nptl/tst-audit-threads-mod1.c +++ b/nptl/tst-audit-threads-mod1.c @@ -1,6 +1,6 @@ /* Dummy audit library for test-audit-threads. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c index 0bb8c49..b36307d 100644 --- a/nptl/tst-audit-threads-mod2.c +++ b/nptl/tst-audit-threads-mod2.c @@ -1,6 +1,6 @@ /* Shared object with a huge number of functions for test-audit-threads. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c index 9fbad50..316867a 100644 --- a/nptl/tst-audit-threads.c +++ b/nptl/tst-audit-threads.c @@ -1,6 +1,6 @@ /* Test multi-threading using LD_AUDIT. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h index 71ef3aa..a3a6c03 100644 --- a/nptl/tst-audit-threads.h +++ b/nptl/tst-audit-threads.h @@ -1,6 +1,6 @@ /* Helper header for test-audit-threads. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-barrier5.c b/nptl/tst-barrier5.c index b34be71..364d111 100644 --- a/nptl/tst-barrier5.c +++ b/nptl/tst-barrier5.c @@ -1,5 +1,5 @@ /* This tests the barrier reset mechanism. - Copyright (C) 2004-2024 Free Software Foundation, Inc. + Copyright (C) 2004-2025 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 diff --git a/nptl/tst-cancel17.c b/nptl/tst-cancel17.c index b456450..a091e56 100644 --- a/nptl/tst-cancel17.c +++ b/nptl/tst-cancel17.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-cancel31.c b/nptl/tst-cancel31.c new file mode 100644 index 0000000..23fdf38 --- /dev/null +++ b/nptl/tst-cancel31.c @@ -0,0 +1,100 @@ +/* Verify side-effects of cancellable syscalls (BZ #12683). + Copyright (C) 2023-2025 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/>. */ + +/* This testcase checks if there is resource leakage if the syscall has + returned from kernelspace, but before userspace saves the return + value. The 'leaker' thread should be able to close the file descriptor + if the resource is already allocated, meaning that if the cancellation + signal arrives *after* the open syscal return from kernel, the + side-effect should be visible to application. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> + +#include <support/xunistd.h> +#include <support/xthread.h> +#include <support/check.h> +#include <support/temp_file.h> +#include <support/support.h> +#include <support/descriptors.h> + +static void * +writeopener (void *arg) +{ + int fd; + for (;;) + { + fd = open (arg, O_WRONLY); + xclose (fd); + } + return NULL; +} + +static void * +leaker (void *arg) +{ + int fd = open (arg, O_RDONLY); + TEST_VERIFY_EXIT (fd > 0); + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0); + xclose (fd); + return NULL; +} + +static int +do_test (void) +{ + enum { + iter_count = 1000 + }; + + char *dir = support_create_temp_directory ("tst-cancel28"); + char *name = xasprintf ("%s/fifo", dir); + TEST_COMPARE (mkfifo (name, 0600), 0); + add_temp_file (name); + + struct support_descriptors *descrs = support_descriptors_list (); + + srand (1); + + xpthread_create (NULL, writeopener, name); + for (int i = 0; i < iter_count; i++) + { + pthread_t td = xpthread_create (NULL, leaker, name); + struct timespec ts = + { .tv_nsec = rand () % 100000, .tv_sec = 0 }; + nanosleep (&ts, NULL); + /* Ignore pthread_cancel result because it might be the + case when pthread_cancel is called when thread is already + exited. */ + pthread_cancel (td); + xpthread_join (td); + } + + support_descriptors_check (descrs); + + support_descriptors_free (descrs); + + free (name); + + return 0; +} + +#include <support/test-driver.c> diff --git a/nptl/tst-cancel4_1.c b/nptl/tst-cancel4_1.c index 7275551..62a7b0f 100644 --- a/nptl/tst-cancel4_1.c +++ b/nptl/tst-cancel4_1.c @@ -1,6 +1,6 @@ /* Check sendmmsg cancellation. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/tst-cancel4_2.c b/nptl/tst-cancel4_2.c index 8c8ba92..ea94f18 100644 --- a/nptl/tst-cancel4_2.c +++ b/nptl/tst-cancel4_2.c @@ -1,6 +1,6 @@ /* Check recvmmsg cancellation. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/tst-cancel7.c b/nptl/tst-cancel7.c index d2350bd..5628c99 100644 --- a/nptl/tst-cancel7.c +++ b/nptl/tst-cancel7.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 @@ -38,6 +38,8 @@ static char *semfilename; static sem_t *sem; +static void do_cleanup (void); + static void * tf (void *arg) { @@ -57,9 +59,6 @@ sl (void) fprintf (f, "%lld\n", (long long) getpid ()); fflush (f); - if (sem_post (sem) != 0) - FAIL_EXIT1 ("sem_post: %m"); - struct flock fl = { .l_type = F_WRLCK, @@ -70,6 +69,9 @@ sl (void) if (fcntl (fileno (f), F_SETLK, &fl) != 0) FAIL_EXIT1 ("fcntl (F_SETFL): %m"); + if (sem_post (sem) != 0) + FAIL_EXIT1 ("sem_post: %m"); + sigset_t ss; sigfillset (&ss); sigsuspend (&ss); @@ -108,6 +110,8 @@ do_prepare (int argc, char *argv[]) xwrite (fd, " ", 1); xclose (fd); + + atexit (do_cleanup); } @@ -116,7 +120,7 @@ do_test (void) { pthread_t th = xpthread_create (NULL, tf, NULL); - /* Wait to cancel until after the pid is written. */ + /* Wait to cancel until after the pid is written and file locked. */ if (sem_wait (sem) != 0) FAIL_EXIT1 ("sem_wait: %m"); diff --git a/nptl/tst-cleanup4.c b/nptl/tst-cleanup4.c index 7ac53e4..14c2581 100644 --- a/nptl/tst-cleanup4.c +++ b/nptl/tst-cleanup4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-cleanup4aux.c b/nptl/tst-cleanup4aux.c index 8f08488..7103219 100644 --- a/nptl/tst-cleanup4aux.c +++ b/nptl/tst-cleanup4aux.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-clock2.c b/nptl/tst-clock2.c index 9b49e2d..336d457 100644 --- a/nptl/tst-clock2.c +++ b/nptl/tst-clock2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-compat-forwarder-mod.c b/nptl/tst-compat-forwarder-mod.c index 41a77fd..c119258 100644 --- a/nptl/tst-compat-forwarder-mod.c +++ b/nptl/tst-compat-forwarder-mod.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2024 Free Software Foundation, Inc. +/* Copyright (C) 2017-2025 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 diff --git a/nptl/tst-compat-forwarder.c b/nptl/tst-compat-forwarder.c index 3ecc59d..fe4f296 100644 --- a/nptl/tst-compat-forwarder.c +++ b/nptl/tst-compat-forwarder.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2024 Free Software Foundation, Inc. +/* Copyright (C) 2017-2025 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 diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c index 1336e9c..bdcb45c 100644 --- a/nptl/tst-cond22.c +++ b/nptl/tst-cond22.c @@ -106,13 +106,13 @@ do_test (void) status = 1; } - printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n", + printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n", c.__data.__wseq.__value32.__high, c.__data.__wseq.__value32.__low, c.__data.__g1_start.__value32.__high, c.__data.__g1_start.__value32.__low, - c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0], - c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1], + c.__data.__g_signals[0], c.__data.__g_size[0], + c.__data.__g_signals[1], c.__data.__g_size[1], c.__data.__g1_orig_size, c.__data.__wrefs); if (pthread_create (&th, NULL, tf, (void *) 1l) != 0) @@ -152,13 +152,13 @@ do_test (void) status = 1; } - printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n", + printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n", c.__data.__wseq.__value32.__high, c.__data.__wseq.__value32.__low, c.__data.__g1_start.__value32.__high, c.__data.__g1_start.__value32.__low, - c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0], - c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1], + c.__data.__g_signals[0], c.__data.__g_size[0], + c.__data.__g_signals[1], c.__data.__g_size[1], c.__data.__g1_orig_size, c.__data.__wrefs); return status; diff --git a/nptl/tst-cond26.c b/nptl/tst-cond26.c index 7df0c33..911b64c 100644 --- a/nptl/tst-cond26.c +++ b/nptl/tst-cond26.c @@ -1,6 +1,6 @@ /* Test unsupported/bad clocks passed to pthread_cond_clockwait. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/tst-context1.c b/nptl/tst-context1.c index 943d8db..f1cb84b 100644 --- a/nptl/tst-context1.c +++ b/nptl/tst-context1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-default-attr.c b/nptl/tst-default-attr.c index d7b9e8f..f78cd77 100644 --- a/nptl/tst-default-attr.c +++ b/nptl/tst-default-attr.c @@ -1,6 +1,6 @@ /* Verify that pthread_[gs]etattr_default_np work correctly. - Copyright (C) 2013-2024 Free Software Foundation, Inc. + Copyright (C) 2013-2025 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 diff --git a/nptl/tst-eintr1.c b/nptl/tst-eintr1.c index d1c1511..d1e16ee 100644 --- a/nptl/tst-eintr1.c +++ b/nptl/tst-eintr1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-exec4.c b/nptl/tst-exec4.c index b9ec4c9..90e63bb 100644 --- a/nptl/tst-exec4.c +++ b/nptl/tst-exec4.c @@ -1,5 +1,5 @@ /* Signal handler and mask set in thread which calls exec. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 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 diff --git a/nptl/tst-exec5.c b/nptl/tst-exec5.c index e96c1dc..ed138f0 100644 --- a/nptl/tst-exec5.c +++ b/nptl/tst-exec5.c @@ -1,5 +1,5 @@ /* Check if posix_spawn does not act as a cancellation entrypoint. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/tst-guard1.c b/nptl/tst-guard1.c new file mode 100644 index 0000000..e3e06df --- /dev/null +++ b/nptl/tst-guard1.c @@ -0,0 +1,369 @@ +/* Basic tests for pthread guard area. + Copyright (C) 2025 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 <array_length.h> +#include <pthreaddef.h> +#include <setjmp.h> +#include <stackinfo.h> +#include <stdio.h> +#include <support/check.h> +#include <support/test-driver.h> +#include <support/xsignal.h> +#include <support/xthread.h> +#include <support/xunistd.h> +#include <sys/mman.h> +#include <stdlib.h> + +static long int pagesz; + +/* To check if the guard region is inaccessible, the thread tries read/writes + on it and checks if a SIGSEGV is generated. */ + +static volatile sig_atomic_t signal_jump_set; +static sigjmp_buf signal_jmp_buf; + +static void +sigsegv_handler (int sig) +{ + if (signal_jump_set == 0) + return; + + siglongjmp (signal_jmp_buf, sig); +} + +static bool +try_access_buf (char *ptr, bool write) +{ + signal_jump_set = true; + + bool failed = sigsetjmp (signal_jmp_buf, 0) != 0; + if (!failed) + { + if (write) + *(volatile char *)(ptr) = 'x'; + else + *(volatile char *)(ptr); + } + + signal_jump_set = false; + return !failed; +} + +static bool +try_read_buf (char *ptr) +{ + return try_access_buf (ptr, false); +} + +static bool +try_write_buf (char *ptr) +{ + return try_access_buf (ptr, true); +} + +static bool +try_read_write_buf (char *ptr) +{ + return try_read_buf (ptr) && try_write_buf(ptr); +} + + +/* Return the guard region of the current thread (it only makes sense on + a thread created by pthread_created). */ + +struct stack_t +{ + char *stack; + size_t stacksize; + char *guard; + size_t guardsize; +}; + +static inline size_t +adjust_stacksize (size_t stacksize) +{ + /* For some ABIs, The guard page depends of the thread descriptor, which in + turn rely on the require static TLS. The only supported _STACK_GROWS_UP + ABI, hppa, defines TLS_DTV_AT_TP and it is not straightforward to + calculate the guard region with current pthread APIs. So to get a + correct stack size assumes an extra page after the guard area. */ +#if _STACK_GROWS_DOWN + return stacksize; +#elif _STACK_GROWS_UP + return stacksize - pagesz; +#endif +} + +struct stack_t +get_current_stack_info (void) +{ + pthread_attr_t attr; + TEST_VERIFY_EXIT (pthread_getattr_np (pthread_self (), &attr) == 0); + void *stack; + size_t stacksize; + TEST_VERIFY_EXIT (pthread_attr_getstack (&attr, &stack, &stacksize) == 0); + size_t guardsize; + TEST_VERIFY_EXIT (pthread_attr_getguardsize (&attr, &guardsize) == 0); + /* The guardsize is reported as the current page size, although it might + be adjusted to a larger value (aarch64 for instance). */ + if (guardsize != 0 && guardsize < ARCH_MIN_GUARD_SIZE) + guardsize = ARCH_MIN_GUARD_SIZE; + +#if _STACK_GROWS_DOWN + void *guard = guardsize ? stack - guardsize : 0; +#elif _STACK_GROWS_UP + stacksize = adjust_stacksize (stacksize); + void *guard = guardsize ? stack + stacksize : 0; +#endif + + pthread_attr_destroy (&attr); + + return (struct stack_t) { stack, stacksize, guard, guardsize }; +} + +struct thread_args_t +{ + size_t stacksize; + size_t guardsize; +}; + +struct thread_args_t +get_thread_args (const pthread_attr_t *attr) +{ + size_t stacksize; + size_t guardsize; + + TEST_COMPARE (pthread_attr_getstacksize (attr, &stacksize), 0); + TEST_COMPARE (pthread_attr_getguardsize (attr, &guardsize), 0); + if (guardsize < ARCH_MIN_GUARD_SIZE) + guardsize = ARCH_MIN_GUARD_SIZE; + + return (struct thread_args_t) { stacksize, guardsize }; +} + +static void +set_thread_args (pthread_attr_t *attr, const struct thread_args_t *args) +{ + xpthread_attr_setstacksize (attr, args->stacksize); + xpthread_attr_setguardsize (attr, args->guardsize); +} + +static void * +tf (void *closure) +{ + struct thread_args_t *args = closure; + + struct stack_t s = get_current_stack_info (); + if (test_verbose) + printf ("debug: [tid=%jd] stack = { .stack=%p, stacksize=%#zx, guard=%p, " + "guardsize=%#zx }\n", + (intmax_t) gettid (), + s.stack, + s.stacksize, + s.guard, + s.guardsize); + + if (args != NULL) + { + TEST_COMPARE (adjust_stacksize (args->stacksize), s.stacksize); + TEST_COMPARE (args->guardsize, s.guardsize); + } + + /* Ensure we can access the stack area. */ + TEST_COMPARE (try_read_buf (s.stack), true); + TEST_COMPARE (try_read_buf (&s.stack[s.stacksize / 2]), true); + TEST_COMPARE (try_read_buf (&s.stack[s.stacksize - 1]), true); + + /* Check if accessing the guard area results in SIGSEGV. */ + if (s.guardsize > 0) + { + TEST_COMPARE (try_read_write_buf (s.guard), false); + TEST_COMPARE (try_read_write_buf (&s.guard[s.guardsize / 2]), false); + TEST_COMPARE (try_read_write_buf (&s.guard[s.guardsize] - 1), false); + } + + return NULL; +} + +/* Test 1: caller provided stack without guard. */ +static void +do_test1 (void) +{ + pthread_attr_t attr; + xpthread_attr_init (&attr); + + size_t stacksize = support_small_thread_stack_size (); + void *stack = xmmap (0, + stacksize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, + -1); + xpthread_attr_setstack (&attr, stack, stacksize); + xpthread_attr_setguardsize (&attr, 0); + + struct thread_args_t args = { stacksize, 0 }; + pthread_t t = xpthread_create (&attr, tf, &args); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); + + xpthread_attr_destroy (&attr); + xmunmap (stack, stacksize); +} + +/* Test 2: same as 1., but with a guard area. */ +static void +do_test2 (void) +{ + pthread_attr_t attr; + xpthread_attr_init (&attr); + + size_t stacksize = support_small_thread_stack_size (); + void *stack = xmmap (0, + stacksize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, + -1); + xpthread_attr_setstack (&attr, stack, stacksize); + xpthread_attr_setguardsize (&attr, pagesz); + + struct thread_args_t args = { stacksize, 0 }; + pthread_t t = xpthread_create (&attr, tf, &args); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); + + xpthread_attr_destroy (&attr); + xmunmap (stack, stacksize); +} + +/* Test 3: pthread_create with default values. */ +static void +do_test3 (void) +{ + pthread_t t = xpthread_create (NULL, tf, NULL); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); +} + +/* Test 4: pthread_create without a guard area. */ +static void +do_test4 (void) +{ + pthread_attr_t attr; + xpthread_attr_init (&attr); + struct thread_args_t args = get_thread_args (&attr); + args.stacksize += args.guardsize; + args.guardsize = 0; + set_thread_args (&attr, &args); + + pthread_t t = xpthread_create (&attr, tf, &args); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); + + xpthread_attr_destroy (&attr); +} + +/* Test 5: pthread_create with non default stack and guard size value. */ +static void +do_test5 (void) +{ + pthread_attr_t attr; + xpthread_attr_init (&attr); + struct thread_args_t args = get_thread_args (&attr); + args.guardsize += pagesz; + args.stacksize += pagesz; + set_thread_args (&attr, &args); + + pthread_t t = xpthread_create (&attr, tf, &args); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); + + xpthread_attr_destroy (&attr); +} + +/* Test 6: thread with the required size (stack + guard) that matches the + test 3, but with a larger guard area. The pthread_create will need to + increase the guard area. */ +static void +do_test6 (void) +{ + pthread_attr_t attr; + xpthread_attr_init (&attr); + struct thread_args_t args = get_thread_args (&attr); + args.guardsize += pagesz; + args.stacksize -= pagesz; + set_thread_args (&attr, &args); + + pthread_t t = xpthread_create (&attr, tf, &args); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); + + xpthread_attr_destroy (&attr); +} + +/* Test 7: pthread_create with default values, the requires size matches the + one from test 3 and 6 (but with a reduced guard ares). The + pthread_create should use the cached stack from previous tests, but it + would require to reduce the guard area. */ +static void +do_test7 (void) +{ + pthread_t t = xpthread_create (NULL, tf, NULL); + void *status = xpthread_join (t); + TEST_VERIFY (status == 0); +} + +static int +do_test (void) +{ + pagesz = sysconf (_SC_PAGESIZE); + + { + struct sigaction sa = { + .sa_handler = sigsegv_handler, + .sa_flags = SA_NODEFER, + }; + sigemptyset (&sa.sa_mask); + xsigaction (SIGSEGV, &sa, NULL); + /* Some system generates SIGBUS accessing the guard area when it is + setup with madvise. */ + xsigaction (SIGBUS, &sa, NULL); + } + + static const struct { + const char *descr; + void (*test)(void); + } tests[] = { + { "user provided stack without guard", do_test1 }, + { "user provided stack with guard", do_test2 }, + { "default attribute", do_test3 }, + { "default attribute without guard", do_test4 }, + { "non default stack and guard sizes", do_test5 }, + { "reused stack with larger guard", do_test6 }, + { "reused stack with smaller guard", do_test7 }, + }; + + for (int i = 0; i < array_length (tests); i++) + { + printf ("debug: test%01d: %s\n", i, tests[i].descr); + tests[i].test(); + } + + return 0; +} + +#include <support/test-driver.c> diff --git a/nptl/tst-initializers1.c b/nptl/tst-initializers1.c index ac37592..1b0c1ab 100644 --- a/nptl/tst-initializers1.c +++ b/nptl/tst-initializers1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2024 Free Software Foundation, Inc. +/* Copyright (C) 2005-2025 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 diff --git a/nptl/tst-minstack-cancel.c b/nptl/tst-minstack-cancel.c index 8a6dc77..446854f 100644 --- a/nptl/tst-minstack-cancel.c +++ b/nptl/tst-minstack-cancel.c @@ -1,5 +1,5 @@ /* Test cancellation with a minimal stack size. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-minstack-exit.c b/nptl/tst-minstack-exit.c index e1f42da..596337e 100644 --- a/nptl/tst-minstack-exit.c +++ b/nptl/tst-minstack-exit.c @@ -1,5 +1,5 @@ /* Test that pthread_exit works with the minimum stack size. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-minstack-throw.cc b/nptl/tst-minstack-throw.cc index b729091..b772185 100644 --- a/nptl/tst-minstack-throw.cc +++ b/nptl/tst-minstack-throw.cc @@ -1,5 +1,5 @@ /* Test that throwing C++ exceptions works with the minimum stack size. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 @@ -24,7 +24,7 @@ #include <support/xthread.h> /* Throw a std::runtime_exception. */ -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void do_throw_exception () { @@ -38,17 +38,17 @@ struct class_with_destructor ~class_with_destructor (); }; -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ class_with_destructor::class_with_destructor () { } -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ class_with_destructor::~class_with_destructor () { } -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void function_with_destructed_object () { diff --git a/nptl/tst-mutex8.c b/nptl/tst-mutex8.c index be38e11..0d9066a 100644 --- a/nptl/tst-mutex8.c +++ b/nptl/tst-mutex8.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-mutexpi10.c b/nptl/tst-mutexpi10.c index 9554512..6d2bbbb 100644 --- a/nptl/tst-mutexpi10.c +++ b/nptl/tst-mutexpi10.c @@ -1,6 +1,6 @@ /* Check if pthread_mutex_clocklock with PRIO_INHERIT fails with clock different than CLOCK_REALTIME. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/tst-mutexpp10.c b/nptl/tst-mutexpp10.c index b074d33..8fcb99d 100644 --- a/nptl/tst-mutexpp10.c +++ b/nptl/tst-mutexpp10.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006-2024 Free Software Foundation, Inc. +/* Copyright (C) 2006-2025 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 diff --git a/nptl/tst-oddstacklimit.c b/nptl/tst-oddstacklimit.c index 089bf76..4d37309 100644 --- a/nptl/tst-oddstacklimit.c +++ b/nptl/tst-oddstacklimit.c @@ -1,5 +1,5 @@ /* Test NPTL with stack limit that is not a multiple of the page size. - Copyright (C) 2012-2024 Free Software Foundation, Inc. + Copyright (C) 2012-2025 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 diff --git a/nptl/tst-once5.cc b/nptl/tst-once5.cc index 31f948c..8c1aeed 100644 --- a/nptl/tst-once5.cc +++ b/nptl/tst-once5.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Free Software Foundation, Inc. +/* Copyright (C) 2015-2025 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 diff --git a/nptl/tst-pthread-affinity-inheritance.c b/nptl/tst-pthread-affinity-inheritance.c new file mode 100644 index 0000000..153fc90 --- /dev/null +++ b/nptl/tst-pthread-affinity-inheritance.c @@ -0,0 +1,72 @@ +/* CPU Affinity inheritance test - pthread_{gs}etaffinity_np. + Copyright The GNU Toolchain Authors. + 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/>. */ + +/* See top level comment in nptl/tst-skeleton-affinity-inheritance.c for a + description of this test. */ +#include <pthread.h> +#include <sched.h> +#include <stdio.h> +#include <string.h> +#include <support/check.h> + +static void +set_my_affinity (size_t size, const cpu_set_t *set) +{ + int ret = pthread_setaffinity_np (pthread_self (), size, set); + + if (ret != 0) + FAIL ("pthread_setaffinity_np returned %d (%s)", ret, strerror (ret)); +} + +static void +verify_my_affinity (int nproc, int nproc_configured, size_t size, + const cpu_set_t *expected_set) +{ + cpu_set_t *set = CPU_ALLOC (nproc_configured); + cpu_set_t *xor_set = CPU_ALLOC (nproc_configured); + + if (set == NULL || xor_set== NULL) + FAIL_EXIT1 ("verify_my_affinity: Failed to allocate cpuset: %m\n"); + + int ret = pthread_getaffinity_np (pthread_self (), size, set); + if (ret != 0) + FAIL ("pthread_getaffinity_np returned %d (%s)", ret, strerror (ret)); + + CPU_XOR_S (size, xor_set, expected_set, set); + + int cpucount = CPU_COUNT_S (size, xor_set); + + if (cpucount > 0) + { + FAIL ("Affinity mask not inherited, " + "following %d CPUs mismatched in the expected and actual sets: ", + cpucount); + for (int cur = 0; cur < nproc && cpucount >= 0; cur++) + if (CPU_ISSET_S (size, cur, xor_set)) + { + printf ("%d ", cur); + cpucount--; + } + printf ("\n"); + } + + CPU_FREE (set); + CPU_FREE (xor_set); +} + +#include "tst-skeleton-affinity-inheritance.c" diff --git a/nptl/tst-pthread-attr-affinity-fail.c b/nptl/tst-pthread-attr-affinity-fail.c index 9e32200..192cc04 100644 --- a/nptl/tst-pthread-attr-affinity-fail.c +++ b/nptl/tst-pthread-attr-affinity-fail.c @@ -1,6 +1,6 @@ /* Check if invalid pthread_attr_getaffinity_np does not run any code in the thread function. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/tst-pthread-attr-affinity.c b/nptl/tst-pthread-attr-affinity.c index 6cede30..425e42c 100644 --- a/nptl/tst-pthread-attr-affinity.c +++ b/nptl/tst-pthread-attr-affinity.c @@ -1,7 +1,7 @@ /* Make sure that pthread_attr_getaffinity_np does not crash when the input cpuset size is smaller than that in the attribute structure. - Copyright (C) 2013-2024 Free Software Foundation, Inc. + Copyright (C) 2013-2025 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 diff --git a/nptl/tst-pthread-attr-sigmask.c b/nptl/tst-pthread-attr-sigmask.c index 958738f..9ec64ff 100644 --- a/nptl/tst-pthread-attr-sigmask.c +++ b/nptl/tst-pthread-attr-sigmask.c @@ -1,5 +1,5 @@ /* Tests for pthread_attr_setsigmask_np, pthread_attr_getsigmask_np. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/tst-pthread-defaultattr-free.c b/nptl/tst-pthread-defaultattr-free.c index 9c53816..304ad38 100644 --- a/nptl/tst-pthread-defaultattr-free.c +++ b/nptl/tst-pthread-defaultattr-free.c @@ -1,5 +1,5 @@ /* Test for user-after-free bug in pthread_getattr_default_np (bug 25999). - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/tst-pthread-gdb-attach.c b/nptl/tst-pthread-gdb-attach.c index e0a2a2b..8971b6d 100644 --- a/nptl/tst-pthread-gdb-attach.c +++ b/nptl/tst-pthread-gdb-attach.c @@ -1,5 +1,5 @@ /* Smoke testing GDB process attach with thread-local variable access. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/tst-pthread-getattr.c b/nptl/tst-pthread-getattr.c index 8283198..0ce6002 100644 --- a/nptl/tst-pthread-getattr.c +++ b/nptl/tst-pthread-getattr.c @@ -1,7 +1,7 @@ /* Make sure that the stackaddr returned by pthread_getattr_np is reachable. - Copyright (C) 2012-2024 Free Software Foundation, Inc. + Copyright (C) 2012-2025 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 diff --git a/nptl/tst-pthread-getcpuclockid-invalid.c b/nptl/tst-pthread-getcpuclockid-invalid.c new file mode 100644 index 0000000..7ac46ac --- /dev/null +++ b/nptl/tst-pthread-getcpuclockid-invalid.c @@ -0,0 +1,55 @@ +/* pthread_getcpuclockid should fail with ESRCH when the thread exits. + Copyright the GNU Toolchain Authors. + 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/>. */ + +/* The input thread descriptor to pthread_getcpuclockid needs to be valid when + the function is called. For the purposes of this test, this means that the + thread should not be detached, have exited, but not joined. This should be + good enough to complete coverage for pthread_getcpuclockid alongside + tst-clock2. */ + +#include <errno.h> +#include <pthread.h> +#include <sched.h> +#include <time.h> + +#include <support/check.h> +#include <support/test-driver.h> +#include <support/xthread.h> + +void * +thr (void *in) +{ + return in; +} + +int +do_test (void) +{ + clockid_t c; + pthread_t t = xpthread_create (NULL, thr, NULL); + + int ret = 0; + while ((ret = pthread_getcpuclockid (t, &c)) == 0) + sched_yield (); + + TEST_COMPARE (ret, ESRCH); + + return 0; +} + +#include <support/test-driver.c> diff --git a/nptl/tst-pthread-key1-static.c b/nptl/tst-pthread-key1-static.c index 9cf93c7..226895a 100644 --- a/nptl/tst-pthread-key1-static.c +++ b/nptl/tst-pthread-key1-static.c @@ -1,5 +1,5 @@ /* Verify that static pthread executable works. - Copyright (C) 2024 Free Software Foundation, Inc. + Copyright (C) 2024-2025 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 diff --git a/nptl/tst-pthread-timedlock-lockloop.c b/nptl/tst-pthread-timedlock-lockloop.c index b7d9c52..48cfafc 100644 --- a/nptl/tst-pthread-timedlock-lockloop.c +++ b/nptl/tst-pthread-timedlock-lockloop.c @@ -1,6 +1,6 @@ /* Make sure pthread_mutex_timedlock doesn't return spurious error codes. - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/tst-pthread_exit-nothreads-static.c b/nptl/tst-pthread_exit-nothreads-static.c index e67f4a7..47a3c31 100644 --- a/nptl/tst-pthread_exit-nothreads-static.c +++ b/nptl/tst-pthread_exit-nothreads-static.c @@ -1,5 +1,5 @@ /* Check that pthread_exit works if there are no threads. Static version. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/tst-pthread_exit-nothreads.c b/nptl/tst-pthread_exit-nothreads.c index 1c3a677..712d2c5 100644 --- a/nptl/tst-pthread_exit-nothreads.c +++ b/nptl/tst-pthread_exit-nothreads.c @@ -1,5 +1,5 @@ /* Check that pthread_exit works if there are no threads. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 diff --git a/nptl/tst-pthread_gettid_np.c b/nptl/tst-pthread_gettid_np.c new file mode 100644 index 0000000..ced4291 --- /dev/null +++ b/nptl/tst-pthread_gettid_np.c @@ -0,0 +1,80 @@ +/* Test for pthread_gettid_np. + Copyright (C) 2025 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; see the file COPYING.LIB. If + not, see <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <stdbool.h> +#include <support/check.h> +#include <support/xthread.h> +#include <unistd.h> + +static pthread_barrier_t barrier; + +static pid_t thread_tid; + +static void * +thread_func (void *ignored) +{ + thread_tid = gettid (); + TEST_VERIFY (thread_tid != getpid ()); + TEST_COMPARE (thread_tid, pthread_gettid_np (pthread_self ())); + xpthread_barrier_wait (&barrier); + /* The main thread calls pthread_gettid_np here. */ + xpthread_barrier_wait (&barrier); + return NULL; +} + +static int +do_test (void) +{ + TEST_COMPARE (pthread_gettid_np (pthread_self ()), getpid ()); + TEST_COMPARE (pthread_gettid_np (pthread_self ()), gettid ()); + + xpthread_barrier_init (&barrier, NULL, 2); + + pthread_t thr = xpthread_create (NULL, thread_func, NULL); + xpthread_barrier_wait (&barrier); + TEST_COMPARE (thread_tid, pthread_gettid_np (thr)); + xpthread_barrier_wait (&barrier); + + while (true) + { + /* Check if the kernel thread is still running. */ + if (tgkill (getpid (), thread_tid, 0)) + { + TEST_COMPARE (errno, ESRCH); + break; + } + + pid_t tid = pthread_gettid_np (thr); + if (tid != thread_tid) + { + TEST_COMPARE (tid, -1); + break; + } + TEST_COMPARE (sched_yield (), 0); + } + + TEST_VERIFY (xpthread_join (thr) == NULL); + + return 0; +} + +#include <support/test-driver.c> diff --git a/nptl/tst-robust-fork.c b/nptl/tst-robust-fork.c index c1a1ec6..8144b3d 100644 --- a/nptl/tst-robust-fork.c +++ b/nptl/tst-robust-fork.c @@ -1,5 +1,5 @@ /* Test the interaction of fork and robust mutexes. - Copyright (C) 2017-2024 Free Software Foundation, Inc. + Copyright (C) 2017-2025 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 diff --git a/nptl/tst-rwlock-pwn.c b/nptl/tst-rwlock-pwn.c index 6f16fb8..92dd206 100644 --- a/nptl/tst-rwlock-pwn.c +++ b/nptl/tst-rwlock-pwn.c @@ -1,5 +1,5 @@ /* Test rwlock with PREFER_WRITER_NONRECURSIVE_NP (bug 23861). - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 diff --git a/nptl/tst-rwlock10.c b/nptl/tst-rwlock10.c index cb8bf89..dc00d2a 100644 --- a/nptl/tst-rwlock10.c +++ b/nptl/tst-rwlock10.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock11.c b/nptl/tst-rwlock11.c index 6efcad9..6733acb 100644 --- a/nptl/tst-rwlock11.c +++ b/nptl/tst-rwlock11.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2003-2024 Free Software Foundation, Inc. + Copyright (C) 2003-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock15.c b/nptl/tst-rwlock15.c index f20ea8b..99c7714 100644 --- a/nptl/tst-rwlock15.c +++ b/nptl/tst-rwlock15.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2024 Free Software Foundation, Inc. +/* Copyright (C) 2015-2025 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 diff --git a/nptl/tst-rwlock17.c b/nptl/tst-rwlock17.c index e99b596..db73b9b 100644 --- a/nptl/tst-rwlock17.c +++ b/nptl/tst-rwlock17.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock18.c b/nptl/tst-rwlock18.c index 3654a2f..6b7ce0a 100644 --- a/nptl/tst-rwlock18.c +++ b/nptl/tst-rwlock18.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock19.c b/nptl/tst-rwlock19.c index 343798a..bc7bfc9 100644 --- a/nptl/tst-rwlock19.c +++ b/nptl/tst-rwlock19.c @@ -1,5 +1,5 @@ /* Test rdlock overflow. - Copyright (C) 2000-2024 Free Software Foundation, Inc. + Copyright (C) 2000-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock2.c b/nptl/tst-rwlock2.c index ca45e90..c9a0a26 100644 --- a/nptl/tst-rwlock2.c +++ b/nptl/tst-rwlock2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/tst-rwlock20.c b/nptl/tst-rwlock20.c index 26e4992..fff3786 100644 --- a/nptl/tst-rwlock20.c +++ b/nptl/tst-rwlock20.c @@ -1,5 +1,5 @@ /* Test program for a read-phase / write-phase explicit hand-over. - Copyright (C) 2017-2024 Free Software Foundation, Inc. + Copyright (C) 2017-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock3.c b/nptl/tst-rwlock3.c index c82d571..3ef8940 100644 --- a/nptl/tst-rwlock3.c +++ b/nptl/tst-rwlock3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/tst-rwlock6.c b/nptl/tst-rwlock6.c index 73f00d6..5a8edd6 100644 --- a/nptl/tst-rwlock6.c +++ b/nptl/tst-rwlock6.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/tst-rwlock7.c b/nptl/tst-rwlock7.c index b74974f..faa5640 100644 --- a/nptl/tst-rwlock7.c +++ b/nptl/tst-rwlock7.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/tst-rwlock8.c b/nptl/tst-rwlock8.c index 31c4472..1ab6c47 100644 --- a/nptl/tst-rwlock8.c +++ b/nptl/tst-rwlock8.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2000-2024 Free Software Foundation, Inc. + Copyright (C) 2000-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-rwlock9.c b/nptl/tst-rwlock9.c index e4a522d..161bcdf 100644 --- a/nptl/tst-rwlock9.c +++ b/nptl/tst-rwlock9.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2000-2024 Free Software Foundation, Inc. + Copyright (C) 2000-2025 Free Software Foundation, Inc. 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 diff --git a/nptl/tst-sched1.c b/nptl/tst-sched1.c index 726e50f..f04334e 100644 --- a/nptl/tst-sched1.c +++ b/nptl/tst-sched1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-sem11.c b/nptl/tst-sem11.c index a82bb73..872cead 100644 --- a/nptl/tst-sem11.c +++ b/nptl/tst-sem11.c @@ -1,5 +1,5 @@ /* Test of semaphores. - Copyright (C) 2007-2024 Free Software Foundation, Inc. + Copyright (C) 2007-2025 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 diff --git a/nptl/tst-sem12.c b/nptl/tst-sem12.c index d4e22d9..2c69f12 100644 --- a/nptl/tst-sem12.c +++ b/nptl/tst-sem12.c @@ -1,5 +1,5 @@ /* Test of semaphores. - Copyright (C) 2007-2024 Free Software Foundation, Inc. + Copyright (C) 2007-2025 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 diff --git a/nptl/tst-sem17.c b/nptl/tst-sem17.c index 9c2ca68..7177f59 100644 --- a/nptl/tst-sem17.c +++ b/nptl/tst-sem17.c @@ -1,6 +1,6 @@ /* Test unsupported/bad clocks passed to sem_clockwait. - Copyright (C) 2019-2024 Free Software Foundation, Inc. + Copyright (C) 2019-2025 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 diff --git a/nptl/tst-setgetname.c b/nptl/tst-setgetname.c index f805286..5199645 100644 --- a/nptl/tst-setgetname.c +++ b/nptl/tst-setgetname.c @@ -1,5 +1,5 @@ /* Test pthread_setname_np and pthread_getname_np. - Copyright (C) 2013-2024 Free Software Foundation, Inc. + Copyright (C) 2013-2025 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 diff --git a/nptl/tst-setgroups.c b/nptl/tst-setgroups.c index 976f4b1..e81c276 100644 --- a/nptl/tst-setgroups.c +++ b/nptl/tst-setgroups.c @@ -1,5 +1,5 @@ /* Test setgroups as root and in the presence of threads (Bug 26248) - Copyright (C) 2020-2024 Free Software Foundation, Inc. + Copyright (C) 2020-2025 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 diff --git a/nptl/tst-setuid1.c b/nptl/tst-setuid1.c index cf1bbf3..d5def2b 100644 --- a/nptl/tst-setuid1.c +++ b/nptl/tst-setuid1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2024 Free Software Foundation, Inc. +/* Copyright (C) 2004-2025 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 diff --git a/nptl/tst-setuid2.c b/nptl/tst-setuid2.c index 33d4e39..8805fa1 100644 --- a/nptl/tst-setuid2.c +++ b/nptl/tst-setuid2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2024 Free Software Foundation, Inc. +/* Copyright (C) 2014-2025 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 @@ -76,7 +76,12 @@ run_on_thread (void (*func) (void)) static void change_thread_ids (void) { +#ifdef __NR_setresuid32 + /* Prefer 32-bit setresuid32 over 16-bit setresuid. */ + long ret = syscall (__NR_setresuid32, 2001, 2002, 2003); +#else long ret = syscall (__NR_setresuid, 2001, 2002, 2003); +#endif if (ret != 0) FAIL ("setresuid (2001, 2002, 2003): %ld", ret); } diff --git a/nptl/tst-signal3.c b/nptl/tst-signal3.c index 712cb63..a100019 100644 --- a/nptl/tst-signal3.c +++ b/nptl/tst-signal3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2024 Free Software Foundation, Inc. +/* Copyright (C) 2002-2025 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 diff --git a/nptl/tst-signal7.c b/nptl/tst-signal7.c index 638ea0c..9408834 100644 --- a/nptl/tst-signal7.c +++ b/nptl/tst-signal7.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2024 Free Software Foundation, Inc. +/* Copyright (C) 2005-2025 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 diff --git a/nptl/tst-skeleton-affinity-inheritance.c b/nptl/tst-skeleton-affinity-inheritance.c new file mode 100644 index 0000000..e1f328a --- /dev/null +++ b/nptl/tst-skeleton-affinity-inheritance.c @@ -0,0 +1,160 @@ +/* CPU Affinity inheritance test - common infrastructure. + Copyright The GNU Toolchain Authors. + 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/>. */ + +/* The general idea of this test is to verify that the set of CPUs assigned to + a task gets inherited by a child (thread or process) of that task. This is + a framework that is included by specific APIs for the test, e.g. + sched_getaffinity/sched_setaffinity and + pthread_setaffinity_np/pthread_getaffinity_np. This is a framework, actual + tests entry points are in nptl/tst-pthread-affinity-inheritance.c and + sysdeps/unix/sysv/linux/tst-sched-affinity-inheritance.c. + + There are two levels to the test with two different CPU masks. The first + level verifies that the affinity set on the main process is inherited by its + children subprocess or thread. The second level verifies that a subprocess + or subthread passes on its affinity to their respective subprocess or + subthread. We set a slightly different mask in both levels to ensure that + they're both inherited. */ + +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <support/test-driver.h> +#include <support/xthread.h> +#include <support/xunistd.h> +#include <sys/sysinfo.h> +#include <sys/wait.h> + +struct test_param +{ + int nproc; + int nproc_configured; + cpu_set_t *set; + size_t size; + bool entry; +}; + +void __attribute__((noinline)) +set_cpu_mask (struct test_param *param, bool entry) +{ + int cpus = param->nproc; + + /* Less CPUS for the first level, if that's possible. */ + if (entry && cpus > 1) + cpus--; + + CPU_ZERO_S (param->size, param->set); + while (cpus > 0) + CPU_SET_S (--cpus, param->size, param->set); + + if (CPU_COUNT_S (param->size, param->set) == 0) + FAIL_EXIT1 ("Failed to add any CPUs to the affinity set\n"); +} + +static void * +child_test (void *arg) +{ + struct test_param *param = arg; + + printf ("%d:%d child\n", getpid (), gettid ()); + verify_my_affinity (param->nproc, param->nproc_configured, param->size, + param->set); + return NULL; +} + +void * +do_one_test (void *arg) +{ + void *(*child) (void *) = NULL; + struct test_param *param = arg; + bool entry = param->entry; + + if (entry) + { + printf ("%d:%d Start test run\n", getpid (), gettid ()); + /* First level: Reenter as a subprocess and then as a subthread. */ + child = do_one_test; + set_cpu_mask (param, true); + set_my_affinity (param->size, param->set); + param->entry = false; + } + else + { + /* Verification for the first level. */ + verify_my_affinity (param->nproc, param->nproc_configured, param->size, + param->set); + + /* Launch the second level test, launching CHILD_TEST as a subprocess and + then as a subthread. Use a different mask to see if it gets + inherited. */ + child = child_test; + set_cpu_mask (param, false); + set_my_affinity (param->size, param->set); + } + + /* Verify that a child of a thread/process inherits the affinity mask. */ + printf ("%d:%d%sdo_one_test: fork\n", getpid (), gettid (), + entry ? " " : " "); + int pid = xfork (); + + if (pid == 0) + { + child (param); + return NULL; + } + + xwaitpid (pid, NULL, 0); + + /* Verify that a subthread of a thread/process inherits the affinity + mask. */ + printf ("%d:%d%sdo_one_test: thread\n", getpid (), gettid (), + entry ? " " : " "); + pthread_t t = xpthread_create (NULL, child, param); + xpthread_join (t); + + return NULL; +} + +static int +do_test (void) +{ + /* Large enough in case the kernel decides to return the larger mask. This + seems to happen on some kernels for S390x. */ + int num_configured_cpus = get_nprocs_conf (); + int num_cpus = get_nprocs (); + + struct test_param param = + { + .nproc = num_cpus, + .nproc_configured = num_configured_cpus, + .set = CPU_ALLOC (num_configured_cpus), + .size = CPU_ALLOC_SIZE (num_configured_cpus), + .entry = true, + }; + + if (param.set == NULL) + FAIL_EXIT1 ("error: CPU_ALLOC (%d) failed\n", num_cpus); + + do_one_test (¶m); + + CPU_FREE (param.set); + + return 0; +} + +#include <support/test-driver.c> diff --git a/nptl/tst-stack2.c b/nptl/tst-stack2.c index 4b055dc..3706058 100644 --- a/nptl/tst-stack2.c +++ b/nptl/tst-stack2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-stack3.c b/nptl/tst-stack3.c index 9edbc05..1103e23 100644 --- a/nptl/tst-stack3.c +++ b/nptl/tst-stack3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-stack4.c b/nptl/tst-stack4.c index fb14085..6110514 100644 --- a/nptl/tst-stack4.c +++ b/nptl/tst-stack4.c @@ -1,6 +1,6 @@ /* Test DTV size overflow when pthread_create reuses old DTV and TLS is used by dlopened shared object. - Copyright (C) 2014-2024 Free Software Foundation, Inc. + Copyright (C) 2014-2025 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 diff --git a/nptl/tst-stack4mod.c b/nptl/tst-stack4mod.c index 7599ee0..4c26df7 100644 --- a/nptl/tst-stack4mod.c +++ b/nptl/tst-stack4mod.c @@ -1,5 +1,5 @@ /* This tests DTV usage with TLS in dlopened shared object. - Copyright (C) 2014-2024 Free Software Foundation, Inc. + Copyright (C) 2014-2025 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 diff --git a/nptl/tst-stackguard1.c b/nptl/tst-stackguard1.c index 9c79368..01f8205 100644 --- a/nptl/tst-stackguard1.c +++ b/nptl/tst-stackguard1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2024 Free Software Foundation, Inc. +/* Copyright (C) 2005-2025 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 diff --git a/nptl/tst-thread-affinity-pthread.c b/nptl/tst-thread-affinity-pthread.c index 35506a9..960774d 100644 --- a/nptl/tst-thread-affinity-pthread.c +++ b/nptl/tst-thread-affinity-pthread.c @@ -1,5 +1,5 @@ /* Multi-threaded test for pthread_getaffinity_np, pthread_setaffinity_np. - Copyright (C) 2015-2024 Free Software Foundation, Inc. + Copyright (C) 2015-2025 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 diff --git a/nptl/tst-thread-affinity-pthread2.c b/nptl/tst-thread-affinity-pthread2.c index b35ab2b..12312d0 100644 --- a/nptl/tst-thread-affinity-pthread2.c +++ b/nptl/tst-thread-affinity-pthread2.c @@ -1,5 +1,5 @@ /* Separate thread test for pthread_getaffinity_np, pthread_setaffinity_np. - Copyright (C) 2015-2024 Free Software Foundation, Inc. + Copyright (C) 2015-2025 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 diff --git a/nptl/tst-thread-affinity-sched.c b/nptl/tst-thread-affinity-sched.c index 37e426b..a686443 100644 --- a/nptl/tst-thread-affinity-sched.c +++ b/nptl/tst-thread-affinity-sched.c @@ -1,5 +1,5 @@ /* Multi-threaded test for sched_getaffinity_np, sched_setaffinity_np. - Copyright (C) 2015-2024 Free Software Foundation, Inc. + Copyright (C) 2015-2025 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 diff --git a/nptl/tst-thread-exit-clobber.cc b/nptl/tst-thread-exit-clobber.cc index b3b6989..91b0e8e 100644 --- a/nptl/tst-thread-exit-clobber.cc +++ b/nptl/tst-thread-exit-clobber.cc @@ -1,5 +1,5 @@ /* Test that pthread_exit does not clobber callee-saved registers. - Copyright (C) 2018-2024 Free Software Foundation, Inc. + Copyright (C) 2018-2025 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 @@ -73,7 +73,7 @@ enum { no_check = -1 }; /* Check that VALUE is the magic value for INDEX, behind a compiler barrier. */ -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void check_magic (int index, unsigned int value) { @@ -103,7 +103,7 @@ check_magic (int index, unsigned int value) /* Check that VALUE is the magic value for INDEX, behind a compiler barrier. Double variant. */ -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void check_magic (int index, double value) { @@ -153,7 +153,7 @@ struct checker call_pthread_exit are used to call pthread_exit indirectly, with the intent of clobbering the register values. */ -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void call_pthread_exit_0 (const values<unsigned int> *pvalues) { @@ -166,7 +166,7 @@ call_pthread_exit_0 (const values<unsigned int> *pvalues) pthread_exit (NULL); } -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void call_pthread_exit_1 (const values<double> *pvalues) { @@ -180,7 +180,7 @@ call_pthread_exit_1 (const values<double> *pvalues) call_pthread_exit_0 (&other_values); } -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void call_pthread_exit () { @@ -192,7 +192,7 @@ call_pthread_exit () pthread_exit. If Nested is true, call pthread_exit indirectly via call_pthread_exit. */ template <class T, bool Nested> -__attribute__ ((noinline, noclone, weak)) +__attribute__ ((weak)) __attribute_optimization_barrier__ void * threadfunc (void *closure) { diff --git a/nptl/tst-thread-setspecific.c b/nptl/tst-thread-setspecific.c index 462c9f0..969e64b 100644 --- a/nptl/tst-thread-setspecific.c +++ b/nptl/tst-thread-setspecific.c @@ -1,6 +1,6 @@ /* Test to verify that passing a pointer to an uninitialized object to pthread_setspecific doesn't trigger bogus uninitialized warnings. - Copyright (C) 2021-2024 Free Software Foundation, Inc. + Copyright (C) 2021-2025 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 @@ -25,7 +25,7 @@ See BZ #27714. */ DIAG_PUSH_NEEDS_COMMENT; -DIAG_IGNORE_NEEDS_COMMENT (6, "-Wmaybe-uninitialized"); +DIAG_IGNORE_NEEDS_COMMENT_GCC (6, "-Wmaybe-uninitialized"); DIAG_IGNORE_NEEDS_COMMENT (6, "-Wuninitialized"); static int diff --git a/nptl/tst-thread_local1.cc b/nptl/tst-thread_local1.cc index 2705205..a51b19c 100644 --- a/nptl/tst-thread_local1.cc +++ b/nptl/tst-thread_local1.cc @@ -1,5 +1,5 @@ /* Test basic thread_local support. - Copyright (C) 2015-2024 Free Software Foundation, Inc. + Copyright (C) 2015-2025 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 @@ -53,27 +53,27 @@ to_string (const counter &c) template <counter *Counter> struct counting { - counting () __attribute__ ((noinline, noclone)); - ~counting () __attribute__ ((noinline, noclone)); - void operation () __attribute__ ((noinline, noclone)); + counting () __attribute_optimization_barrier__; + ~counting () __attribute_optimization_barrier__; + void operation () __attribute_optimization_barrier__; }; template<counter *Counter> -__attribute__ ((noinline, noclone)) +__attribute_optimization_barrier__ counting<Counter>::counting () { ++Counter->constructed; } template<counter *Counter> -__attribute__ ((noinline, noclone)) +__attribute_optimization_barrier__ counting<Counter>::~counting () { ++Counter->destructed; } template<counter *Counter> -void __attribute__ ((noinline, noclone)) +void __attribute_optimization_barrier__ counting<Counter>::operation () { // Optimization barrier. diff --git a/nptl/tst-tls3-malloc.c b/nptl/tst-tls3-malloc.c index 9ac11a8..17dcb0a 100644 --- a/nptl/tst-tls3-malloc.c +++ b/nptl/tst-tls3-malloc.c @@ -1,5 +1,5 @@ /* Test TLS allocation with an interposed malloc. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 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 diff --git a/nptl/tst-tls3.c b/nptl/tst-tls3.c index 3d8c4e4..d76026e 100644 --- a/nptl/tst-tls3.c +++ b/nptl/tst-tls3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-tls3mod.c b/nptl/tst-tls3mod.c index b35d9fb..a72ab22 100644 --- a/nptl/tst-tls3mod.c +++ b/nptl/tst-tls3mod.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-tls5.c b/nptl/tst-tls5.c index eb2d65e..1fe7ac6 100644 --- a/nptl/tst-tls5.c +++ b/nptl/tst-tls5.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-tls6.sh b/nptl/tst-tls6.sh index 450ee78..2334e7e 100755 --- a/nptl/tst-tls6.sh +++ b/nptl/tst-tls6.sh @@ -1,6 +1,6 @@ #!/bin/bash # A tls test. -# Copyright (C) 2003-2024 Free Software Foundation, Inc. +# Copyright (C) 2003-2025 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 diff --git a/nptl/tst-tpp.h b/nptl/tst-tpp.h index 72f6737..7214934 100644 --- a/nptl/tst-tpp.h +++ b/nptl/tst-tpp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2006-2024 Free Software Foundation, Inc. +/* Copyright (C) 2006-2025 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 diff --git a/nptl/tst-tsd3.c b/nptl/tst-tsd3.c index 3875d02..95e1ce5 100644 --- a/nptl/tst-tsd3.c +++ b/nptl/tst-tsd3.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/tst-tsd4.c b/nptl/tst-tsd4.c index ad9ef0d..ac75ec3 100644 --- a/nptl/tst-tsd4.c +++ b/nptl/tst-tsd4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/unwind.c b/nptl/unwind.c index 3688981..ea0a55a 100644 --- a/nptl/unwind.c +++ b/nptl/unwind.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2024 Free Software Foundation, Inc. +/* Copyright (C) 2003-2025 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 diff --git a/nptl/vars.c b/nptl/vars.c index 0ad918c..034888b 100644 --- a/nptl/vars.c +++ b/nptl/vars.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2024 Free Software Foundation, Inc. +/* Copyright (C) 2004-2025 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 |