summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2015-03-08 12:38:06 -0400
committerEric S. Raymond <esr@thyrsus.com>2015-03-08 12:38:06 -0400
commitfc0e032da5ca1c4b1e04a146220909eddebb6b86 (patch)
tree0d13d63aebe1159ca20a41847a6ebe371d7e9c75
parent0deeeb2b1fb55d78c4abedbf88c8f46d9b300ed6 (diff)
downloadgpsd-fc0e032da5ca1c4b1e04a146220909eddebb6b86.tar.gz
ppsthread.c is now fully decoupled from the libgpsd_core.c structures.
The files ntpshm.h ntpshmread.c ntpshmwrite.c ppsthread.[ch] timespec_str.[ch] now form a standalone group which can be used for NTP communication and PPS thread monitoring. Separation is not yet perfect, as ppsthread.c requires gpsd_config.h for HAVE_SYS_TIMEPPS_H and npshmread.c/ntpshmwrite.c both require compiler.h. All regression tests pass. PPS is live on a GR-601W.
-rw-r--r--gpsmon.c1
-rw-r--r--ntpshmread.c1
-rw-r--r--ppsthread.c52
3 files changed, 52 insertions, 2 deletions
diff --git a/gpsmon.c b/gpsmon.c
index b39eee94..0e0b428c 100644
--- a/gpsmon.c
+++ b/gpsmon.c
@@ -31,6 +31,7 @@
#include "gpsdclient.h"
#include "revision.h"
#include "strfuncs.h"
+#include "timespec_str.h"
#define BUFLEN 2048
diff --git a/ntpshmread.c b/ntpshmread.c
index 1282f779..11532e1a 100644
--- a/ntpshmread.c
+++ b/ntpshmread.c
@@ -20,7 +20,6 @@
#endif /* S_SPLINT_S*/
#include "ntpshm.h"
-#include "compiler.h"
struct shmTime /*@null@*/ *shm_get(const int unit, const bool create, const bool forall)
/* initialize a SHM segment */
diff --git a/ppsthread.c b/ppsthread.c
index 0edf9ecb..68b07070 100644
--- a/ppsthread.c
+++ b/ppsthread.c
@@ -47,6 +47,7 @@
#include <string.h>
#include <stdio.h>
+#include <stdbool.h>
#include <limits.h>
#include <errno.h>
#include <pthread.h>
@@ -56,8 +57,9 @@
#include <unistd.h>
#endif /* S_SPLINT_S */
+#include "gpsd_config.h"
#include "timespec_str.h"
-#include "gpsd.h"
+#include "ppsthread.h"
#ifdef PPS_ENABLE
#if defined(HAVE_SYS_TIMEPPS_H)
@@ -81,6 +83,54 @@
#include <glob.h>
#endif
+/* normalize a timespec
+ *
+ * three cases to note
+ * if tv_sec is positve, then tv_nsec must be positive
+ * if tv_sec is negative, then tv_nsec must be negative
+ * if tv_sec is zero, then tv_nsec may be positive or negative.
+ *
+ * this only handles the case where two normalized timespecs
+ * are added or subracted. (e.g. only a one needs to be borrowed/carried
+ */
+/*@-type -noeffect@*/ /* splint is confused about struct timespec */
+/*@unused@*/static inline void TS_NORM( struct timespec *ts)
+{
+ if ( ( 1 <= ts->tv_sec ) ||
+ ( (0 == ts->tv_sec ) && (0 <= ts->tv_nsec ) ) ) {
+ /* result is positive */
+ if ( 1000000000 <= ts->tv_nsec ) {
+ /* borrow from tv_sec */
+ ts->tv_nsec -= 1000000000;
+ ts->tv_sec++;
+ } else if ( 0 > (ts)->tv_nsec ) {
+ /* carry to tv_sec */
+ ts->tv_nsec += 1000000000;
+ ts->tv_sec--;
+ }
+ } else {
+ /* result is negative */
+ if ( -1000000000 >= ts->tv_nsec ) {
+ /* carry to tv_sec */
+ ts->tv_nsec += 1000000000;
+ ts->tv_sec--;
+ } else if ( 0 < ts->tv_nsec ) {
+ /* borrow from tv_sec */
+ ts->tv_nsec -= 1000000000;
+ ts->tv_sec++;
+ }
+ }
+}
+/*@+type +noeffect@*/
+
+/* subtract two timespec */
+#define TS_SUB(r, ts1, ts2) \
+ do { \
+ (r)->tv_sec = (ts1)->tv_sec - (ts2)->tv_sec; \
+ (r)->tv_nsec = (ts1)->tv_nsec - (ts2)->tv_nsec; \
+ TS_NORM( r ); \
+ } while (0)
+
static pthread_mutex_t ppslast_mutex = PTHREAD_MUTEX_INITIALIZER;
#if defined(HAVE_SYS_TIMEPPS_H)