Mailing List archive

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

[linux-dvb] Re: refactoring



On Fri, 15 Oct 2004, Holger Waechtler wrote:
>
> Gerd Knorr wrote:
>
> >>>Syncronization will become _very_ nasty with that approach through,
> >>>I doubt it is a good idea ...
> >>>
> >>>
> >
> >
> >
> >>synchronisation of what? Do you mean audio/video synchronisation via PCR?
> >>
> >>
> >
> >No.  Syncronization of the DMA buffers.  With one application doing DMA
> >this is trivial:  The kernel will notify the application when a new
> >buffer has been filled, the application will notify the kernel when it
> >is done with processing the data in there and the buffer can be refilled
> >with new data, end of story.
> >
> >With multiple apps having read access to the very same DMA buffer ring
> >this suddenly becomes much more complex.  Especially the handling of
> >nasty corner cases like this one (and there are probably more):  One
> >application gets stuck for some reason and stops releasing the processed
> >buffers.  Might be a bug.  Might be a app streaming stuff over the
> >network and the network is overloaded.  Whatever, doesn't matter.  How
> >do you handle that?
> >
> >
>
> The entire ringbuffer of DMA areas is exposed read-only to the
> application and every client can query via ioctl() the current DMA write
> pointer position or the number ov valid (filled) DMA areas, or simply a
> bitfield describing which DMA buffers are filled with data.
>
> Ringbuffer read-pointers need to get handled by the application,  the
> situation is basically similiar to the one when you program a DMA driver
> in kernel space, you can only read the current write position register
> from the hardware.

As you may recall this is what I've done in my Mac drivers. But I've taken
it one step further and exported the current write position via a
single-page memory mapping to userspace as well (so there are two memory
mappings, one big one and one small one).

The driver gives the user information about where in the mapping the level
is to be found and how to turn it into a number of bytes. For PCI devices,
this means that the userspace program doesn't ever have to cross into the
kernel in the normal process of decoding, so there is no overhead there
(the small mapping exported is part of their PCI register address space).
Moreover, it means that the kernel drivers aren't interested when new data
is ready, so they don't have to setup or handle interrupts - once a
channel has been tuned the kernel drivers sit back and do nothing. Unless
you ask for signal level, ucblocks, etc. - and for the record I used
absolute counts similar to how Gerd wrote in his recent mail ... it means
>1 user can read them without stuffing the others up.

Of course, all this functionality and buffer level calculation is wrapped
up in a nice userspace library with the main API being 'gimme more
packets' called whenever the program wants more TS packets. It returns
where they start and how long they go for (in the big mapping).

The best thing I like about the big memory mapping is that it is up to the
userspace program to keep up. If it is slow the kernel doesn't have to do
any tricky buffering which would only make it worse for a constant stream.
The worst thing about a big mapping is that the memory is always taken up.

Anyway, this approach has worked really well for me but ymmv.

> Holger

{P^/




Home | Main Index | Thread Index