From patchwork Sat Aug 10 01:00:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 34051 Received: (qmail 80413 invoked by alias); 10 Aug 2019 01:04:19 -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 80346 invoked by uid 89); 10 Aug 2019 01:04:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT autolearn=ham version=3.3.1 spammy= X-HELO: esa3.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1565399057; x=1596935057; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f+X/tHUzgjtjobnYg/ZfgqZxV7wyNGPVLDIJsPRvou8=; b=ZT+USjoO8zcTPu3MUNVN90IORVKVTx3u7tuD2QUdxyHqC5pLZRBi22Y8 6sjy0iovjvob8BiWMS1MnleXcirVTNKkV7nm03JASHIhDz2p5lOPz2FTp 5USI+6k50lmlUV7cNaH8yvPHZWwjhrIJeXx0Cbdkw0ERNsSNeLBMncdow bSGykanHUXzwGPUStK4M0I4GRa6ln7MxQUKA9Pq+qpO2QLpEeginPaiGQ 8ZI3MgZ2AQh1IOcr0rr26ymdaquFKqqQ0OlQqa9GAwCWMMJtOfOL/RMC1 F+e2XhPMWmYIwgqqd7uoCheIxgajP5JYfh2bGnwkZn2jR5ZQILWOdTqEN A==; IronPort-SDR: 9qPwpX/7u/78vfTD6C07sdMHeXOkxCnAQ5VF3lkQyRCOdgFuQq+4aNiy3yxt5faw/06gLQRS+C Prd8vVxiScmq/BDr3ZlbOMj2LLD6gdM7xpn6Hnewo6r49HvuoJGA4owpN1+fmR29TO5pFwRFlK ADvxDdUeVidMexsfGl6k26IT3hkG+xqjGYXDrsG6iGmPUbUHQTh4v3xIpY/rHq9JaphAFVZXyf XnekZwXDoiqIAFyfpASL6IEsdnMhXw0Pgdq9eJCAqOeu8kf8Bc62jrNVCGhFvfLZSfUS9UIC1u 78Q= IronPort-SDR: Do3rsfCZa2rr2nBh9mYCsKTq6hZZLdM1gUqz8cVlM34BO/t0PyHORf+86mDSe9JfnornWZxCaL T1XNIGB4/Amu4Bcbw7OfXDeEB7ZWfTBi2X6b73Pkcs+Sc3hr6hWxGP7UJzhm1RNAlViLikFZQn Rw1a0AgoE5epFrdZziKTN1gp9FFSgvJa5RRQxICgBXrlwAMztp5gyFZZ1xPs5Q+xRRLKgVl8AX 8qa8bTrtKh0CVU3GN9Svh+sfWfyxq5ZCBFmGCYiC+0WqdbFmOIneRoaxyHDHUkcOmIq89WAtOZ EnIsEXe1z0FaAZzTk981w0BP IronPort-SDR: 4zqf7SbMcty6RuJ448rFvU2AXO0mAXN/rYMkwyZwEe0eoEpWmxYqw8t3jQsKC1QfnkWF4Z2pJX AzTFkt9Kupp2VxirncTc/2WzDw1LMBRoirQUcG+PvqL1luqZvGUz+jb17c9uNpzan7N2z9KG7Q A3vQJKigI6yC2tIiObxYjIm19sZ/GhC/U+6S0Nf7yK1ZxsyI8l0yuRBHeIg76d4WmItVlrToSu HRUaw2dHUiTQbeFoyFgjGTUnNS7udRU+qKV9qOjVvCfgj+VN3If2jwmrzNTQ6RyCTY0rOjyAD4 3bQ= From: Alistair Francis To: libc-alpha@sourceware.org Cc: arnd@arndb.de, adhemerval.zanella@linaro.org, fweimer@redhat.com, palmer@sifive.com, macro@wdc.com, zongbox@gmail.com, alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v4 24/24] timerfd_settime: Use 64-bit call if avaliable Date: Fri, 9 Aug 2019 18:00:56 -0700 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Signed-off-by: Alistair Francis --- sysdeps/unix/sysv/linux/Makefile | 2 + sysdeps/unix/sysv/linux/sys/timerfd.h | 21 +++-- sysdeps/unix/sysv/linux/syscalls.list | 1 - sysdeps/unix/sysv/linux/timerfd_settime.c | 104 ++++++++++++++++++++++ 4 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/timerfd_settime.c diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 1ab6bcbfc81..89128e80868 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -19,6 +19,8 @@ sysdep_routines += clone umount umount2 readahead \ eventfd eventfd_read eventfd_write prlimit \ personality epoll_wait tee vmsplice splice \ open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get + timerfd_settime + CFLAGS-gethostid.c = -fexceptions CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/unix/sysv/linux/sys/timerfd.h b/sysdeps/unix/sysv/linux/sys/timerfd.h index 5e5ad351a0d..51f63b357c1 100644 --- a/sysdeps/unix/sysv/linux/sys/timerfd.h +++ b/sysdeps/unix/sysv/linux/sys/timerfd.h @@ -24,6 +24,13 @@ /* Get the platform-dependent flags. */ #include +#if __TIMESIZE == 32 +struct __itimerspec64 + { + struct __timespec64 it_interval; + struct __timespec64 it_value; + }; +#endif /* Bits to be set in the FLAGS parameter of `timerfd_settime'. */ enum @@ -40,16 +47,16 @@ __BEGIN_DECLS /* Return file descriptor for new interval timer source. */ extern int timerfd_create (__clockid_t __clock_id, int __flags) __THROW; -/* Set next expiration time of interval timer source UFD to UTMR. If - FLAGS has the TFD_TIMER_ABSTIME flag set the timeout value is - absolute. Optionally return the old expiration time in OTMR. */ -extern int timerfd_settime (int __ufd, int __flags, - const struct itimerspec *__utmr, - struct itimerspec *__otmr) __THROW; - /* Return the next expiration time of UFD. */ extern int timerfd_gettime (int __ufd, struct itimerspec *__otmr) __THROW; __END_DECLS +/* Set next expiration time of interval timer source UFD to UTMR. If + FLAGS has the TFD_TIMER_ABSTIME flag set the timeout value is + absolute. Optionally return the old expiration time in OTMR. */ +int timerfd_settime (int __ufd, int __flags, + const struct itimerspec *__utmr, + struct itimerspec *__otmr) __THROW; + #endif /* sys/timerfd.h */ diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 4844d1a9a3b..3fa1a5de63a 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -96,7 +96,6 @@ fremovexattr - fremovexattr i:is fremovexattr mq_setattr - mq_getsetattr i:ipp mq_setattr timerfd_create EXTRA timerfd_create i:ii timerfd_create -timerfd_settime EXTRA timerfd_settime64 i:iipp timerfd_settime timerfd_gettime EXTRA timerfd_gettime64 i:ip timerfd_gettime fanotify_init EXTRA fanotify_init i:ii fanotify_init diff --git a/sysdeps/unix/sysv/linux/timerfd_settime.c b/sysdeps/unix/sysv/linux/timerfd_settime.c new file mode 100644 index 00000000000..830faeada77 --- /dev/null +++ b/sysdeps/unix/sysv/linux/timerfd_settime.c @@ -0,0 +1,104 @@ +/* Copyright (C) 2003-2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2003. + + 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 + +int +timerfd_settime (int __ufd, int __flags, const struct itimerspec *__utmr, + struct itimerspec *__otmr) +{ +#ifdef __ASSUME_TIME64_SYSCALLS + /* Delete the kernel timer object. */ + return INLINE_SYSCALL (timerfd_settime64, 4, __ufd, __flags, __utmr, __otmr); +#else + int ret; +# ifdef __NR_timerfd_settime64 +# if __TIMESIZE == 64 + ret = INLINE_SYSCALL (timerfd_settime64, 4, __ufd, __flags, __utmr, __otmr); + + if (ret == 0 || errno != ENOSYS) + { + return ret; + } +# else + struct __itimerspec64 ts64; + ret = INLINE_SYSCALL (timerfd_settime64, 4, __ufd, __flags, __utmr, &ts64); + + if (ret == 0 || errno != ENOSYS) + { + __utmr->it_interval.tv_sec = ts64.it_interval.tv_sec + __utmr->it_interval.tv_nsec = ts64.it_interval.tv_nsec + if (! in_time_t_range (__utmr->it_interval.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + __utmr->it_value.tv_sec = ts64.it_value.tv_sec + __utmr->it_value.tv_nsec = ts64.it_value.tv_nsec + if (! in_time_t_range (__utmr->it_value.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + return 0; + } +# endif /* __TIMESIZE == 64 */ +# endif /* __NR_timerfd_settime */ +# if __TIMESIZE == 64 + struct itimerspec ts32; + + if (! in_time_t_range (__utmr->it_interval.tv_sec) || + ! in_time_t_range (__utmr->it_value.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + ret = INLINE_SYSCALL (timerfd_settime, 4, __ufd, __flags, __utmr, &ts32); + + if (ret == 0 || errno != ENOSYS) + { + __utmr->it_interval.tv_sec = ts32.it_interval.tv_sec + __utmr->it_interval.tv_nsec = ts32.it_interval.tv_nsec + if (! in_time_t_range (__utmr->it_interval.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + __utmr->it_value.tv_sec = ts32.it_value.tv_sec + __utmr->it_value.tv_nsec = ts32.it_value.tv_nsec + if (! in_time_t_range (__utmr->it_value.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + return 0; + } + return ret; +# else + return INLINE_SYSCALL (timerfd_settime, 4, __ufd, __flags, __utmr, __otmr); +# endif /* __TIMESIZE == 64 */ +#endif /* __ASSUME_TIME64_SYSCALLS */ +}