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