summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libgps_shm.c10
-rw-r--r--www/hacking.html5
2 files changed, 15 insertions, 0 deletions
diff --git a/libgps_shm.c b/libgps_shm.c
index daf0f632..5a6c2442 100644
--- a/libgps_shm.c
+++ b/libgps_shm.c
@@ -55,6 +55,16 @@ int gps_shm_read(struct gps_data_t *gpsdata)
struct shmexport_t *shared = (struct shmexport_t *)gpsdata->privdata;
before = shared->bookend1;
+ /*
+ * The bookend-consistency technique wants this to be a forward copy.
+ * But it is not guaranteed, that memcpy() works this way, and some compilers on some platforms
+ * are known to implement it as a reverse copy. Notably GCC does
+ * this on x64 Atom.
+ *
+ * The safest thing to do here would be to use a naive C implementation
+ * of forward byte copy, but if we did that we'd be sacrificing the
+ * superior performance of the asm optimization GCC does for
+ */
(void)memcpy((void *)gpsdata,
(void *)&shared->gpsdata,
sizeof(struct gps_data_t));
diff --git a/www/hacking.html b/www/hacking.html
index 0c9d858d..132a25e2 100644
--- a/www/hacking.html
+++ b/www/hacking.html
@@ -567,6 +567,11 @@ typedefs.</p>
<p>(No, we don't know why splint doesn't handle these natively.)</p>
+<p>If you are porting to GCC on x64 Atom or any other compiler/machine
+combination where you suspect memcpy(3) might be implemented by
+reverse rather than forward copy, it may screw up the shared-memory
+export. Read the comment about this in libgps_shm.c and beware.</p>
+
<h2 id="architecture">Architecture and how to hack it</h2>
<p>There are two useful ways to think about the GPSD architecture.