]> Savannah Git Hosting - gnulib.git/commitdiff
nproc: Use affinity mask even in out-of-memory situations.
authorBruno Haible <bruno@clisp.org>
Mon, 11 Nov 2024 14:40:52 +0000 (15:40 +0100)
committerBruno Haible <bruno@clisp.org>
Mon, 11 Nov 2024 14:40:52 +0000 (15:40 +0100)
* lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated
cpu_set_t as fallback. Add comments.

ChangeLog
lib/nproc.c

index c95151da24259cf0ce24dec18b71134d58f509ff..afce32cf8b7961c06f60ca0df9a6def31d83294a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-11-11  Bruno Haible  <bruno@clisp.org>
+
+       nproc: Use affinity mask even in out-of-memory situations.
+       * lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated
+       cpu_set_t as fallback. Add comments.
+
 2024-11-11  Florian Weimer  <fweimer@redhat.com>
 
        nproc: Use affinity mask even on systems with more than 1024 CPUs.
index 48bc3d06fa90ad2f88dd8a70e7810642dfc8a396..0b5898d88ffb6d07a6c4c6f178be8c675f791a9b 100644 (file)
@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void)
           return count;
       }
   }
-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \
-  && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
+  /* There are two ways to use the sched_getaffinity() function:
+       - With a statically-sized cpu_set_t.
+       - With a dynamically-sized cpu_set_t.
+     Documentation:
+     <https://www.kernel.org/doc/man-pages/online/pages/man2/sched_getaffinity.2.html>
+     <https://www.kernel.org/doc/man-pages/online/pages/man3/CPU_SET.3.html>
+     The second way has the advantage that it works on systems with more than
+     1024 CPUs.  The first way has the advantage that it works also when memory
+     is tight.  */
+# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
   {
     unsigned int alloc_count = 1024;
-    while (1)
+    for (;;)
       {
         cpu_set_t *set = CPU_ALLOC (alloc_count);
         if (set == NULL)
-          return 0;
+          /* Out of memory.  */
+          break;
         unsigned int size = CPU_ALLOC_SIZE (alloc_count);
         if (sched_getaffinity (0, size, set) == 0)
           {
@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void)
           }
         if (errno != EINVAL)
           {
+            /* Some other error.  */
             CPU_FREE (set);
             return 0;
           }
         CPU_FREE (set);
+        /* Retry with some larger cpu_set_t.  */
         alloc_count *= 2;
         if (alloc_count == 0)
+          /* Integer overflow.  Avoid an endless loop.  */
           return 0;
       }
   }
-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
+# endif
   {
     cpu_set_t set;