diff options
-rw-r--r-- | gpsd.c | 4 | ||||
-rw-r--r-- | gpsd.h-tail | 3 | ||||
-rw-r--r-- | libgpsd_core.c | 9 | ||||
-rw-r--r-- | ppsthread.c | 56 | ||||
-rw-r--r-- | serial.c | 16 |
5 files changed, 80 insertions, 8 deletions
@@ -1857,6 +1857,10 @@ int main(int argc, char *argv[]) exit(1); } +#if defined(PPS_ENABLE) + pps_early_init( &context); +#endif /* PPS_ENABLE */ + #if defined(SYSTEMD_ENABLE) && defined(CONTROL_SOCKET_ENABLE) sd_socket_count = sd_get_socket_count(); if (sd_socket_count > 0 && control_socket != NULL) { diff --git a/gpsd.h-tail b/gpsd.h-tail index c7b3054c..edc8930f 100644 --- a/gpsd.h-tail +++ b/gpsd.h-tail @@ -887,6 +887,9 @@ extern void ntpshm_latch(struct gps_device_t *device, /*@out@*/struct timedrift extern void ntpshm_link_deactivate(struct gps_device_t *); extern void ntpshm_link_activate(struct gps_device_t *); #endif /* NTPSHM_ENABLE */ +#ifdef PPS_ENABLE +extern void pps_early_init(struct gps_context_t *); +#endif /* PPS_ENABLE */ /* normalize a timespec */ #define TS_NORM(ts) \ diff --git a/libgpsd_core.c b/libgpsd_core.c index 726e6976..579d32e1 100644 --- a/libgpsd_core.c +++ b/libgpsd_core.c @@ -67,6 +67,10 @@ void gpsd_acquire_reporting_lock(void) err = pthread_mutex_lock(&report_mutex); /*@ +unrecog @*/ if ( 0 != err ) { + /* POSIX says pthread_mutex_lock() should only fail if the + thread holding the lock has died. Best for gppsd to just die + because things are FUBAR. */ + (void) fprintf(stderr,"pthread_mutex_lock() failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); @@ -80,6 +84,11 @@ void gpsd_release_reporting_lock(void) err = pthread_mutex_unlock(&report_mutex); /*@ +unrecog @*/ if ( 0 != err ) { + /* POSIX says pthread_mutex_unlock() should only fail when + trying to unlock a lock that does not exist, or is not owned by + this thread. This should never happen, so best for gpsd to die + because things are FUBAR. */ + (void) fprintf(stderr,"pthread_mutex_unlock() failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); diff --git a/ppsthread.c b/ppsthread.c index 5e96aa4b..1f47db2c 100644 --- a/ppsthread.c +++ b/ppsthread.c @@ -75,6 +75,19 @@ static pthread_mutex_t ppslast_mutex; +void pps_early_init( struct gps_context_t * context ) { + int err; + + /*@ -unrecog (splint has no pthread declarations as yet) @*/ + err = pthread_mutex_init(&ppslast_mutex, NULL); + /*@ +unrecog @*/ + if ( 0 != err ) { + gpsd_report(&context->errout, LOG_ERROR, + "PPS: pthread_mutex_init() : %s\n", + strerror(errno)); + } +} + #if defined(HAVE_SYS_TIMEPPS_H) /*@-compdestroy -nullpass -unrecog@*/ static int init_kernel_pps(struct gps_device_t *session) @@ -300,7 +313,7 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg) break; } gpsd_report(&session->context->errout, LOG_PROG, - "PPS ioctl(TIOCMIWAIT) on %s succeeded", + "PPS ioctl(TIOCMIWAIT) on %s succeeded\n", session->gpsdata.dev.path); /* quick, grab a copy of last_fixtime before it changes */ last_fixtime_real = session->last_fixtime.real; @@ -509,9 +522,14 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg) ok = true; log = "5Hz PPS pulse\n"; } - } else if (999000 > cycle) { + } else if (900000 > cycle) { + /* Yes, 10% window. The Rasberry Pi clock is very coarse + * when it starts and chronyd may be doing a fast slew. + * chronyd by default will slew up to 8.334% ! + * Don't worry, ntpd and chronyd will do further sanitizing.*/ log = "Too long for 5Hz, too short for 1Hz\n"; - } else if (1001000 > cycle) { + } else if (1100000 > cycle) { + /* Yes, 10% window. */ /* looks like PPS pulse or square wave */ if (0 == duration) { ok = true; @@ -555,6 +573,8 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg) } if (ok) { + /* pthread error return */ + int pthread_err; /* offset is the skew from expected to observed pulse time */ double offset; /* delay after last fix */ @@ -613,14 +633,24 @@ static /*@null@*/ void *gpsd_ppsmonitor(void *arg) if (session->context->pps_hook != NULL) session->context->pps_hook(session, &drift); /*@ -unrecog (splint has no pthread declarations as yet) @*/ - (void)pthread_mutex_lock(&ppslast_mutex); + pthread_err = pthread_mutex_lock(&ppslast_mutex); + if ( 0 != pthread_err ) { + gpsd_report(&session->context->errout, LOG_ERROR, + "PPS: pthread_mutex_lock() : %s\n", + strerror(errno)); + } /*@ +unrecog @*/ /*@-type@*/ /* splint is confused about struct timespec */ session->ppslast = drift; /*@+type@*/ session->ppscount++; /*@ -unrecog (splint has no pthread declarations as yet) @*/ - (void)pthread_mutex_unlock(&ppslast_mutex); + pthread_err = pthread_mutex_unlock(&ppslast_mutex); + if ( 0 != pthread_err ) { + gpsd_report(&session->context->errout, LOG_ERROR, + "PPS: pthread_mutex_unlock() : %s\n", + strerror(errno)); + } /*@ +unrecog @*/ /*@+compdef@*/ /*@-type@*/ /* splint is confused about struct timespec */ @@ -697,14 +727,26 @@ int pps_thread_lastpps(struct gps_device_t *session, struct timedrift_t *td) /* return a copy of the drift at the time of the last PPS */ { volatile int ret; + /* pthread error return */ + int pthread_err; /*@ -unrecog (splint has no pthread declarations as yet) @*/ - (void)pthread_mutex_lock(&ppslast_mutex); + pthread_err = pthread_mutex_lock(&ppslast_mutex); + if ( 0 != pthread_err ) { + gpsd_report(&session->context->errout, LOG_ERROR, + "PPS: pthread_mutex_lock() : %s\n", + strerror(errno)); + } /*@ +unrecog @*/ *td = session->ppslast; ret = session->ppscount; /*@ -unrecog (splint has no pthread declarations as yet) @*/ - (void)pthread_mutex_unlock(&ppslast_mutex); + pthread_err = pthread_mutex_unlock(&ppslast_mutex); + if ( 0 != pthread_err ) { + gpsd_report(&session->context->errout, LOG_ERROR, + "PPS: pthread_mutex_unlock() : %s\n", + strerror(errno)); + } /*@ +unrecog @*/ return ret; @@ -610,13 +610,27 @@ ssize_t gpsd_serial_write(struct gps_device_t * session, } void gpsd_optimize_io(struct gps_device_t *session, - const int minlength, const bool textual UNUSED) + int minlength, const bool textual UNUSED) /* optimize I/O mode depending on the minimum packet size */ { /* bail out if this is not actually a tty */ if (isatty(session->gpsdata.gps_fd) == 0) return; +#ifdef __NetBSD__ + /* + * Apparently NetBSD termios (at least on pty on netbsd-[56]) has + * trouble with VMIN=n VTIME=1. Or reads are aftempted when no + * bytes are present and none arrive, in which case read is + * correct for waiting indefinitely. Until this is + * debugged/fixed, avoid it, because even if it doesn't affect + * actual operation (unknown) it's important to preserve + * regression tests to allow bisecting for other bugs. + * http://pubs.opengroup.org/onlinepubs/007908799/xbd/termios.html + */ + minlength = 1; +#endif + /* * This is an optimization hack. The idea is to get away from * character-at-a-time I/O in order to slow down the rate at |