+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.
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)
{
}
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;