summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwjt <wjt@web>2015-11-05 03:37:43 -0800
committergypsy <iki-gypsy@freedesktop.org>2015-11-05 03:37:43 -0800
commit6509e0a0e4aed049ec40d42df583ab7cc45ec5cb (patch)
tree9d1649801765cadeec87731e79ca61fc8f7cf419
parent0b411fe1f7c5dc2dbc4fb20653f2021babffd2c3 (diff)
Import this old page
-rw-r--r--why-not-gpsd.mdwn190
1 files changed, 190 insertions, 0 deletions
diff --git a/why-not-gpsd.mdwn b/why-not-gpsd.mdwn
new file mode 100644
index 0000000..a74e90b
--- /dev/null
+++ b/why-not-gpsd.mdwn
@@ -0,0 +1,190 @@
+Why Should You Use Gypsy over GPSD
+==================================
+
+### (Or what I see as the problems in GPSD and how Gypsy solves them)
+
+Gypsy and [GPSD](http://gpsd.berlios.de) share the same problem space:
+multiplexing GPS data from one device to many clients. So why was Gypsy
+written from scratch instead of working on GPSD and implementing Gypsy
+as an extension of the original GPSD? In this document I hope to explain
+the flaws in GPSD at a design level and at the level of users of GPSD
+(both users of the program and of the API)
+
+One major design decision made by the GPSD team is that there should be
+no memory allocation functions."Don't Use Malloc" is one of the bullet
+points in the contribution guidelines
+(http://gpsd.berlios.de/hacking.html\#malloc).
+
+> The best way to avoid having dynamic-memory allocation problems is not
+> to use malloc/free at all. The gpsd daemon doesn't (though the
+> client-side code does). Thus, even the longest-running instance can't
+> have memory leaks. The only cost for this turned out to be embedding a
+> PATH\_MAX-sized buffer in the gpsd.h structure.
+> Don't undo this by using malloc/free in a driver or anywhere else.
+
+This cost analysis is not quite true. It means that all arrays must be
+preallocated even if the memory is not used for the program at all.
+There was, at one point, an array of 1024 device structures which
+allowed for 1024 devices to be connected. This whole array was allocated
+even if there was only one device (which is a more common case than
+1024). Each structure was 20K, which meant there was about 14meg wasted.
+Recent versions of gpsd have reduced this count to only 4 structures,
+which is only a waste of 60k or so in the common case. While this isn't
+such a terrible waste any more, it is still a bandaid over the problem
+rather than a solution. Rather having a sensible memory allocation
+strategy would make the code less complicated and mean that there was no
+wasted memory at all.\
+ Using statically allocated buffers is not in itself bad, Gypsy uses
+them in certain places in the code, but its not for fear of leaking
+memory, its for speed in the NMEA parsing code which has many small
+string operations run many times a second. In code like this, mallocing
+small pieces of memory to free them a few lines later is a minor
+performance hit and fragments the memory which always annoys the memory
+manager.
+
+GPSD is designed around the idea that it can be accessed remotely. It
+sets itself up as a server on port 2947. By default, as of recent
+versions, the behaviour is only to allow connections from the local
+machine, but the functionality is still there if needed and local
+connections are treated the same as remote connections.\
+ The problem is I have a hard time coming up with use cases for this in
+either general use cases for GPS devices, or the use cases GPSD was
+designed for (http://gpsd.berlios.de/hacking.html\#audience). But
+because of this useless feature (which is turned off by default) the
+common use case is made more complicated because of the primitive IPC
+that GPSD needs to use to support it.
+
+GPSD was written originally in 1995, back then there were few options
+for sane IPC (CORBA being rather heavyweight) and using TCPIP sockets
+might have been the best option. However, nearly 15 years later, we have
+a very successful IPC protocol in D-Bus which provides the things that
+GPSD's string and socket based protocol lacks such as type safety.\
+ GPSD works that your client opens a socket to the server and sends it a
+command. The commands are currently all letters, although at the time of
+writing there is only one letter left unused and so a new format is
+being discussed. GPSD replies to every letter with a string. Each
+parameter in the string is separated by (what appears to be a random
+number of) spaces. The Y command is separated by spaces, except for the
+quads which are separated by commas.
+
+These inconsistencies make it awkward to parse by hand and although
+GPSD supplies libgps which handles this for you, as we shall see, it has
+issues of its own which make it, in my opinion, a less optimal solution.
+The proposed version of the GPSD message protocol currently allows for
+multiple letter commands and for multiple line responses. This again
+adds to the complexity of parsing, which is all something that a proper
+IPC system such as D-Bus provides.
+
+GPSD provides a client library called libgps which simplifies writing
+client programs that interface with the daemon. This library handles all
+the parsing of the GPSD replies and passes the client a structure with
+the values filled in.
+
+There is both a push and a pull method of accessing the GPS data. In
+both methods the user sets a callback function. The push method is done
+via threads and the callback is called in a separate thread whenever the
+data is received from GPSD. In the pull method, the client calls
+gps\_poll and the program blocks until data is available. When data is
+available the callback is called and the program continues.
+
+The first problem is that the options for a programmer are either
+blocking or threads. This is fine for a non-interactive console program,
+but for GUI programmers blocking calls are a big no no. Every blocking
+call potentially freezes the UI. On the other hand in many GUI toolkits
+using threads is awkward and no GUI operations may happen from a
+secondary thread. Again this complicates the programs using the API.\
+ The second problem with the API as it stands is that there is no way to
+pass data to the callback meaning that any data needed by the callback
+must be a global variable. Again in a simple non-interactive console
+program global variables are not too big a deal, but for a GUI program
+they are frowned upon.
+
+Thirdly the API has no concept of objects. Only one callback can be
+registered for each of the methods (one for the thread method, and one
+for the poll method).This again means that the one callback has to do
+everything that needs to be done in the program related to GPS
+functions. While again it is possible, it complicates object oriented
+programs and breaks the encapsulation of data.
+
+GPSD is designed to be run at system start, and stopped when the system
+is shutdown (or for USB/bluetooth hotplug devices started when that
+device is plugged in or removed). If a client is started before GPSD is
+running (for example a GPS applet is started before the BT device is
+connected), then the only way for it to know that GPSD is for it to
+attempt to connect to the GPSD socket and keep trying every so often
+until it succeeds. This makes gpsd client programs very busy, always
+having to wake up to check to see if it can connect and on a system that
+runs on batteries having processes that can't sleep very often is a bad
+thing that drains away the battery.
+
+Because GPSD is designed to always be running and always report fix
+data, there is no provision for turning it on and off, except by killing
+the process. For systems that try to minimise processor usage while the
+device is idle, this makes it hard for programs, as they have to either
+be listening to GPSD emitting data, or trying to connect to the socket
+to see if GPSD has started up again.
+
+Also with regards to clients being woken up, even when GPSD is running
+clients get notified about everything, even if they don't care about it.
+GPSD emits a new fix on every NMEA sentence received, which for most GPS
+devices is about 5 a second and each time the clients are all woken up
+even if they don't care about the data that has changed. GPSD has no way
+for clients to say that they are only interested in position data, or
+only in whether the device has a fix or not. Even if the GPS unit is
+stationary, satellite data is constantly changing, and the clients will
+be woken up on every message.
+
+Finally, and this may seem like a picky point, but the code is filled
+with comments that lint can check its perfectness. The problem, to me,
+is that all this just clutters the code and makes it harder to read and
+understand, but like I said, this is just a personal thing.
+
+How Does Gypsy Solve These Problems?
+====================================
+
+GPSD feels like it was written with no real applications in mind, that
+libgps was an after thought and it provides the bare minimum required to
+access the daemon and the daemon was not designed with how clients might
+want to use the data. Gypsy on the other hand was born out of
+frustration with the way GPSD did things and so how applications might
+want to use the GPS data was the driving force behind its design.\
+ Gypsy was written around D-Bus. D-Bus provides a powerful signalling
+system where clients register their interest in certain signals with the
+bus, and they are woken up only when that signal is emitted. Clients do
+not have to poll to find out if data has changed or whether the daemon
+is running. If the signal watches are added before daemon starts, then
+the only thing that happens is that they won't do anything until the
+daemon starts.
+
+Gypsy also provides finer grained signals. There are currently five
+different signals that a client can listen for:
+
+- PositionChanged - Emitted when latitude, longitude or altitude are
+ changed
+- CourseChanged - Emitted when the direction, speed or climb change
+- SatellitesChanged - Emitted when some part of the satellite data has
+ changed
+- FixStatusChanged - Emitted when the GPS gets or loses a fix
+- ConnectionChanged - Emitted when the GPS device is connected or
+ disconnected
+
+With these different signals, a client which is only interested in the
+whether the GPS has a fix or not only needs to connect to the
+FixStatusChanged signal and it will not be woken up if the satellite
+position changes, only if the fix status changes. This allows processes
+to sleep a lot more.
+
+Even though the GPS device is constantly sending Gypsy data, Gypsy
+checks whether or not the data has changed before emitting a signal. So
+if, for example, the device is stationary, no PositionChanged signals
+will be emitted until the device starts to move again, once more
+allowing programs to sleep more often.
+
+Using D-Bus allows the API to be combined with main loops using the
+D-Bus object bindings. Gypsy comes with libgypsy which is a GObject
+binding for the D-Bus protocol allowing Gypsy to be used in a GObject
+based system such as Gtk+ or GNOME. Other object bindings could be
+written to integrate Gypsy with QT and KDE for example.
+
+Hopefully with Gypsy, we can great a much more powerful location-aware
+system for modern desktops.