ok, i added "duplex polling with retry". i am now seeing interesting
behaviour that i need to understand (and correct):

1) the behaviour (see trace below)
2) summary

if capture is not ready at the same time as playback, returning to
poll to wait for capture often works. but not always. sometimes, it
takes another entire period to return from poll, causing an xrun.

3) my hypothesis

from looking at the implementation of poll in the ALSA kernel code, 
we do not check whether there is the required space/data available
before going to sleep on the descriptor. 

it therefore appears to me that we have a data race on an SMP machine.
if user space goes back into poll in the interval between the playback
stream being marked ready and the capture stream being marked ready,
it has to wait for the next interrupt to wake up, because nothing is
going to realize that in fact, sufficient data is available to skip
the poll_wait() call.

you could narrow the window for the race by using snd_pcm_avail_update()
to check *before* going back to poll(2), but that doesn't eliminate
the race, it just makes it less likely.

i don't know if my hypothesis is correct, but the evidence has all the
character of a data race, and fits my reading of the driver code and
understanding of how the kernel handles poll(2).

comments? did i forget a key item again ? :)

is there any existing code that uses poll(2) for full duplex and
demonstrates working operation?

--p

trace (trident driver, period_size = 64, buffer_size = 2 *
period_size), thread running SCHED_FIFO, mlockall(2) called
successfully, SMP system, running kernel 2.4.0+ll, SR=44.1kHz, period
interval = 1.45msec.
----------------------------------------------------------------------

c? 1 p? 1 poll on 2 fds   <= polling both descriptors
time in poll: 1289.788889 usecs since last = 1489.891111 usecs
playback is ready
capture is ready          <= bingo!
hw avail: c:64 p:66
this time = 64
        contiguous = 64

c? 1 p? 1 poll on 2 fds
time in poll: 1189.177778 usecs since last = 1416.164444 usecs
playback is ready
capture is ready         <= bingo!
hw avail: c:64 p:65
this time = 64
        contiguous = 64

c? 1 p? 1 poll on 2 fds
time in poll: 1292.844444 usecs since last = 1471.657778 usecs
playback is ready
capture is ready        <= bingo!
hw avail: c:64 p:66
this time = 64
        contiguous = 64

c? 1 p? 1 poll on 2 fds
time in poll: 1257.471111 usecs since last = 1448.635556 usecs
playback is ready
capture is ready         <= bingo!
hw avail: c:64 p:65
this time = 64
        contiguous = 64

c? 1 p? 1 poll on 2 fds
time in poll: 1282.644444 usecs since last = 1462.120000 usecs
playback is ready
capture is ready         <= bingo!
hw avail: c:65 p:65
this time = 64
        contiguous = 64

c? 1 p? 1 poll on 2 fds
time in poll: 1245.588889 usecs since last = 1439.144444 usecs
playback is ready             <= ok
ALSA: capture poll timeout    <= oops, we missed capture that time
c? 1 p? 0 poll on 1 fds       <= back to poll, this time just on the capture descriptor
time in poll: 2801.817778 usecs since last = 2932.122222 usecs  <= wake up 2.9msec 
later
capture is ready              <= well yeah, its about time
ALSA I/O: xrun of 70 frames, (1.587 msecs) <= no surpise here, and the
                                              numbers add up as well (1.587 + period 
size =~ 2.9msec)
                




_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to