summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2015-03-07 01:57:32 -0500
committerEric S. Raymond <esr@thyrsus.com>2015-03-07 01:57:32 -0500
commite92b21041e00778c72362620ad9d62ffa94613db (patch)
tree2871a2dda9955daabb8efab913cd3b13684cb8f8
parent02c9c43a3aaaf73f84fdf9fbc96e9a32e546d273 (diff)
downloadgpsd-e92b21041e00778c72362620ad9d62ffa94613db.tar.gz
Another step in prying ntplib loose. Partly decouple ppsthread.c fom sessions.
All regression tests pass.
-rw-r--r--gpsd.h-tail16
-rw-r--r--gpsmon.c18
-rw-r--r--libgpsd_core.c21
-rw-r--r--ppsthread.c53
-rw-r--r--ppsthread.h47
5 files changed, 104 insertions, 51 deletions
diff --git a/gpsd.h-tail b/gpsd.h-tail
index 0be3877b..318ebf37 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <stdarg.h>
#include "gps.h"
+#include "ppsthread.h"
#include "compiler.h"
/*
@@ -499,12 +500,7 @@ struct gps_device_t {
volatile /*@null@*/ struct shmTime *shm_pps;
# endif /* PPS_ENABLE */
#endif /* NTP_ENABLE */
- volatile struct {
- timestamp_t real;
- /* clock must be a timespec as it is in nSec and
- * a timestamp_t will lose precision */
- struct timespec clock; /* system clock time when last fix received */
- } last_fixtime; /* so updates happen once */
+ volatile struct pps_fixtime_t last_fixtime; /* so updates happen once */
#ifdef PPS_ENABLE
#if defined(HAVE_SYS_TIMEPPS_H)
pps_handle_t kernelpps_handle;
@@ -513,8 +509,7 @@ struct gps_device_t {
/*@null@*/ char *(*thread_report_hook)(struct gps_device_t *,
struct timedelta_t *);
/*@null@*/ void (*thread_wrap_hook)(struct gps_device_t *);
- volatile struct timedelta_t ppslast;
- volatile int ppscount;
+ struct pps_state_t pps_state;
#endif /* PPS_ENABLE */
double mag_var; /* magnetic variation in degrees */
bool back_to_nmea; /* back to NMEA on revert? */
@@ -971,13 +966,8 @@ extern void pps_early_init(struct gps_context_t *);
extern void timespec_str(const struct timespec *, /*@out@*/char *, int);
#define TIMESPEC_LEN 22 /* required length of a timespec buffer */
-#ifdef PPS_ENABLE
-extern void pps_thread_stash_fixtime(struct gps_device_t *,
- timestamp_t, struct timespec);
-#endif /* PPS_ENABLE */
extern void pps_thread_activate(struct gps_device_t *);
extern void pps_thread_deactivate(struct gps_device_t *);
-extern int pps_thread_lastpps(struct gps_device_t *, struct timedelta_t *);
extern void errout_reset(struct gpsd_errout_t *errout);
diff --git a/gpsmon.c b/gpsmon.c
index 04739324..e951b6b4 100644
--- a/gpsmon.c
+++ b/gpsmon.c
@@ -249,7 +249,19 @@ void pps_update(WINDOW *win, int y, int x)
/*@-type -noeffect@*/ /* splint is confused about struct timespec */
struct timedelta_t ppstimes;
- if (pps_thread_lastpps(&session, &ppstimes) > 0) {
+ int status = pps_thread_lastpps(&session.pps_state, &ppstimes);
+
+ if (status == PPS_LOCK_ERR) {
+ char errbuf[BUFSIZ] = "unknown error";
+ (void)strerror_r(errno, errbuf,(int) sizeof(errbuf));
+ gpsd_report(&session.context->errout, LOG_ERROR,
+ "PPS: pthread_mutex_unlock() : %s\n", errbuf);
+ } else if (status == PPS_LOCK_ERR) {
+ char errbuf[BUFSIZ] = "unknown error";
+ (void)strerror_r(errno, errbuf,(int) sizeof(errbuf));
+ gpsd_report(&session.context->errout, LOG_ERROR,
+ "PPS: pthread_mutex_lock() : %s\n", errbuf);
+ } else {
/* NOTE: can not use double here due to precision requirements */
struct timespec timedelta;
(void)wmove(win, y, x);
@@ -790,9 +802,9 @@ static void gpsmon_hook(struct gps_device_t *device, gps_mask_t changed UNUSED)
"------------------- PPS offset: %.20s ------\n ",
timedelta_str);
/* coverity[missing_lock] */
- session.ppslast = noclobber.pps;
+ session.pps_state.ppslast = noclobber.pps;
/* coverity[missing_lock] */
- session.ppscount++;
+ session.pps_state.ppscount++;
}
}
else
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 7fae7006..d9db154a 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -307,8 +307,7 @@ void gpsd_init(struct gps_device_t *session, struct gps_context_t *context,
/*@i2@*/session->last_fixtime.clock.tv_sec = 0;
/*@i2@*/session->last_fixtime.clock.tv_nsec = 0;
#ifdef PPS_ENABLE
- memset( (void *)&session->ppslast, 0, sizeof(session->ppslast));
- session->ppscount = 0;
+ memset((void *)&session->pps_state, 0, sizeof(session->pps_state));
#endif /* PPS_ENABLE */
/*@ -mayaliasunique @*/
@@ -406,8 +405,7 @@ void gpsd_clear(struct gps_device_t *session)
/*@i2@*/session->last_fixtime.clock.tv_sec = 0;
/*@i2@*/session->last_fixtime.clock.tv_nsec = 0;
#ifdef PPS_ENABLE
- memset( (void *)&session->ppslast, 0, sizeof(session->ppslast));
- session->ppscount = 0;
+ memset((void *)&session->pps_state, 0, sizeof(session->pps_state));
#endif /* PPS_ENABLE */
session->opentime = timestamp();
@@ -1619,6 +1617,7 @@ void ntp_latch(struct gps_device_t *device, struct timedelta_t /*@out@*/*td)
/* latch the fact that we've saved a fix */
{
double fix_time, integral, fractional;
+ int status;
/* this should be an invariant of the way this function is called */
assert(isnan(device->newdata.time)==0);
@@ -1648,8 +1647,20 @@ void ntp_latch(struct gps_device_t *device, struct timedelta_t /*@out@*/*td)
#ifdef PPS_ENABLE
/* thread-safe update */
/*@-compdef@*/
- pps_thread_stash_fixtime(device, device->newdata.time, td->clock);
+ status = pps_thread_stash_fixtime(&device->last_fixtime,
+ device->newdata.time, td->clock);
/*@+compdef@*/
+ if (status == PPS_LOCK_ERR) {
+ char errbuf[BUFSIZ] = "unknown error";
+ (void)strerror_r(errno, errbuf,(int) sizeof(errbuf));
+ gpsd_report(&device->context->errout, LOG_ERROR,
+ "PPS: pthread_mutex_unlock() : %s\n", errbuf);
+ } else if (status == PPS_LOCK_ERR) {
+ char errbuf[BUFSIZ] = "unknown error";
+ (void)strerror_r(errno, errbuf,(int) sizeof(errbuf));
+ gpsd_report(&device->context->errout, LOG_ERROR,
+ "PPS: pthread_mutex_lock() : %s\n", errbuf);
+ }
#endif /* PPS_ENABLE */
}
#endif /* NTP_ENABLE */
diff --git a/ppsthread.c b/ppsthread.c
index 73d1cfdc..52512bc8 100644
--- a/ppsthread.c
+++ b/ppsthread.c
@@ -704,9 +704,9 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg)
}
/*@ +unrecog @*/
/*@-type@*/ /* splint is confused about struct timespec */
- session->ppslast = ppstimes;
+ session->pps_state.ppslast = ppstimes;
/*@+type@*/
- session->ppscount++;
+ session->pps_state.ppscount++;
/*@ -unrecog (splint has no pthread declarations as yet) @*/
pthread_err = pthread_mutex_unlock(&ppslast_mutex);
if ( 0 != pthread_err ) {
@@ -787,33 +787,31 @@ void pps_thread_deactivate(struct gps_device_t *session)
/*@+nullstate +mustfreeonly@*/
}
-void pps_thread_stash_fixtime(struct gps_device_t *session,
+int pps_thread_stash_fixtime(volatile struct pps_fixtime_t *last_fixtime,
timestamp_t realtime, struct timespec clocktime)
/* thread-safe update of last fix time - only way we pass data in */
{
+ int ret = PPS_THREAD_OK;
+
/*@ -unrecog (splint has no pthread declarations as yet) @*/
int pthread_err = pthread_mutex_lock(&ppslast_mutex);
- if ( 0 != pthread_err ) {
- char errbuf[BUFSIZ] = "unknown error";
- (void)strerror_r(errno, errbuf, (int)sizeof(errbuf));
- gpsd_report(&session->context->errout, LOG_ERROR,
- "PPS: pthread_mutex_lock() : %s\n", errbuf);
- }
+ if ( 0 != pthread_err )
+ ret = PPS_LOCK_ERR;
+ else {
/*@ +unrecog @*/
- session->last_fixtime.real = realtime;
- session->last_fixtime.clock = clocktime;
+ last_fixtime->real = realtime;
+ last_fixtime->clock = clocktime;
+ }
/*@ -unrecog (splint has no pthread declarations as yet) @*/
pthread_err = pthread_mutex_unlock(&ppslast_mutex);
- if ( 0 != pthread_err ) {
- char errbuf[BUFSIZ] = "unknown error";
- (void)strerror_r(errno, errbuf, (int)sizeof(errbuf));
- gpsd_report(&session->context->errout, LOG_ERROR,
- "PPS: pthread_mutex_unlock() : %s\n", errbuf);
- }
+ if ( 0 != pthread_err )
+ ret = PPS_UNLOCK_ERR;
/*@ +unrecog @*/
+
+ return ret;
}
-int pps_thread_lastpps(struct gps_device_t *session, struct timedelta_t *td)
+int pps_thread_lastpps(struct pps_state_t *pps_state, struct timedelta_t *td)
/* return the delta at the time of the last PPS - only way we pass data out */
{
volatile int ret;
@@ -822,22 +820,17 @@ int pps_thread_lastpps(struct gps_device_t *session, struct timedelta_t *td)
/*@ -unrecog (splint has no pthread declarations as yet) @*/
pthread_err = pthread_mutex_lock(&ppslast_mutex);
- if ( 0 != pthread_err ) {
- char errbuf[BUFSIZ] = "unknown error";
- (void)strerror_r(errno, errbuf,(int) sizeof(errbuf));
- gpsd_report(&session->context->errout, LOG_ERROR,
- "PPS: pthread_mutex_lock() : %s\n", errbuf);
+ if ( 0 != pthread_err )
+ ret = PPS_LOCK_ERR;
+ else {
+ /*@ +unrecog @*/
+ *td = pps_state->ppslast;
+ ret = pps_state->ppscount;
}
- /*@ +unrecog @*/
- *td = session->ppslast;
- ret = session->ppscount;
/*@ -unrecog (splint has no pthread declarations as yet) @*/
pthread_err = pthread_mutex_unlock(&ppslast_mutex);
if ( 0 != pthread_err ) {
- char errbuf[BUFSIZ] = "unknown error";
- (void)strerror_r(errno, errbuf, (int)sizeof(errbuf));
- gpsd_report(&session->context->errout, LOG_ERROR,
- "PPS: pthread_mutex_unlock() : %s\n", errbuf);
+ ret = PPS_UNLOCK_ERR;
}
/*@ +unrecog @*/
diff --git a/ppsthread.h b/ppsthread.h
new file mode 100644
index 00000000..ae7bd886
--- /dev/null
+++ b/ppsthread.h
@@ -0,0 +1,47 @@
+/*
+ * This file is Copyright (c) 2015 by the GPSD project
+ * BSD terms apply: see the file COPYING in the distribution root for details.
+ */
+
+#ifndef PPSTHREAD_H
+#define PPSTHREAD_H
+
+#include <stdbool.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#ifndef HAVE_TIMEDELTA
+
+struct timedelta_t {
+ struct timespec real;
+ struct timespec clock;
+};
+
+#define HAVE_TIMEDELTA
+#endif /* HAVE_TIMEDELTA */
+
+struct pps_state_t {
+ volatile struct timedelta_t ppslast;
+ volatile int ppscount;
+};
+
+struct pps_fixtime_t {
+ timestamp_t real;
+ /* clock must be a timespec as it is in nSec and
+ * a timestamp_t will lose precision */
+ struct timespec clock; /* system clock time when last fix received */
+};
+
+#define PPS_THREAD_OK 0
+#define PPS_LOCK_ERR -1
+#define PPS_UNLOCK_ERR -2
+
+extern int pps_thread_stash_fixtime(volatile struct pps_fixtime_t *,
+ timestamp_t, struct timespec);
+extern int pps_thread_lastpps(struct pps_state_t *, struct timedelta_t *);
+
+#endif /* PPSTHREAD_H */
+
+/* end */