[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [gpsd-dev] Updated docs on NTP segment management
From: |
Eric S. Raymond |
Subject: |
Re: [gpsd-dev] Updated docs on NTP segment management |
Date: |
Wed, 18 Feb 2015 18:19:06 -0500 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
Gary E. Miller <address@hidden>:
> > The SHM export code I wrote using this technique seems to work.
>
> 'seems to work' does not give me warm and fuzzy feelings. Several had
> similar thoughts on the gpsmon PPS, and we know how that turned out.
You should have seen my detailed reply to Hal Murray on this by now.
What I invented for the job turned out to be a belt-and-suspenders
variation on a fairly well-known (and sound) technique called
"optimistic locking" (I was told this in comments when I blogged about
it).
It'll work unless both (a) the memory-barrier instructions don't
barrier, and (b) the bitblt instruction that memcpy compiles to is
interruptible.
Maybe this will prove enlightening:
shmexport.c:
void shm_update(struct gps_context_t *context, struct gps_data_t *gpsdata)
/* export an update to all listeners */
{
if (context->shmexport != NULL)
{
static int tick;
volatile struct shmexport_t *shared = (struct shmexport_t
*)context->shmexport;
++tick;
/*
* Following block of instructions must not be reordered, otherwise
* havoc will ensue.
*
* This is a simple optimistic-concurrency technique. We write
* the second bookend first, then the data, then the first bookend.
* Reader copies what it sees in normal order; that way, if we
* start to write the segment during the read, the second bookend will
* get clobbered first and the data can be detected as bad.
*/
shared->bookend2 = tick;
memory_barrier();
memcpy((void *)((char *)context->shmexport + offsetof(struct
shmexport_t, gpsdata)),
(void *)gpsdata,
sizeof(struct gps_data_t));
memory_barrier();
#ifndef USE_QT
shared->gpsdata.gps_fd = SHM_PSEUDO_FD;
#else
shared->gpsdata.gps_fd = (void *)(intptr_t)SHM_PSEUDO_FD;
#endif /* USE_QT */
memory_barrier();
shared->bookend1 = tick;
}
}
libgps_shm.c:
int gps_shm_read(struct gps_data_t *gpsdata)
/* read an update from the shared-memory segment */
{
/*@ -compdestroy */
if (gpsdata->privdata == NULL)
return -1;
else
{
int before, after;
void *private_save = gpsdata->privdata;
volatile struct shmexport_t *shared = (struct shmexport_t
*)PRIVATE(gpsdata)->shmseg;
struct gps_data_t noclobber;
/*
* Following block of instructions must not be reordered,
* otherwise havoc will ensue. The memory_barrier() call
* should prevent reordering of the data accesses.
*
* This is a simple optimistic-concurrency technique. We wrote
* the second bookend first, then the data, then the first bookend.
* Reader copies what it sees in normal order; that way, if we
* start to write the segment during the read, the second bookend will
* get clobbered first and the data can be detected as bad.
*/
before = shared->bookend1;
memory_barrier();
(void)memcpy((void *)&noclobber,
(void *)&shared->gpsdata,
sizeof(struct gps_data_t));
memory_barrier();
after = shared->bookend2;
if (before != after)
return 0;
else {
(void)memcpy((void *)gpsdata,
(void *)&noclobber,
sizeof(struct gps_data_t));
/address@hidden@*/gpsdata->privdata = private_save;
PRIVATE(gpsdata)->tick = after;
if ((gpsdata->set & REPORT_IS)!=0) {
if (gpsdata->fix.mode >= 2)
gpsdata->status = STATUS_FIX;
else
gpsdata->status = STATUS_NO_FIX;
gpsdata->set = STATUS_SET;
}
return (int)sizeof(struct gps_data_t);
}
}
/*@ +compdestroy */
}
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
- Re: [gpsd-dev] Updated docs on NTP segment management, (continued)
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/17
- Re: [gpsd-dev] Updated docs on NTP segment management, Hal Murray, 2015/02/17
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/17
- Re: [gpsd-dev] Updated docs on NTP segment management, Hal Murray, 2015/02/17
- Re: [gpsd-dev] Updated docs on NTP segment management, Harlan Stenn, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Hal Murray, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Eric S. Raymond, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Eric S. Raymond, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management,
Eric S. Raymond <=
- Re: [gpsd-dev] Updated docs on NTP segment management, Harlan Stenn, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Eric S. Raymond, 2015/02/18
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/19
- Re: [gpsd-dev] Updated docs on NTP segment management, Eric S. Raymond, 2015/02/19
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/20
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/20
- Re: [gpsd-dev] Updated docs on NTP segment management, Harlan Stenn, 2015/02/20
- Re: [gpsd-dev] Updated docs on NTP segment management, Harlan Stenn, 2015/02/20
- Re: [gpsd-dev] Updated docs on NTP segment management, Miroslav Lichvar, 2015/02/23
- Re: [gpsd-dev] Updated docs on NTP segment management, Gary E. Miller, 2015/02/23