[alsa-devel] problems writing pcm driver
Takashi Iwai
tiwai at suse.de
Wed Aug 22 12:08:24 CEST 2007
At Wed, 22 Aug 2007 02:54:28 -0700 (PDT),
Trent Piepho wrote:
>
> On Wed, 22 Aug 2007, Takashi Iwai wrote:
> > > On Tue, 21 Aug 2007, Takashi Iwai wrote:
> > > > At Mon, 20 Aug 2007 13:47:48 -0700 (PDT),
> > > > Trent Piepho wrote:
> > > > > Atomicity:
> > > > > trigger, pointer, and ack are atomic with respect to themselves. e.g., two
> > > > > copies of the trigger callback can't be running at the same time. That much
> > > > > is clear. But are they atomic with respect to each other? Can the trigger
> > > > > callback run at the same time as the pointer callback? How about the atomic
> > > > > callbacks with respect to the non-atomic ones? Can trigger run at the same
> > > > > time as prepare?
> > > >
> > > > No, these callbacks are exclusive. In principle, they are called with
> > > > substream->lock spinlock already held by the PCM core, so they cannot
> > > > be called at the same time as long as belonging to the same PCM
> > > > substream instance.
> > >
> > > The driver writing howto says for hw_params, "is that this callback is
> > > non-atomic (schedulable)."
> > >
> > > If it's non-atomic, that would mean to me that it can be called multiple
> > > times at once, and at the same time as other callbacks. But, you're saying
> > > that's not the case?
> >
> > No, in that context, non-atomic means schedulable. That is, the
> > function can get scheduled safely. It's outside the spinlock.
>
> I see, it's not the normal definition of atomic:
> http://en.wikipedia.org/wiki/Atomic_operations
>
> I suggest something like "schedulable" or "process context". When I see "X
> is not atomic" I think that means I need to code the function to be
> re-entrant.
Yeah, maybe it's better.
> > About the concurrent access: since the PCM substream instance is
> > exclusive, all PCM callbacks are also basically exclusive. Even open
> > and close are already protected via mutex in PCM core. Thus they
> > cannot be called simultaneously for the same substream instance. (For
> > different substreams, they can be called.)
>
> Speaking of open, does one need to worry about the same pcm device being
> opened multiple times?
Two cases that open/close can be called for the same PCM instance:
- for different directions (full-duplex), playback and capture
- for different substreams (only when multiple substreams are defined)
> I see code in the open callback of the bt87x driver
> and the cx88-alsa driver that checks if the chip has already been opened
> using atomic bit ops. I'm guessing this is correct the bt87x driver, which
> has two substreams of which only one can be used at one time. But in the
> cx88-alsa driver, which has only one substream, it is unnecessary.
Yes, likely so.
> I've figured out one of my problems, and it looks like it's not my fault.
>
> I tried running arecord piped to aplay, both using the ca0106 driver, and
> it works ok. Very few overruns. So this operation with this buffer size
> _can_ be done.
> arecord -v -D hw:0,0 -f DAT --buffer-size=512 | aplay -D hw:0,1 --buffer-size=512
>
> So, I do the same thing with the device I'm working on, running arecord on
> hw:1,0, but it doesn't work so well! It's ok for a minute or two, but then
> I start getting a lot of overruns. I thought it was my driver, but then I
> noticed something.
>
> Once the overruns start, they were consistently about 3.5 seconds apart.
> If I increased the arecord buffer size to 1024, they were 7 seconds apart,
> at 2048 they were 13 seconds apart.
>
> When I recorded and played back using the ca0106 card, both the ADC and DAC
> were probably using the same master clock signal and the rates were locked.
> But the other card was using a different clock and must have been producing
> data faster than the ca0106 would play it. After a while the pipe buffer
> would fill up and arecord would block too long waiting for aplay to consume
> its data, and there would be an overrun. That empties the driver's pcm
> buffer, but not the pipe between arecord and aplay. So as soon as the pcm
> buffer fills up, another overrun. Each time the pcm buffer doubles in
> size, it takes twice as long to fill up, and the time between overruns
> doubles.
Indeed, the sync with multiple devices in such a small buffer size is
often difficult.
Takashi
More information about the Alsa-devel
mailing list