about summary refs log tree commit diff
path: root/nptl/pthread_getattr_np.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/pthread_getattr_np.c')
-rw-r--r--nptl/pthread_getattr_np.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
index 0925ced37f..df11b1ff1d 100644
--- a/nptl/pthread_getattr_np.c
+++ b/nptl/pthread_getattr_np.c
@@ -135,18 +135,35 @@ pthread_getattr_np (thread_id, attr)
 
   if (ret == 0)
     {
-      iattr->cpuset = (cpu_set_t *) malloc (sizeof (cpu_set_t));
-      if (iattr->cpuset == NULL)
-	ret = ENOMEM;
-      else
+      size_t size = 32;
+      cpu_set_t *cpuset = NULL;
+
+      do
 	{
-	  ret = pthread_getaffinity_np (thread_id, iattr->cpuset);
-	  if (ret == ENOSYS)
+	  void *newp = realloc (cpuset, size);
+	  if (newp == NULL)
 	    {
-	      free (iattr->cpuset);
-	      iattr->cpuset = NULL;
-	      ret = 0;
+	      free (cpuset);
+	      ret = ENOMEM;
 	    }
+	  cpuset = (cpu_set_t *) newp;
+
+	  ret = __pthread_getaffinity_np (thread_id, size, cpuset);
+	}
+      /* Pick some ridiculous upper limit.  Is 8 million CPUs enough?  */
+      while (ret == EINVAL && size < 1024 * 1024);
+
+      if (ret == 0)
+	{
+	  iattr->cpuset = cpuset;
+	  iattr->cpusetsize = size;
+	}
+      else
+	{
+	  free (cpuset);
+	  if (ret == ENOSYS)
+	    /* There is no such functionality.  */
+	    ret = 0;
 	}
     }