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/
msg20515/pgp00000.pgp
Description: PGP signature
