From patchwork Mon Feb 18 21:11:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 158650 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2938604jaa; Mon, 18 Feb 2019 13:12:13 -0800 (PST) X-Google-Smtp-Source: AHgI3IaJjpK66ftf6GCxUH+hRq5LGSyk6GtY8oqn1cCtdPQVUi5t1sYhAM3OsBcLmeH3LgyoLhac X-Received: by 2002:a62:e082:: with SMTP id d2mr26847152pfm.240.1550524333347; Mon, 18 Feb 2019 13:12:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550524333; cv=none; d=google.com; s=arc-20160816; b=i0bSmStn8ZsVzAI6dv7auvjM9CjgxUd2Tk+7qi7t5M+XgzQAaWMbV/mAvE6aZLS0AF hfB+2NIo4uYLRMaxOlmV1NrptwxT/epnIUpz1PEonEWQMOOF3RDSFNVqzrdtNm3qWxTZ PL+rd9wE8RQUFAtIftWK4a0Yl4EwziieUcxrWW1vPBQ7bClvsjp02LhHn/Ez282BboYN 3fEH0sMteBX4SBbgiXotaiU8A0QEXZ6x7qUMUF83AtuOnRIuLveK4V7F3LD1GaiAkPmK rTxl4x383ctG4kLLan+I5ARabLkbI2dUzimgRSAldBSeH9Z5kixVdDLKKT39CScy2iDf Bqug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from:dkim-signature:delivered-to:sender :list-help:list-post:list-archive:list-subscribe:list-unsubscribe :list-id:precedence:mailing-list:dkim-signature:domainkey-signature; bh=EFc/IFOmR/HJropjP+qariZeJFr3GvH17qimUSrZ9mo=; b=yrLazsdH2Bi9ecFds5wcbHvQZizdsiumOZgssNdDp/v5KFU4457RRnG4/B7WPCTnpo 4o7SJsbtPklQF3tCjo6Cj+MbWqDBBeFY8CyYtxoaHV/8ymXvBRFHw+/8Ti5KZKEJinBv vZTnvCWXMaDHAbhtzlYIzktIrQj0rR42ZT76hCnR93TEqkPd4Hq0duv4nPc5u0Gc/RhG Ogkjk+ocZ526h6xFAWq1PCev9INJImZCqY/C7wmSVEa35iVBNqDVW8puO9UR1lRndAXE kNgjKKsWvgsAL8yUexd6T1gYjZk1hIE5MrKErToudVRafPbGRvg+DtUUoGeRChxM4Mmb m1GQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=MSnVGP4M; dkim=pass header.i=@linaro.org header.s=google header.b=zBfjM3NZ; spf=pass (google.com: domain of libc-alpha-return-100125-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100125-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id u24si4839966pfa.78.2019.02.18.13.12.13 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 13:12:13 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-100125-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=MSnVGP4M; dkim=pass header.i=@linaro.org header.s=google header.b=zBfjM3NZ; spf=pass (google.com: domain of libc-alpha-return-100125-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100125-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=GKQ6pbRpFNs8mIShw6/N28QXkbsTjjg2q85nDiVttjrnhxMIJPPcf GrgQGtMCdQUISvzv++8WXX7/iq3q51zwxyYbUbMjH5FiHxn2Fu3/hYlVc4KeAo2P Y0spb0wJo0Y92/3QIjWCHQsAGYOyTcWQau7NVJuf9Zjf4WnhhgNssY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=m/WpfW3Sp2tfs+W1ItgvGS5xHVg=; b=MSnVGP4MfGmTR+FliDW/KQoxtnoA PQ+J/rKldk5VgyKxf5+XCRCbSHoOUIfeCtTiN8X55vSscoytrhdmoynWedTnlejz oXCQhgtS2p5uwxaclwNNIECLTamnpmyocD6EU3UhKDwTtdlY8HswmtEQAao3tG3z 3iNUM+D83T/QxzE= Received: (qmail 61062 invoked by alias); 18 Feb 2019 21:11:42 -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 60931 invoked by uid 89); 18 Feb 2019 21:11:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1000000000, clock, timer, activities X-HELO: mail-qt1-f194.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id; bh=EFc/IFOmR/HJropjP+qariZeJFr3GvH17qimUSrZ9mo=; b=zBfjM3NZrnqY1wMP9BQpoMwIgOVIwu66EdPMdoV8P1+C0e3BRtMLMUEoWkpu+RQ47T 2JjaJ186PfEIDJXCQCVGmCddlSHJKrEIXJ+IOzk8Jf3fpynbexnpv9wT1nDP0ZoMsxqA 8W2aFfJN2vu6xZigm119BPP9n2sRx6oCD8GHDNOnDo1vii3rTlINrEt+EMuuvUtAZa3Y 8j6cK5xORbOOdQxmOeVpQdyx/JaGLdJVoTdVGVIVDIZh69F76vsGm3T11TXPSrq8WxPX 7a+A8UtkB4RTGy5qq+WQ9mMzM2+2lM/S/vElg9CQkdwWXXlUrvvnyHRtawleYAz+9ChV p3rA== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Date: Mon, 18 Feb 2019 18:11:23 -0300 Message-Id: <20190218211128.1869-1-adhemerval.zanella@linaro.org> This patch removes CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID support from clock_gettime and clock_settime generic implementation. For Linux, kernel already provides supports through the syscall and Hurd HTL lacks __pthread_clock_gettime and __pthread_clock_settime internal implementation. As described in clock_gettime man-page [1] on 'Historical note for SMP system', implementing CLOCK_{THREAD,PROCESS}_CPUTIME_ID with timer registers is error-prone and susceptible to timing and accurary issues that the libc can not deal without kernel support. This allows removes unused code which, however, still incur in some runtime overhead in thread creation (the struct pthread cpuclock_offset initialization). If hurd eventually wants to support them it should either either implement as a kernel facility (or something related due its architecture) or in system specific implementation. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also checked on a i686-gnu build. * nptl/Makefile (libpthread-routines): Remove pthread_clock_gettime and pthread_clock_settime. * nptl/pthreadP.h (__find_thread_by_id): Remove prototype. * elf/dl-support.c [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset): Remove. (_dl_non_dynamic_init): Remove _dl_cpuclock_offset setting. * elf/rtld.c (_dl_start_final): Likewise. * nptl/allocatestack.c (__find_thread_by_id): Remove function. * sysdeps/generic/ldsodefs.h [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset): Remove. * sysdeps/mach/hurd/dl-sysdep.c [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset): Remove. * nptl/descr.h (struct pthread): Rename cpuclock_offset to cpuclock_offset_ununsed. * nptl/nptl-init.c (__pthread_initialize_minimal_internal): Remove cpuclock_offset set. * nptl/pthread_create.c (START_THREAD_DEFN): Likewise. * sysdeps/nptl/fork.c (__libc_fork): Likewise. * nptl/pthread_clock_gettime.c: Remove file. * nptl/pthread_clock_settime.c: Likewise. * sysdeps/unix/clock_gettime.c (hp_timing_gettime): Remove function. [HP_TIMING_AVAIL] (realtime_gettime): Remove CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID support. * sysdeps/unix/clock_settime.c (hp_timing_gettime): Likewise. [HP_TIMING_AVAIL] (realtime_gettime): Likewise. * sysdeps/posix/clock_getres.c (hp_timing_getres): Likewise. [HP_TIMING_AVAIL] (__clock_getres): Likewise. * sysdeps/unix/clock_nanosleep.c (CPUCLOCK_P, INVALID_CLOCK_P): Likewise. (__clock_nanosleep): Remove CPUCLOCK_P and INVALID_CLOCK_P usage. [1] http://man7.org/linux/man-pages/man2/clock_gettime.2.html --- elf/dl-support.c | 8 ---- elf/rtld.c | 2 - nptl/Makefile | 1 - nptl/allocatestack.c | 48 ------------------------ nptl/descr.h | 3 +- nptl/nptl-init.c | 3 -- nptl/pthreadP.h | 10 ----- nptl/pthread_clock_gettime.c | 67 ---------------------------------- nptl/pthread_clock_settime.c | 54 --------------------------- nptl/pthread_create.c | 7 ---- sysdeps/generic/ldsodefs.h | 5 --- sysdeps/mach/hurd/dl-sysdep.c | 8 ---- sysdeps/nptl/fork.c | 8 ---- sysdeps/posix/clock_getres.c | 46 +---------------------- sysdeps/unix/clock_gettime.c | 65 +-------------------------------- sysdeps/unix/clock_nanosleep.c | 30 ++------------- sysdeps/unix/clock_settime.c | 61 +------------------------------ 17 files changed, 9 insertions(+), 417 deletions(-) delete mode 100644 nptl/pthread_clock_gettime.c delete mode 100644 nptl/pthread_clock_settime.c -- 2.17.1 diff --git a/elf/dl-support.c b/elf/dl-support.c index 42c350c75d..0a8b636d02 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -129,11 +129,6 @@ void *_dl_random; #include #include -/* Initial value of the CPU clock. */ -#ifndef HP_TIMING_NONAVAIL -hp_timing_t _dl_cpuclock_offset; -#endif - void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls; size_t _dl_pagesize = EXEC_PAGESIZE; @@ -314,9 +309,6 @@ _dl_non_dynamic_init (void) _dl_main_map.l_phdr = GL(dl_phdr); _dl_main_map.l_phnum = GL(dl_phnum); - if (HP_SMALL_TIMING_AVAIL) - HP_TIMING_NOW (_dl_cpuclock_offset); - _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; /* Set up the data structures for the system-supplied DSO early, diff --git a/elf/rtld.c b/elf/rtld.c index c1cc1b01f2..1f124b31fc 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -403,8 +403,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) # endif #endif - HP_TIMING_NOW (GL(dl_cpuclock_offset)); - /* Initialize the stack end variable. */ __libc_stack_end = __builtin_frame_address (0); diff --git a/nptl/Makefile b/nptl/Makefile index 5acfdcceff..f9bc5cc887 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -109,7 +109,6 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ pthread_once \ old_pthread_atfork \ pthread_getcpuclockid \ - pthread_clock_gettime pthread_clock_settime \ shm-directory \ sem_init sem_destroy \ sem_open sem_close sem_unlink \ diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index d8e8570a7d..fcbc46f0d7 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -963,54 +963,6 @@ __reclaim_stacks (void) } -#if HP_TIMING_AVAIL -# undef __find_thread_by_id -/* Find a thread given the thread ID. */ -attribute_hidden -struct pthread * -__find_thread_by_id (pid_t tid) -{ - struct pthread *result = NULL; - - lll_lock (stack_cache_lock, LLL_PRIVATE); - - /* Iterate over the list with system-allocated threads first. */ - list_t *runp; - list_for_each (runp, &stack_used) - { - struct pthread *curp; - - curp = list_entry (runp, struct pthread, list); - - if (curp->tid == tid) - { - result = curp; - goto out; - } - } - - /* Now the list with threads using user-allocated stacks. */ - list_for_each (runp, &__stack_user) - { - struct pthread *curp; - - curp = list_entry (runp, struct pthread, list); - - if (curp->tid == tid) - { - result = curp; - goto out; - } - } - - out: - lll_unlock (stack_cache_lock, LLL_PRIVATE); - - return result; -} -#endif - - #ifdef SIGSETXID static void setxid_mark_thread (struct xid_command *cmdp, struct pthread *t) diff --git a/nptl/descr.h b/nptl/descr.h index 4ef33ae465..cb7d4c2282 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -343,8 +343,7 @@ struct pthread unsigned int setxid_futex; #if HP_TIMING_AVAIL - /* Offset of the CPU clock at start thread start time. */ - hp_timing_t cpuclock_offset; + hp_timing_t cpuclock_offset_ununsed; #endif /* If the thread waits to join another one the ID of the latter is diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index b5895fabf3..6691211e4e 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -276,9 +276,6 @@ __pthread_initialize_minimal_internal (void) THREAD_SETMEM (pd, user_stack, true); if (LLL_LOCK_INITIALIZER != 0) THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER); -#if HP_TIMING_AVAIL - THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset)); -#endif /* Initialize the robust mutex data. */ { diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 626bd4b096..f0facfdb7d 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -401,16 +401,6 @@ extern int __pthread_multiple_threads attribute_hidden; extern int *__libc_multiple_threads_ptr attribute_hidden; #endif -/* Find a thread given its TID. */ -extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden -#ifdef SHARED -; -#else -weak_function; -#define __find_thread_by_id(tid) \ - (__find_thread_by_id ? (__find_thread_by_id) (tid) : (struct pthread *) NULL) -#endif - extern void __pthread_init_static_tls (struct link_map *) attribute_hidden; extern size_t __pthread_get_minstack (const pthread_attr_t *attr); diff --git a/nptl/pthread_clock_gettime.c b/nptl/pthread_clock_gettime.c deleted file mode 100644 index f1d9104b24..0000000000 --- a/nptl/pthread_clock_gettime.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2001-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see . */ - -#include -#include -#include -#include "pthreadP.h" - - -#if HP_TIMING_AVAIL -int -__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, - struct timespec *tp) -{ - hp_timing_t tsc; - - /* Get the current counter. */ - HP_TIMING_NOW (tsc); - - /* This is the ID of the thread we are looking for. */ - pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE; - - /* Compute the offset since the start time of the process. */ - if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid)) - /* Our own clock. */ - tsc -= THREAD_GETMEM (THREAD_SELF, cpuclock_offset); - else - { - /* This is more complicated. We have to locate the thread based - on the ID. This means walking the list of existing - threads. */ - struct pthread *thread = __find_thread_by_id (tid); - if (thread == NULL) - { - __set_errno (EINVAL); - return -1; - } - - /* There is a race here. The thread might terminate and the stack - become unusable. But this is the user's problem. */ - tsc -= thread->cpuclock_offset; - } - - /* Compute the seconds. */ - tp->tv_sec = tsc / freq; - - /* And the nanoseconds. This computation should be stable until - we get machines with about 16GHz frequency. */ - tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq; - - return 0; -} -#endif diff --git a/nptl/pthread_clock_settime.c b/nptl/pthread_clock_settime.c deleted file mode 100644 index 0fe6482f78..0000000000 --- a/nptl/pthread_clock_settime.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2001-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see . */ - -#include -#include -#include -#include "pthreadP.h" - - -#if HP_TIMING_AVAIL -int -__pthread_clock_settime (clockid_t clock_id, hp_timing_t offset) -{ - /* This is the ID of the thread we are looking for. */ - pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE; - - /* Compute the offset since the start time of the process. */ - if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid)) - /* Our own clock. */ - THREAD_SETMEM (THREAD_SELF, cpuclock_offset, offset); - else - { - /* This is more complicated. We have to locate the thread based - on the ID. This means walking the list of existing - threads. */ - struct pthread *thread = __find_thread_by_id (tid); - if (thread == NULL) - { - __set_errno (EINVAL); - return -1; - } - - /* There is a race here. The thread might terminate and the stack - become unusable. But this is the user's problem. */ - thread->cpuclock_offset = offset; - } - - return 0; -} -#endif diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 2bd2b10727..18b7bbe765 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -379,13 +379,6 @@ START_THREAD_DEFN { struct pthread *pd = START_THREAD_SELF; -#if HP_TIMING_AVAIL - /* Remember the time when the thread was started. */ - hp_timing_t now; - HP_TIMING_NOW (now); - THREAD_SETMEM (pd, cpuclock_offset, now); -#endif - /* Initialize resolver state pointer. */ __resp = &pd->res; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 37cab6f06b..346bbb812d 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -352,11 +352,6 @@ struct rtld_global /* The object to be initialized first. */ EXTERN struct link_map *_dl_initfirst; -#if HP_SMALL_TIMING_AVAIL - /* Start time on CPU clock. */ - EXTERN hp_timing_t _dl_cpuclock_offset; -#endif - /* Map of shared object to be profiled. */ EXTERN struct link_map *_dl_profile_map; diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index a58338c930..72c80a8a46 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -62,10 +62,6 @@ int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion void *__libc_stack_end = NULL; rtld_hidden_data_def(__libc_stack_end) -#if HP_TIMING_AVAIL -hp_timing_t _dl_cpuclock_offset; -#endif - /* TODO: Initialize. */ void *_dl_random attribute_relro = NULL; @@ -246,10 +242,6 @@ unfmh(); /* XXX */ /* Initialize frequently used global variable. */ GLRO(dl_pagesize) = __getpagesize (); -#if HP_TIMING_AVAIL - HP_TIMING_NOW (_dl_cpuclock_offset); -#endif - fmh(); /* XXX */ /* See hurd/hurdstartup.c; this deals with getting information diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c index 14b69a6f89..3f357665bd 100644 --- a/sysdeps/nptl/fork.c +++ b/sysdeps/nptl/fork.c @@ -83,14 +83,6 @@ __libc_fork (void) if (__fork_generation_pointer != NULL) *__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR; -#if HP_TIMING_AVAIL - /* The CPU clock of the thread and process have to be set to zero. */ - hp_timing_t now; - HP_TIMING_NOW (now); - THREAD_SETMEM (self, cpuclock_offset, now); - GL(dl_cpuclock_offset) = now; -#endif - #ifdef __NR_set_robust_list /* Initialize the robust mutex list setting in the kernel which has been reset during the fork. We do not check for errors because if diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c index dac4761fcc..01024a3f55 100644 --- a/sysdeps/posix/clock_getres.c +++ b/sysdeps/posix/clock_getres.c @@ -24,37 +24,6 @@ #include -#if HP_TIMING_AVAIL -static long int nsec; /* Clock frequency of the processor. */ - -static int -hp_timing_getres (struct timespec *res) -{ - if (__glibc_unlikely (nsec == 0)) - { - hp_timing_t freq; - - /* This can only happen if we haven't initialized the `nsec' - variable yet. Do this now. We don't have to protect this - code against multiple execution since all of them should - lead to the same result. */ - freq = __get_clockfreq (); - if (__glibc_unlikely (freq == 0)) - /* Something went wrong. */ - return -1; - - nsec = MAX (UINT64_C (1000000000) / freq, 1); - } - - /* Fill in the values. - The seconds are always zero (unless we have a 1Hz machine). */ - res->tv_sec = 0; - res->tv_nsec = nsec; - - return 0; -} -#endif - static inline int realtime_getres (struct timespec *res) { @@ -87,21 +56,8 @@ __clock_getres (clockid_t clock_id, struct timespec *res) break; default: -#if HP_TIMING_AVAIL - if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) - == CLOCK_THREAD_CPUTIME_ID) - retval = hp_timing_getres (res); - else -#endif - __set_errno (EINVAL); - break; - -#if HP_TIMING_AVAIL - case CLOCK_PROCESS_CPUTIME_ID: - case CLOCK_THREAD_CPUTIME_ID: - retval = hp_timing_getres (res); + __set_errno (EINVAL); break; -#endif } return retval; diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c index 33a1f3335c..10a6c96d9d 100644 --- a/sysdeps/unix/clock_gettime.c +++ b/sysdeps/unix/clock_gettime.c @@ -24,57 +24,6 @@ #include -#if HP_TIMING_AVAIL -/* Clock frequency of the processor. We make it a 64-bit variable - because some jokers are already playing with processors with more - than 4GHz. */ -static hp_timing_t freq; - - -/* This function is defined in the thread library. */ -extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, - struct timespec *tp) - __attribute__ ((__weak__)); - -static int -hp_timing_gettime (clockid_t clock_id, struct timespec *tp) -{ - hp_timing_t tsc; - - if (__glibc_unlikely (freq == 0)) - { - /* This can only happen if we haven't initialized the `freq' - variable yet. Do this now. We don't have to protect this - code against multiple execution since all of them should - lead to the same result. */ - freq = __get_clockfreq (); - if (__glibc_unlikely (freq == 0)) - /* Something went wrong. */ - return -1; - } - - if (clock_id != CLOCK_PROCESS_CPUTIME_ID - && __pthread_clock_gettime != NULL) - return __pthread_clock_gettime (clock_id, freq, tp); - - /* Get the current counter. */ - HP_TIMING_NOW (tsc); - - /* Compute the offset since the start time of the process. */ - tsc -= GL(dl_cpuclock_offset); - - /* Compute the seconds. */ - tp->tv_sec = tsc / freq; - - /* And the nanoseconds. This computation should be stable until - we get machines with about 16GHz frequency. */ - tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq; - - return 0; -} -#endif - - static inline int realtime_gettime (struct timespec *tp) { @@ -105,20 +54,8 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp) break; default: -#if HP_TIMING_AVAIL - if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) - == CLOCK_THREAD_CPUTIME_ID) - retval = hp_timing_gettime (clock_id, tp); - else -#endif - __set_errno (EINVAL); - break; - -#if HP_TIMING_AVAIL - case CLOCK_PROCESS_CPUTIME_ID: - retval = hp_timing_gettime (clock_id, tp); + __set_errno (EINVAL); break; -#endif } return retval; diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c index 7722d1111c..b27608570c 100644 --- a/sysdeps/unix/clock_nanosleep.c +++ b/sysdeps/unix/clock_nanosleep.c @@ -19,23 +19,8 @@ #include #include #include -#include #include -#if HP_TIMING_AVAIL -# define CPUCLOCK_P(clock) \ - ((clock) == CLOCK_PROCESS_CPUTIME_ID \ - || ((clock) & ((1 << CLOCK_IDFIELD_SIZE) - 1)) == CLOCK_THREAD_CPUTIME_ID) -#else -# define CPUCLOCK_P(clock) 0 -#endif - -#ifndef INVALID_CLOCK_P -# define INVALID_CLOCK_P(cl) \ - ((cl) < CLOCK_REALTIME || (cl) > CLOCK_THREAD_CPUTIME_ID) -#endif - - /* This implementation assumes that these is only a `nanosleep' system call. So we have to remap all other activities. */ int @@ -51,14 +36,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL; /* POSIX specifies EINVAL for this case. */ -#ifdef SYSDEP_NANOSLEEP - SYSDEP_NANOSLEEP; -#endif - - if (CPUCLOCK_P (clock_id)) - return ENOTSUP; - - if (INVALID_CLOCK_P (clock_id)) + if (clock_id < CLOCK_REALTIME || clock_id > CLOCK_THREAD_CPUTIME_ID) return EINVAL; /* If we got an absolute time, remap it. */ @@ -71,7 +49,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, assert (sizeof (sec) >= sizeof (now.tv_sec)); /* Get the current time for this clock. */ - if (__builtin_expect (__clock_gettime (clock_id, &now), 0) != 0) + if (__clock_gettime (clock_id, &now) != 0) return errno; /* Compute the difference. */ @@ -90,12 +68,12 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, /* Make sure we are not modifying the struct pointed to by REM. */ rem = NULL; } - else if (__builtin_expect (flags, 0) != 0) + else if (flags != 0) return EINVAL; else if (clock_id != CLOCK_REALTIME) /* Not supported. */ return ENOTSUP; - return __builtin_expect (__nanosleep (req, rem), 0) ? errno : 0; + return __nanosleep (req, rem), 0 ? errno : 0; } weak_alias (__clock_nanosleep, clock_nanosleep) diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c index dcf9ff660a..109a1ad872 100644 --- a/sysdeps/unix/clock_settime.c +++ b/sysdeps/unix/clock_settime.c @@ -21,59 +21,11 @@ #include -#if HP_TIMING_AVAIL -/* Clock frequency of the processor. We make it a 64-bit variable - because some jokers are already playing with processors with more - than 4GHz. */ -static hp_timing_t freq; - - -/* This function is defined in the thread library. */ -extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset) - __attribute__ ((__weak__)); - - -static int -hp_timing_settime (clockid_t clock_id, const struct timespec *tp) -{ - hp_timing_t tsc; - hp_timing_t usertime; - - /* First thing is to get the current time. */ - HP_TIMING_NOW (tsc); - - if (__glibc_unlikely (freq == 0)) - { - /* This can only happen if we haven't initialized the `freq' - variable yet. Do this now. We don't have to protect this - code against multiple execution since all of them should lead - to the same result. */ - freq = __get_clockfreq (); - if (__glibc_unlikely (freq == 0)) - /* Something went wrong. */ - return -1; - } - - /* Convert the user-provided time into CPU ticks. */ - usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull; - - /* Determine the offset and use it as the new base value. */ - if (clock_id == CLOCK_PROCESS_CPUTIME_ID - || __pthread_clock_settime == NULL) - GL(dl_cpuclock_offset) = tsc - usertime; - else - __pthread_clock_settime (clock_id, tsc - usertime); - - return 0; -} -#endif - - /* Set CLOCK to value TP. */ int __clock_settime (clockid_t clock_id, const struct timespec *tp) { - int retval; + int retval = -1; /* Make sure the time cvalue is OK. */ if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000) @@ -93,16 +45,7 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp) break; default: -# if HP_TIMING_AVAIL - if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID - || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID) - retval = hp_timing_settime (clock_id, tp); - else -# endif - { - __set_errno (EINVAL); - retval = -1; - } + __set_errno (EINVAL); break; } From patchwork Mon Feb 18 21:11:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 158649 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2938413jaa; Mon, 18 Feb 2019 13:12:01 -0800 (PST) X-Google-Smtp-Source: AHgI3IZ1sR1+k4nd/Df64YaRZKLsLNC2qHWvOXpMmke8UFjkFU8/LhED4tQDFCSZ0Lv1Ybaxw1do X-Received: by 2002:a62:4254:: with SMTP id p81mr26039934pfa.185.1550524321529; Mon, 18 Feb 2019 13:12:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550524321; cv=none; d=google.com; s=arc-20160816; b=w3XpzrEnHW8heSJvo84vGEYNWI2qKNMkJ9DbijF/wDZImbTjEZpaWr6jPf6kyKMOgh wXnMufyvpfpNr3AymkaKNMTdlBWVHexOMzLd1SS3ogJ02AkMGgfeJRP0YVQpjEHtBpXU tKFGnsSY+Tba6lMV6+1MseA7tJl/AdljAvxqn/12ASOmPVMgmzvst6YJSXMneciwuTdn vCr1B1x1prJQ4CKzLJioSNsvyt5htQ3gw8zOUqxdLBbgNalm28B1JvGmu0mUvJyybuRB SmwYJZ/rn38whpD425FlK+YtwgYnAZ2c1fgS8fVnXjFI0uh39X/DqlUrr/UbZS6cHZ+G wmaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=sTKeh7xLlpBEWwhYozLZU7XnJkRQ0oCpX2E+snoaAU8=; b=bcGJc625Tp8TFiEvH+tRrIARXaqC28f0vrV+3LgLvCuGv2dZOm2qqLqAr2gGN0X5An oKFrWllpk0PZjOOznrLDvHagjo4RAesSIwPPtfDO4mP7c8dP+J1HdsV2lZelEw8mV7m6 AJwVrP6rLjRTw2nzMPp1o0yaP7nOE39bDNn4sIpEdFGc52cgU8S38UiuJy0Oi5seBGOS 6DyRRk59hYWsWegbjOGCDAKnc7M30tiJBl0nREcGxFzBibmiOMP8ywAHorCDrdkjKkEt S5OKrH/xaNM1wBYhTRezc0CxpG9uUql915RAz2KPEEQ+AY7JUypPiKm2pBpKTycNoUV+ u5RA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=P8Bw9Kk7; dkim=pass header.i=@linaro.org header.s=google header.b=Xb7zYANY; spf=pass (google.com: domain of libc-alpha-return-100124-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100124-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id x38si14062132pgl.419.2019.02.18.13.12.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 13:12:01 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-100124-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=P8Bw9Kk7; dkim=pass header.i=@linaro.org header.s=google header.b=Xb7zYANY; spf=pass (google.com: domain of libc-alpha-return-100124-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100124-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=Z2CeDkFoWoYOb12N1ox1F4aFdua+qJ1 OuShf6Uo2+bFdTLc2EYEFxmvzR4C0Y8eBMceMvKe5A92iWoUrF1P1htyey5S+tzt cdwMIrcfjt1WMbMSUS4plpBnO6p1EOtGBI2x5I+pEB9j3PSwQ4LE3rEjuN6jB6mz q3UZ/F/9X9X4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=CPsoMxEsk5JXPENaTJStaW89EbY=; b=P8Bw9 Kk7175OUElUTKcdQ3s+IHdwidSvUioNV9rjfLNrSWNbQlkHRoLZ0J+tTqJFDfzsv IQbzqxj4CH6CccAspA3g1kA8ZtsSBUuhmw96dwVNdXbKvGXUu3tVnL+H67PfAkbC GEEb+XTfVJzJkM75nY8iwjp7APHfDW0aTQ11AA= Received: (qmail 60724 invoked by alias); 18 Feb 2019 21:11:40 -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 60608 invoked by uid 89); 18 Feb 2019 21:11:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Try, distributed, sk:interna, consolidate X-HELO: mail-qk1-f195.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=sTKeh7xLlpBEWwhYozLZU7XnJkRQ0oCpX2E+snoaAU8=; b=Xb7zYANY22xahYX7TCiMsS3tv6CwbuOHLG7lqYD0vBTvBG6AZAM52lELXKwJve3zVw 5CpBslU4Ltw+dmLrk4smqt3pW+eL3oAoqpdCMkdWx0l/aTms5Xiihty0vY87GRWwYUqe O45o29mqD+nXBhTvymi+WEiQNk1kwaGbzngO9aZNFFNjLaNRFMukemrviA/reh6t5YSW A2kw7UpCYWX8T+ummuL37bBNmF5zTL2eRPuvyUGRFNaLxlJWSvuiUpQVdHl4Vc4Arrok lEVrZocq4SyrX2vWUJI02gh335ihwCpgYMvxodS6Q0yeaU0gCR/GT1KzNeLUrQkNPCkE xE2w== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS, THREAD}_CPUTIME_ID Date: Mon, 18 Feb 2019 18:11:24 -0300 Message-Id: <20190218211128.1869-2-adhemerval.zanella@linaro.org> In-Reply-To: <20190218211128.1869-1-adhemerval.zanella@linaro.org> References: <20190218211128.1869-1-adhemerval.zanella@linaro.org> Changes from previous version: - Remove ia64 itc drift check and assume kernel handles it correctly. --- This patch assumes that clock_getres syscall always support CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, so there is no need to fallback to hp-timing support for _SC_MONOTONIC_CLOCK. This allows simplify the sysconf support to always use the syscall. The ia64 implementation is also simplified and consolidate in one file. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. * sysdeps/unix/sysv/linux/ia64/has_cpuclock.c: Remove file. * sysdeps/unix/sysv/linux/ia64/sysconf.c: Likewise. * sysdeps/unix/sysv/linux/sysconf.c (has_cpuclock): Remove function. (check_clock_getres): New function. (__sysconf): Use check_clock_getres instead of has_cpuclock. --- sysdeps/unix/sysv/linux/ia64/has_cpuclock.c | 51 --------------------- sysdeps/unix/sysv/linux/ia64/sysconf.c | 30 ------------ sysdeps/unix/sysv/linux/sysconf.c | 48 ++++++------------- 3 files changed, 13 insertions(+), 116 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/ia64/has_cpuclock.c delete mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf.c -- 2.17.1 diff --git a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c b/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c deleted file mode 100644 index b3afb37f8b..0000000000 --- a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 2000-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include - -static int itc_usable; - -static int -has_cpuclock (void) -{ - if (__builtin_expect (itc_usable == 0, 0)) - { - int newval = 1; - int fd = __open_nocancel ("/proc/sal/itc_drift", O_RDONLY); - if (__builtin_expect (fd != -1, 1)) - { - char buf[16]; - /* We expect the file to contain a single digit followed by - a newline. If the format changes we better not rely on - the file content. */ - if (__read_nocancel (fd, buf, sizeof buf) != 2 - || buf[0] != '0' || buf[1] != '\n') - newval = -1; - - __close_nocancel_nostatus (fd); - } - - itc_usable = newval; - } - - return itc_usable; -} diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf.c b/sysdeps/unix/sysv/linux/ia64/sysconf.c deleted file mode 100644 index ef75322f1f..0000000000 --- a/sysdeps/unix/sysv/linux/ia64/sysconf.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Get file-specific information about a file. Linux/ia64 version. - Copyright (C) 2003-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - - -#include "has_cpuclock.c" -#define HAS_CPUCLOCK(name) (has_cpuclock () ? _POSIX_VERSION : -1) - - -/* Now the generic Linux version. */ -#include diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c index 4b297ba35f..2027444488 100644 --- a/sysdeps/unix/sysv/linux/sysconf.c +++ b/sysdeps/unix/sysv/linux/sysconf.c @@ -35,33 +35,18 @@ static long int posix_sysconf (int name); -#ifndef HAS_CPUCLOCK static long int -has_cpuclock (int name) +check_clock_getres (clockid_t clk_id) { -# if defined __NR_clock_getres || HP_TIMING_AVAIL - /* If we have HP_TIMING, we will fall back on that if the system - call does not work, so we support it either way. */ -# if !HP_TIMING_AVAIL - /* Check using the clock_getres system call. */ struct timespec ts; INTERNAL_SYSCALL_DECL (err); - int r = INTERNAL_SYSCALL (clock_getres, err, 2, - (name == _SC_CPUTIME - ? CLOCK_PROCESS_CPUTIME_ID - : CLOCK_THREAD_CPUTIME_ID), - &ts); + /* Avoid setting errno to we can check whether the kernel supports + the CLK_ID. */ + int r = INTERNAL_SYSCALL_CALL (clock_getres, err, clk_id, &ts); if (INTERNAL_SYSCALL_ERROR_P (r, err)) return -1; -# endif return _POSIX_VERSION; -# else - return -1; -# endif } -# define HAS_CPUCLOCK(name) has_cpuclock (name) -#endif - /* Get the value of the system variable NAME. */ long int @@ -71,29 +56,21 @@ __sysconf (int name) switch (name) { - struct rlimit rlimit; -#ifdef __NR_clock_getres case _SC_MONOTONIC_CLOCK: - /* Check using the clock_getres system call. */ - { - struct timespec ts; - INTERNAL_SYSCALL_DECL (err); - int r; - r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts); - return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION; - } -#endif - + return check_clock_getres (CLOCK_MONOTONIC); case _SC_CPUTIME: + return check_clock_getres (CLOCK_PROCESS_CPUTIME_ID); case _SC_THREAD_CPUTIME: - return HAS_CPUCLOCK (name); + return check_clock_getres (CLOCK_THREAD_CPUTIME_ID); - case _SC_ARG_MAX: + case _SC_ARG_MAX: { + struct rlimit rlimit; /* Use getrlimit to get the stack limit. */ if (__getrlimit (RLIMIT_STACK, &rlimit) == 0) return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4); return legacy_ARG_MAX; + } break; case _SC_NGROUPS_MAX: /* Try to read the information from the /proc/sys/kernel/ngroups_max @@ -101,13 +78,14 @@ __sysconf (int name) procfname = "/proc/sys/kernel/ngroups_max"; break; - case _SC_SIGQUEUE_MAX: + case _SC_SIGQUEUE_MAX: { + struct rlimit rlimit; if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0) return rlimit.rlim_cur; /* The /proc/sys/kernel/rtsig-max file contains the answer. */ procfname = "/proc/sys/kernel/rtsig-max"; - break; + } break; default: break; From patchwork Mon Feb 18 21:11:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 158652 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2938954jaa; Mon, 18 Feb 2019 13:12:38 -0800 (PST) X-Google-Smtp-Source: AHgI3IaYFNZ4ma0gXP3TGrg7gHsopGwWf3WNLTp9t9O25UccjniMWsjYeQbKh/2NDmuVGxtc8K6d X-Received: by 2002:a62:76d4:: with SMTP id r203mr26435686pfc.15.1550524358061; Mon, 18 Feb 2019 13:12:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550524358; cv=none; d=google.com; s=arc-20160816; b=FSFDiH8UhFwTKVUL6AB92Go7G3afJL4b8cejdKK4S9y7ymxxV4slzNNv5GIZAkCX6T F8xbiR7Dis+z14gaNqNGa2D5gK4TGy1Yo0Hz4cajeEaPzlqOsWES0TysrrhUSMG/Q7bQ p+E8KyJyHaT9WBud61zkxUVRLQW+Jq5hTuiP3vP25kwn68wI6VDc7JtUP3WchQC8VIy/ AwJCLTA/jf/g2WEhjvcRkWPvDgARmUEaHGTBkmKLrF8XTfV+W6DDXoq8NigyTj3Dqj0M 906XojYf3hHg3ELGH2ifJsJuKPDD4IuX7xHJfkTluDFxPd4yBQju7ZStUMcRW6nGWx6T TkAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=XIeDb4Crb6AkGf/TmDYiEpwj053vxH+VyRJUjwwFkcE=; b=Tzhic0ecbgIdBaxVB2pP+eVKMpOziYlegviL2mVu9bSsJQyQdzV1UtA7cFD89ulHwJ Ez/eKuDahgU0b8umUvmoygxMseZlbOaT4p+k9OT1WEhrEIQAg6f5TsTXmWzN6qjQrFuI hpmfG1LfevT7FEuyZIVO6eTqIps3HPb+Lt+I8GXir41A8XPvmuw3Qgoo8+XXDYOpZb/E VBnWAi/4hfMahHTedU0e7tBjE+lIThCtEG6xtNXT5tD+YQfId1UFEMYtJBL86NgKs0/O dR+1h2g31xlMU2HDDyIlaKQFnsNKVX5EsBo2zsOFWDCBFeQjWEOBqu8BCMUEAVxu+Srm uM8A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b="R6W/6IaZ"; dkim=pass header.i=@linaro.org header.s=google header.b=WpLct4TH; spf=pass (google.com: domain of libc-alpha-return-100127-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100127-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id i11si1933777pfi.61.2019.02.18.13.12.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 13:12:38 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-100127-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b="R6W/6IaZ"; dkim=pass header.i=@linaro.org header.s=google header.b=WpLct4TH; spf=pass (google.com: domain of libc-alpha-return-100127-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100127-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=GGRg4ZhvvMDPNzlDwaa6nJq9G/Y4kLm Epl3rwpoS19XujS4QaUmsfyyWclTCXWOzFKMUUzrtJK3yCPHoMfAwTB0BaviQIJO k6b5fBWlu1ezpAOMBvu9EVBPMcfuiW070mJSer3aVoXB2Om2xxRp1fPSswsWcvaw KdzH04gbpBM8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=3lxaSFHAQfg4y1qIYSdIx3dcMo0=; b=R6W/6 IaZQntvXrafwIAxxLq2ZtDA0YMVlLz8nglvwvI3yqETWdQ2WJZqECoKTax/wLJ/G RfZqKA58gCmNuIzDQZa5kRzBb6R+Dht221eShoplCN4ZveX7cbvOyeCyubPnr2Gf 39+bNfeoX3CQCfyilJ2Nw0A6YWkeEaSHiHmm54= Received: (qmail 61746 invoked by alias); 18 Feb 2019 21:11:46 -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 61629 invoked by uid 89); 18 Feb 2019 21:11:46 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=insure, 1107, distributed, MHz X-HELO: mail-qt1-f195.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=XIeDb4Crb6AkGf/TmDYiEpwj053vxH+VyRJUjwwFkcE=; b=WpLct4THwAcYtxjUcX2hf8UTLNMIbNbgs96NWplfxrwFDvjUZ4thZ79cFHdK3OwoTb Kb5M9DpjaaPC+XVE0CpqcfrbjWl0JmGpw8ktU5Df4rYbslkHmj1tdQ7hLuSYRmOJqRnI TIf0oQuNf4VO+s7EseayqwgNuS7oalEXYEyFYqnRQpG8LsoU+YE+2FFPNWGKkyiMCnx2 U8HwPJmBTMWlaSYgsaMAaFC+ahtzlqK2GjfIPR1kGAEocPQPS6aDJEGElkWJLm34ENyp tj/BkZCdovoechYBDQFQR8gkk0A2FBFeOH6OsUgHD4RKY6AZIh/Cwwhe/G/HCaMcpAUM RXYQ== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 3/6] Remove __get_clockfreq Date: Mon, 18 Feb 2019 18:11:25 -0300 Message-Id: <20190218211128.1869-3-adhemerval.zanella@linaro.org> In-Reply-To: <20190218211128.1869-1-adhemerval.zanella@linaro.org> References: <20190218211128.1869-1-adhemerval.zanella@linaro.org> With clock_getres, clock_gettime, and clock_settime refactor to remove the generic CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID support through hp-timing, there is no usage of internal __get_clockfreq. This patch removes both generic and Linux implementation.. Checked with a build against aarch64-linux-gnu, i686-linux-gnu, ia64-linux-gnu, sparc64-linux-gnu, powerpc-linux-gnu-power4. * include/libc-internal.h (__get_clockfreq): Remove prototype. * rt/Makefile (clock-routines): Remove get_clockfreq. * rt/get_clockfreq.c: Remove file. * sysdeps/unix/sysv/linux/i386/get_clockfreq.c: Likewise. * sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Likewise. * sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c: Move code to ... * sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: ... here. --- include/libc-internal.h | 3 - rt/Makefile | 2 +- rt/get_clockfreq.c | 27 -- sysdeps/unix/sysv/linux/i386/get_clockfreq.c | 88 ------ sysdeps/unix/sysv/linux/ia64/get_clockfreq.c | 87 ------ .../unix/sysv/linux/powerpc/get_clockfreq.c | 107 -------- .../sysv/linux/powerpc/get_timebase_freq.c | 81 +++++- .../sysv/linux/sparc/sparc64/get_clockfreq.c | 250 ------------------ 8 files changed, 81 insertions(+), 564 deletions(-) delete mode 100644 rt/get_clockfreq.c delete mode 100644 sysdeps/unix/sysv/linux/i386/get_clockfreq.c delete mode 100644 sysdeps/unix/sysv/linux/ia64/get_clockfreq.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c -- 2.17.1 diff --git a/include/libc-internal.h b/include/libc-internal.h index 70edd77f81..db4d12432c 100644 --- a/include/libc-internal.h +++ b/include/libc-internal.h @@ -36,9 +36,6 @@ libc_hidden_proto (__profile_frequency) extern void __cyg_profile_func_enter (void *this_fn, void *call_site); extern void __cyg_profile_func_exit (void *this_fn, void *call_site); -/* Get frequency of the system processor. */ -extern hp_timing_t __get_clockfreq (void); - /* Free all allocated resources. */ extern void __libc_freeres (void); libc_hidden_proto (__libc_freeres) diff --git a/rt/Makefile b/rt/Makefile index 0789bb8db7..9ea8394565 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -28,7 +28,7 @@ aio-routines := aio_cancel aio_error aio_fsync aio_misc aio_read \ aio_read64 aio_return aio_suspend aio_write \ aio_write64 lio_listio lio_listio64 aio_sigqueue \ aio_notify -clock-routines := get_clockfreq clock_getcpuclockid \ +clock-routines := clock_getcpuclockid \ clock_getres clock_gettime clock_settime \ clock_nanosleep timer-routines := timer_create timer_delete timer_getoverr \ diff --git a/rt/get_clockfreq.c b/rt/get_clockfreq.c deleted file mode 100644 index e62a7a5118..0000000000 --- a/rt/get_clockfreq.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Get frequency of the system processor. - Copyright (C) 2000-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -hp_timing_t -__get_clockfreq (void) -{ - /* There is no generic way to find this out since we have in general - no counter register either. */ - return 0; -} diff --git a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c b/sysdeps/unix/sysv/linux/i386/get_clockfreq.c deleted file mode 100644 index 621d52491b..0000000000 --- a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Get frequency of the system processor. i386/Linux version. - Copyright (C) 2000-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - -hp_timing_t -__get_clockfreq (void) -{ - /* We read the information from the /proc filesystem. It contains at - least one line like - cpu MHz : 497.840237 - or also - cpu MHz : 497.841 - We search for this line and convert the number in an integer. */ - static hp_timing_t result; - int fd; - - /* If this function was called before, we know the result. */ - if (result != 0) - return result; - - fd = __open ("/proc/cpuinfo", O_RDONLY); - if (__glibc_likely (fd != -1)) - { - /* XXX AFAIK the /proc filesystem can generate "files" only up - to a size of 4096 bytes. */ - char buf[4096]; - ssize_t n; - - n = __read (fd, buf, sizeof buf); - if (__builtin_expect (n, 1) > 0) - { - char *mhz = memmem (buf, n, "cpu MHz", 7); - - if (__glibc_likely (mhz != NULL)) - { - char *endp = buf + n; - int seen_decpoint = 0; - int ndigits = 0; - - /* Search for the beginning of the string. */ - while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') - ++mhz; - - while (mhz < endp && *mhz != '\n') - { - if (*mhz >= '0' && *mhz <= '9') - { - result *= 10; - result += *mhz - '0'; - if (seen_decpoint) - ++ndigits; - } - else if (*mhz == '.') - seen_decpoint = 1; - - ++mhz; - } - - /* Compensate for missing digits at the end. */ - while (ndigits++ < 6) - result *= 10; - } - } - - __close (fd); - } - - return result; -} diff --git a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c b/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c deleted file mode 100644 index 581f87f3e6..0000000000 --- a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Get frequency of the system processor. IA-64/Linux version. - Copyright (C) 2001-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include - - -hp_timing_t -__get_clockfreq (void) -{ - /* We read the information from the /proc filesystem. It contains at - least one line like - itc MHz : 733.390988 - We search for this line and convert the number in an integer. */ - static hp_timing_t result; - int fd; - - /* If this function was called before, we know the result. */ - if (result != 0) - return result; - - fd = __open ("/proc/cpuinfo", O_RDONLY); - if (__builtin_expect (fd != -1, 1)) - { - /* XXX AFAIK the /proc filesystem can generate "files" only up - to a size of 4096 bytes. */ - char buf[4096]; - ssize_t n; - - n = __read (fd, buf, sizeof buf); - if (__builtin_expect (n, 1) > 0) - { - char *mhz = memmem (buf, n, "itc MHz", 7); - - if (__builtin_expect (mhz != NULL, 1)) - { - char *endp = buf + n; - int seen_decpoint = 0; - int ndigits = 0; - - /* Search for the beginning of the string. */ - while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') - ++mhz; - - while (mhz < endp && *mhz != '\n') - { - if (*mhz >= '0' && *mhz <= '9') - { - result *= 10; - result += *mhz - '0'; - if (seen_decpoint) - ++ndigits; - } - else if (*mhz == '.') - seen_decpoint = 1; - - ++mhz; - } - - /* Compensate for missing digits at the end. */ - while (ndigits++ < 6) - result *= 10; - } - } - - __close (fd); - } - - return result; -} diff --git a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c deleted file mode 100644 index 98668fa718..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Get frequency of the system processor. powerpc/Linux version. - Copyright (C) 2000-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include - -hp_timing_t -__get_clockfreq (void) -{ - hp_timing_t result = 0L; - -#ifdef SHARED - /* The vDSO does not return an error (it clear cr0.so on returning). */ - INTERNAL_SYSCALL_DECL (err); - result = - INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0); -#else - /* We read the information from the /proc filesystem. /proc/cpuinfo - contains at least one line like: - timebase : 33333333 - We search for this line and convert the number into an integer. */ - int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY); - if (__glibc_likely (fd != -1)) - return result; - - /* The timebase will be in the 1st 1024 bytes for systems with up - to 8 processors. If the first read returns less then 1024 - bytes read, we have the whole cpuinfo and can start the scan. - Otherwise we will have to read more to insure we have the - timebase value in the scan. */ - char buf[1024]; - ssize_t n; - - n = __read_nocancel (fd, buf, sizeof (buf)); - if (n == sizeof (buf)) - { - /* We are here because the 1st read returned exactly sizeof - (buf) bytes. This implies that we are not at EOF and may - not have read the timebase value yet. So we need to read - more bytes until we know we have EOF. We copy the lower - half of buf to the upper half and read sizeof (buf)/2 - bytes into the lower half of buf and repeat until we - reach EOF. We can assume that the timebase will be in - the last 512 bytes of cpuinfo, so two 512 byte half_bufs - will be sufficient to contain the timebase and will - handle the case where the timebase spans the half_buf - boundry. */ - const ssize_t half_buf = sizeof (buf) / 2; - while (n >= half_buf) - { - memcpy (buf, buf + half_buf, half_buf); - n = __read_nocancel (fd, buf + half_buf, half_buf); - } - if (n >= 0) - n += half_buf; - } - __close_nocancel (fd); - - if (__glibc_likely (n > 0)) - { - char *mhz = memmem (buf, n, "timebase", 7); - - if (__glibc_likely (mhz != NULL)) - { - char *endp = buf + n; - - /* Search for the beginning of the string. */ - while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') - ++mhz; - - while (mhz < endp && *mhz != '\n') - { - if (*mhz >= '0' && *mhz <= '9') - { - result *= 10; - result += *mhz - '0'; - } - - ++mhz; - } - } - } -#endif - - return result; -} diff --git a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c index 5903a909e3..23e7694d87 100644 --- a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c +++ b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c @@ -17,11 +17,90 @@ . */ #include +#include + #include +#include +#include uint64_t __get_timebase_freq (void) { - return (uint64_t) __get_clockfreq (); + hp_timing_t result = 0L; + +#ifdef SHARED + /* The vDSO does not return an error (it clear cr0.so on returning). */ + INTERNAL_SYSCALL_DECL (err); + result = + INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0); +#else + /* We read the information from the /proc filesystem. /proc/cpuinfo + contains at least one line like: + timebase : 33333333 + We search for this line and convert the number into an integer. */ + int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY); + if (__glibc_likely (fd != -1)) + return result; + + /* The timebase will be in the 1st 1024 bytes for systems with up + to 8 processors. If the first read returns less then 1024 + bytes read, we have the whole cpuinfo and can start the scan. + Otherwise we will have to read more to insure we have the + timebase value in the scan. */ + char buf[1024]; + ssize_t n; + + n = __read_nocancel (fd, buf, sizeof (buf)); + if (n == sizeof (buf)) + { + /* We are here because the 1st read returned exactly sizeof + (buf) bytes. This implies that we are not at EOF and may + not have read the timebase value yet. So we need to read + more bytes until we know we have EOF. We copy the lower + half of buf to the upper half and read sizeof (buf)/2 + bytes into the lower half of buf and repeat until we + reach EOF. We can assume that the timebase will be in + the last 512 bytes of cpuinfo, so two 512 byte half_bufs + will be sufficient to contain the timebase and will + handle the case where the timebase spans the half_buf + boundry. */ + const ssize_t half_buf = sizeof (buf) / 2; + while (n >= half_buf) + { + memcpy (buf, buf + half_buf, half_buf); + n = __read_nocancel (fd, buf + half_buf, half_buf); + } + if (n >= 0) + n += half_buf; + } + __close_nocancel (fd); + + if (__glibc_likely (n > 0)) + { + char *mhz = memmem (buf, n, "timebase", 7); + + if (__glibc_likely (mhz != NULL)) + { + char *endp = buf + n; + + /* Search for the beginning of the string. */ + while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') + ++mhz; + + while (mhz < endp && *mhz != '\n') + { + if (*mhz >= '0' && *mhz <= '9') + { + result *= 10; + result += *mhz - '0'; + } + + ++mhz; + } + } + } +#endif + + return result; } weak_alias (__get_timebase_freq, __ppc_get_timebase_freq) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c b/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c deleted file mode 100644 index 87853d6b6e..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c +++ /dev/null @@ -1,250 +0,0 @@ -/* Get frequency of the system processor. sparc64 version. - Copyright (C) 2001-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static hp_timing_t -__get_clockfreq_via_cpuinfo (void) -{ - hp_timing_t result; - int fd; - - result = 0; - - fd = __open ("/proc/cpuinfo", O_RDONLY); - if (fd != -1) - { - char buf[8192]; - ssize_t n; - - n = __read (fd, buf, sizeof buf); - if (n > 0) - { - char *mhz = memmem (buf, n, "Cpu0ClkTck", 7); - - if (mhz != NULL) - { - char *endp = buf + n; - - /* Search for the beginning of the string. */ - while (mhz < endp - && (*mhz < '0' || *mhz > '9') - && (*mhz < 'a' || *mhz > 'f') - && *mhz != '\n') - ++mhz; - - while (mhz < endp && *mhz != '\n') - { - if ((*mhz >= '0' && *mhz <= '9') || - (*mhz >= 'a' && *mhz <= 'f')) - { - result <<= 4; - if (*mhz >= '0' && *mhz <= '9') - result += *mhz - '0'; - else - result += (*mhz - 'a') + 10; - } - ++mhz; - } - } - } - - __close (fd); - } - - return result; -} - -static hp_timing_t -__get_clockfreq_via_proc_openprom (void) -{ - hp_timing_t result; - int obp_fd; - - result = 0; - - obp_fd = __open ("/proc/openprom", O_RDONLY); - if (obp_fd != -1) - { - unsigned long int buf[4096 / sizeof (unsigned long int)]; - struct dirent64 *dirp = (struct dirent64 *) buf; - ssize_t len; - - while ((len = __getdents64 (obp_fd, (char *) dirp, sizeof (buf))) > 0) - { - struct dirent64 *this_dirp = dirp; - - while (len > 0) - { - char node[strlen ("/proc/openprom/") - + _D_ALLOC_NAMLEN (this_dirp) - + strlen ("/clock-frequency")]; - char *prop; - int fd; - - /* Note that - strlen("/clock-frequency") > strlen("/device_type") - */ - __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"), - this_dirp->d_name), - "/device_type"); - fd = __open (node, O_RDONLY); - if (fd != -1) - { - char type_string[128]; - int ret; - - ret = __read (fd, type_string, sizeof (type_string)); - if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0) - { - int clkfreq_fd; - - __stpcpy (prop, "/clock-frequency"); - clkfreq_fd = __open (node, O_RDONLY); - if (clkfreq_fd != -1) - { - if (__read (clkfreq_fd, type_string, - sizeof (type_string)) > 0) - result = (hp_timing_t) - strtoumax (type_string, NULL, 16); - __close (clkfreq_fd); - } - } - __close (fd); - } - - if (result != 0) - break; - - len -= this_dirp->d_reclen; - this_dirp = (struct dirent64 *) - ((char *) this_dirp + this_dirp->d_reclen); - } - if (result != 0) - break; - } - __close (obp_fd); - } - - return result; -} - -static void set_obp_int (struct openpromio *op, int val) -{ - char *cp = op->oprom_array; - int *ip = (int *) cp; - - *ip = val; -} - -static int get_obp_int (struct openpromio *op) -{ - char *cp = op->oprom_array; - int *ip = (int *) cp; - - return *ip; -} - -static hp_timing_t -__get_clockfreq_via_dev_openprom (void) -{ - hp_timing_t result; - int obp_dev_fd; - - result = 0; - - obp_dev_fd = __open ("/dev/openprom", O_RDONLY); - if (obp_dev_fd != -1) - { - char obp_buf[8192]; - struct openpromio *obp_cmd = (struct openpromio *)obp_buf; - int ret; - - obp_cmd->oprom_size = - sizeof (obp_buf) - sizeof (unsigned int); - set_obp_int (obp_cmd, 0); - ret = __ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd); - if (ret == 0) - { - int cur_node = get_obp_int (obp_cmd); - - while (cur_node != 0 && cur_node != -1) - { - obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int); - strcpy (obp_cmd->oprom_array, "device_type"); - ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd); - if (ret == 0 - && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0) - { - obp_cmd->oprom_size = (sizeof (obp_buf) - - sizeof (unsigned int)); - strcpy (obp_cmd->oprom_array, "clock-frequency"); - ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd); - if (ret == 0) - result = (hp_timing_t) get_obp_int (obp_cmd); - } - obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int); - set_obp_int (obp_cmd, cur_node); - ret = __ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd); - if (ret < 0) - break; - cur_node = get_obp_int (obp_cmd); - } - } - } - - return result; -} - -hp_timing_t -__get_clockfreq (void) -{ - static hp_timing_t result; - - /* If this function was called before, we know the result. */ - if (result != 0) - return result; - - /* We first read the information from the /proc/cpuinfo file. - It contains at least one line like - Cpu0ClkTick : 000000002cb41780 - We search for this line and convert the number in an integer. */ - result = __get_clockfreq_via_cpuinfo (); - if (result != 0) - return result; - - /* If that did not work, try to find an OpenPROM node - with device_type equal to 'cpu' using /dev/openprom - and fetch the clock-frequency property from there. */ - result = __get_clockfreq_via_dev_openprom (); - if (result != 0) - return result; - - /* Finally, try the same lookup as above but using /proc/openprom. */ - result = __get_clockfreq_via_proc_openprom (); - - return result; -} From patchwork Mon Feb 18 21:11:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 158651 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2938772jaa; Mon, 18 Feb 2019 13:12:24 -0800 (PST) X-Google-Smtp-Source: AHgI3IYpdldDknoAHZeBBjwcq1YC7swbl+16xIitaQPTZnj+VeutO3cPANyrfd8W3wASTuPQXhQt X-Received: by 2002:a62:39c5:: with SMTP id u66mr25887361pfj.245.1550524344878; Mon, 18 Feb 2019 13:12:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550524344; cv=none; d=google.com; s=arc-20160816; b=w6y90JHnr1pGFoEmCOzsdMpZ8lI7jBaU2Wl1bmFse+R1q7kH8XpvaegtIUQoG1ejxP 83MIu1xs8IEetJk1jTP7JuLTWOzS2PGGCum0I/o2KjEk5GRGPmHWf6nj2A1JvWZQCc7n EFkABC8uORtAPRiLg2V4l5GKtV/gXGkWjAHy/AimiOfPoMU78PGLAeG0qH7GpvX/CLiU FxQBKCtB/FwMi3vCq/4LCj/b7mN0lggq1hYyh2ISOCFeInJDsQX2PYoyKV7TX5zfWAIQ ydE1N64n1VrqABofL9B+ljlRYDBa8PJKP6OFVDm/moTDiIQu63enAI9gDS5WAqcUd3T0 StQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=+ngNda9kpTZE19QLoRBzELu9DzT2KQbqCJlVtBolT/Y=; b=b1iiOIw+CUIOnPr0n7ygt2GO+oY2VQs4TTSR00sE90rg6bFUprDgfS6DV9KR1kUVlW L8+JsvyhZT4wA8KMqrGk0ATdGFeKz82zUh5C8L5lgI13dQ1TZai+tC6rg/LIerrQEXdm mZH1vObsfmCJdYRUJv8/UIiVYLhsbxIFD/d6NOJHfPtWSDTDyj/Jsk7qhCJQFwxyz+AZ EqF2D3RJFKoWLeSK5wLW6JfrtSGUCC47QTbqMqbO03MklOSiGeDXfx8Zaq04LhDGV2tV SauPazUcMNxsk96MwWdOJ8qPq600pJv21QFPg812FQ6HQT147G99TfnvfoKhNqFu1rPg AX1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=AvPLUDzy; dkim=pass header.i=@linaro.org header.s=google header.b=x+ISccG2; spf=pass (google.com: domain of libc-alpha-return-100126-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100126-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id d1si14418337plr.145.2019.02.18.13.12.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 13:12:24 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-100126-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=AvPLUDzy; dkim=pass header.i=@linaro.org header.s=google header.b=x+ISccG2; spf=pass (google.com: domain of libc-alpha-return-100126-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100126-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=Du8V/m23o5acSeWdZ9lwxnryBOjJ+Ri NU6pbZouOKVs598NGRXteQrY781KOEdtYmdLO9BmWwYvv0enMpgX+tlFjIlqOw1U Lgaer9wjaRtF+pqfZxPHLnNCvJIl3sc0QHSENjYz2PW14V9IKW6RjMS8sX/yO8KL D3mUEVNVeurY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=M22FNFieaC0M9lzGf/Wyp6gxcnE=; b=AvPLU Dzy5jkcAZvO1DAIw1P9bGUKR4iLpIssPJlN2GzdiiY2WkTjc3RSk5rjY7gcqDhVz 1ailGMOV5wAjt2lUGvYwobRei0ylKt0VpWubxNY64mWm8aPm6BnapG6y4C7W/BMb lgnk9l5jXgORB4wHfRcqZ07m/Hdn8l1rKr+K+4= Received: (qmail 61375 invoked by alias); 18 Feb 2019 21:11:44 -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 61251 invoked by uid 89); 18 Feb 2019 21:11:43 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=clock, distributed, accuracy, resp X-HELO: mail-qt1-f196.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=+ngNda9kpTZE19QLoRBzELu9DzT2KQbqCJlVtBolT/Y=; b=x+ISccG2CxsPVXa3MT7/dTAS5bqfdEshFnTLhMQywTzgXO56zov5Nj0ZlCMCbjKbmn DQz2pVNbhdRBaPCufFL9gJIgR4KBpDKzDxY9h1E1jB/sACuLZFSaQFeQ43ReFMaznEBB DC4LKttFVaWxSCcCjdM9sDJqJNbH7LTIQje7GRZX0M8K+1/MuHfg82Le6Z9lRp+y2T8/ 9lun5L3cFRmXBsJ5WE9ANy0S5GtJr8WfP0Eyd/hmecGFHFTnQDpt7mLwyY2OfhQj873X XRZ8P8tkZBiZhOcjVsDu4Pk+sJpBNyN9Jz4DBPUf6UIwt2/k3/Aas+tfbfmeg6zH2p6B 48Rw== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits Date: Mon, 18 Feb 2019 18:11:26 -0300 Message-Id: <20190218211128.1869-4-adhemerval.zanella@linaro.org> In-Reply-To: <20190218211128.1869-1-adhemerval.zanella@linaro.org> References: <20190218211128.1869-1-adhemerval.zanella@linaro.org> Changes from previous version: - Change random_bits return type to uint32_t and shuffle the bits internally to avoid clock bias. --- This patch removes the HP_TIMING_BITS usage for fast random bits and replace with clock_gettime (CLOCK_MONOTONIC). It has unspecified starting time and nano-second accuracy, so its randomness is significantly better than gettimeofday. Althoug it should incur in more overhead (specially for architecture that support hp-timing), the symbol is also common implemented as a vDSO. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also checked on a i686-gnu build. * include/random-bits.h: New file. * resolv/res_mkquery.c [HP_TIMING_AVAIL] (RANDOM_BITS, (__res_context_mkquery): Remove usage hp-timing usage and replace with random_bits. * resolv/res_send.c [HP_TIMING_AVAIL] (nameserver_offset): Likewise. * sysdeps/posix/tempname.c [HP_TIMING_AVAIL] (__gen_tempname): Likewise. --- include/random-bits.h | 41 ++++++++++++++++++++++++++++++++++++++++ resolv/res_mkquery.c | 19 +++---------------- resolv/res_send.c | 12 ++---------- sysdeps/posix/tempname.c | 19 +++---------------- 4 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 include/random-bits.h -- 2.17.1 diff --git a/include/random-bits.h b/include/random-bits.h new file mode 100644 index 0000000000..5ab53450af --- /dev/null +++ b/include/random-bits.h @@ -0,0 +1,41 @@ +/* Fast pseudo-random bits based on clock_gettime. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _RANDOM_BITS_H +# define _RANDOM_BITS_H + +#include +#include + +/* Provides fast pseudo-random bits through clock_gettime. It has unspecified + starting time, nano-second accuracy, its randomness is significantly better + than gettimeofday, and for mostly architectures it is implemented through + vDSO instead of a syscall. Since the source is a system clock, the upper + bits will have less entropy. */ +static inline uint32_t +random_bits (void) +{ + struct timespec tv; + __clock_gettime (CLOCK_MONOTONIC, &tv); + /* Shuffle the lower bits to minimize the clock bias. */ + uint32_t ret = tv.tv_nsec ^ tv.tv_sec; + ret ^= (ret << 24) | (ret >> 8); + return ret; +} + +#endif diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index 19b8b402c4..dd43d347af 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -82,6 +82,7 @@ * SOFTWARE. */ +#include #include #include #include @@ -92,12 +93,7 @@ #include #include #include - -#include -#include -#if HP_TIMING_AVAIL -# define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; } -#endif +#include int __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname, @@ -120,16 +116,7 @@ __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname, /* We randomize the IDs every time. The old code just incremented by one after the initial randomization which still predictable if the application does multiple requests. */ - int randombits; -#ifdef RANDOM_BITS - RANDOM_BITS (randombits); -#else - struct timeval tv; - __gettimeofday (&tv, NULL); - randombits = (tv.tv_sec << 8) ^ tv.tv_usec; -#endif - - hp->id = randombits; + hp->id = random_bits (); hp->opcode = op; hp->rd = (ctx->resp->options & RES_RECURSE) != 0; hp->rcode = NOERROR; diff --git a/resolv/res_send.c b/resolv/res_send.c index fa040c1198..1b59b6080c 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -109,7 +109,7 @@ #include #include #include -#include +#include #if PACKETSZ > 65536 #define MAXPACKET PACKETSZ @@ -309,15 +309,7 @@ nameserver_offset (struct __res_state *statp) if ((offset & 1) == 0) { /* Initialization is required. */ -#if HP_TIMING_AVAIL - uint64_t ticks; - HP_TIMING_NOW (ticks); - offset = ticks; -#else - struct timeval tv; - __gettimeofday (&tv, NULL); - offset = ((tv.tv_sec << 8) ^ tv.tv_usec); -#endif + offset = random_bits (); /* The lowest bit is the most random. Preserve it. */ offset <<= 1; diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c index 2ed39d1a42..5217cb38e1 100644 --- a/sysdeps/posix/tempname.c +++ b/sysdeps/posix/tempname.c @@ -71,22 +71,8 @@ #endif #ifdef _LIBC -# include -# if HP_TIMING_AVAIL -# define RANDOM_BITS(Var) \ - if (__glibc_unlikely (value == UINT64_C (0))) \ - { \ - /* If this is the first time this function is used initialize \ - the variable we accumulate the value in to some somewhat \ - random value. If we'd not do this programs at startup time \ - might have a reduced set of possible names, at least on slow \ - machines. */ \ - struct timeval tv; \ - __gettimeofday (&tv, NULL); \ - value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ - } \ - HP_TIMING_NOW (Var) -# endif +# include +# define RANDOM_BITS(Var) ((Var) = random_bits ()) #endif /* Use the widest available unsigned type if uint64_t is not @@ -237,6 +223,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) } #endif value += random_time_bits ^ __getpid (); + value += random_bits () ^ __getpid (); for (count = 0; count < attempts; value += 7777, ++count) { From patchwork Mon Feb 18 21:11:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 158654 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2939365jaa; Mon, 18 Feb 2019 13:13:06 -0800 (PST) X-Google-Smtp-Source: AHgI3Ib5aUS0ssyQDU8Djvf3IrQoVQn5OANnTWybD6onus+PUCu6PAW7mHFc2u1QAHutXuYfdQv8 X-Received: by 2002:a63:5964:: with SMTP id j36mr20597871pgm.210.1550524386322; Mon, 18 Feb 2019 13:13:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550524386; cv=none; d=google.com; s=arc-20160816; b=ue2GzR/pSOdAGRZyo2/DZhjJP4f/dtmTfYDUeuOJTaGrMEmrB10M3k1kRBSO3qQBgp 21a5mPNDxctUVajWg2QJMrVa0oRrDLejcgznLxRi9vVRnPskQAz4ysZeH6Q5iF1DZ+JS B7jsEv4LRLTRG/0xKAPcijVeY4DjATmz/N43+i+oiUAZels8mjP5XtTj/iabf2mI4HaI jhPNBfi6aOSEL0AeKEfhTNdre9lsIJ1OuCQ3BPgsjn0VvFQKBqFzuv1YbAk1Qss/QnT7 t6fkq/vhVCmAIHEELvsEa7YjJ/mHTnP6tpLCHIUiF5W31bVvUj7xmdii+UreFoKUuJao fDuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=0cjAVdkREGvhTKeZ9UF64qUXltWwjDDnbNIKrXRCJz8=; b=LNy7RJdOzWvCcv/b7iTqB4a4ZL9q7OQCTBz1jJD1zZEBMF5OB4pbwuauV2HEQxlOlN HJZ2agOHnWHXBQMr7Koe86rAkt8zY1+sZOH8NZVJddFMQLpKo8E/R/HgZmzNKOjcL+5K i2ld9Z0/RYePY7oJMmdstXAfKQ08Iwhc6XSNZjb3bN8X71QI2Oz1L3oSnJz45KzaL/Tb 7Qitkx1fHnv90a9mORBWb17pTL9qsvKRo6MVxT+b6MM2kQbU6XsIqeXVU1AVDvpDrQi5 TRlZYI7oQxmFAtWGWt6XIuSUSIMSVSwD5ytrE8yxez6dLZVcpTD6AMg6LYJosqrD5AHi V05A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=e8yDTvvo; dkim=pass header.i=@linaro.org header.s=google header.b=eO14smar; spf=pass (google.com: domain of libc-alpha-return-100129-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100129-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id x3si13987519pgf.453.2019.02.18.13.13.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 13:13:06 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-100129-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=e8yDTvvo; dkim=pass header.i=@linaro.org header.s=google header.b=eO14smar; spf=pass (google.com: domain of libc-alpha-return-100129-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100129-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=aZusUHIXJth1++uJ3viYSvp+H8Mj6OD HtY2FvJ1dM5nrSlcHTAAIyDuWJLzbCH5TjATF1Tmk8FiENbnHxGPU8KYYQWeDJgI n+VS8qNxIUzlblqo/PDxJSxypQRGKjN0LXEgrRwxhh4KEKeJhZzlviyWNw0UB97j Wsg8aCAB1tWk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=TeCOvH+RID1Wuu+ROPJw7CrKZcg=; b=e8yDT vvojwLdSoUsmjFTpbmYWKHqX2D0rQtsycDFZyVubpUUJbs/GHe3U15zFqRMZze1S gIC7aL9vLUHrYajrRzWreplx0T2d3jmBK228xl9WgVlxA/DKidi9xzO0/SgtZDxD r0cwoGg8zmq8iUkAO8HqFQIzjD6bZp3fHyQkKg= Received: (qmail 62225 invoked by alias); 18 Feb 2019 21:11:49 -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 62112 invoked by uid 89); 18 Feb 2019 21:11:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=audit, selfcontained, self-contained, timer X-HELO: mail-qk1-f182.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=0cjAVdkREGvhTKeZ9UF64qUXltWwjDDnbNIKrXRCJz8=; b=eO14smara/C4gQRPo9MwLtHFscbIP1jcSQsM31b4XYssuP9gxDPcC1Pr5DGa3cLHTb KF+eKu7rQW42nb8PCbcydFGHACmD4I8XRLu3fxV9oCJchpV1CrRXJStfXGv45hVRHukB NcPg1qd3SddgByzi7k49d86hsR/B2h/ocMPfTbqBK3dp4drr9DgdB8fxk5N+ktlIonnE 2E1owrg0IkQ4Zodkegv8i9vJju0Rov0gRQy/8soiLoajg73MIj0Ul7muYjTS2wZ2+n7Q BT6v0a2cVf/JanD7f7lHNJPiWxO3mfATOuO1H2OGawECqEWGulUlEx0bV/GPnGGM/0ib CErQ== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 5/6] Refactor hp-timing rtld usage Date: Mon, 18 Feb 2019 18:11:27 -0300 Message-Id: <20190218211128.1869-5-adhemerval.zanella@linaro.org> In-Reply-To: <20190218211128.1869-1-adhemerval.zanella@linaro.org> References: <20190218211128.1869-1-adhemerval.zanella@linaro.org> Changes from previous version: - Add rtld_timer_start, rtld_timer_stop, and rtld_timer_accum to simplify the profiling timer calculation. It allows remove the declaration of some temporary variables. - Simplify print_statistics and refactor HP_TIMING_PRINT to remove 'cycle' print. --- This patch refactor how hp-timing is used on loader code for statistics report. The HP_TIMING_AVAIL and HP_SMALL_TIMING_AVAIL are removed and HP_TIMING_INLINE is used instead to check for hp-timing avaliability. For alpha, which only defines HP_SMALL_TIMING_AVAIL, the HP_TIMING_INLINE is set iff for IS_IN(rtld). Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also checked the builds for all afected ABIs. * benchtests/bench-timing.h: Replace HP_TIMING_AVAIL with HP_TIMING_INLINE. * nptl/descr.h: Likewise. * elf/rtld.c (RLTD_TIMING_DECLARE, RTLD_TIMING_NOW, RTLD_TIMING_DIFF, RTLD_TIMING_ACCUM_NT, RTLD_TIMING_SET): Define. (dl_start_final_info, _dl_start_final, dl_main, print_statistics): Abstract hp-timing usage with RTLD_* macros. * sysdeps/alpha/hp-timing.h (HP_TIMING_INLINE): Define iff IS_IN(rtld). (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Remove. * sysdeps/generic/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL, HP_TIMING_NONAVAIL): Likewise. * sysdeps/ia64/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Likewise. * sysdeps/powerpc/powerpc32/power4/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Likewise. * sysdeps/powerpc/powerpc64/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Likewise. * sysdeps/sparc/sparc32/sparcv9/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Likewise. * sysdeps/sparc/sparc64/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Likewise. * sysdeps/x86/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Likewise. * sysdeps/generic/hp-timing-common.h: Update comment with HP_TIMING_AVAIL removal. (HP_TIMING_PRINT_SIZE): New define. (HP_TIMING_PRINT): Remove cycle printing. --- benchtests/bench-timing.h | 2 +- elf/rtld.c | 281 +++++++++---------- nptl/descr.h | 2 +- sysdeps/alpha/hp-timing.h | 18 +- sysdeps/generic/hp-timing-common.h | 8 +- sysdeps/generic/hp-timing.h | 5 - sysdeps/ia64/hp-timing.h | 4 - sysdeps/powerpc/powerpc32/power4/hp-timing.h | 4 - sysdeps/powerpc/powerpc64/hp-timing.h | 4 - sysdeps/sparc/sparc32/sparcv9/hp-timing.h | 2 - sysdeps/sparc/sparc64/hp-timing.h | 2 - sysdeps/x86/hp-timing.h | 4 - 12 files changed, 144 insertions(+), 192 deletions(-) -- 2.17.1 diff --git a/benchtests/bench-timing.h b/benchtests/bench-timing.h index 41b7324527..93fe379f99 100644 --- a/benchtests/bench-timing.h +++ b/benchtests/bench-timing.h @@ -21,7 +21,7 @@ #include #include -#if HP_TIMING_AVAIL && !defined USE_CLOCK_GETTIME +#if HP_TIMING_INLINE && !defined USE_CLOCK_GETTIME # define GL(x) _##x # define GLRO(x) _##x typedef hp_timing_t timing_t; diff --git a/elf/rtld.c b/elf/rtld.c index 1f124b31fc..18d30074ea 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -46,6 +46,49 @@ #include +/* Only enables rtld profiling for architectures which provides non generic + hp-timing support. The generic support requires either syscall + (clock_gettime), which will incur in extra overhead on loading time. + Using vDSO is also an option, but it will require extra support on loader + to setup the vDSO pointer before its usage. */ +#if HP_TIMING_INLINE +# define RLTD_TIMING_DECLARE(var, classifier,...) \ + classifier hp_timing_t var __VA_ARGS__ +# define RTLD_TIMING_VAR(var) RLTD_TIMING_DECLARE (var, ) +# define RTLD_TIMING_SET(var, value) (var) = (value) +# define RTLD_TIMING_REF(var) &(var) + +static inline void +rtld_timer_start (hp_timing_t *var) +{ + HP_TIMING_NOW (*var); +} + +static inline void +rtld_timer_stop (hp_timing_t *var, hp_timing_t start) +{ + hp_timing_t stop; + HP_TIMING_NOW (stop); + HP_TIMING_DIFF (*var, start, stop); +} + +static inline void +rtld_timer_accum (hp_timing_t *sum, hp_timing_t start) +{ + hp_timing_t stop; + rtld_timer_stop (&stop, start); + HP_TIMING_ACCUM_NT(*sum, stop); +} +#else +# define RLTD_TIMING_DECLARE(var, classifier...) +# define RTLD_TIMING_SET(var, value) +# define RTLD_TIMING_VAR(var) +# define RTLD_TIMING_REF(var) 0 +# define rtld_timer_start(var) +# define rtld_timer_stop(var, start) +# define rtld_timer_accum(sum, start) +#endif + /* Avoid PLT use for our local calls at startup. */ extern __typeof (__mempcpy) __mempcpy attribute_hidden; @@ -62,7 +105,7 @@ static void print_missing_version (int errcode, const char *objname, const char *errsting); /* Print the various times we collected. */ -static void print_statistics (hp_timing_t *total_timep); +static void print_statistics (const hp_timing_t *total_timep); /* Add audit objects. */ static void process_dl_audit (char *str); @@ -303,11 +346,9 @@ static struct libname_list _dl_rtld_libname; static struct libname_list _dl_rtld_libname2; /* Variable for statistics. */ -#ifndef HP_TIMING_NONAVAIL -static hp_timing_t relocate_time; -static hp_timing_t load_time attribute_relro; -static hp_timing_t start_time attribute_relro; -#endif +RLTD_TIMING_DECLARE (relocate_time, static); +RLTD_TIMING_DECLARE (load_time, static, attribute_relro); +RLTD_TIMING_DECLARE (start_time, static, attribute_relro); /* Additional definitions needed by TLS initialization. */ #ifdef TLS_INIT_HELPER @@ -335,9 +376,7 @@ static ElfW(Addr) _dl_start_final (void *arg); struct dl_start_final_info { struct link_map l; -#if !defined HP_TIMING_NONAVAIL && HP_TIMING_INLINE - hp_timing_t start_time; -#endif + RTLD_TIMING_VAR (start_time); }; static ElfW(Addr) _dl_start_final (void *arg, struct dl_start_final_info *info); @@ -371,16 +410,11 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) { ElfW(Addr) start_addr; - if (HP_SMALL_TIMING_AVAIL) - { - /* If it hasn't happen yet record the startup time. */ - if (! HP_TIMING_INLINE) - HP_TIMING_NOW (start_time); -#if !defined DONT_USE_BOOTSTRAP_MAP && !defined HP_TIMING_NONAVAIL - else - start_time = info->start_time; + /* If it hasn't happen yet record the startup time. */ + rtld_timer_start (&start_time); +#if !defined DONT_USE_BOOTSTRAP_MAP + RTLD_TIMING_SET (start_time, info->start_time); #endif - } /* Transfer data about ourselves to the permanent link_map structure. */ #ifndef DONT_USE_BOOTSTRAP_MAP @@ -412,27 +446,11 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) entry point on the same stack we entered on. */ start_addr = _dl_sysdep_start (arg, &dl_main); -#ifndef HP_TIMING_NONAVAIL - hp_timing_t rtld_total_time; - if (HP_SMALL_TIMING_AVAIL) - { - hp_timing_t end_time; - - /* Get the current time. */ - HP_TIMING_NOW (end_time); - - /* Compute the difference. */ - HP_TIMING_DIFF (rtld_total_time, start_time, end_time); - } -#endif - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS)) { -#ifndef HP_TIMING_NONAVAIL - print_statistics (&rtld_total_time); -#else - print_statistics (NULL); -#endif + RTLD_TIMING_VAR (rtld_total_time); + rtld_timer_stop (&rtld_total_time, start_time); + print_statistics (RTLD_TIMING_REF(rtld_total_time)); } return start_addr; @@ -457,11 +475,10 @@ _dl_start (void *arg) #define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP #include "dynamic-link.h" - if (HP_TIMING_INLINE && HP_SMALL_TIMING_AVAIL) #ifdef DONT_USE_BOOTSTRAP_MAP - HP_TIMING_NOW (start_time); + rtld_timer_start (&start_time); #else - HP_TIMING_NOW (info.start_time); + rtld_timer_start (&info.start_time); #endif /* Partly clean the `bootstrap_map' structure up. Don't use @@ -1078,11 +1095,6 @@ dl_main (const ElfW(Phdr) *phdr, unsigned int i; bool prelinked = false; bool rtld_is_main = false; -#ifndef HP_TIMING_NONAVAIL - hp_timing_t start; - hp_timing_t stop; - hp_timing_t diff; -#endif void *tcbp = NULL; GL(dl_init_static_tls) = &_dl_nothread_init_static_tls; @@ -1258,12 +1270,11 @@ of this helper program; chances are you did not intend to run this program.\n\ } else { - HP_TIMING_NOW (start); + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); _dl_map_object (NULL, rtld_progname, lt_executable, 0, __RTLD_OPENEXEC, LM_ID_BASE); - HP_TIMING_NOW (stop); - - HP_TIMING_DIFF (load_time, start, stop); + rtld_timer_stop (&load_time, start); } /* Now the map for the main executable is available. */ @@ -1666,20 +1677,18 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); if (__glibc_unlikely (preloadlist != NULL)) { - HP_TIMING_NOW (start); + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD"); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (diff, start, stop); - HP_TIMING_ACCUM_NT (load_time, diff); + rtld_timer_accum (&load_time, start); } if (__glibc_unlikely (preloadarg != NULL)) { - HP_TIMING_NOW (start); + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); npreloads += handle_preload_list (preloadarg, main_map, "--preload"); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (diff, start, stop); - HP_TIMING_ACCUM_NT (load_time, diff); + rtld_timer_accum (&load_time, start); } /* There usually is no ld.so.preload file, it should only be used @@ -1739,7 +1748,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); file[file_size - 1] = '\0'; } - HP_TIMING_NOW (start); + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); if (file != problem) { @@ -1757,9 +1767,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); npreloads += do_preload (p, main_map, preload_file); } - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (diff, start, stop); - HP_TIMING_ACCUM_NT (load_time, diff); + rtld_timer_accum (&load_time, start); /* We don't need the file anymore. */ __munmap (file, file_size); @@ -1783,11 +1791,12 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD specified some libraries to load, these are inserted before the actual dependencies in the executable's searchlist for symbol resolution. */ - HP_TIMING_NOW (start); - _dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (diff, start, stop); - HP_TIMING_ACCUM_NT (load_time, diff); + { + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); + _dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0); + rtld_timer_accum (&load_time, start); + } /* Mark all objects as being in the global scope. */ for (i = main_map->l_searchlist.r_nlist; i > 0; ) @@ -2180,12 +2189,10 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) { ElfW(Rela) *conflict, *conflictend; -#ifndef HP_TIMING_NONAVAIL - hp_timing_t start; - hp_timing_t stop; -#endif - HP_TIMING_NOW (start); + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); + assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); conflict = (ElfW(Rela) *) main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; @@ -2193,8 +2200,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); ((char *) conflict + main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); _dl_resolve_conflicts (main_map, conflict, conflictend); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (relocate_time, start, stop); + + rtld_timer_stop (&relocate_time, start); } @@ -2222,15 +2229,12 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); know that because it is self-contained). */ int consider_profiling = GLRO(dl_profile) != NULL; -#ifndef HP_TIMING_NONAVAIL - hp_timing_t start; - hp_timing_t stop; -#endif /* If we are profiling we also must do lazy reloaction. */ GLRO(dl_lazy) |= consider_profiling; - HP_TIMING_NOW (start); + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); unsigned i = main_map->l_searchlist.r_nlist; while (i-- > 0) { @@ -2257,9 +2261,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); if (l->l_tls_blocksize != 0 && tls_init_tp_called) _dl_add_to_slotinfo (l); } - HP_TIMING_NOW (stop); - - HP_TIMING_DIFF (relocate_time, start, stop); + rtld_timer_stop (&relocate_time, start); /* Now enable profiling if needed. Like the previous call, this has to go here because the calls it makes should use the @@ -2302,19 +2304,14 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); re-relocation, we might call a user-supplied function (e.g. calloc from _dl_relocate_object) that uses TLS data. */ -#ifndef HP_TIMING_NONAVAIL - hp_timing_t start; - hp_timing_t stop; - hp_timing_t add; -#endif + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); - HP_TIMING_NOW (start); /* Mark the link map as not yet relocated again. */ GL(dl_rtld_map).l_relocated = 0; _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (add, start, stop); - HP_TIMING_ACCUM_NT (relocate_time, add); + + rtld_timer_accum (&relocate_time, start); } /* Do any necessary cleanups for the startup OS interface code. @@ -2746,46 +2743,51 @@ process_envvars (enum mode *modep) } } +#if HP_TIMING_INLINE +static void +print_statistics_item (const char *title, hp_timing_t time, + hp_timing_t total) +{ + char cycles[HP_TIMING_PRINT_SIZE]; + HP_TIMING_PRINT (cycles, sizeof (cycles), time); + + char relative[3 * sizeof (hp_timing_t) + 2]; + char *cp = _itoa ((1000ULL * time) / total, relative + sizeof (relative), + 10, 0); + /* Sets the decimal point. */ + char *wp = relative; + switch (relative + sizeof (relative) - cp) + { + case 3: + *wp++ = *cp++; + /* Fall through. */ + case 2: + *wp++ = *cp++; + /* Fall through. */ + case 1: + *wp++ = '.'; + *wp++ = *cp++; + } + *wp = '\0'; + _dl_debug_printf ("%s: %s cycles (%s%%)\n", title, cycles, relative); +} +#endif /* Print the various times we collected. */ static void __attribute ((noinline)) -print_statistics (hp_timing_t *rtld_total_timep) +print_statistics (const hp_timing_t *rtld_total_timep) { -#ifndef HP_TIMING_NONAVAIL - char buf[200]; - char *cp; - char *wp; - - /* Total time rtld used. */ - if (HP_SMALL_TIMING_AVAIL) - { - HP_TIMING_PRINT (buf, sizeof (buf), *rtld_total_timep); - _dl_debug_printf ("\nruntime linker statistics:\n" - " total startup time in dynamic loader: %s\n", buf); - - /* Print relocation statistics. */ - char pbuf[30]; - HP_TIMING_PRINT (buf, sizeof (buf), relocate_time); - cp = _itoa ((1000ULL * relocate_time) / *rtld_total_timep, - pbuf + sizeof (pbuf), 10, 0); - wp = pbuf; - switch (pbuf + sizeof (pbuf) - cp) - { - case 3: - *wp++ = *cp++; - /* Fall through. */ - case 2: - *wp++ = *cp++; - /* Fall through. */ - case 1: - *wp++ = '.'; - *wp++ = *cp++; - } - *wp = '\0'; - _dl_debug_printf ("\ - time needed for relocation: %s (%s%%)\n", buf, pbuf); - } +#if HP_TIMING_INLINE + { + char cycles[HP_TIMING_PRINT_SIZE]; + HP_TIMING_PRINT (cycles, sizeof (cycles), *rtld_total_timep); + _dl_debug_printf ("\nruntime linker statistics:\n" + " total startup time in dynamic loader: %s cycles\n", + cycles); + print_statistics_item (" time needed for relocation", + relocate_time, *rtld_total_timep); + } #endif unsigned long int num_relative_relocations = 0; @@ -2826,31 +2828,8 @@ print_statistics (hp_timing_t *rtld_total_timep) GL(dl_num_cache_relocations), num_relative_relocations); -#ifndef HP_TIMING_NONAVAIL - /* Time spend while loading the object and the dependencies. */ - if (HP_SMALL_TIMING_AVAIL) - { - char pbuf[30]; - HP_TIMING_PRINT (buf, sizeof (buf), load_time); - cp = _itoa ((1000ULL * load_time) / *rtld_total_timep, - pbuf + sizeof (pbuf), 10, 0); - wp = pbuf; - switch (pbuf + sizeof (pbuf) - cp) - { - case 3: - *wp++ = *cp++; - /* Fall through. */ - case 2: - *wp++ = *cp++; - /* Fall through. */ - case 1: - *wp++ = '.'; - *wp++ = *cp++; - } - *wp = '\0'; - _dl_debug_printf ("\ - time needed to load objects: %s (%s%%)\n", - buf, pbuf); - } +#if HP_TIMING_INLINE + print_statistics_item (" time needed to load objects", + load_time, *rtld_total_timep); #endif } diff --git a/nptl/descr.h b/nptl/descr.h index cb7d4c2282..b4db99fe3f 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -342,7 +342,7 @@ struct pthread /* Lock for synchronizing setxid calls. */ unsigned int setxid_futex; -#if HP_TIMING_AVAIL +#if HP_TIMING_INLINE hp_timing_t cpuclock_offset_ununsed; #endif diff --git a/sysdeps/alpha/hp-timing.h b/sysdeps/alpha/hp-timing.h index 481132663c..08d8d6627c 100644 --- a/sysdeps/alpha/hp-timing.h +++ b/sysdeps/alpha/hp-timing.h @@ -17,16 +17,13 @@ License along with the GNU C Library. If not, see . */ -#ifndef _HP_TIMING_H -#define _HP_TIMING_H 1 +#ifndef _HP_TIMING_ALPHA_H +#define _HP_TIMING_ALPHA_H 1 +#if IS_IN(rtld) /* We always have the timestamp register, but it's got only a 4 second range. Use it for ld.so profiling only. */ -#define HP_TIMING_AVAIL (0) -#define HP_SMALL_TIMING_AVAIL (1) - -/* We indeed have inlined functions. */ -#define HP_TIMING_INLINE (1) +# define HP_TIMING_INLINE (1) /* We use 32 bit values for the times. */ typedef unsigned int hp_timing_t; @@ -34,13 +31,16 @@ typedef unsigned int hp_timing_t; /* The "rpcc" instruction returns a 32-bit counting half and a 32-bit "virtual cycle counter displacement". Subtracting the two gives us a virtual cycle count. */ -#define HP_TIMING_NOW(VAR) \ +# define HP_TIMING_NOW(VAR) \ do { \ unsigned long int x_; \ asm volatile ("rpcc %0" : "=r"(x_)); \ (VAR) = (int) (x_) - (int) (x_ >> 32); \ } while (0) +# include -#include +#else +# include +#endif /* IS_IN(rtld) */ #endif /* hp-timing.h */ diff --git a/sysdeps/generic/hp-timing-common.h b/sysdeps/generic/hp-timing-common.h index 0ffb853444..8749d25647 100644 --- a/sysdeps/generic/hp-timing-common.h +++ b/sysdeps/generic/hp-timing-common.h @@ -20,8 +20,6 @@ /* In case a platform supports timers in the hardware the following macros and types must be defined: - - HP_TIMING_AVAIL: test for availability. - - HP_TIMING_INLINE: this macro is non-zero if the functionality is not implemented using function calls but instead uses some inlined code which might simply consist of a few assembler instructions. We have to @@ -47,16 +45,16 @@ /* Accumulate ADD into SUM. No attempt is made to be thread-safe. */ #define HP_TIMING_ACCUM_NT(Sum, Diff) ((Sum) += (Diff)) +#define HP_TIMING_PRINT_SIZE (3 * sizeof (hp_timing_t) + 1) + /* Write a decimal representation of the timing value into the given string. */ #define HP_TIMING_PRINT(Dest, Len, Val) \ do { \ - char __buf[20]; \ + char __buf[HP_TIMING_PRINT_SIZE]; \ char *__dest = (Dest); \ size_t __len = (Len); \ char *__cp = _itoa ((Val), __buf + sizeof (__buf), 10, 0); \ size_t __cp_len = MIN (__buf + sizeof (__buf) - __cp, __len); \ memcpy (__dest, __cp, __cp_len); \ - memcpy (__dest + __cp_len, " cycles", \ - MIN (__len - __cp_len, sizeof (" cycles"))); \ __dest[__len - 1] = '\0'; \ } while (0) diff --git a/sysdeps/generic/hp-timing.h b/sysdeps/generic/hp-timing.h index fb2a6036fc..278998d2c2 100644 --- a/sysdeps/generic/hp-timing.h +++ b/sysdeps/generic/hp-timing.h @@ -25,8 +25,6 @@ the system call might be too high. */ /* Provide dummy definitions. */ -#define HP_TIMING_AVAIL (0) -#define HP_SMALL_TIMING_AVAIL (0) #define HP_TIMING_INLINE (0) typedef int hp_timing_t; #define HP_TIMING_NOW(var) @@ -34,7 +32,4 @@ typedef int hp_timing_t; #define HP_TIMING_ACCUM_NT(Sum, Diff) #define HP_TIMING_PRINT(Buf, Len, Val) -/* Since this implementation is not available we tell the user about it. */ -#define HP_TIMING_NONAVAIL 1 - #endif /* hp-timing.h */ diff --git a/sysdeps/ia64/hp-timing.h b/sysdeps/ia64/hp-timing.h index 17ef023a11..2ca248a530 100644 --- a/sysdeps/ia64/hp-timing.h +++ b/sysdeps/ia64/hp-timing.h @@ -20,10 +20,6 @@ #ifndef _HP_TIMING_H #define _HP_TIMING_H 1 -/* We always assume having the timestamp register. */ -#define HP_TIMING_AVAIL (1) -#define HP_SMALL_TIMING_AVAIL (1) - /* We indeed have inlined functions. */ #define HP_TIMING_INLINE (1) diff --git a/sysdeps/powerpc/powerpc32/power4/hp-timing.h b/sysdeps/powerpc/powerpc32/power4/hp-timing.h index 0d77aa0992..ed2ca9bc7a 100644 --- a/sysdeps/powerpc/powerpc32/power4/hp-timing.h +++ b/sysdeps/powerpc/powerpc32/power4/hp-timing.h @@ -20,10 +20,6 @@ #ifndef _HP_TIMING_H #define _HP_TIMING_H 1 -/* We always assume having the timestamp register. */ -#define HP_TIMING_AVAIL (1) -#define HP_SMALL_TIMING_AVAIL (1) - /* We indeed have inlined functions. */ #define HP_TIMING_INLINE (1) diff --git a/sysdeps/powerpc/powerpc64/hp-timing.h b/sysdeps/powerpc/powerpc64/hp-timing.h index fb9ac1ce2a..01678cd634 100644 --- a/sysdeps/powerpc/powerpc64/hp-timing.h +++ b/sysdeps/powerpc/powerpc64/hp-timing.h @@ -20,10 +20,6 @@ #ifndef _HP_TIMING_H #define _HP_TIMING_H 1 -/* We always assume having the timestamp register. */ -#define HP_TIMING_AVAIL (1) -#define HP_SMALL_TIMING_AVAIL (1) - /* We indeed have inlined functions. */ #define HP_TIMING_INLINE (1) diff --git a/sysdeps/sparc/sparc32/sparcv9/hp-timing.h b/sysdeps/sparc/sparc32/sparcv9/hp-timing.h index 6a4ab08679..3270c5b40a 100644 --- a/sysdeps/sparc/sparc32/sparcv9/hp-timing.h +++ b/sysdeps/sparc/sparc32/sparcv9/hp-timing.h @@ -20,8 +20,6 @@ #ifndef _HP_TIMING_H #define _HP_TIMING_H 1 -#define HP_TIMING_AVAIL (1) -#define HP_SMALL_TIMING_AVAIL (1) #define HP_TIMING_INLINE (1) typedef unsigned long long int hp_timing_t; diff --git a/sysdeps/sparc/sparc64/hp-timing.h b/sysdeps/sparc/sparc64/hp-timing.h index db95c02a8d..0f02b2a98f 100644 --- a/sysdeps/sparc/sparc64/hp-timing.h +++ b/sysdeps/sparc/sparc64/hp-timing.h @@ -20,8 +20,6 @@ #ifndef _HP_TIMING_H #define _HP_TIMING_H 1 -#define HP_TIMING_AVAIL (1) -#define HP_SMALL_TIMING_AVAIL (1) #define HP_TIMING_INLINE (1) typedef unsigned long int hp_timing_t; diff --git a/sysdeps/x86/hp-timing.h b/sysdeps/x86/hp-timing.h index 9b6a998bcd..ccb9f9250a 100644 --- a/sysdeps/x86/hp-timing.h +++ b/sysdeps/x86/hp-timing.h @@ -22,10 +22,6 @@ #include #if MINIMUM_ISA == 686 || MINIMUM_ISA == 8664 -/* We always assume having the timestamp register. */ -# define HP_TIMING_AVAIL (1) -# define HP_SMALL_TIMING_AVAIL (1) - /* We indeed have inlined functions. */ # define HP_TIMING_INLINE (1) From patchwork Mon Feb 18 21:11:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 158653 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2939122jaa; Mon, 18 Feb 2019 13:12:49 -0800 (PST) X-Google-Smtp-Source: AHgI3IbSiTw20icyZxCJ/BF3THrkTD8mWtZJZu7e9d2ij0DhNX7rq37XgYJ778jt4tsdltB4nBri X-Received: by 2002:a17:902:9689:: with SMTP id n9mr27390780plp.8.1550524369333; Mon, 18 Feb 2019 13:12:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550524369; cv=none; d=google.com; s=arc-20160816; b=mYYOqCzRDIMxbPy5pJwx/i3SYnTKq8q2i0LtY+j3SM+qVSYqeENoq1A9r6OajlCQtP mHrVcuqtaPuN5mREVJmSO3ltrE4JP90hmHzruA66ALZxnqmehVzSfPPX+KrEaPdmIvST zBZJAIhJ/oODYoZoAb82dAsT69jvLk3vMm3wygQ7qhEMOPBHmQSpZOXBNMlGq/LMpXk1 4nLd25SFeK39/n/VJLD/zag1m6gRfbkp7V9/XyJ1Rwl8c1dvPF3f7+OlVM49ETPHQYZ7 Msz6qnYzmxnYMCP06YxepQUfxx+45C3yNy8AxAYhQktTli/xuEAb3quuwOqNv/7pmwSP zaOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=ae7tinx+9uU2fL6OqdPq77k0Et4cg5MzskL5mv7tIak=; b=fdobIPEmQT7NvDnEa8GZ8OqT9HhzVRtYsRrJhP1Cy2mNtBGU9bQV59pnVok/VYLMZV YsKWITuSzVYUwZX/02jHkbL+ZE5CTZN8cNzNQCfXL1yTGd3NZcdRjK+fYXVggEQkc/uB xOGDwsnFuSWiw6Vycnc2BZbDnjxXTXf/jYfTW5AFoQkRJlTzKwBr6MKNmRcOoKTE37Pk eJIVtHdWGFOU4lhHInNfWIFn021/uaDftMan5vmJHTPrRPR8YLsX7VUHIJ6imSbG+eJw IpsGHdG29bfXTCToS4ADZpXPhyLivcJV3xy3QyOI4P1AL0GzbeOki8PnA2cZ39yfl6Ts b89A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=BUoPTcWT; dkim=pass header.i=@linaro.org header.s=google header.b=n2MHxoyy; spf=pass (google.com: domain of libc-alpha-return-100128-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100128-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 31si15161981plh.274.2019.02.18.13.12.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Feb 2019 13:12:49 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-100128-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=BUoPTcWT; dkim=pass header.i=@linaro.org header.s=google header.b=n2MHxoyy; spf=pass (google.com: domain of libc-alpha-return-100128-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-100128-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=by9Yvh5os6CUpKd77pEqiYD9XV2FUb9 hjD0BwJB00VouNZX1a86HLxJTE/7Qb1QtR+r2/MkznzpRf7KsLzs4L7kCuKkDw1K 8elie2b9LyMfRgwpJoVI4zC0DG5lqQSR3auSzXXklHgy6i9yk76JpkEsPA0/XQAe JPeYwivkIdnA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=OnwgENVgHFA5S7gEfVAv6PZjcgM=; b=BUoPT cWTXL1Iybca0vREz5xztNFyiIZIRyaslYCqdLF+GhSh2VZidIPVIPYXF3776gjXX oLKgS3VSTppX31o95XS0AXXARrcjWav64PxBdx5kjsTfLMLrElUTRHJX/wUydnmS OG/XklQ+jCumCw4oadJyCPhxBKJP8nvl47/H2k= Received: (qmail 61824 invoked by alias); 18 Feb 2019 21:11:47 -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 61690 invoked by uid 89); 18 Feb 2019 21:11:46 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=wilcodijkstraarmcom, sk:wilcod, sk:WilcoD, sk:wilco.d X-HELO: mail-qt1-f194.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ae7tinx+9uU2fL6OqdPq77k0Et4cg5MzskL5mv7tIak=; b=n2MHxoyy4pSnjsrzAzGw0girQlpr5705/XScTc2TR4fzSLtgQDbNCmCN9PtNvGIunU 4TBQFPGjibsQrFRWnqG+zyWyv4bns+eyxXc7vWvBugGGg/I9j74bA/QPSTklZ1Nh54U9 PLpgxVNpArfrYPKzZHHxOxmXM5FemAnAejhiCWp+HTQsQQ50/0D1X8bw0b/ldAGdAfzn wZ1I4ilIDKmbiDIp7U8f9Rwk05LfneyTR8HPlmsJSiiC/c56v4Ny0JCYsu8V6/no0DNf tSHVNVr3w91GLvZ/MJKtNPzUR/gT28iymds6YSthw3XbO8vva23sDPUTibndwsYQEwy6 ZAgw== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Wilco Dijkstra Subject: [PATCH v2 6/6] Add generic hp-timing support Date: Mon, 18 Feb 2019 18:11:28 -0300 Message-Id: <20190218211128.1869-6-adhemerval.zanella@linaro.org> In-Reply-To: <20190218211128.1869-1-adhemerval.zanella@linaro.org> References: <20190218211128.1869-1-adhemerval.zanella@linaro.org> From: Wilco Dijkstra Add missing generic hp_timing support. It uses clock_gettime (CLOCK_MONOTONIC) which has unspecified starting time, nano-second accuracy, and should faster on architectures that implementes the symbol as vDSO. Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also checked the builds for all afected ABIs. * benchtests/Makefile (USE_CLOCK_GETTIME) Remove. * benchtests/README: Update description. * benchtests/bench-timing.h: Default to hp-timing. * sysdeps/generic/hp-timing.h (HP_TIMING_DIFF, HP_TIMING_ACCUM_NT, HP_TIMING_PRINT): Remove. (HP_TIMING_NOW): Add generic implementation. (hp_timing_t): Change to uint64_t. --- benchtests/Makefile | 6 ----- benchtests/README | 7 +----- benchtests/bench-timing.h | 44 +++++++------------------------------ sysdeps/generic/hp-timing.h | 25 +++++++++++++-------- 4 files changed, 25 insertions(+), 57 deletions(-) -- 2.17.1 diff --git a/benchtests/Makefile b/benchtests/Makefile index d00993eca4..cdc89488d6 100644 --- a/benchtests/Makefile +++ b/benchtests/Makefile @@ -127,17 +127,11 @@ endif CPPFLAGS-nonlib += -DDURATION=$(BENCH_DURATION) -D_ISOMAC -# Use clock_gettime to measure performance of functions. The default is to use -# HP_TIMING if it is available. -ifdef USE_CLOCK_GETTIME -CPPFLAGS-nonlib += -DUSE_CLOCK_GETTIME -else # On x86 processors, use RDTSCP, instead of RDTSC, to measure performance # of functions. All x86 processors since 2010 support RDTSCP instruction. ifdef USE_RDTSCP CPPFLAGS-nonlib += -DUSE_RDTSCP endif -endif DETAILED_OPT := diff --git a/benchtests/README b/benchtests/README index aaf0b659e2..c4f03fd872 100644 --- a/benchtests/README +++ b/benchtests/README @@ -27,12 +27,7 @@ BENCH_DURATION. The benchmark suite does function call measurements using architecture-specific high precision timing instructions whenever available. When such support is -not available, it uses clock_gettime (CLOCK_PROCESS_CPUTIME_ID). One can force -the benchmark to use clock_gettime by invoking make as follows: - - $ make USE_CLOCK_GETTIME=1 bench - -Again, one must run `make bench-clean' before changing the measurement method. +not available, it uses clock_gettime (CLOCK_MONOTONIC). On x86 processors, RDTSCP instruction provides more precise timing data than RDTSC instruction. All x86 processors since 2010 support RDTSCP diff --git a/benchtests/bench-timing.h b/benchtests/bench-timing.h index 93fe379f99..e213dec3fd 100644 --- a/benchtests/bench-timing.h +++ b/benchtests/bench-timing.h @@ -18,49 +18,21 @@ #undef attribute_hidden #define attribute_hidden +#define __clock_gettime clock_gettime #include #include -#if HP_TIMING_INLINE && !defined USE_CLOCK_GETTIME -# define GL(x) _##x -# define GLRO(x) _##x +#define GL(x) _##x +#define GLRO(x) _##x typedef hp_timing_t timing_t; -# define TIMING_TYPE "hp_timing" +#define TIMING_TYPE "hp_timing" -# define TIMING_INIT(res) ({ (res) = 1; }) +#define TIMING_INIT(res) ({ (res) = 1; }) -# define TIMING_NOW(var) HP_TIMING_NOW (var) -# define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end)) -# define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff)) - -#else - -#include -typedef uint64_t timing_t; - -# define TIMING_TYPE "clock_gettime" - -/* Measure the resolution of the clock so we can scale the number of - benchmark iterations by this value. */ -# define TIMING_INIT(res) \ -({ \ - struct timespec start; \ - clock_getres (CLOCK_PROCESS_CPUTIME_ID, &start); \ - (res) = start.tv_nsec; \ -}) - -# define TIMING_NOW(var) \ -({ \ - struct timespec tv; \ - clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tv); \ - (var) = (uint64_t) (tv.tv_nsec + (uint64_t) 1000000000 * tv.tv_sec); \ -}) - -# define TIMING_DIFF(diff, start, end) (diff) = (end) - (start) -# define TIMING_ACCUM(sum, diff) (sum) += (diff) - -#endif +#define TIMING_NOW(var) HP_TIMING_NOW (var) +#define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end)) +#define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff)) #define TIMING_PRINT_MEAN(d_total_s, d_iters) \ printf ("\t%g", (d_total_s) / (d_iters)) diff --git a/sysdeps/generic/hp-timing.h b/sysdeps/generic/hp-timing.h index 278998d2c2..2528279558 100644 --- a/sysdeps/generic/hp-timing.h +++ b/sysdeps/generic/hp-timing.h @@ -20,16 +20,23 @@ #ifndef _HP_TIMING_H #define _HP_TIMING_H 1 -/* There are no generic definitions for the times. We could write something - using the `gettimeofday' system call where available but the overhead of - the system call might be too high. */ +#include +#include +#include -/* Provide dummy definitions. */ +/* It should not be used for ld.so. */ #define HP_TIMING_INLINE (0) -typedef int hp_timing_t; -#define HP_TIMING_NOW(var) -#define HP_TIMING_DIFF(Diff, Start, End) -#define HP_TIMING_ACCUM_NT(Sum, Diff) -#define HP_TIMING_PRINT(Buf, Len, Val) + +typedef uint64_t hp_timing_t; + +/* The clock_gettime (CLOCK_MONOTONIC) has unspecified starting time, + nano-second accuracy, and for some architectues is implemented as + vDSO symbol. */ +#define HP_TIMING_NOW(var) \ +({ \ + struct timespec tv; \ + __clock_gettime (CLOCK_MONOTONIC, &tv); \ + (var) = (tv.tv_nsec + UINT64_C(1000000000) * tv.tv_sec); \ +}) #endif /* hp-timing.h */