summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2015-01-26 09:08:01 -0500
committerEric S. Raymond <esr@thyrsus.com>2015-01-26 09:08:58 -0500
commitf0669f3ed0b300ebd5567afc3c1dd2d179551dc6 (patch)
treed9c8d2d5970a4ba5cf067dd74710d47542ae649b
parentce9d79d63bcc2d439ac22449910e0d91997c4e47 (diff)
downloadgpsd-f0669f3ed0b300ebd5567afc3c1dd2d179551dc6.tar.gz
Implement and document the buzzkill option.
All regression tests pass.
-rw-r--r--SConstruct1
-rw-r--r--build.txt34
-rw-r--r--gpsd.c18
3 files changed, 48 insertions, 5 deletions
diff --git a/SConstruct b/SConstruct
index f379e624..211c9a1b 100644
--- a/SConstruct
+++ b/SConstruct
@@ -155,6 +155,7 @@ boolopts = (
("nofloats", False, "float ops are expensive, suppress error estimates"),
("squelch", False, "squelch gpsd_report/gpsd_hexdump to save cpu"),
("ncurses", True, "build with ncurses"),
+ ("buzzkill", True, "adaptive-delay logic to cope with select buzzing"),
# Build control
("shared", True, "build shared libraries, not static"),
("implicit_link", imloads,"implicit linkage is supported in shared libs"),
diff --git a/build.txt b/build.txt
index 2847be60..baffd00b 100644
--- a/build.txt
+++ b/build.txt
@@ -352,6 +352,40 @@ scons minimal=yes socket_export=yes nmea0183=yes
will do that.
+== Configuration problem cases
+
+This section describes cases in which the default build is known to be
+unavoidably broken and a custom configuration is required to do the
+right thing.
+
+Presently there is only one such case; buzzkill=yes (the default) can
+conflict with nmea2000=yes (the default), causing problems if you try
+to watch both a CAN/NMEA2000 device and a serial device. The only
+remedy is a custom build with buzzkill=no.
+
+The buzzkill option is intended to thwart problems due to gpsd's main
+select(2) loop buzzing (spinning too fast). On battery-powered SBCs
+and mobile devices this can cause serious and unnecessary power drain;
+this has been observed on the Raspberry Pi and sporadically on
+particular Android phone hardware. There are at least two reasons it
+can happen; one is defective select(2) device-driver hooks that return
+a data-ready when they shouldn't, the other is tty layers that return
+data in single characters or small packets even when it's arriving in
+packet-sized chunks.
+
+GPSD with buzzkill=yes watches the incoming data rate from all devices
+and adaptively inserts delays in the main loop if it thinks it sees
+buzzing. This logic is routed around if all devices have types that never
+require delays, notably pseudo-ttys and UDP packet streams.
+
+With nmea2000=yes the code tries to read NME2000 packets from a CANbus
+interface at high speed. The resulting data flow can look like
+buzzing, but the CAN driver pretends to be a pseudo-tty to avoid delay
+insertion. The problem arises if you try to watch both a conventional
+tty and a CAN interface at the same time; this foils the buzzkill
+guard, and you will lose CAN packets due to inserted delays. To
+prevent this, build with buzzkill=no.
+
== Port and toolchain testing ==
'scons check' will run a comprehensive regression-test suite. You
diff --git a/gpsd.c b/gpsd.c
index 1f89d1b8..efaa8d09 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -1778,6 +1778,7 @@ static void gpsd_terminate(struct gps_context_t *context CONDITIONALLY_UNUSED)
#endif /* PPS_ENABLE */
}
+#ifdef BUZZKILL_ENABLE
static void adaptive_delay(void)
/* sleep a calculated time only if we have a buggy select() */
{
@@ -1826,6 +1827,7 @@ static void adaptive_delay(void)
}
return;
}
+#endif /* BUZZKILL_ENABLE */
/*@ -mustfreefresh @*/
int main(int argc, char *argv[])
@@ -2206,14 +2208,20 @@ int main(int argc, char *argv[])
while (0 == signalled) {
fd_set efds;
+#ifdef BUZZKILL_ENABLE
/*
- * Adaptive delay to prevent buzzing if the tty layer returns data
- * one character at a time and too fast. This pushes CPU usage up and
- * eats power. This has been directly observed as a problem on the
- * Raspberry Pi, and is probably behind occasional reports of
- * GPSD-related excessive power drain on Android phones.
+ * Adaptive delay to prevent buzzing if the tty layer returns
+ * data one character at a time and too fast. Buzzing pushes
+ * CPU usage up and eats power.
+ *
+ * This has been directly observed as a problem on the
+ * Raspberry Pi. A buzzing problem with outright defective
+ * select(2) implementations is probably behind occasional
+ * reports of GPSD-related excessive power drain on Android
+ * phones.
*/
(void) adaptive_delay();
+#endif /* BUZZKILL_ENABLE */
switch(gpsd_await_data(&rfds, &efds, maxfd, &all_fds, &context.errout))
{