diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2015-01-26 09:08:01 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2015-01-26 09:08:58 -0500 |
commit | f0669f3ed0b300ebd5567afc3c1dd2d179551dc6 (patch) | |
tree | d9c8d2d5970a4ba5cf067dd74710d47542ae649b | |
parent | ce9d79d63bcc2d439ac22449910e0d91997c4e47 (diff) | |
download | gpsd-f0669f3ed0b300ebd5567afc3c1dd2d179551dc6.tar.gz |
Implement and document the buzzkill option.
All regression tests pass.
-rw-r--r-- | SConstruct | 1 | ||||
-rw-r--r-- | build.txt | 34 | ||||
-rw-r--r-- | gpsd.c | 18 |
3 files changed, 48 insertions, 5 deletions
@@ -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"), @@ -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 @@ -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)) { |