From patchwork Thu Sep 7 22:41:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Albert ARIBAUD (3ADEV)" X-Patchwork-Id: 811201 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-84325-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="I2LAotUg"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xpFqZ5nDmz9sCZ for ; Fri, 8 Sep 2017 08:43:54 +1000 (AEST) 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=L/xRdMpNFARitf7XH1PCw5Dr0r+DSMv WTvapJ3sT/z7hMZjih1yaAI5wfFvUbRCobajPnn1JL7NbrqHW4N74adhA5l6BbAJ xo+wwu8hZYHSvK/L2lz6Bgw2KuBDiel50L4KK5h02DdMQdHfMJecHWGBVvSEPIsr c/uOXDbTGLKE= 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=oXY/zTTHn0Ycgo4bRRZgg3UmaAk=; b=I2LAo tUgU22rJQRMTmO5zlW4SW3aK3wykp2PxduZJZLdp4vL8OB/axX2VpQ6oYDc2VNgE Ea2UxVNJXOQe1ujlTrF0WSSL283yDyHZlkIMKpi57/xAM8bPM0nm1kBkr9wk6Mbp 5IAM9X5r7rUvcj6gHZpF3rMG/4s1yWV5XSe0/U= Received: (qmail 63763 invoked by alias); 7 Sep 2017 22:42:59 -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 63641 invoked by uid 89); 7 Sep 2017 22:42:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy= X-HELO: smtp6-g21.free.fr From: "Albert ARIBAUD (3ADEV)" To: libc-alpha@sourceware.org Cc: "Albert ARIBAUD (3ADEV)" Subject: [RFC PATCH 07/52] Y2038: add function __clock_gettime64 Date: Fri, 8 Sep 2017 00:41:34 +0200 Message-Id: <20170907224219.12483-8-albert.aribaud@3adev.fr> In-Reply-To: <20170907224219.12483-7-albert.aribaud@3adev.fr> References: <20170907224219.12483-1-albert.aribaud@3adev.fr> <20170907224219.12483-2-albert.aribaud@3adev.fr> <20170907224219.12483-3-albert.aribaud@3adev.fr> <20170907224219.12483-4-albert.aribaud@3adev.fr> <20170907224219.12483-5-albert.aribaud@3adev.fr> <20170907224219.12483-6-albert.aribaud@3adev.fr> <20170907224219.12483-7-albert.aribaud@3adev.fr> Note: __clock_gettime64 is implemented in VDSO. Signed-off-by: Albert ARIBAUD (3ADEV) --- include/time.h | 8 ++++++ sysdeps/unix/clock_gettime.c | 46 ++++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/arm/Versions | 3 +++ sysdeps/unix/sysv/linux/arm/init-first.c | 15 +++++++++++ sysdeps/unix/sysv/linux/arm/libc-vdso.h | 1 + sysdeps/unix/sysv/linux/clock_gettime.c | 44 ++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+) diff --git a/include/time.h b/include/time.h index c436c44539..eeefbb4e98 100644 --- a/include/time.h +++ b/include/time.h @@ -20,6 +20,11 @@ libc_hidden_proto (localtime) libc_hidden_proto (strftime) libc_hidden_proto (strptime) +/* Indicates whether the underlying kernel has 64-bit time support. + This is required for e.g. librt, which cannot directly check the + flag variable that init-first.c sets when detecting support. */ +extern int __y2038_kernel_support (void); + #if BYTE_ORDER == BIG_ENDIAN struct __timespec64 { @@ -43,6 +48,9 @@ extern __typeof (clock_settime) __clock_settime; extern __typeof (clock_nanosleep) __clock_nanosleep; extern __typeof (clock_getcpuclockid) __clock_getcpuclockid; +extern int __clock_gettime64 (clockid_t __clock_id, + struct __timespec64 *__tp) __THROW; + /* Now define the internal interfaces. */ struct tm; diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c index 5262066f51..ac224c919b 100644 --- a/sysdeps/unix/clock_gettime.c +++ b/sysdeps/unix/clock_gettime.c @@ -134,3 +134,49 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp) } weak_alias (__clock_gettime, clock_gettime) libc_hidden_def (__clock_gettime) + +/* Get current value of CLOCK and store it in TP, 64-bit version. */ +int +__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) +{ + int retval = -1; + + switch (clock_id) + { +#ifdef SYSDEP_GETTIME64 + SYSDEP_GETTIME64; +#endif + +#ifndef HANDLED_REALTIME + case CLOCK_REALTIME: + { + struct timeval tv; + retval = gettimeofday (&tv, NULL); + if (retval == 0) + TIMEVAL_TO_TIMESPEC (&tv, tp); + } + break; +#endif + + default: +#ifdef SYSDEP_GETTIME64_CPU + SYSDEP_GETTIME64_CPU (clock_id, tp); +#endif +#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 && !defined HANDLED_CPUTIME + case CLOCK_PROCESS_CPUTIME_ID: + retval = hp_timing_gettime (clock_id, tp); + break; +#endif + } + + return retval; +} diff --git a/sysdeps/unix/sysv/linux/arm/Versions b/sysdeps/unix/sysv/linux/arm/Versions index f7feda3650..a2655d6262 100644 --- a/sysdeps/unix/sysv/linux/arm/Versions +++ b/sysdeps/unix/sysv/linux/arm/Versions @@ -27,5 +27,8 @@ libc { __localtime64; __localtime64_r; __mktime64; __timelocal64_r; __timegm64; + __clock_gettime64; + __vdso_clock_gettime64; + __y2038_kernel_support; } } diff --git a/sysdeps/unix/sysv/linux/arm/init-first.c b/sysdeps/unix/sysv/linux/arm/init-first.c index 3c289c2a25..61c01a56a7 100644 --- a/sysdeps/unix/sysv/linux/arm/init-first.c +++ b/sysdeps/unix/sysv/linux/arm/init-first.c @@ -23,6 +23,14 @@ int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden; int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *); +long (*VDSO_SYMBOL(clock_gettime64)) (clockid_t, struct __timespec64 *); + +int __y2038_linux_support; + +int __y2038_kernel_support (void) +{ + return __y2038_linux_support; +} static inline void _libc_vdso_platform_setup (void) @@ -36,6 +44,13 @@ _libc_vdso_platform_setup (void) p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26); PTR_MANGLE (p); VDSO_SYMBOL (clock_gettime) = p; + + /* (aaribaud) TODO: map to version where clock_gettime64 officially appears */ + p = _dl_vdso_vsym ("__vdso_clock_gettime64", NULL); + PTR_MANGLE (p); + VDSO_SYMBOL (clock_gettime64) = p; + + __y2038_linux_support = (p != NULL) ? 1 : 0; } # define VDSO_SETUP _libc_vdso_platform_setup diff --git a/sysdeps/unix/sysv/linux/arm/libc-vdso.h b/sysdeps/unix/sysv/linux/arm/libc-vdso.h index ae37b574e1..ee0e5941c0 100644 --- a/sysdeps/unix/sysv/linux/arm/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/arm/libc-vdso.h @@ -27,6 +27,7 @@ extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden; extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *); +extern long (*VDSO_SYMBOL(clock_gettime64)) (clockid_t, struct __timespec64 *); #endif diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index e232f69a4f..df4e16e6db 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -44,4 +44,48 @@ break #define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */ +/* 64-bit versions */ + +/* The REALTIME and MONOTONIC clock are definitely supported in the + kernel. */ +#define SYSDEP_GETTIME64 \ + SYSDEP_GETTIME64_CPUTIME; \ + case CLOCK_REALTIME: \ + case CLOCK_MONOTONIC: \ + if (__y2038_linux_support) \ + { \ + retval = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); \ + } \ + else \ + { \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &ts32); \ + if (retval==0) \ + { \ + tp->tv_sec = ts32.tv_sec; \ + tp->tv_nsec = ts32.tv_nsec; \ + tp->tv_pad = 0; \ + } \ + } \ + break + +#define SYSDEP_GETTIME64_CPU(clock_id, tp) \ + if (__y2038_linux_support) \ + { \ + retval = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); \ + } \ + else \ + { \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &ts32); \ + if (retval==0) \ + { \ + tp->tv_sec = ts32.tv_sec; \ + tp->tv_nsec = ts32.tv_nsec; \ + tp->tv_pad = 0; \ + } \ + } \ + break +#define SYSDEP_GETTIME64_CPUTIME \ + struct timespec ts32; \ + extern int __y2038_linux_support; + #include