This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC v4 06/24] sysdeps/timespec_get: Use clock_gettime64 if avaliable


On Mon, Aug 12, 2019 at 12:46 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Fri, 9 Aug 2019, Alistair Francis wrote:
>
> > diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
> > index 52080ddf08a..97ef9c5f799 100644
> > --- a/sysdeps/unix/sysv/linux/timespec_get.c
> > +++ b/sysdeps/unix/sysv/linux/timespec_get.c
> > @@ -24,6 +24,58 @@
> >  #endif
> >  #include <sysdep-vdso.h>
> >
> > +int
> > +__timespec_get (struct timespec *ts, int base)
> > +{
> > +#ifdef __ASSUME_TIME64_SYSCALLS
> > +  return INTERNAL_VSYSCALL (clock_gettime64, err, 2, CLOCK_REALTIME, ts);
> > +#else
>
> This has the usual problems with missing conversions.

Is this the type of layout you are looking for? (untested, just a general idea)

int
__timespec_get64 (struct __timespec64 *ts, int base)
{
#ifdef __ASSUME_TIME64_SYSCALLS
  return INTERNAL_VSYSCALL (clock_gettime64, err, 2, CLOCK_REALTIME, ts);
#else
  long int ret;
# ifdef __NR_clock_gettime64
  ret = INTERNAL_VSYSCALL (clock_gettime64, err, 2, CLOCK_REALTIME, ts);

  if (ret == 0 || errno != ENOSYS)
    {
      return ret;
    }
# endif /* __NR_clock_gettime64 */
  struct timespec ts32;

  if (! in_time_t_range (ts->tv_sec))
    {
      __set_errno (EOVERFLOW);
      return -1;
    }

  valid_timespec64_to_timespec (ts, &ts32);
  ret = INTERNAL_VSYSCALL (clock_gettime, err, 2, CLOCK_REALTIME, &ts32);

  if ((ret == 0 || errno != ENOSYS) && ts)
    {
      ts->tv_sec = ts32.tv_sec;
      ts->tv_nsec = ts32.tv_nsec;
    }
  return ret;
#endif
}

#if __TIMESIZE != 64
int
__timespec_get32 (struct timespec *ts, int base)
{
  struct __timespec64 ts64;

  ret = __timespec_get64 (ts64, base);

  if ((ret == 0 || errno != ENOSYS) && ts)
    {
      ts->tv_sec = ts64.tv_sec;
      ts->tv_nsec = ts64.tv_nsec;
    }

  return ret;
}
#endif

#if __TIMESIZE == 64
# define __timespec_get __timespec_get64
#else
# define __timespec_get __timespec_get32
#endif

/* Set TS to calendar time based in time base BASE.  */
int
timespec_get (struct timespec *ts, int base)
{
  switch (base)
    {
      int res;
      INTERNAL_SYSCALL_DECL (err);
    case TIME_UTC:
      res = __timespec_get (ts, base);
      if (INTERNAL_SYSCALL_ERROR_P (res, err))
        return 0;
      break;

    default:
      return 0;
    }

  return base;
}

Alistair

>
> --
> Joseph S. Myers
> joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]