[07/15] nptl: Use exit_lock when accessing TID on pthread_setaffinity

Message ID 20210930200051.1017457-8-adhemerval.zanella@linaro.org
State New
Headers show
Series
  • Fix various NPTL synchronization issues
Related show

Commit Message

Noah Goldstein via Libc-alpha Sept. 30, 2021, 8 p.m.
Also return ESRCH if the thread is already terminated at the time of
the call.  This is slight better than setting the calling thread
affinity (current behaviour).

Checked on x86_64-linux-gnu.
---
 nptl/pthread_setaffinity.c           | 25 +++++++++++++++----------
 sysdeps/pthread/tst-pthread-exited.c |  7 +++++++
 2 files changed, 22 insertions(+), 10 deletions(-)

-- 
2.30.2

Patch

diff --git a/nptl/pthread_setaffinity.c b/nptl/pthread_setaffinity.c
index 2ae6ae694c..cefc48e7c5 100644
--- a/nptl/pthread_setaffinity.c
+++ b/nptl/pthread_setaffinity.c
@@ -15,10 +15,8 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
+#include <libc-lock.h>
 #include <pthreadP.h>
-#include <sysdep.h>
-#include <sys/types.h>
 #include <shlib-compat.h>
 
 
@@ -26,15 +24,22 @@  int
 __pthread_setaffinity_new (pthread_t th, size_t cpusetsize,
 			   const cpu_set_t *cpuset)
 {
-  const struct pthread *pd = (const struct pthread *) th;
-  int res;
+  struct pthread *pd = (struct pthread *) th;
 
-  res = INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid, cpusetsize,
-			       cpuset);
+  /* Block all signals, as required by pd->exit_lock.  */
+  sigset_t old_mask;
+  __libc_signal_block_all (&old_mask);
+  __libc_lock_lock (pd->exit_lock);
 
-  return (INTERNAL_SYSCALL_ERROR_P (res)
-	  ? INTERNAL_SYSCALL_ERRNO (res)
-	  : 0);
+  int res = pd->tid == 0
+	    ? ESRCH
+	    : -INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid, cpusetsize,
+				      cpuset);
+
+  __libc_lock_unlock (pd->exit_lock);
+  __libc_signal_restore_set (&old_mask);
+
+  return res;
 }
 versioned_symbol (libc, __pthread_setaffinity_new,
 		  pthread_setaffinity_np, GLIBC_2_34);
diff --git a/sysdeps/pthread/tst-pthread-exited.c b/sysdeps/pthread/tst-pthread-exited.c
index c27e856dea..567d6b9b49 100644
--- a/sysdeps/pthread/tst-pthread-exited.c
+++ b/sysdeps/pthread/tst-pthread-exited.c
@@ -43,6 +43,13 @@  do_test (void)
     TEST_COMPARE (r, ESRCH);
   }
 
+  {
+    cpu_set_t cpuset;
+    CPU_ZERO (&cpuset);
+    int r = pthread_setaffinity_np (thr, sizeof (cpuset), &cpuset);
+    TEST_COMPARE (r, ESRCH);
+  }
+
   xpthread_join (thr);
 
   return 0;