From patchwork Thu Jun 17 11:51:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 43879 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 093B1393A43C for ; Thu, 17 Jun 2021 12:06:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 093B1393A43C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1623931587; bh=zF1iKOoU1pLZtHHMQhlYyiw0IQ8qo5s3OunKYYepjWk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=wrFpFWXcIHOi/wJ8MbdvFkPjKifJTJqRnE4jl+1fmU95wGNwJ5cB29xtM1RBcx+4Y Gdd13+7s/qbj5cjXQMGGY9a6tEfxNbwh3JLOAX7HRwbKbeG2qC38a+erLfzqRt3fgH yhZ/GmWwlGFfX8rlGOYCZOwEY+svW8gxlb6Cuoww= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x834.google.com (mail-qt1-x834.google.com [IPv6:2607:f8b0:4864:20::834]) by sourceware.org (Postfix) with ESMTPS id 855FB3894C1E for ; Thu, 17 Jun 2021 11:51:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 855FB3894C1E Received: by mail-qt1-x834.google.com with SMTP id o20so4419660qtr.8 for ; Thu, 17 Jun 2021 04:51:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zF1iKOoU1pLZtHHMQhlYyiw0IQ8qo5s3OunKYYepjWk=; b=BBbxswygg2zc33ypGLx3ljjjJWcWJAP2tWpLDL1I/X722OAOTYPjOIDt3P7Dln2dol /D7hAzVwRsIMZeQjjKjA4k4z13utjcGmiXGW/Sq3uGLvPGrGOfcU8wstUK/qI7J1cucn diBVnmYpVQnmly8CEVPqGI/OLyoQG+UUy3ZkOQ7hBKSSYT3CYS8+FxbaeI9AYVTiWVn/ 4DOmeoP7rBPA1PuIfTDKygfDSxKw9y0pf1P+i1/oUpi6BYiT/moD8+dZYwRVojY1J47P g3pk9JLLMYjGm+RtSHlEZdjpa4bTZ9lZXvuFsxFHj0jCBndUL0ccRC+Q1czzLcJIzKCF 0EzQ== X-Gm-Message-State: AOAM530sHV2YcJKCcJg1Ip/IQiIx6Jo3YwpsG8mKSsOQLz6ykxk0Yw8h XAa0PTHrdPqhKGXJqXeAjVES5gdXbXGM8w== X-Google-Smtp-Source: ABdhPJz2XoHvwbCv6euBD6mbVctaHAmuoY0B5kTEHq4/05SAeFdExEjE5umfBYkulBMfkzrj+vpKGg== X-Received: by 2002:ac8:5685:: with SMTP id h5mr4712191qta.255.1623930698988; Thu, 17 Jun 2021 04:51:38 -0700 (PDT) Received: from birita.. ([177.194.59.218]) by smtp.googlemail.com with ESMTPSA id p12sm3016435qtw.61.2021.06.17.04.51.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Jun 2021 04:51:38 -0700 (PDT) To: libc-alpha@sourceware.org, Lukasz Majewski , Carlos O'Donell Subject: [PATCH 18/18] linux: Only use 64-bit syscall if required for clock_nanosleep Date: Thu, 17 Jun 2021 08:51:04 -0300 Message-Id: <20210617115104.1359598-19-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210617115104.1359598-1-adhemerval.zanella@linaro.org> References: <20210617115104.1359598-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall if the provided timeout fits in a 32-bit one. The 64-bit usage should be rare since the timeout is a relative one. Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel (with and without --enable-kernel=5.1) and on x86_64-linux-gnu. Reviewed-by: Lukasz Majewski --- sysdeps/unix/sysv/linux/clock_nanosleep.c | 47 +++++++++++++---------- time/Makefile | 9 +++++ time/tst-clock_nanosleep.c | 40 +++++++++++-------- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c index 007f1736cb..46b0f1e269 100644 --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -27,8 +27,9 @@ /* We can simply use the syscall. The CPU clocks are not supported with this function. */ int -__clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req, - struct __timespec64 *rem) +__clock_nanosleep_time64 (clockid_t clock_id, int flags, + const struct __timespec64 *req, + struct __timespec64 *rem) { if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL; @@ -37,33 +38,37 @@ __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec /* If the call is interrupted by a signal handler or encounters an error, it returns a positive value similar to errno. */ + #ifndef __NR_clock_nanosleep_time64 # define __NR_clock_nanosleep_time64 __NR_clock_nanosleep #endif - int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id, - flags, req, rem); - -#ifndef __ASSUME_TIME64_SYSCALLS - if (r == 0 || r != -ENOSYS) - return -r; - if (! in_time_t_range (req->tv_sec)) + int r; +#ifdef __ASSUME_TIME64_SYSCALLS + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id, flags, req, + rem); +#else + bool is32bit = in_time_t_range (req->tv_sec); + if (!is32bit) { - __set_errno (EOVERFLOW); - return -1; + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id, flags, + req, rem); + if (r == -ENOSYS) + r = -EOVERFLOW; } - - struct timespec tr32; - struct timespec ts32 = valid_timespec64_to_timespec (*req); - r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags, - &ts32, &tr32); - if (INTERNAL_SYSCALL_ERROR_P (r)) + else { - if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0) - *rem = valid_timespec_to_timespec64 (tr32); + struct timespec tr32; + struct timespec ts32 = valid_timespec64_to_timespec (*req); + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, clock_id, flags, &ts32, + &tr32); + if (INTERNAL_SYSCALL_ERROR_P (r)) + { + if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0) + *rem = valid_timespec_to_timespec64 (tr32); + } } -#endif /* __ASSUME_TIME64_SYSCALLS */ - +#endif return -r; } diff --git a/time/Makefile b/time/Makefile index c84bd5d3ec..0bea84966c 100644 --- a/time/Makefile +++ b/time/Makefile @@ -86,6 +86,15 @@ $(objpfx)tst-strftime2.out: $(gen-locales) $(objpfx)tst-strftime3.out: $(gen-locales) endif +ifeq (yes,$(build-shared)) +librt = $(common-objpfx)rt/librt.so +else +librt = $(common-objpfx)rt/librt.a +endif + +$(objpfx)tst-clock_nanosleep: $(librt) +$(objpfx)tst-clock_nanosleep-time64: $(librt) + tz-cflags = -DTZDIR='"$(zonedir)"' \ -DTZDEFAULT='"$(localtime-file)"' \ -DTZDEFRULES='"$(posixrules-file)"' diff --git a/time/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c index 47537435c1..a5a7f9430a 100644 --- a/time/tst-clock_nanosleep.c +++ b/time/tst-clock_nanosleep.c @@ -20,38 +20,48 @@ #include #include #include - +#include +#include +#include /* Test that clock_nanosleep() does sleep. */ -static int -do_test (void) +static void +clock_nanosleep_test (void) { /* Current time. */ struct timeval tv1; - (void) gettimeofday (&tv1, NULL); + gettimeofday (&tv1, NULL); - struct timespec ts; - ts.tv_sec = 1; - ts.tv_nsec = 0; + struct timespec ts = { 1, 0 }; TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts)); /* At least one second must have passed. */ struct timeval tv2; - (void) gettimeofday (&tv2, NULL); + gettimeofday (&tv2, NULL); tv2.tv_sec -= tv1.tv_sec; tv2.tv_usec -= tv1.tv_usec; if (tv2.tv_usec < 0) --tv2.tv_sec; - if (tv2.tv_sec < 1) - { - puts ("clock_nanosleep didn't sleep long enough"); - return 1; - } + TEST_VERIFY (tv2.tv_sec >= 1); +} + +static void +clock_nanosleep_large_timeout (void) +{ + support_create_timer (0, 100000000, false, NULL); + struct timespec ts = { TYPE_MAXIMUM (time_t), 0 }; + int r = clock_nanosleep (CLOCK_REALTIME, 0, &ts, NULL); + TEST_VERIFY (r == EINTR || r == EOVERFLOW); +} +static int +do_test (void) +{ + clock_nanosleep_test (); + clock_nanosleep_large_timeout (); return 0; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include