[PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime.
Adhemerval Zanella
adhemerval.zanella@linaro.org
Thu Aug 29 20:30:00 GMT 2019
On 28/08/2019 12:32, Zack Weinberg wrote:
> Since gettimeofday will shortly be implemented in terms of
> clock_gettime on all platforms, internal code should use clock_gettime
> directly; in addition to removing a layer of indirection, this will
> allow us to remove the PLT-bypass gunk for gettimeofday. (We can't
> quite do that yet, but it'll be coming later in this patch series.)
> In many cases, the changed code does fewer conversions.
>
> The changed code always assumes __clock_gettime (CLOCK_REALTIME)
> cannot fail. Most of the call sites were assuming gettimeofday could
> not fail, but a few places were checking for errors. POSIX says
> clock_gettime can only fail if the clock constant is invalid or
> unsupported, and CLOCK_REALTIME is the one and only clock constant
> that's required to be supported. For consistency I grepped the entire
> source tree for any other places that checked for errors from
> __clock_gettime (CLOCK_REALTIME), found one, and changed it too.
>
> (For the record, POSIX also says gettimeofday can never fail.)
>
> (It would be nice if we could declare that GNU systems will always
> support CLOCK_MONOTONIC as well as CLOCK_REALTIME; there are several
> places where we are using CLOCK_REALTIME where _MONOTONIC would be
> more appropriate, and/or trying to use _MONOTONIC and then falling
> back to _REALTIME. But the Hurd doesn't support CLOCK_MONOTONIC yet,
> and it looks like adding it would involve substantial changes to
> gnumach's internals and API. Oh well.)
>
> A few Hurd-specific files were changed to use __host_get_time instead
> of __clock_gettime, as this seemed tidier. We also assume this cannot
> fail. Skimming the code in gnumach leads me to believe the only way
> it could fail is if __mach_host_self also failed, and our
> Hurd-specific code consistently assumes that can't happen, so I'm
> going with that.
>
> With the exception of support/support_test_main.c, test cases are not
> modified, mainly because I didn't want to have to figure out which
> test cases were testing gettimeofday specifically.
>
> The definition of GETTIME in sysdeps/generic/memusage.h had a typo and
> was not reading tv_sec at all. I fixed this. It appears nobody has been
> generating malloc traces on a machine that doesn't have a superseding
> definition.
I think memusage.h is candidate for some cleanup, it basically replicate the
same interface hp-timing.h provides while I think GET_SP could just use
__builtin_frame_address (0) instead (and remove all the required arch-specific
implementations).
>
> There are a whole bunch of places where the code could be simplified
> by factoring out timespec subtraction and/or comparison logic, but I
> want to keep this patch as mechanical as possible.
>
> * inet/deadline.c (__deadline_current_time)
> * login/logout.c (logout)
> * login/logwtmp.c (logwtmp)
> * nis/nis_call.c (__nisfind_server)
> * nptl/pthread_join_common.c (timedwait_tid)
> * nptl/pthread_mutex_timedlock.c (__pthread_mutex_clocklock_common)
> * nscd/nscd_helper.c (wait_on_socket, open_socket)
> * resolv/gai_misc.c (handle_requests)
> * resolv/gai_suspend.c (gai_suspend)
> * resolv/res_send.c (evNowTime)
> * sunrpc/auth_des.c (authdes_marshal, authdes_destroy)
> * sunrpc/auth_unix.c (authunix_create, authunix_refresh)
> * sunrpc/create_xid.c (_create_xid)
> * sunrpc/svcauth_des.c (_svcauth_des)
> * sysdeps/generic/memusage.h (GETTIME)
> * sysdeps/mach/nanosleep.c (__libc_nanosleep)
> * sysdeps/posix/tempname.c (RANDOM_BITS)
> * sysdeps/pthread/aio_misc.c (handle_fildes_io)
> * sysdeps/pthread/aio_suspend.c (aio_suspend):
> Use __clock_gettime (CLOCK_REALTIME) instead of __gettimeofday.
> Assume __clock_gettime (CLOCK_REALTIME) cannot fail.
> Include time.h if necessary.
>
> * sysdeps/posix/timespec_get.c (timespec_get):
> Assume __clock_gettime (CLOCK_REALTIME) cannot fail.
>
> * sysdeps/mach/hurd/getitimer.c (__getitimer)
> * sysdeps/mach/hurd/setitimer.c (setitimer_locked)
> * sysdeps/mach/hurd/times.c (__times):
> Use __host_get_time instead of __gettimeofday.
> Include mach.h if necessary.
> Assume __host_get_time (__mach_host_self ()) cannot fail.
>
> * sysdeps/mach/usleep.c (usleep): Remove unnecessary calls to
> __gettimeofday.
>
> * support/support_test_main.c (print_timestamp): Take a struct
> timespec argument, not a struct timeval.
> (signal_handler): Update to match.
> Use clock_gettime (CLOCK_REALTIME) instead of gettimeofday.
> Assume clock_gettime (CLOCK_REALTIME) cannot fail.
>
> * sysdeps/generic/memusage.h (GETTIME): Correct typo causing
> the seconds field of each timestamp to be ignored.
>
> * sysdeps/unix/make-syscall.sh: Change an example in a comment
> from referring to gettimeofday, to referring to sigaction.
Looks ok with some adjustments below.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> inet/deadline.c | 8 +-------
> login/logout.c | 9 +++++----
> login/logwtmp.c | 7 +++----
> nis/nis_call.c | 4 +++-
> nptl/pthread_join_common.c | 7 +++----
> nptl/pthread_mutex_timedlock.c | 7 +++----
> nscd/nscd_helper.c | 24 +++++++++++------------
> resolv/gai_misc.c | 6 +++---
> resolv/gai_suspend.c | 6 +++---
> resolv/res_send.c | 7 +------
> sunrpc/auth_des.c | 19 ++++++++++--------
> sunrpc/auth_unix.c | 9 +++++----
> sunrpc/create_xid.c | 6 +++---
> sunrpc/svcauth_des.c | 7 ++++++-
> support/support_test_main.c | 23 +++++++++++-----------
> sysdeps/generic/memusage.h | 16 +++++++--------
> sysdeps/mach/hurd/getitimer.c | 6 +++---
> sysdeps/mach/hurd/setitimer.c | 8 ++------
> sysdeps/mach/hurd/times.c | 7 +++----
> sysdeps/mach/nanosleep.c | 36 ++++++++++++++++++++++------------
> sysdeps/mach/usleep.c | 5 -----
> sysdeps/posix/tempname.c | 9 ++++-----
> sysdeps/posix/timespec_get.c | 14 ++++---------
> sysdeps/pthread/aio_misc.c | 6 +++---
> sysdeps/pthread/aio_suspend.c | 6 +++---
> sysdeps/unix/make-syscalls.sh | 2 +-
> 26 files changed, 127 insertions(+), 137 deletions(-)
>
> diff --git a/inet/deadline.c b/inet/deadline.c
> index ab275c266d..082e279bce 100644
> --- a/inet/deadline.c
> +++ b/inet/deadline.c
> @@ -29,13 +29,7 @@ __deadline_current_time (void)
> {
> struct deadline_current_time result;
> if (__clock_gettime (CLOCK_MONOTONIC, &result.current) != 0)
> - {
> - struct timeval current_tv;
> - if (__gettimeofday (¤t_tv, NULL) == 0)
> - __libc_fatal ("Fatal error: gettimeofday system call failed\n");
> - result.current.tv_sec = current_tv.tv_sec;
> - result.current.tv_nsec = current_tv.tv_usec * 1000;
> - }
> + __clock_gettime (CLOCK_REALTIME, &result.current);
> assert (result.current.tv_sec >= 0);
> return result;
> }
Ok.
> diff --git a/login/logout.c b/login/logout.c
> index 5015c1af0b..f1313ded77 100644
> --- a/login/logout.c
> +++ b/login/logout.c
> @@ -19,6 +19,7 @@
> #include <errno.h>
> #include <string.h>
> #include <utmp.h>
> +#include <time.h>
> #include <sys/time.h>
>
> int
> @@ -45,10 +46,10 @@ logout (const char *line)
> /* Clear information about who & from where. */
> memset (ut->ut_name, '\0', sizeof ut->ut_name);
> memset (ut->ut_host, '\0', sizeof ut->ut_host);
> - struct timeval tv;
> - __gettimeofday (&tv, NULL);
> - ut->ut_tv.tv_sec = tv.tv_sec;
> - ut->ut_tv.tv_usec = tv.tv_usec;
> +
> + struct timespec ts;
> + __clock_gettime (CLOCK_REALTIME, &ts);
> + TIMESPEC_TO_TIMEVAL (&ut->ut_tv, &ts);
> ut->ut_type = DEAD_PROCESS;
>
> if (pututline (ut) != NULL)
Ok.
> diff --git a/login/logwtmp.c b/login/logwtmp.c
> index 50d14976c7..ec41375383 100644
> --- a/login/logwtmp.c
> +++ b/login/logwtmp.c
> @@ -36,10 +36,9 @@ logwtmp (const char *line, const char *name, const char *host)
> strncpy (ut.ut_name, name, sizeof ut.ut_name);
> strncpy (ut.ut_host, host, sizeof ut.ut_host);
>
> - struct timeval tv;
> - __gettimeofday (&tv, NULL);
> - ut.ut_tv.tv_sec = tv.tv_sec;
> - ut.ut_tv.tv_usec = tv.tv_usec;
> + struct timespec ts;
> + __clock_gettime (CLOCK_REALTIME, &ts);
> + TIMESPEC_TO_TIMEVAL (&ut.ut_tv, &ts);
>
> updwtmp (_PATH_WTMP, &ut);
> }
Ok.
> diff --git a/nis/nis_call.c b/nis/nis_call.c
> index a48ecc39a8..db81fa3568 100644
> --- a/nis/nis_call.c
> +++ b/nis/nis_call.c
> @@ -709,6 +709,7 @@ __nisfind_server (const_nis_name name, int search_parent,
> nis_error status;
> directory_obj *obj;
> struct timeval now;
> + struct timespec ts;
> unsigned int server_used = ~0;
> unsigned int current_ep = ~0;
>
> @@ -718,7 +719,8 @@ __nisfind_server (const_nis_name name, int search_parent,
> if (*dir != NULL)
> return NIS_SUCCESS;
>
> - (void) gettimeofday (&now, NULL);
> + __clock_gettime (CLOCK_REALTIME, &ts);
> + TIMESPEC_TO_TIMEVAL (&now, &ts);
>
> if ((flags & NO_CACHE) == 0)
> *dir = nis_server_cache_search (name, search_parent, &server_used,
Ok.
> diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
> index 5224ee2110..f1b14266de 100644
> --- a/nptl/pthread_join_common.c
> +++ b/nptl/pthread_join_common.c
> @@ -46,15 +46,14 @@ timedwait_tid (pid_t *tidp, const struct timespec *abstime)
> /* Repeat until thread terminated. */
> while ((tid = *tidp) != 0)
> {
> - struct timeval tv;
> struct timespec rt;
>
> /* Get the current time. */
> - __gettimeofday (&tv, NULL);
> + __clock_gettime (CLOCK_REALTIME, &rt);
>
> /* Compute relative timeout. */
> - rt.tv_sec = abstime->tv_sec - tv.tv_sec;
> - rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
> + rt.tv_sec = abstime->tv_sec - rt.tv_sec;
> + rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
> if (rt.tv_nsec < 0)
> {
> rt.tv_nsec += 1000000000;
Ok.
> diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
> index 52c258e33d..2b194e5bee 100644
> --- a/nptl/pthread_mutex_timedlock.c
> +++ b/nptl/pthread_mutex_timedlock.c
> @@ -567,15 +567,14 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
> goto failpp;
> }
>
> - struct timeval tv;
> struct timespec rt;
>
> /* Get the current time. */
> - (void) __gettimeofday (&tv, NULL);
> + __clock_gettime (CLOCK_REALTIME, &rt);
This seems to be using space instead of tabs.
>
> /* Compute relative timeout. */
> - rt.tv_sec = abstime->tv_sec - tv.tv_sec;
> - rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
> + rt.tv_sec = abstime->tv_sec - rt.tv_sec;
> + rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
> if (rt.tv_nsec < 0)
> {
> rt.tv_nsec += 1000000000;
Ok.
> diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
> index 733c2a60cd..a6568d07c8 100644
> --- a/nscd/nscd_helper.c
> +++ b/nscd/nscd_helper.c
> @@ -59,9 +59,10 @@ wait_on_socket (int sock, long int usectmo)
> /* Handle the case where the poll() call is interrupted by a
> signal. We cannot just use TEMP_FAILURE_RETRY since it might
> lead to infinite loops. */
> - struct timeval now;
> - (void) __gettimeofday (&now, NULL);
> - long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
> + struct timespec now;
> + __clock_gettime (CLOCK_REALTIME, &now);
> + long int end = (now.tv_sec * 1000 + usectmo
> + + (now.tv_nsec + 500000) / 1000000);
> long int timeout = usectmo;
> while (1)
> {
Ok.
> @@ -70,8 +71,9 @@ wait_on_socket (int sock, long int usectmo)
> break;
>
> /* Recompute the timeout time. */
> - (void) __gettimeofday (&now, NULL);
> - timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
> + __clock_gettime (CLOCK_REALTIME, &now);
> + timeout = end - ((now.tv_sec * 1000
> + + (now.tv_nsec + 500000) / 1000000));
> }
> }
>
Ok.
> @@ -191,9 +193,7 @@ open_socket (request_type type, const char *key, size_t keylen)
> memcpy (reqdata->key, key, keylen);
>
> bool first_try = true;
> - struct timeval tvend;
> - /* Fake initializing tvend. */
> - asm ("" : "=m" (tvend));
> + struct timespec tvend = { 0, 0 };
> while (1)
> {
> #ifndef MSG_NOSIGNAL
> @@ -212,18 +212,18 @@ open_socket (request_type type, const char *key, size_t keylen)
>
> /* The daemon is busy wait for it. */
> int to;
> - struct timeval now;
> - (void) __gettimeofday (&now, NULL);
> + struct timespec now;
> + __clock_gettime (CLOCK_REALTIME, &now);
> if (first_try)
> {
> - tvend.tv_usec = now.tv_usec;
> + tvend.tv_nsec = now.tv_nsec;
> tvend.tv_sec = now.tv_sec + 5;
> to = 5 * 1000;
> first_try = false;
> }
> else
> to = ((tvend.tv_sec - now.tv_sec) * 1000
> - + (tvend.tv_usec - now.tv_usec) / 1000);
> + + (tvend.tv_nsec - now.tv_nsec) / 1000000);
>
> struct pollfd fds[1];
> fds[0].fd = sock;
ok.
> diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
> index 69d7086ae6..5d1e310147 100644
> --- a/resolv/gai_misc.c
> +++ b/resolv/gai_misc.c
> @@ -357,13 +357,13 @@ handle_requests (void *arg)
> something to arrive in it. */
> if (runp == NULL && optim.gai_idle_time >= 0)
> {
> - struct timeval now;
> + struct timespec now;
> struct timespec wakeup_time;
>
> ++idle_thread_count;
> - gettimeofday (&now, NULL);
> + __clock_gettime (CLOCK_REALTIME, &now);
> wakeup_time.tv_sec = now.tv_sec + optim.gai_idle_time;
> - wakeup_time.tv_nsec = now.tv_usec * 1000;
> + wakeup_time.tv_nsec = now.tv_nsec;
> if (wakeup_time.tv_nsec >= 1000000000)
> {
> wakeup_time.tv_nsec -= 1000000000;
Ok.
> diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c
> index eee3bcebe9..8f81e5a3dd 100644
> --- a/resolv/gai_suspend.c
> +++ b/resolv/gai_suspend.c
> @@ -91,11 +91,11 @@ gai_suspend (const struct gaicb *const list[], int ent,
> {
> /* We have to convert the relative timeout value into an
> absolute time value with pthread_cond_timedwait expects. */
> - struct timeval now;
> + struct timespec now;
> struct timespec abstime;
>
> - __gettimeofday (&now, NULL);
> - abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
> + __clock_gettime (CLOCK_REALTIME, &now);
> + abstime.tv_nsec = timeout->tv_nsec + now.tv_nsec;
> abstime.tv_sec = timeout->tv_sec + now.tv_sec;
> if (abstime.tv_nsec >= 1000000000)
> {
Ok.
> diff --git a/resolv/res_send.c b/resolv/res_send.c
> index ed27f3abf8..2b971cf5d2 100644
> --- a/resolv/res_send.c
> +++ b/resolv/res_send.c
> @@ -172,12 +172,7 @@ evCmpTime(struct timespec a, struct timespec b) {
>
> static void
> evNowTime(struct timespec *res) {
> - struct timeval now;
> -
> - if (gettimeofday(&now, NULL) < 0)
> - evConsTime(res, 0, 0);
> - else
> - TIMEVAL_TO_TIMESPEC (&now, res);
> + __clock_gettime(CLOCK_REALTIME, res);
> }
>
>
Ok.
> diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
> index 5b6f985bc2..9079b30397 100644
> --- a/sunrpc/auth_des.c
> +++ b/sunrpc/auth_des.c
> @@ -41,6 +41,7 @@
> #include <rpc/xdr.h>
> #include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
> #include <sys/socket.h>
> +#include <time.h>
> #include <shlib-compat.h>
>
> #define MILLION 1000000L
> @@ -246,15 +247,15 @@ authdes_marshal (AUTH *auth, XDR *xdrs)
> int status;
> int len;
> register int32_t *ixdr;
> - struct timeval tval;
> + struct timespec now;
>
> /*
> * Figure out the "time", accounting for any time difference
> * with the server if necessary.
> */
> - __gettimeofday (&tval, (struct timezone *) NULL);
> - ad->ad_timestamp.tv_sec = tval.tv_sec + ad->ad_timediff.tv_sec;
> - ad->ad_timestamp.tv_usec = tval.tv_usec + ad->ad_timediff.tv_usec;
> + __clock_gettime (CLOCK_REALTIME, &now);
> + ad->ad_timestamp.tv_sec = now.tv_sec + ad->ad_timediff.tv_sec;
> + ad->ad_timestamp.tv_usec = (now.tv_nsec / 1000) + ad->ad_timediff.tv_usec;
> if (ad->ad_timestamp.tv_usec >= MILLION)
> {
> ad->ad_timestamp.tv_usec -= MILLION;
Ok.
> @@ -445,21 +446,23 @@ authdes_destroy (AUTH *auth)
> static bool_t
> synchronize (struct sockaddr *syncaddr, struct rpc_timeval *timep)
> {
> - struct timeval mytime;
> + struct timespec mytime;
> struct rpc_timeval timeout;
> + long myusec;
s/long/long int/ due code convention.
>
> timeout.tv_sec = RTIME_TIMEOUT;
> timeout.tv_usec = 0;
> if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0)
> return FALSE;
>
> - __gettimeofday (&mytime, (struct timezone *) NULL);
> + __clock_gettime (CLOCK_REALTIME, &mytime);
> timep->tv_sec -= mytime.tv_sec;
> - if (mytime.tv_usec > timep->tv_usec)
> + myusec = mytime.tv_nsec / 1000;
> + if (myusec > timep->tv_usec)
> {
> timep->tv_sec -= 1;
> timep->tv_usec += MILLION;
> }
> - timep->tv_usec -= mytime.tv_usec;
> + timep->tv_usec -= myusec;
> return TRUE;
> }
Ok.
> diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
> index b035fdd870..ff0d2eb933 100644
> --- a/sunrpc/auth_unix.c
> +++ b/sunrpc/auth_unix.c
> @@ -43,6 +43,7 @@
> #include <stdio.h>
> #include <string.h>
> #include <unistd.h>
> +#include <time.h>
> #include <libintl.h>
> #include <sys/param.h>
> #include <wchar.h>
> @@ -96,7 +97,7 @@ authunix_create (char *machname, uid_t uid, gid_t gid, int len,
> {
> struct authunix_parms aup;
> char mymem[MAX_AUTH_BYTES];
> - struct timeval now;
> + struct timespec now;
> XDR xdrs;
> AUTH *auth;
> struct audata *au;
> @@ -122,7 +123,7 @@ no_memory:
> /*
> * fill in param struct from the given params
> */
> - (void) __gettimeofday (&now, (struct timezone *) 0);
> + __clock_gettime (CLOCK_REALTIME, &now);
> aup.aup_time = now.tv_sec;
> aup.aup_machname = machname;
> aup.aup_uid = uid;
Ok.
> @@ -276,7 +277,7 @@ authunix_refresh (AUTH *auth)
> {
> struct audata *au = AUTH_PRIVATE (auth);
> struct authunix_parms aup;
> - struct timeval now;
> + struct timespec now;
> XDR xdrs;
> int stat;
>
> @@ -297,7 +298,7 @@ authunix_refresh (AUTH *auth)
> goto done;
>
> /* update the time and serialize in place */
> - (void) __gettimeofday (&now, (struct timezone *) 0);
> + __clock_gettime (CLOCK_REALTIME, &now);
> aup.aup_time = now.tv_sec;
> xdrs.x_op = XDR_ENCODE;
> XDR_SETPOS (&xdrs, 0);
Ok.
> diff --git a/sunrpc/create_xid.c b/sunrpc/create_xid.c
> index a44187f07c..8d1e722dad 100644
> --- a/sunrpc/create_xid.c
> +++ b/sunrpc/create_xid.c
> @@ -39,10 +39,10 @@ _create_xid (void)
> pid_t pid = getpid ();
> if (is_initialized != pid)
> {
> - struct timeval now;
> + struct timespec now;
>
> - __gettimeofday (&now, (struct timezone *) 0);
> - __srand48_r (now.tv_sec ^ now.tv_usec ^ pid,
> + __clock_gettime (CLOCK_REALTIME, &now);
> + __srand48_r (now.tv_sec ^ now.tv_nsec ^ pid,
> &__rpc_lrand48_data);
> is_initialized = pid;
> }
Ok.
> diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
> index c5a512d6f8..7607abc818 100644
> --- a/sunrpc/svcauth_des.c
> +++ b/sunrpc/svcauth_des.c
> @@ -44,6 +44,7 @@
> #include <limits.h>
> #include <string.h>
> #include <stdint.h>
> +#include <time.h>
> #include <sys/param.h>
> #include <netinet/in.h>
> #include <rpc/rpc.h>
> @@ -295,7 +296,11 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
> debug ("timestamp before last seen");
> return AUTH_REJECTEDVERF; /* replay */
> }
> - __gettimeofday (¤t, (struct timezone *) NULL);
> + {
> + struct timespec now;
> + __clock_gettime (CLOCK_REALTIME, &now);
> + TIMESPEC_TO_TIMEVAL (¤t, &now);
> + }
> current.tv_sec -= window; /* allow for expiration */
> if (!BEFORE (¤t, ×tamp))
> {
Ok.
> diff --git a/support/support_test_main.c b/support/support_test_main.c
> index 7e7b9edbb0..d8397a840c 100644
> --- a/support/support_test_main.c
> +++ b/support/support_test_main.c
> @@ -88,16 +88,18 @@ static pid_t test_pid;
> static void (*cleanup_function) (void);
>
> static void
> -print_timestamp (const char *what, struct timeval tv)
> +print_timestamp (const char *what, struct timespec tv)
> {
> struct tm tm;
> + /* Casts of tv.tv_nsec below are necessary because the type of
> + tv_nsec is not literally long int on all supported platforms. */
> if (gmtime_r (&tv.tv_sec, &tm) == NULL)
> - printf ("%s: %lld.%06d\n",
> - what, (long long int) tv.tv_sec, (int) tv.tv_usec);
> + printf ("%s: %lld.%09ld\n",
> + what, (long long int) tv.tv_sec, (long int) tv.tv_nsec);
> else
> - printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
> + printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%09ld\n",
> what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
> - tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
> + tm.tm_hour, tm.tm_min, tm.tm_sec, (long int) tv.tv_nsec);
> }
>
> /* Timeout handler. We kill the child and exit with an error. */
Ok.
> @@ -110,8 +112,8 @@ signal_handler (int sig)
>
> /* Do this first to avoid further interference from the
> subprocess. */
> - struct timeval now;
> - bool now_available = gettimeofday (&now, NULL) == 0;
> + struct timespec now;
> + clock_gettime (CLOCK_REALTIME, &now);
> struct stat64 st;
> bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
>
> @@ -165,12 +167,9 @@ signal_handler (int sig)
> printf ("Timed out: killed the child process but it exited %d\n",
> WEXITSTATUS (status));
>
> - if (now_available)
> - print_timestamp ("Termination time", now);
> + print_timestamp ("Termination time", now);
> if (st_available)
> - print_timestamp ("Last write to standard output",
> - (struct timeval) { st.st_mtim.tv_sec,
> - st.st_mtim.tv_nsec / 1000 });
> + print_timestamp ("Last write to standard output", st.st_mtim);
>
> /* Exit with an error. */
> exit (1);
Ok.
> diff --git a/sysdeps/generic/memusage.h b/sysdeps/generic/memusage.h
> index 480bdf79ee..c29feb8edd 100644
> --- a/sysdeps/generic/memusage.h
> +++ b/sysdeps/generic/memusage.h
> @@ -26,14 +26,14 @@
> #endif
>
> #ifndef GETTIME
> -# define GETTIME(low,high) \
> - { \
> - struct timeval tval; \
> - uint64_t usecs; \
> - gettimeofday (&tval, NULL); \
> - usecs = (uint64_t) tval.tv_usec + (uint64_t) tval.tv_usec * 1000000; \
> - low = usecs & 0xffffffff; \
> - high = usecs >> 32; \
> +# define GETTIME(low,high) \
> + { \
> + struct timespec now; \
> + uint64_t usecs; \
> + __clock_gettime (CLOCK_REALTIME, &now); \
> + usecs = (uint64_t)now.tv_nsec / 1000 + (uint64_t)now.tv_sec * 1000000; \
> + low = usecs & 0xffffffff; \
> + high = usecs >> 32; \
> }
> #endif
>
Although not incorrect, I think we can just use clock_gettime here and avoid
libmemusage.so to use GLIBC_PRIVATE symbols.
> diff --git a/sysdeps/mach/hurd/getitimer.c b/sysdeps/mach/hurd/getitimer.c
> index 69a0751ead..5af723f62a 100644
> --- a/sysdeps/mach/hurd/getitimer.c
> +++ b/sysdeps/mach/hurd/getitimer.c
> @@ -19,8 +19,9 @@
> #include <errno.h>
> #include <sys/time.h>
> #include <hurd.h>
> +#include <mach.h>
>
> -/* XXX Temporary cheezoid implementation; see __setitmr.c. */
> +/* XXX Temporary cheezoid implementation; see setitimer.c. */
>
> /* These are defined in __setitmr.c. */
> extern spin_lock_t _hurd_itimer_lock;
> @@ -61,8 +62,7 @@ __getitimer (enum __itimer_which which, struct itimerval *value)
> }
>
> /* Get the time now. */
> - if (__gettimeofday (&elapsed, NULL) < 0)
> - return -1;
> + __host_get_time (__mach_host_self (), (time_value_t *) &elapsed);
>
> /* Extract the current timer setting; and the time it was set, so we can
> calculate the time elapsed so far. */
This is not strickly conformant (casting struct with different types). I would
recommend do do this instead:
{
time_value_t tv;
__host_get_time (__mach_host_self (), &tv);
elapsed.tv_sec = tv.seconds;
elapsed.tv_usec = tv.microseconds;
}
> diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
> index 61e37c5f5d..b82582a60f 100644
> --- a/sysdeps/mach/hurd/setitimer.c
> +++ b/sysdeps/mach/hurd/setitimer.c
> @@ -23,6 +23,7 @@
> #include <hurd/signal.h>
> #include <hurd/sigpreempt.h>
> #include <hurd/msg_request.h>
> +#include <mach.h>
> #include <mach/message.h>
>
> /* XXX Temporary cheezoid implementation of ITIMER_REAL/SIGALRM. */
> @@ -239,12 +240,7 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old,
> if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0 || old != NULL)
> {
> /* Calculate how much time is remaining for the pending alarm. */
> - if (__gettimeofday (&now, NULL) < 0)
> - {
> - __spin_unlock (&_hurd_itimer_lock);
> - _hurd_critical_section_unlock (crit);
> - return -1;
> - }
> + __host_get_time (__mach_host_self (), (time_value_t *) &now);
> elapsed = now;
> subtract_timeval (&elapsed, &_hurd_itimer_started);
> remaining = _hurd_itimerval.it_value;
Ditto.
> diff --git a/sysdeps/mach/hurd/times.c b/sysdeps/mach/hurd/times.c
> index 7758311d83..0f48c784a9 100644
> --- a/sysdeps/mach/hurd/times.c
> +++ b/sysdeps/mach/hurd/times.c
> @@ -42,7 +42,7 @@ __times (struct tms *tms)
> struct task_basic_info bi;
> struct task_thread_times_info tti;
> mach_msg_type_number_t count;
> - union { time_value_t tvt; struct timeval tv; } now;
> + time_value_t now;
> error_t err;
>
> count = TASK_BASIC_INFO_COUNT;
> @@ -65,10 +65,9 @@ __times (struct tms *tms)
> /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN) can be. */
> tms->tms_cutime = tms->tms_cstime = 0;
>
> - if (__gettimeofday (&now.tv, NULL) < 0)
> - return -1;
> + __host_get_time (__mach_host_self (), &now);
>
> - return (clock_from_time_value (&now.tvt)
> + return (clock_from_time_value (&now)
> - clock_from_time_value (&bi.creation_time));
> }
> weak_alias (__times, times)
Looks ok.
> diff --git a/sysdeps/mach/nanosleep.c b/sysdeps/mach/nanosleep.c
> index b4790aaf31..f9b821a6e2 100644
> --- a/sysdeps/mach/nanosleep.c
> +++ b/sysdeps/mach/nanosleep.c
> @@ -18,16 +18,26 @@
>
> #include <errno.h>
> #include <mach.h>
> -#include <sys/time.h>
> #include <time.h>
> #include <unistd.h>
>
> +# define timespec_sub(a, b, result) \
> + do { \
> + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
> + (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
> + if ((result)->tv_nsec < 0) { \
> + --(result)->tv_sec; \
> + (result)->tv_nsec += 1000000000; \
> + } \
> + } while (0)
> +
Not a fan to replicate a funcitonality that we already in libsupport,
but I think we might cleanup this up later.
> int
> __libc_nanosleep (const struct timespec *requested_time,
> - struct timespec *remaining)
> + struct timespec *remaining)
> {
> mach_port_t recv;
> - struct timeval before, after;
> + struct timespec before;
> + error_t err;
>
> if (requested_time->tv_sec < 0
> || requested_time->tv_nsec < 0
> @@ -43,20 +53,20 @@ __libc_nanosleep (const struct timespec *requested_time,
>
> recv = __mach_reply_port ();
>
> - if (remaining && __gettimeofday (&before, NULL) < 0)
> - return -1;
> - error_t err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
> - 0, 0, recv, ms, MACH_PORT_NULL);
> + if (remaining != 0)
> + __clock_gettime (CLOCK_REALTIME, &before);
> +
> + err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
> + 0, 0, recv, ms, MACH_PORT_NULL);
> __mach_port_destroy (mach_task_self (), recv);
> if (err == EMACH_RCV_INTERRUPTED)
> {
> - if (remaining && __gettimeofday (&after, NULL) >= 0)
> + if (remaining != 0)
> {
> - struct timeval req_time, elapsed, rem;
> - TIMESPEC_TO_TIMEVAL (&req_time, requested_time);
> - timersub (&after, &before, &elapsed);
> - timersub (&req_time, &elapsed, &rem);
> - TIMEVAL_TO_TIMESPEC (&rem, remaining);
> + struct timespec after, elapsed;
> + __clock_gettime (CLOCK_REALTIME, &after);
Indentation seems off here.
> + timespec_sub (&after, &before, &elapsed);
> + timespec_sub (requested_time, &elapsed, remaining);
> }
>
> errno = EINTR;
> diff --git a/sysdeps/mach/usleep.c b/sysdeps/mach/usleep.c
> index 5d4bd205e1..8428ace6ef 100644
> --- a/sysdeps/mach/usleep.c
> +++ b/sysdeps/mach/usleep.c
> @@ -25,17 +25,12 @@ int
> usleep (useconds_t useconds)
> {
> mach_port_t recv;
> - struct timeval before, after;
>
> recv = __mach_reply_port ();
>
> - if (__gettimeofday (&before, NULL) < 0)
> - return -1;
> (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
> 0, 0, recv, (useconds + 999) / 1000, MACH_PORT_NULL);
> __mach_port_destroy (mach_task_self (), recv);
> - if (__gettimeofday (&after, NULL) < 0)
> - return -1;
>
> return 0;
> }
Not sure why hurd is calling get __gettimeofday here...
> diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
> index 310df3c4ca..c3956498ce 100644
> --- a/sysdeps/posix/tempname.c
> +++ b/sysdeps/posix/tempname.c
> @@ -50,7 +50,7 @@
> #include <string.h>
>
> #include <fcntl.h>
> -#include <sys/time.h>
> +#include <time.h>
> #include <stdint.h>
> #include <unistd.h>
>
> @@ -63,7 +63,6 @@
> # define struct_stat64 struct stat
> # define __gen_tempname gen_tempname
> # define __getpid getpid
> -# define __gettimeofday gettimeofday
> # define __mkdir mkdir
> # define __open open
> # define __lxstat64(version, file, buf) lstat (file, buf)
> @@ -76,9 +75,9 @@
> # else
> # define RANDOM_BITS(Var) \
> { \
> - struct timeval tv; \
> - __gettimeofday (&tv, NULL); \
> - (Var) = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
> + struct timespec ts; \
> + clock_gettime (CLOCK_REALTIME, &ts); \
> + (Var) = ((uint64_t) tv.tv_nsec << 16) ^ tv.tv_sec; \
> }
> #endif
>
Ok.
> diff --git a/sysdeps/posix/timespec_get.c b/sysdeps/posix/timespec_get.c
> index 98d3136287..781a624c7d 100644
> --- a/sysdeps/posix/timespec_get.c
> +++ b/sysdeps/posix/timespec_get.c
> @@ -23,16 +23,10 @@
> int
> timespec_get (struct timespec *ts, int base)
> {
> - switch (base)
> + if (base == TIME_UTC)
> {
> - case TIME_UTC:
> - if (__clock_gettime (CLOCK_REALTIME, ts) < 0)
> - return 0;
> - break;
> -
> - default:
> - return 0;
> + __clock_gettime (CLOCK_REALTIME, ts);
> + return base;
> }
> -
> - return base;
> + return 0;
> }
Ok.
> diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c
> index 0180ddb3c3..49ab08de3a 100644
> --- a/sysdeps/pthread/aio_misc.c
> +++ b/sysdeps/pthread/aio_misc.c
> @@ -614,13 +614,13 @@ handle_fildes_io (void *arg)
> something to arrive in it. */
> if (runp == NULL && optim.aio_idle_time >= 0)
> {
> - struct timeval now;
> + struct timespec now;
> struct timespec wakeup_time;
>
> ++idle_thread_count;
> - __gettimeofday (&now, NULL);
> + __clock_gettime (CLOCK_REALTIME, &now);
Indentation seems off here.
> wakeup_time.tv_sec = now.tv_sec + optim.aio_idle_time;
> - wakeup_time.tv_nsec = now.tv_usec * 1000;
> + wakeup_time.tv_nsec = now.tv_nsec;
> if (wakeup_time.tv_nsec >= 1000000000)
> {
> wakeup_time.tv_nsec -= 1000000000;
Ok.
> diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c
> index 06bd914672..fdd4087abb 100644
> --- a/sysdeps/pthread/aio_suspend.c
> +++ b/sysdeps/pthread/aio_suspend.c
> @@ -183,11 +183,11 @@ aio_suspend (const struct aiocb *const list[], int nent,
> {
> /* We have to convert the relative timeout value into an
> absolute time value with pthread_cond_timedwait expects. */
> - struct timeval now;
> + struct timespec now;
> struct timespec abstime;
>
> - __gettimeofday (&now, NULL);
> - abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
> + __clock_gettime (CLOCK_REALTIME, &now);
> + abstime.tv_nsec = timeout->tv_nsec + now.tv_nsec;
> abstime.tv_sec = timeout->tv_sec + now.tv_sec;
> if (abstime.tv_nsec >= 1000000000)
> {
Ok.
> diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
> index 6a5c10d54e..2b8c9ea49c 100644
> --- a/sysdeps/unix/make-syscalls.sh
> +++ b/sysdeps/unix/make-syscalls.sh
> @@ -27,7 +27,7 @@
> # n: scalar buffer length (e.g., 3rd arg to read)
> # N: pointer to value/return scalar buffer length (e.g., 6th arg to recvfrom)
> # p: non-NULL pointer to typed object (e.g., any non-void* arg)
> -# P: optionally-NULL pointer to typed object (e.g., 2nd argument to gettimeofday)
> +# P: optionally-NULL pointer to typed object (e.g., 3rd argument to sigaction)
> # s: non-NULL string (e.g., 1st arg to open)
> # S: optionally-NULL string (e.g., 1st arg to acct)
> # v: vararg scalar (e.g., optional 3rd arg to open)
>
Not sure if this is really required, afaik gettimeofday won't be deprecated anytime
soon.
More information about the Libc-alpha
mailing list