[PATCH v2 10/19] nptl: Use tidlock when accessing TID on pthread_getaffinity_np

Adhemerval Zanella adhemerval.zanella@linaro.org
Mon Aug 23 19:50:38 GMT 2021


Checked on x86_64-linux-gnu.
---
 nptl/pthread_getaffinity.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/nptl/pthread_getaffinity.c b/nptl/pthread_getaffinity.c
index 18261ddae0..5268d86e6e 100644
--- a/nptl/pthread_getaffinity.c
+++ b/nptl/pthread_getaffinity.c
@@ -29,12 +29,24 @@
 int
 __pthread_getaffinity_np (pthread_t th, size_t cpusetsize, cpu_set_t *cpuset)
 {
-  const struct pthread *pd = (const struct pthread *) th;
+  struct pthread *pd = (struct pthread *) th;
 
-  int res = INTERNAL_SYSCALL_CALL (sched_getaffinity, pd->tid,
-				   MIN (INT_MAX, cpusetsize), cpuset);
-  if (INTERNAL_SYSCALL_ERROR_P (res))
-    return INTERNAL_SYSCALL_ERRNO (res);
+  /* Block all signal, since the lock is recursive and used on pthread_cancel
+     (which should be async-signal-safe).  */
+  sigset_t oldmask;
+  __libc_signal_block_all (&oldmask);
+  lll_lock (pd->tidlock, LLL_PRIVATE);
+
+  int res = pd->tid == 0
+	    ? -ESRCH
+	    : INTERNAL_SYSCALL_CALL (sched_getaffinity, pd->tid,
+				     MIN (INT_MAX, cpusetsize), cpuset);
+
+  lll_unlock (pd->tidlock, LLL_PRIVATE);
+  __libc_signal_restore_set (&oldmask);
+
+  if (res < 0)
+    return -res;
 
   /* Clean the rest of the memory the kernel didn't do.  */
   memset ((char *) cpuset + res, '\0', cpusetsize - res);
-- 
2.30.2



More information about the Libc-alpha mailing list