+ if (query == NPROC_CURRENT_OVERRIDABLE)
+ {
+ /* Test the environment variable OMP_NUM_THREADS, recognized also by all
+ programs that are based on OpenMP. The OpenMP spec says that the
+ value assigned to the environment variable "may have leading and
+ trailing white space". */
+ const char *envvalue = getenv ("OMP_NUM_THREADS");
+
+ if (envvalue != NULL)
+ {
+ while (*envvalue != '\0' && c_isspace (*envvalue))
+ envvalue++;
+ /* Convert it from decimal to 'unsigned long'. */
+ if (c_isdigit (*envvalue))
+ {
+ char *endptr = NULL;
+ unsigned long int value = strtoul (envvalue, &endptr, 10);
+
+ if (endptr != NULL)
+ {
+ while (*endptr != '\0' && c_isspace (*endptr))
+ endptr++;
+ if (*endptr == '\0')
+ return (value > 0 ? value : 1);
+ }
+ }
+ }
+
+ query = NPROC_CURRENT;
+ }
+ /* Here query is one of NPROC_ALL, NPROC_CURRENT. */
+
+ /* On systems with a modern affinity mask system call, we have
+ sysconf (_SC_NPROCESSORS_CONF)
+ >= sysconf (_SC_NPROCESSORS_ONLN)
+ >= num_processors_via_affinity_mask ()
+ The first number is the number of CPUs configured in the system.
+ The second number is the number of CPUs available to the scheduler.
+ The third number is the number of CPUs available to the current process.
+
+ Note! On Linux systems with glibc, the first and second number come from
+ the /sys and /proc file systems (see
+ glibc/sysdeps/unix/sysv/linux/getsysstats.c).
+ In some situations these file systems are not mounted, and the sysconf
+ call returns 1, which does not reflect the reality. */
+
+ if (query == NPROC_CURRENT)
+ {
+ /* Try the modern affinity mask system call. */
+ {
+ unsigned long nprocs = num_processors_via_affinity_mask ();
+
+ if (nprocs > 0)
+ return nprocs;
+ }
+
+#if defined _SC_NPROCESSORS_ONLN
+ { /* This works on glibc, MacOS X 10.5, FreeBSD, AIX, OSF/1, Solaris,
+ Cygwin, Haiku. */
+ long int nprocs = sysconf (_SC_NPROCESSORS_ONLN);
+ if (nprocs > 0)
+ return nprocs;
+ }
+#endif
+ }
+ else /* query == NPROC_ALL */
+ {
+#if defined _SC_NPROCESSORS_CONF
+ { /* This works on glibc, MacOS X 10.5, FreeBSD, AIX, OSF/1, Solaris,
+ Cygwin, Haiku. */
+ long int nprocs = sysconf (_SC_NPROCESSORS_CONF);
+
+# if __GLIBC__ >= 2 && defined __linux__
+ /* On Linux systems with glibc, this information comes from the /sys and
+ /proc file systems (see glibc/sysdeps/unix/sysv/linux/getsysstats.c).
+ In some situations these file systems are not mounted, and the
+ sysconf call returns 1. But we wish to guarantee that
+ num_processors (NPROC_ALL) >= num_processors (NPROC_CURRENT). */
+ if (nprocs == 1)
+ {
+ unsigned long nprocs_current = num_processors_via_affinity_mask ();
+
+ if (nprocs_current > 0)
+ nprocs = nprocs_current;
+ }
+# endif
+
+ if (nprocs > 0)
+ return nprocs;
+ }
+#endif
+ }
+
+#if HAVE_PSTAT_GETDYNAMIC
+ { /* This works on HP-UX. */
+ struct pst_dynamic psd;
+ if (pstat_getdynamic (&psd, sizeof psd, 1, 0) >= 0)
+ {
+ /* The field psd_proc_cnt contains the number of active processors.
+ In newer releases of HP-UX 11, the field psd_max_proc_cnt includes
+ deactivated processors. */
+ if (query == NPROC_CURRENT)
+ {
+ if (psd.psd_proc_cnt > 0)
+ return psd.psd_proc_cnt;
+ }
+ else
+ {
+ if (psd.psd_max_proc_cnt > 0)
+ return psd.psd_max_proc_cnt;
+ }
+ }
+ }
+#endif
+
+#if HAVE_SYSMP && defined MP_NAPROCS && defined MP_NPROCS
+ { /* This works on IRIX. */
+ /* MP_NPROCS yields the number of installed processors.
+ MP_NAPROCS yields the number of processors available to unprivileged
+ processes. */
+ int nprocs =
+ sysmp (query == NPROC_CURRENT && getpid () != 0
+ ? MP_NAPROCS
+ : MP_NPROCS);
+ if (nprocs > 0)
+ return nprocs;
+ }
+#endif
+
+ /* Finally, as fallback, use the APIs that don't distinguish between
+ NPROC_CURRENT and NPROC_ALL. */
+
+#if HAVE_SYSCTL && defined HW_NCPU
+ { /* This works on MacOS X, FreeBSD, NetBSD, OpenBSD. */
+ int nprocs;
+ size_t len = sizeof (nprocs);
+ static int mib[2] = { CTL_HW, HW_NCPU };
+
+ if (sysctl (mib, ARRAY_SIZE (mib), &nprocs, &len, NULL, 0) == 0
+ && len == sizeof (nprocs)
+ && 0 < nprocs)
+ return nprocs;
+ }
+#endif
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ { /* This works on native Windows platforms. */
+ SYSTEM_INFO system_info;
+ GetSystemInfo (&system_info);
+ if (0 < system_info.dwNumberOfProcessors)
+ return system_info.dwNumberOfProcessors;
+ }