[LinuxPPS] select() on /dev/pps

tlhackque tlhackque at yahoo.com
Fri Aug 28 12:54:44 CEST 2015


On 03-Aug-15 11:19, Rodolfo Giometti wrote:
> On Thu, Jul 30, 2015 at 09:39:27AM +0200, Xavier Bestel wrote:
>> Hi,
>>
>> for an application of mine I would need to be able to wait for
>> events on a char device and on a PPS device; on the char device the
>> select() call is the obvious candidate, but it doesn't seem to work
>> on the PPS device. That is, select() always returns immediately
>> telling some data is available, and a PPS_FETCH either returns
>> immediately if flags=0 or waits for 1s if flags=PPS_TIME_INVALID;
>>
>> That looks wrong to me. IMHO select() should wait for 1s and
>> PPS_FETCH should "consume" the data without waiting.
>> If it should work, could you tell me where is my code wrong ?
> If I well remember the current implementation of the RFC2783 does not
> require to use select() to block until the next timestamp is captured
> (see section 3.4.3 - New functions: access to PPS timestamps).
>
> Of course you can feel free to modify the current select() behaviour
> and propose a patch! :-)
>
> Ciao,
>
> Rodolfo
>
Intuitively, select() could work as the OP expects, as pps_fetch() is
analogous to a read(2). 
However pps_fetch() doesn't operate on the device, but on the
pps_handle.  A pps_handle is
not select()able, and read(2) on the underlying PPS device is not
defined.  In fact, only pps_create
uses the device's filedes.

Thus, the RFC's statement in 3.4.3 is stronger than you recall:
  "The API does
   not directly support the use of the select() or poll() system calls
   to wait for PPS events."

"Patching select()" would not result in a portable solution and would
take a long time to deploy.  Further, it would require the pps drivers
to implement a poll() method.  In the general case, it's non-trivial
because pps devices tend to wrap physical devices, such as serial lines,
and these already support poll for read() and write() of serial data. 
This is probably why the RFC was written with this restriction.

A better approach is for the user program to create a thread or fork to
do blocking reads on PPS.

A fork can pipe() the values to the main thread, which can select() the
pipe and read(2) the values.

Or a fork/thread can put the value in shared memory queue and use
eventfd(2) to signal the main thread's select() by write(2) a '1' to the
event fd for each event.  The main thread select()s or poll()s on the
event fd; read(2) will return the number of entries in the queue.

Shared memory will have less overhead, but requires a little more coding.

Either approach requires no RFC or kernel change, as it's entirely
within user space.

The other consideration is that support for blocking reads is optional
for a PPS source.   If an implementation doesn't support PPS_CANWAIT,
you have to rely on timeouts rather than blocking for a timestamp.  See
time_pps_getcap() .

https://tools.ietf.org/html/rfc2783 is worth reading...
 





More information about the discussions mailing list