int __get_nprocs () { /* XXX Here will come a test for the new system call. */ const size_t buffer_size = __libc_use_alloca (8192) ? 8192 : 512; char *buffer = alloca (buffer_size); char *buffer_end = buffer + buffer_size; char *cp = buffer_end; char *re = buffer_end; int result = 1; #ifdef O_CLOEXEC const int flags = O_RDONLY | O_CLOEXEC; #else const int flags = O_RDONLY; #endif /* The /proc/stat format is more uniform, use it by default. */ int fd = open_not_cancel_2 ("/proc/stat", flags); if (fd != -1) { result = 0; char *l; while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) /* The current format of /proc/stat has all the cpu* entries at the front. We assume here that stays this way. */ if (strncmp (l, "cpu", 3) != 0) break; else if (isdigit (l[3])) ++result; close_not_cancel_no_status (fd); } else { fd = open_not_cancel_2 ("/proc/cpuinfo", flags); if (fd != -1) { GET_NPROCS_PARSER (fd, buffer, cp, re, buffer_end, result); close_not_cancel_no_status (fd); } } return result; }
int __get_nprocs () { char buffer[8192]; int result = 1; /* XXX Here will come a test for the new system call. */ /* The /proc/stat format is more uniform, use it by default. */ FILE *fp = fopen ("/proc/stat", "rc"); if (fp != NULL) { /* No threads use this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); result = 0; while (fgets_unlocked (buffer, sizeof (buffer), fp) != NULL) if (strncmp (buffer, "cpu", 3) == 0 && isdigit (buffer[3])) ++result; fclose (fp); } else { fp = fopen ("/proc/cpuinfo", "rc"); if (fp != NULL) { /* No threads use this stream. */ __fsetlocking (fp, FSETLOCKING_BYCALLER); GET_NPROCS_PARSER (fp, buffer, result); fclose (fp); } } return result; }
int __get_nprocs (void) { static int cached_result = -1; static time_t timestamp; time_t now = time (NULL); time_t prev = timestamp; atomic_read_barrier (); if (now == prev && cached_result > -1) return cached_result; /* XXX Here will come a test for the new system call. */ const size_t buffer_size = __libc_use_alloca (8192) ? 8192 : 512; char *buffer = alloca (buffer_size); char *buffer_end = buffer + buffer_size; char *cp = buffer_end; char *re = buffer_end; const int flags = O_RDONLY | O_CLOEXEC; int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags); char *l; int result = 0; if (fd != -1) { l = next_line (fd, buffer, &cp, &re, buffer_end); if (l != NULL) do { char *endp; unsigned long int n = strtoul (l, &endp, 10); if (l == endp) { result = 0; break; } unsigned long int m = n; if (*endp == '-') { l = endp + 1; m = strtoul (l, &endp, 10); if (l == endp) { result = 0; break; } } result += m - n + 1; l = endp; while (l < re && isspace (*l)) ++l; } while (l < re); __close_nocancel_nostatus (fd); if (result > 0) goto out; } cp = buffer_end; re = buffer_end; /* Default to an SMP system in case we cannot obtain an accurate number. */ result = 2; /* The /proc/stat format is more uniform, use it by default. */ fd = __open_nocancel ("/proc/stat", flags); if (fd != -1) { result = 0; while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) /* The current format of /proc/stat has all the cpu* entries at the front. We assume here that stays this way. */ if (strncmp (l, "cpu", 3) != 0) break; else if (isdigit (l[3])) ++result; __close_nocancel_nostatus (fd); } else { fd = __open_nocancel ("/proc/cpuinfo", flags); if (fd != -1) { GET_NPROCS_PARSER (fd, buffer, cp, re, buffer_end, result); __close_nocancel_nostatus (fd); } } out: cached_result = result; atomic_write_barrier (); timestamp = now; return result; }