Re: [Alsa-devel] Re: [linux-audio-dev] Re: minimum tick time

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [Alsa-devel] Re: [linux-audio-dev] Re: minimum tick time
From: Paul Davis (pbd_AT_Op.Net)
Date: Thu Nov 08 2001 - 05:27:47 EET


>I think I know the source of Maarten's question. In the
>alsa-lib/test/latency.c the "readbuf" routine has the following code:
>
> do {
> r = snd_pcm_readi(handle, buf, len);
> } while (r == -EAGAIN);
>
>For the non-blocking case this would take up 100% of the CPU time. I
>wrote about this before on the alsa-devel list. Since its running in
>SCHED_RR it tends to not let anything else run while it does (i.e.
>machine freezes, except for sound output). So I believe the question
>Maarten is asking, is how do I program a low latency audio application
>without hogging the CPU. I think the answer is poll. The reason I
>believe he was asking about increasing the system timer interval, is the
>assumption was that poll was limited to the interval of the system
>timer. I don't believe this is the case though, but to be honest don't
>really know how an application would get scheduled to wake up once ALSA
>is ready to send/receive a chunk of audio.

Ah, OK. yes, i suppose this might not be clear.

when you set the size of a "period" in ALSA, you are basically setting
the interval at which the h/w will interrupt the host system to notify
it that space/data is available. so, if you set it for 128 frames at
48kHz, when the h/w will interrupt us every 2.3msec.

if you call poll(2) on the file descriptors returned by
snd_pcm_poll_descriptors() (and there may be more than one for some
kinds of PCM "devices"), then what you're actually doing is this:
      
      * tell the kernel that the thread calling poll(2) wants
         to sleep until either space and/or data is available (whether
         its space or data will depend on which stream the PCM handle
         is for and whether you use POLLIN or POLLOUT)

now, when the h/w interrupts the host system, the ALSA drivers handle
it, and one of the things that the interrupt handler will do is to
mark any threads waiting on space/data as ready to run. so, at some
point in the future, the thread that was sleeping inside the poll(2)
call is now scheduled back onto a processor, and continues to run
(i.e. calls code to actually move data to/from the h/w).

so, the net result is that your thread can be woken up at regular
intervals by the kernel, as a result of the audio h/w interrupt. where
low latency comes into play is in helping to limit the time between
the interrupt handler marking your thread as ready to run, and the
thread actually running again. if your thread is using SCHED_FIFO or
SCHED_RR, then essentially at the completion of the interrupt handler,
your thread will be scheduled to run again, which is way better than
if its in the default SCHED_OTHER scheduling class. this is important,
because a low period sizes, you've got very little time (perhaps as
low as 0.66msec for 64 frames at 96kHz) to (1) get scheduled (2) run
your code (3) tell the driver that you did whatever you did. if it
doesn't happen in time, and another interrupt arrives, there's a
chance that you're in xrun territory (depending on a number of
things). linux (and almost all "general purpose" OS's) are simply not
set up to handle this kind of thing "by default". in the linux case,
this is easily fixed by applying the low latency patch and enabling
it.

the system timer has *nothing* to do with this mechanism
whatsoever. the scheduling relies entirely on (1) the h/w interrupt
and (2) the interval between your thread being marked ready to run by
the interrupt handler and it actually running again.

--p


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Thu Nov 08 2001 - 05:27:52 EET