aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-06-22 09:50:39 -0400
committerUlrich Drepper <drepper@gmail.com>2011-06-22 09:50:39 -0400
commit852eb34d5c56bc75bdd82327fcf310d98655f6b0 (patch)
tree9fdcbffbbf1b1d40137a5a72904acbe941bf5634 /sysdeps/unix/sysv
parent6e502e19455c6110dd4487d91b7b7d6d8121f9ba (diff)
downloadglibc-852eb34d5c56bc75bdd82327fcf310d98655f6b0.tar
glibc-852eb34d5c56bc75bdd82327fcf310d98655f6b0.tar.gz
glibc-852eb34d5c56bc75bdd82327fcf310d98655f6b0.tar.bz2
glibc-852eb34d5c56bc75bdd82327fcf310d98655f6b0.zip
Rate limit expensive _SC_NPROCESSORS_ONLN computation
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index af454b650d..a13b6e3e37 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -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 @@ next_line (int fd, char *const buffer, char **cp, char **re,
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;
@@ -169,6 +195,10 @@ __get_nprocs ()
}
}
+ cached_result = result;
+ atomic_write_barrier ();
+ timestamp = ts.tv_sec;
+
return result;
}
weak_alias (__get_nprocs, get_nprocs)