This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC v5 03/21] sysdeps/gettimeofday: Use clock_gettime64 if avaliable
- From: Alistair Francis <alistair dot francis at wdc dot com>
- To: libc-alpha at sourceware dot org
- Cc: arnd at arndb dot de, adhemerval dot zanella at linaro dot org, fweimer at redhat dot com, palmer at sifive dot com, macro at wdc dot com, zongbox at gmail dot com, alistair dot francis at wdc dot com, alistair23 at gmail dot com
- Date: Thu, 29 Aug 2019 09:50:08 -0700
- Subject: [RFC v5 03/21] sysdeps/gettimeofday: Use clock_gettime64 if avaliable
- Ironport-sdr: bnkG7jgyXsia+bTheYn1/leX3tunUE2ytBfYbJ3wPfwXALG/RN5MHhEEuYTrteckvjPARdejkV LuoIKZmjjrwTjDIvgVV/3oCxsGbLFN3GOe2Z5gtnDfLkbO8mhXljv0wpiRs9NbVlp8B8F/NLX3 /j2gPEClsBAGQIMcnifobMS87PWDQGGsQkNHstaT0iEnEZ4vvDtU/88vx2E8R7bDMHMT4UPlwT cNlzGGI0HFJzN4KcI7HzdEMFHuf2iHFq2HJUE+NprJY+jyl73pzvqvpeQLR1bKc2yiGdfyXYfm qlk=
- Ironport-sdr: 1hrquiv9Wtspp4pKCSk4U9G1r2/jIC1gc2Y7RX1aqhiakR9DPCMOIo/JEgQBqWyCr+tUSJYSIi yTfwT5fE3KuhEfo1pnsZE+oqx7/KsuMhLQUA4zKgOXxCm+I6shRx+Anjcgk4FFyrbaxH9smeTJ qHGKInCAhdKwiJKlMUy6EDqXhd01jlsIJmYFfrwknvTEWoZziDouM0XV7LNQYTS0lZs0T7s68/ EzDKU8rcnWDOHWSEZD0UfgsdbQTIxTP+MVafqGrAG1mJo2Ho7dMJBLDZra7Uql0jvs0tK8VpHU vt82plzU3pW3Sx5xQYyKoHdb
- Ironport-sdr: Bo+dRVBLFXca4etiqCeHYIpG2yhkzSOqNgNwXjsAd5ZmcnLUaHfiuxzIzjMTkLhokeQLUs1WAs NXqHH+pFyWH+QgIZ8Tupha0dpAFk8PzX6jEokTR4ATjKphzHQhLkAhP5Kxn4DRFALwupZjqq0D SinLPz8gs+XKW1bTOPSd8Mm9tAFGNwC47fKnhZf8B03h2rf/rjwWplSKXWb+dwOHkKkf2ky4nX u8eYvIOjOfOj0OuUTmF13UL3/bz47InJSHBGeyremspkaj9pxVbe7KzySEPhWPMlwOn8tU0avr 9n4=
- References: <cover.1567097252.git.alistair.francis@wdc.com>
- Wdcironportexception: Internal
Not all architectures support the obsolete gettimeofday so use the
newer clock_gettime64 syscall if it is avaliable. This fixes RV32
build issues.
This has the side effect of not setting the struct timezone *tz variable
if __ASSUME_TIME64_SYSCALLS or __NR_clock_gettime64 is defined!!!
The struct timezone *tz variable contaions information on the current
timezone, in this structure:
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
On 32-bit systems with __ARCH_WANT_TIME32_SYSCALLS not defined there is
no way way to get the struct timezone via a syscall. AFAIK there are no
plans to add suppor to a future kernel.
Most callers of gettimeofday() don't use the timezone data, see
example code from Debian below.
If __ASSUME_TIME64_SYSCALLS and __NR_clock_gettime64 are not defined
then struct timezone *tz will be set as usual.
Example code from Debian:
struct timeval my_gettime(void)
{
struct timezone tz_ignored;
struct timeval tv;
gettimeofday(&tv, &tz_ignored);
return tv;
}
Arnd used Debian code search and found the following uses of struct timezone:
drivers/media/platform/vivid/vivid-rds-gen.c:
(sys_tz.tz_minuteswest >= 0 ? 0x20 : 0) |
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:
record->end_utc_bias = cpu_to_le16(sys_tz.tz_minuteswest * 60);
drivers/scsi/3w-9xxx.c: local_time = (u32)(ktime_get_real_seconds() -
(sys_tz.tz_minuteswest * 60));
drivers/scsi/3w-sas.c: local_time = (u32)(ktime_get_real_seconds() -
(sys_tz.tz_minuteswest * 60));
drivers/scsi/aacraid/commsup.c: local_time = (now->tv_sec -
(sys_tz.tz_minuteswest * 60));
drivers/scsi/arcmsr/arcmsr_hba.c:
time64_to_tm(ktime_get_real_seconds(), -sys_tz.tz_minuteswest * 60,
&tm);
drivers/scsi/mvumi.c: local_time = (time -
(sys_tz.tz_minuteswest * 60));
drivers/scsi/smartpqi/smartpqi_init.c: time64_to_tm(local_time,
-sys_tz.tz_minuteswest * 60, &tm);
fs/affs/amigaffs.c: secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365
+ 2) * 24 * 60 * 60);
fs/affs/inode.c: sys_tz.tz_minuteswest * 60;
fs/fat/misc.c: sys_tz.tz_minuteswest) * SECS_PER_MIN;
fs/hfs/hfs_fs.h: return ut + sys_tz.tz_minuteswest * 60;
fs/hfs/inode.c: HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60;
fs/hfs/sysdep.c: diff = sys_tz.tz_minuteswest * 60 -
HFS_I(inode)->tz_secondswest;
fs/hpfs/hpfs_fn.h: return t + sys_tz.tz_minuteswest * 60 +
hpfs_sb(s)->sb_timeshift;
fs/udf/udftime.c: offset = -sys_tz.tz_minuteswest;
kernel/debug/kdb/kdb_main.c: sys_tz.tz_minuteswest);
kernel/time/ntp.c: adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
kernel/time/timekeeping.c: if (sys_tz.tz_minuteswest != 0) {
kernel/time/vsyscall.c: vdata[CS_HRES_COARSE].tz_minuteswest =
sys_tz.tz_minuteswest;
lib/vdso/gettimeofday.c: tz->tz_minuteswest =
vd[CS_HRES_COARSE].tz_minuteswest;
net/netfilter/xt_time.c: stamp -= 60 * sys_tz.tz_minuteswest;
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* sysdeps/unix/sysv/linux/gettimeofday.c: Use clock_gettime64 syscall
for gettimeofday.
---
sysdeps/unix/sysv/linux/gettimeofday.c | 59 +++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
index a74f03825a5..af342f219ec 100644
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -32,8 +32,65 @@
int
__gettimeofday (struct timeval *tv, struct timezone *tz)
{
- return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+ long int ret_64;
+#ifdef __ASSUME_TIME64_SYSCALLS
+# ifndef __NR_clock_gettime64
+# define __NR_clock_gettime64 __NR_clock_gettime
+# endif
+ struct timespec now;
+
+ ret_64 = INLINE_VSYSCALL (clock_gettime64, 2, CLOCK_REALTIME,
+ &now);
+
+ if (ret_64 == 0 || errno != ENOSYS)
+ valid_timespec64_to_timeval((struct __timespec64*) &now, tv);
+
+ return ret_64;
+#else
+# ifdef __NR_clock_gettime64
+ ret_64 = INLINE_VSYSCALL (clock_gettime64, 2, CLOCK_REALTIME,
+ &now);
+
+ if (ret_64 == 0 || errno != ENOSYS)
+ {
+ valid_timespec64_to_timeval((struct __timespec64*) &now, tv);
+ return ret_64;
+ }
+# endif /* __NR_clock_gettime64 */
+ int ret = INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+
+ if (! in_time_t_range (tv->tv_sec))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ return ret;
+#endif
}
+
+#if __TIMESIZE != 64
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ int ret;
+ timeval64 tv64;
+ struct __timespec64 now;
+
+ ret = __gettimeofday (&tv64, tz);
+
+ if (ret == 0 || errno != ENOSYS)
+ {
+ /* Convert from timespec to timeval */
+ tv->tv_sec = tv64.tv_sec;
+ tv->tv_usec = tv64.tv_nsec;
+ return ret;
+ }
+
+ return ret;
+}
+#endif
+
libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
libc_hidden_weak (gettimeofday)
--
2.22.0