about summary refs log tree commit diff
path: root/src/time
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-07-23 23:45:33 -0400
committerRich Felker <dalias@aerifal.cx>2011-07-23 23:45:33 -0400
commite3eb49321c85e43fcc6842f3f57ee097b32555e4 (patch)
tree126e8f35f23c92fdb7ff8f805c7d59b662c8b7ae /src/time
parentc0fe5b9da9f98b83262717c0090817f1fbb3d8a0 (diff)
downloadmusl-e3eb49321c85e43fcc6842f3f57ee097b32555e4.tar.gz
musl-e3eb49321c85e43fcc6842f3f57ee097b32555e4.tar.xz
musl-e3eb49321c85e43fcc6842f3f57ee097b32555e4.zip
some preliminaries for vdso clock support
these changes also make it so clock_gettime(CLOCK_REALTIME, &ts) works
even on pre-2.6 kernels, emulated via the gettimeofday syscall. there
is no cost for the fallback check, as it falls under the error case
that already must be checked for storing the error code in errno, but
which would normally be hidden inside __syscall_ret.
Diffstat (limited to 'src/time')
-rw-r--r--src/time/clock_gettime.c25
-rw-r--r--src/time/gettimeofday.c7
-rw-r--r--src/time/time.c10
3 files changed, 35 insertions, 7 deletions
diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c
index c345c46e..c27c9e9e 100644
--- a/src/time/clock_gettime.c
+++ b/src/time/clock_gettime.c
@@ -1,7 +1,28 @@
 #include <time.h>
+#include <errno.h>
+#include <stdint.h>
 #include "syscall.h"
+#include "libc.h"
 
-int clock_gettime(clockid_t clk, struct timespec *ts)
+int __vdso_clock_gettime(clockid_t, struct timespec *) __attribute__((weak));
+static int (*cgt)(clockid_t, struct timespec *) = __vdso_clock_gettime;
+
+int __clock_gettime(clockid_t clk, struct timespec *ts)
 {
-	return syscall(SYS_clock_gettime, clk, ts);
+	int r;
+	if (cgt) return cgt(clk, ts);
+	r = __syscall(SYS_clock_gettime, clk, ts);
+	if (!r) return r;
+	if (r == -ENOSYS) {
+		if (clk == CLOCK_REALTIME) {
+			__syscall(SYS_gettimeofday, clk, ts, 0);
+			ts->tv_nsec = (int)ts->tv_nsec * 1000;
+			return 0;
+		}
+		r = -EINVAL;
+	}
+	errno = -r;
+	return -1;
 }
+
+weak_alias(__clock_gettime, clock_gettime);
diff --git a/src/time/gettimeofday.c b/src/time/gettimeofday.c
index 2436e490..09afb70b 100644
--- a/src/time/gettimeofday.c
+++ b/src/time/gettimeofday.c
@@ -1,8 +1,13 @@
+#include <time.h>
 #include <sys/time.h>
 #include "syscall.h"
 
 int gettimeofday(struct timeval *tv, void *tz)
 {
-	__syscall(SYS_gettimeofday, tv, 0);
+	struct timespec ts;
+	if (!tv) return 0;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	tv->tv_sec = ts.tv_sec;
+	tv->tv_usec = (int)ts.tv_nsec / 1000;
 	return 0;
 }
diff --git a/src/time/time.c b/src/time/time.c
index 05e075b9..22754850 100644
--- a/src/time/time.c
+++ b/src/time/time.c
@@ -2,10 +2,12 @@
 #include <sys/time.h>
 #include "syscall.h"
 
+int __clock_gettime(clockid_t, struct timespec *);
+
 time_t time(time_t *t)
 {
-	struct timeval tv;
-	__syscall(SYS_gettimeofday, &tv, 0);
-	if (t) *t = tv.tv_sec;
-	return tv.tv_sec;
+	struct timespec ts;
+	__clock_gettime(CLOCK_REALTIME, &ts);
+	if (t) *t = ts.tv_sec;
+	return ts.tv_sec;
 }