This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC v4 24/24] timerfd_settime: Use 64-bit call if avaliable
- From: Alistair Francis <alistair23 at gmail dot com>
- To: Alistair Francis <alistair dot francis at wdc dot com>
- Cc: GNU C Library <libc-alpha at sourceware dot org>, Arnd Bergmann <arnd at arndb dot de>, Adhemerval Zanella <adhemerval dot zanella at linaro dot org>, Florian Weimer <fweimer at redhat dot com>, Palmer Dabbelt <palmer at sifive dot com>, macro at wdc dot com, Zong Li <zongbox at gmail dot com>
- Date: Fri, 9 Aug 2019 18:27:39 -0700
- Subject: Re: [RFC v4 24/24] timerfd_settime: Use 64-bit call if avaliable
- References: <cover.1565398513.git.alistair.francis@wdc.com> <ef25779c773ca08b586f27ee80d61acde0b9bd7f.1565398514.git.alistair.francis@wdc.com>
On Fri, Aug 9, 2019 at 6:04 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
This commit was clearly not tested very well (it's missing
semicolons), just see it more as pseudo code.
Alistair
> 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 <bits/timerfd.h>
>
> +#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 <drepper@redhat.com>, 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 <http://www.gnu.org/licenses/>. */
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <time.h>
> +#include <sysdep.h>
> +
> +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 */
> +}
> --
> 2.22.0
>