summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2015-03-01 23:57:01 -0500
committerEric S. Raymond <esr@thyrsus.com>2015-03-01 23:57:01 -0500
commit44b3532e07d2e3790a75ccd5a75f19deefa71e82 (patch)
tree3d1bd2eaf9a5134dbcee9247e5f31343c7e96fde
parent4964c68cf4ebca29d745ba02c4ba3da4a68e9abd (diff)
downloadgpsd-44b3532e07d2e3790a75ccd5a75f19deefa71e82.tar.gz
Implement POSIX clock_gettime(3) for systems that lack it (like Mac OS X).
On Mac OS X it will get proper nanosecond precision; elsewhere, only microseconds. Hides the conformance failure from the rest of the code. All regression tests pass.
-rw-r--r--SConstruct9
-rw-r--r--clock_gettime.c47
-rw-r--r--gpsutils.c6
-rw-r--r--libgps.h2
-rw-r--r--libgps_dbus.c1
-rw-r--r--libgpsd_core.c6
-rw-r--r--ntpshmread.c9
-rw-r--r--ppsthread.c15
8 files changed, 58 insertions, 37 deletions
diff --git a/SConstruct b/SConstruct
index 7b2f6cf7..e82857d5 100644
--- a/SConstruct
+++ b/SConstruct
@@ -751,6 +751,14 @@ pid_t getsid(pid_t pid);
}
# endif
#endif
+#ifndef HAVE_CLOCK_GETTIME
+# ifdef __cplusplus
+extern "C" {
+typedef int clockid_t;
+#define CLOCK_REALTIME 0
+int clock_gettime(clockid_t, struct timespec *);
+# endif
+#endif
#define GPSD_CONFIG_H
@@ -823,6 +831,7 @@ libgpsd_version = "%d.%d.%d" %(libgpsd_version_soname, libgpsd_version_age, libg
libgps_sources = [
"ais_json.c",
"bits.c",
+ "clock_gettime.c",
"daemon.c",
"gpsutils.c",
"gpsdclient.c",
diff --git a/clock_gettime.c b/clock_gettime.c
new file mode 100644
index 00000000..b6b7dff1
--- /dev/null
+++ b/clock_gettime.c
@@ -0,0 +1,47 @@
+/*
+ * Simulate ANSI/POSIX conformance on platforms that don't have it
+ *
+ * This file is Copyright (c) 2010 by the GPSD project
+ * BSD terms apply: see the file COPYING in the distribution root for details.
+ */
+#include <time.h>
+#include <sys/time.h>
+
+#include "compiler.h"
+
+#ifdef __MACH__
+#include <mach/clock.h>
+#include <mach/mach.h>
+#endif
+
+#ifndef HAVE_CLOCK_GETTIME
+int clock_gettime(clockid_t clk_id UNUSED, struct timespec *tp)
+{
+#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
+ clock_serv_t cclock;
+ mach_timespec_t mts;
+ host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
+ clock_get_time(cclock, &mts);
+ mach_port_deallocate(mach_task_self(), cclock);
+ ts.tv_sec = mts.tv_sec;
+ ts.tv_nsec = mts.tv_nsec;
+#else
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL) < 0)
+ return -1;
+ tp->ts_sec = tv.tv_sec;
+ tp->ts_nsec = tv.tv_usec * 1000;
+ /* paranoid programming */
+ if (1000000 <= (tv)->tv_usec) {
+ (tv)->tv_usec -= 1000000;
+ (tv)->tv_sec++;
+ } else if (0 > (tv)->tv_usec) {
+ (tv)->tv_usec += 1000000;
+ (tv)->tv_sec--;
+ }
+ return 0;
+#endif /* __MACH__ */
+}
+#endif /* HAVE_CLOCK_GETTIME */
+
+/* end */
diff --git a/gpsutils.c b/gpsutils.c
index fa15bc49..e7000f70 100644
--- a/gpsutils.c
+++ b/gpsutils.c
@@ -299,15 +299,9 @@ void gps_merge_fix( /*@ out @*/ struct gps_fix_t *to,
* near microSec. Do not use near PPS which is nanoSec precise */
timestamp_t timestamp(void)
{
-#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
/*@i2@*/(void)clock_gettime(CLOCK_REALTIME, &ts);
/*@i3@*/return (timestamp_t)(ts.tv_sec + ts.tv_nsec * 1e-9);
-#else
- struct timeval tv;
- (void)gettimeofday(&tv, NULL);
- return (timestamp_t)(tv.tv_sec + tv.tv_usec * 1e-6);
-#endif
}
time_t mkgmtime(register struct tm * t)
diff --git a/libgps.h b/libgps.h
index 914c4df2..9ef0ae37 100644
--- a/libgps.h
+++ b/libgps.h
@@ -10,6 +10,8 @@
#define SHM_PSEUDO_FD -1
#define DBUS_PSEUDO_FD -2
+#include "compiler.h"
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/libgps_dbus.c b/libgps_dbus.c
index 092e0bdf..826f12d4 100644
--- a/libgps_dbus.c
+++ b/libgps_dbus.c
@@ -14,7 +14,6 @@
#include "gps.h"
#include "gpsd_config.h"
-#include "compiler.h"
#include "libgps.h"
#if defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S)
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 210aa596..a1a1a44e 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -1658,13 +1658,7 @@ void ntp_latch(struct gps_device_t *device, struct timedelta_t /*@out@*/*td)
/* this should be an invariant of the way this function is called */
assert(isnan(device->newdata.time)==0);
-#ifdef HAVE_CLOCK_GETTIME
/*@i2@*/(void)clock_gettime(CLOCK_REALTIME, &td->clock);
-#else
- struct timeval clock_tv;
- (void)gettimeofday(&clock_tv, NULL);
- TVTOTS(&td->clock, &clock_tv);
-#endif /* HAVE_CLOCK_GETTIME */
fix_time = device->newdata.time;
#ifdef TIMEHINT_ENABLE
diff --git a/ntpshmread.c b/ntpshmread.c
index 092e6e95..7a9206e3 100644
--- a/ntpshmread.c
+++ b/ntpshmread.c
@@ -74,16 +74,7 @@ enum segstat_t shm_query(/*@null@*/struct shmTime *shm_in, /*@out@*/struct shm_s
/*@-type@*//* splint is confused about struct timespec */
shm_stat->tvc.tv_sec = shm_stat->tvc.tv_nsec = 0;
-#ifdef HAVE_CLOCK_GETTIME
clock_gettime(CLOCK_REALTIME, &shm_stat->tvc);
-#else
- {
- struct timeval tv;
- (void)gettimeofday(&tv, NULL);
- shm_stat->tvc.tv_sec = tv.tv_sec;
- shm_stat->tvc.tv_nsec = tv.tv_usec * 1000;
- }
-#endif
/* relying on word access to be atomic here */
if (shm->valid == 0) {
diff --git a/ppsthread.c b/ppsthread.c
index ad8750a4..b8a716c7 100644
--- a/ppsthread.c
+++ b/ppsthread.c
@@ -269,9 +269,6 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
/* the system clock ime, to the nSec, when the last fix received */
/* using a double would cause loss of precision */
struct timespec last_fixtime_clock = {0, 0};
-#ifndef HAVE_CLOCK_GETTIME
- struct timeval clock_tv = {0, 0};
-#endif /* HAVE_CLOCK_GETTIME */
struct timespec clock_ts = {0, 0};
time_t last_second_used = 0;
#if defined(TIOCMIWAIT)
@@ -359,24 +356,12 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
/*@-noeffect@*/
/* get the time after we just woke up */
-#ifdef HAVE_CLOCK_GETTIME
- /* using clock_gettime() here, that is nSec,
- * not uSec like gettimeofday */
if ( 0 > clock_gettime(CLOCK_REALTIME, &clock_ts) ) {
/* uh, oh, can not get time! */
gpsd_report(&session->context->errout, LOG_ERROR,
"PPS clock_gettime() failed\n");
break;
}
-#else
- if ( 0 > gettimeofday(&clock_tv, NULL) ) {
- /* uh, oh, can not get time! */
- gpsd_report(&session->context->errout, LOG_ERROR,
- "PPS gettimeofday() failed\n");
- break;
- }
- TVTOTS( &clock_ts, &clock_tv);
-#endif /* HAVE_CLOCK_GETTIME */
/*@+noeffect@*/
/* got the edge, got the time just after the edge, now quickly