On Tue, Jul 16, 2002 at 11:30:59AM +0300, Nadav Har'El wrote:
> On Tue, Jul 16, 2002, Muli Ben-Yehuda wrote about "device files implementing mmap":
> >...
> > My question: how does the kernel "notify" the user space process that
> > there's new data to be read, 'n' bytes, starting from offset 'foo' in
> > the buffer? Is there a standard way to do it?
> > 
> > The little research I've just done indicates that there's no standard
> > way. The drivers I've looked at use a combination of poll/select and
> > ioctl (yuck) to implement it. Does anyone know of a standard (or at
> > least well accepted) way to accomplish this feat? I don't mind
> 
> Well, you want your driver to give the user two features: a way to sleep
> until data in in the buffer, and then a way to know which part of the
> buffer is new data (offset+length). Obviously, you can have the sleeping
> part done with select() and then the fetching-offset-and-length part done
> with ioctl(), but you called this "yuck".

There's also the problem that the buffer needs to be protected from
concurrent access to it by both user space and kernel space. 

> If the "yucky" part is that you need two system calls, well, you can put
> current offset in the buffer inside the buffer itself, in a fixed position.
> But I'm not sure how you'd protect this offset from concurrent access (if
> you at all need such protection). Some drivers (e.g., /dev/epoll) don't

Single reader, single writer... 

> need such protection, and only use a double-buffer to protect the kernel
> and the user-space from reading and writing at the same spot
concurrently.

... but this is a must. 

> Another alternative I can think of is to have the read() system call on your
> device always return 8 bytes (say), two integers specifying the offset and
> size of the new data (which the user will need to fetch using the mapped
> memory). In this case, one system call - read() - will both block until new
> data arrives and fetch the location of that data. You can select() and then
> read() - but I don't see how this would be better than the select() and then
> ioctl() which you called "yuck".

This is one that I'll have to benchmark (small read + mmap vs. large
read), but it still doesn't solve the synchronization issue. How does
the double buffer technique solve it?

This is turning into a mystery. Pretty much every sound/video driver
out there does this 'mmap into a ring buffer and let user space read
it', they can't all be racy! More digging into the code is required. 
-- 
http://vipe.technion.ac.il/~mulix/
http://syscalltrack.sf.net/

Attachment: msg20515/pgp00000.pgp
Description: PGP signature

Reply via email to