forked from pool/glibc
146 lines
3.6 KiB
Diff
146 lines
3.6 KiB
Diff
|
From glibc.git (for 2.15):
|
||
|
|
||
|
2011-06-23 H.J. Lu <hongjiu.lu@intel.com>
|
||
|
|
||
|
* sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Use
|
||
|
__gettimeofday instead of gettimeofday.
|
||
|
|
||
|
2011-06-22 Ulrich Drepper <drepper@gmail.com>
|
||
|
|
||
|
* sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Use
|
||
|
/sys/devices/system/cpu/online if it is usable.
|
||
|
|
||
|
* sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Rate limit
|
||
|
reading the information from the /proc filesystem to once a second.
|
||
|
|
||
|
--- glibc-2.13/sysdeps/unix/sysv/linux/getsysstats.c 2010-04-08 10:45:22.000000000 +0200
|
||
|
+++ glibc.git/sysdeps/unix/sysv/linux/getsysstats.c 2011-06-27 09:56:27.359389056 +0200
|
||
|
@@ -1,5 +1,5 @@
|
||
|
/* Determine various system internal values, Linux version.
|
||
|
- Copyright (C) 1996-2003,2006,2007,2009,2010 Free Software Foundation, Inc.
|
||
|
+ Copyright (C) 1996-2003,2006,2007,2009,2010,2011 Free Software Foundation, Inc.
|
||
|
This file is part of the GNU C Library.
|
||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||
|
|
||
|
@@ -35,6 +35,16 @@
|
||
|
|
||
|
#include <atomic.h>
|
||
|
#include <not-cancel.h>
|
||
|
+#include <kernel-features.h>
|
||
|
+
|
||
|
+#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
|
||
|
+# undef INTERNAL_VSYSCALL
|
||
|
+# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
|
||
|
+# undef INLINE_VSYSCALL
|
||
|
+# define INLINE_VSYSCALL INLINE_SYSCALL
|
||
|
+#else
|
||
|
+# include <bits/libc-vdso.h>
|
||
|
+#endif
|
||
|
|
||
|
|
||
|
/* How we can determine the number of available processors depends on
|
||
|
@@ -128,6 +138,22 @@
|
||
|
int
|
||
|
__get_nprocs ()
|
||
|
{
|
||
|
+ static int cached_result;
|
||
|
+ static time_t timestamp;
|
||
|
+
|
||
|
+#ifdef __ASSUME_POSIX_TIMERS
|
||
|
+ struct timespec ts;
|
||
|
+ INTERNAL_SYSCALL_DECL (err);
|
||
|
+ INTERNAL_VSYSCALL (clock_gettime, err, 2, CLOCK_REALTIME, &ts);
|
||
|
+#else
|
||
|
+ struct timeval ts;
|
||
|
+ __gettimeofday (&ts, NULL);
|
||
|
+#endif
|
||
|
+ time_t prev = timestamp;
|
||
|
+ atomic_read_barrier ();
|
||
|
+ if (ts.tv_sec == prev)
|
||
|
+ 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;
|
||
|
@@ -135,20 +161,65 @@
|
||
|
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
|
||
|
+ int fd = open_not_cancel_2 ("/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_not_cancel_no_status (fd);
|
||
|
+
|
||
|
+ if (result > 0)
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ cp = buffer_end;
|
||
|
+ re = buffer_end;
|
||
|
+ result = 1;
|
||
|
+
|
||
|
/* The /proc/stat format is more uniform, use it by default. */
|
||
|
- int fd = open_not_cancel_2 ("/proc/stat", flags);
|
||
|
+ 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. */
|
||
|
@@ -169,6 +240,11 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ out:
|
||
|
+ cached_result = result;
|
||
|
+ atomic_write_barrier ();
|
||
|
+ timestamp = ts.tv_sec;
|
||
|
+
|
||
|
return result;
|
||
|
}
|
||
|
weak_alias (__get_nprocs, get_nprocs)
|