From patchwork Thu Jun 12 16:37:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Meador Inge X-Patchwork-Id: 1469 Received: (qmail 22779 invoked by alias); 12 Jun 2014 16:37:24 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 22768 invoked by uid 89); 12 Jun 2014 16:37:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com From: Meador Inge To: Subject: [PATCH][BZ #16996] get_nprocs: Only return explictly set cache values Date: Thu, 12 Jun 2014 11:37:16 -0500 Message-ID: <1402591036-29454-1-git-send-email-meadori@codesourcery.com> MIME-Version: 1.0 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 #include #include 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; When 'timestamp == 0', as in the above test case, an unitialized cache value is returned. This patch fixes the problem by ensuring that 'cached_result' has been set at least once before returning it. I checked for regressions with 'make check' and verified that the described test case works, but couldn't find a good way to automate the test in the GLIBC testsuite. OK? 2014-06-12 Meador Inge [BZ #16996] sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Ensure that the cached result has been set before returning it. --- sysdeps/unix/sysv/linux/getsysstats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index b6a6fe3..755c259 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. */