[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gpsd-dev] SHM refclock improvements

From: Hal Murray
Subject: Re: [gpsd-dev] SHM refclock improvements
Date: Tue, 28 Aug 2012 15:01:51 -0700

> How will we be able to know if an ntpd is capable of the new SHM mode??

That's a key question.  I don't have any great ideas.

Plan one is to release a new ntpd that handles the new mode, wait for it to 
get widely distributed, then release a new gpsd that takes advantage of it.  
That's likely to take a long time.

The "wait" could be reduced if ntpd and gpsd could get coordinated on handing 
new releases to the upstream distributions.

We could use 2 chunks of shared memory.  gpsd writes to both, ntpd uses a 
mode bit or tries both.

If we do that, the new format should probably include some way of 
communicating what versions are supported so we don't have to do this dance 


Back to the original problem:

address@hidden said:
> We're looking to improve NTP's SHM refclock interface.

I looked carefully at this stuff several years ago and I couldn't convince 
myself that it would actually work correctly.  I forget the details.  I may 
be able to reconstruct something.  This stuff is tricky.  The details 
probably depend upon the machine architecture.

A year or 2 ago, there was a proposal to do-it-clean and use pthreads 
locking.  I think the discussion was on usenet.  That's a nice idea, but I 
don't know how to write the code for this case.  Does pthreads support 
locking when memory is shared between jobs rather than different threads or 
forks in the same job?  The problem is who does the initialization?  We don't 
know which side gets started first.  What happens if one side crashes and 
restarts?  There should be a FAQ that covers this, if only to say "don't do 

I used to work with people who were wizards at this stuff.  I asked one of 
them how to do it.  His suggestion is roughly:

The shared memory uses 2 variables to control locking.  Call them X and Y.

The writer bumps X, updates the data, then sets Y to X.

The reader grabs Y, grabs the data, then grabs X.
If X != Y, the data is invalid.
(The reader should ignore the first valid data in case it's left over from 
ages ago or initial memory was zeroed or ....)

The key is that the writer updates X then Y while the reader reads them in 
the opposite order.

Note that the reader never writes to shared memory and the writer never reads 
anything.  That allows multiple readers.

X and Y need to be sized so they are atomically updatable.  The code also 
needs cache flushes in the right places.  I think a cache flush is a no-op on 
x86.  I think it needs real code on ARM and others.  There should be a FAQ on 
this, but I didn't find it with a quick search.

These are my opinions.  I hate spam.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]