diff options
author | Meador Inge <meadori@codesourcery.com> | 2014-06-13 14:02:04 +0530 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@redhat.com> | 2014-06-13 14:02:04 +0530 |
commit | 995a46bbfba9964e328e3947130919d8bd3cd62a (patch) | |
tree | c36f1da1cc528a8cfc1d891310be2599c0507532 | |
parent | febf6cc58c36cd5a978b8b5faedb5a932eb44c98 (diff) | |
download | glibc-995a46bbfba9964e328e3947130919d8bd3cd62a.tar glibc-995a46bbfba9964e328e3947130919d8bd3cd62a.tar.gz glibc-995a46bbfba9964e328e3947130919d8bd3cd62a.tar.bz2 glibc-995a46bbfba9964e328e3947130919d8bd3cd62a.zip |
get_nprocs: Only return explictly set cache values (BZ #16996)
The implementation of __get_nprocs uses a stactic variable to cache
the value of the current number of processors. The caching breaks when
'time (NULL) == 0':
$ cat nproc.c
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char *argv[])
{
time_t t;
struct timeval tv = {0, 0};
printf("settimeofday({0, 0}, NULL) = %d\n", settimeofday(&tv, NULL));
t = time(NULL);
printf("Time: %d, CPUs: %d\n", (unsigned int)t, get_nprocs());
return 0;
}
$ gcc -O3 nproc.c
$ ./a.out
settimeofday({0, 0}, NULL) = -1
Time: 1401311578, CPUs: 4
$ sudo ./a.out
settimeofday({0, 0}, NULL) = 0
Time: 0, CPUs: 0
The problem is with the condition used to check whether a cached
value should be returned or not:
static int cached_result;
static time_t timestamp;
time_t now = time (NULL);
time_t prev = timestamp;
atomic_read_barrier ();
if (now == prev)
return cached_result;
This patch fixes the problem by ensuring that 'cached_result' has
been set at least once before returning it.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/getsysstats.c | 4 |
3 files changed, 9 insertions, 3 deletions
@@ -1,3 +1,9 @@ +2014-06-13 Meador Inge <meadori@codesourcery.com> + + [BZ #16996] + sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Ensure + that the cached result has been set before returning it. + 2014-06-12 Roland McGrath <roland@hack.frob.com> * nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Moved ... @@ -19,7 +19,7 @@ Version 2.20 16791, 16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16849, 16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915, 16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966, - 16967, 16977, 16978, 16984, 16990, 17009, 17042, 17048. + 16967, 16977, 16978, 16984, 16990, 16996, 17009, 17042, 17048. * The minimum Linux kernel version that this version of the GNU C Library can be used with is 2.6.32. diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index b6a6fe3e2f..755c259862 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c +++ b/sysdeps/unix/sysv/linux/getsysstats.c @@ -126,13 +126,13 @@ next_line (int fd, char *const buffer, char **cp, char **re, int __get_nprocs (void) { - static int cached_result; + static int cached_result = -1; static time_t timestamp; time_t now = time (NULL); time_t prev = timestamp; atomic_read_barrier (); - if (now == prev) + if (now == prev && cached_result > -1) return cached_result; /* XXX Here will come a test for the new system call. */ |