summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2016-09-07 01:03:12 +0000
committerPatrick Mooney <pmooney@oxide.computer>2020-09-04 20:37:06 +0000
commit88b8d9620aed414dab5fb34108dee58556f060f0 (patch)
tree0de29614f985c711529e1b9f071b26d8c7f674ba
parent5365b8a5984eca60a3cedc7f9f738e51fb056bec (diff)
downloadillumos-joyent-88b8d9620aed414dab5fb34108dee58556f060f0.tar.gz
7709 hrt2ts and friends are too clever for their own good
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Jason King <jason.king@joyent.com> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r--usr/src/lib/libc/port/sys/time_util.c12
-rw-r--r--usr/src/uts/common/os/timers.c49
2 files changed, 45 insertions, 16 deletions
diff --git a/usr/src/lib/libc/port/sys/time_util.c b/usr/src/lib/libc/port/sys/time_util.c
index 93a07aaee0..b6ea0291e2 100644
--- a/usr/src/lib/libc/port/sys/time_util.c
+++ b/usr/src/lib/libc/port/sys/time_util.c
@@ -22,10 +22,9 @@
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Joyent, Inc.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <time.h>
#include <errno.h>
@@ -39,6 +38,10 @@
void
hrt2ts(hrtime_t hrt, timespec_t *tsp)
{
+#if defined(__amd64)
+ tsp->tv_sec = hrt / NANOSEC;
+ tsp->tv_nsec = hrt % NANOSEC;
+#else
uint32_t sec, nsec, tmp;
tmp = (uint32_t)(hrt >> 30);
@@ -60,6 +63,7 @@ hrt2ts(hrtime_t hrt, timespec_t *tsp)
}
tsp->tv_sec = (time_t)sec;
tsp->tv_nsec = nsec;
+#endif /* defined(__amd64) */
}
/*
@@ -67,8 +71,8 @@ hrt2ts(hrtime_t hrt, timespec_t *tsp)
* All *timedwait() system call traps expect relative time.
*/
void
-abstime_to_reltime(clockid_t clock_id,
- const timespec_t *abstime, timespec_t *reltime)
+abstime_to_reltime(clockid_t clock_id, const timespec_t *abstime,
+ timespec_t *reltime)
{
extern int __clock_gettime(clockid_t, timespec_t *);
timespec_t now;
diff --git a/usr/src/uts/common/os/timers.c b/usr/src/uts/common/os/timers.c
index 61acc6cf97..53be806026 100644
--- a/usr/src/uts/common/os/timers.c
+++ b/usr/src/uts/common/os/timers.c
@@ -22,6 +22,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Joyent, Inc.
*/
/*
@@ -1172,6 +1173,14 @@ timespectohz64(timespec_t *tv)
void
hrt2ts(hrtime_t hrt, timestruc_t *tsp)
{
+#if defined(__amd64)
+ /*
+ * The cleverness explained above is unecessary on x86_64 CPUs where
+ * modern compilers are able to optimize down to faster operations.
+ */
+ tsp->tv_sec = hrt / NANOSEC;
+ tsp->tv_nsec = hrt % NANOSEC;
+#else
uint32_t sec, nsec, tmp;
tmp = (uint32_t)(hrt >> 30);
@@ -1193,20 +1202,28 @@ hrt2ts(hrtime_t hrt, timestruc_t *tsp)
}
tsp->tv_sec = (time_t)sec;
tsp->tv_nsec = nsec;
+#endif /* defined(__amd64) */
}
/*
* Convert from timestruc_t to hrtime_t.
- *
- * The code below is equivalent to:
- *
- * hrt = tsp->tv_sec * NANOSEC + tsp->tv_nsec;
- *
- * but requires no integer multiply.
*/
hrtime_t
ts2hrt(const timestruc_t *tsp)
{
+#if defined(__amd64) || defined(__i386)
+ /*
+ * On modern x86 CPUs, the simple version is faster.
+ */
+ return ((tsp->tv_sec * NANOSEC) + tsp->tv_nsec);
+#else
+ /*
+ * The code below is equivalent to:
+ *
+ * hrt = tsp->tv_sec * NANOSEC + tsp->tv_nsec;
+ *
+ * but requires no integer multiply.
+ */
hrtime_t hrt;
hrt = tsp->tv_sec;
@@ -1215,6 +1232,7 @@ ts2hrt(const timestruc_t *tsp)
hrt = (hrt << 7) - hrt - hrt - hrt;
hrt = (hrt << 9) + tsp->tv_nsec;
return (hrt);
+#endif /* defined(__amd64) || defined(__i386) */
}
/*
@@ -1246,6 +1264,13 @@ tv2hrt(struct timeval *tvp)
void
hrt2tv(hrtime_t hrt, struct timeval *tvp)
{
+#if defined(__amd64)
+ /*
+ * Like hrt2ts, the simple version is faster on x86_64.
+ */
+ tvp->tv_sec = hrt / NANOSEC;
+ tvp->tv_usec = (hrt % NANOSEC) / (NANOSEC / MICROSEC);
+#else
uint32_t sec, nsec, tmp;
uint32_t q, r, t;
@@ -1267,17 +1292,17 @@ hrt2tv(hrtime_t hrt, struct timeval *tvp)
sec++;
}
tvp->tv_sec = (time_t)sec;
-/*
- * this routine is very similar to hr2ts, but requires microseconds
- * instead of nanoseconds, so an interger divide by 1000 routine
- * completes the conversion
- */
+ /*
+ * this routine is very similar to hr2ts, but requires microseconds
+ * instead of nanoseconds, so an interger divide by 1000 routine
+ * completes the conversion
+ */
t = (nsec >> 7) + (nsec >> 8) + (nsec >> 12);
q = (nsec >> 1) + t + (nsec >> 15) + (t >> 11) + (t >> 14);
q = q >> 9;
r = nsec - q*1000;
tvp->tv_usec = q + ((r + 24) >> 10);
-
+#endif /* defined(__amd64) */
}
int