Albert Santoni wrote: > Hi Bjorn and Pau, > > Thanks for the enlightening responses. After thinking about what you've > both written for a day, I have a few more questions: > > 1) It looks like the watchdog thread attempts to run at higher priority > than the callback thread, so it can do its job. However, when the > callback thread is running with realtime priority, what priority does > the watchdog thread run with? I'm wondering if the watchdog thread can't > do its job if you have a realtime priority callback thread. If that's > true, then if you have a series of callback underruns (ie. they don't > finish in time), more and more callback threads might be created, and > you might unintentionally end up with the equivalent of a fork-bomb. > (Too many threads crashing the kernel... ?) In Linux there are 99 priority levels for SCHED_FIFO (so called realtime) threads. It is common practice to run a watchdog thread with higher priority when you use SCHED_FIFO threads. The operating system will always make sure that a higher priority thread will preempt a lower one once it becomes runnable (e.g. when it's timer expires).
> > 2) Besides Ross Bencina's notes on lock-free and wait-free algorithms > ( http://www.audiomulch.com/~rossb/code/lockfree/ ), are there any good > resources people can recommend on the topic? (Books, websites, etc.) http://www.google.com/search?q=yann+orlarey+lock+free should give you a head start. Not easy material though. > > 3) In Mixxx, there are two spots where we dump audio from the callback > into a separate worker thread, and in order to notify the worker thread > that there's data that needs processing, we use a QWaitCondtion. The > QWaitCondition requires the use of a QMutex around calls to it, so we > end up locking/unlocking this mutex in the callback thread (bad). Is > using something like PortAudio's ringbuffer an appropriate solution for > eliminating the mutex/wait condition in this situation? QWaitCondition is probably some sort of wrapper around a phread conditional variable, which indeed needs a mutex to avoid problems. Although this is not strictly required if you have a single writer/single reader setup if I remember correctly. The better way might be to use a semaphore that is increased by the realtime thread. Signaling a semaphore should be realtime safe, and the other thread can block on it. The combination of a lock-free ringbuffer and a semaphore can give you what you need. In an answer to your original question: if portaudio kills the thread at underrun, it should also provide a cleanup callback to recover from the scenario you describel, or it has a broken design. Unless of course the API specifies that you're not allowed to do this stuff in the callback. It would be a very strange design if portaudio were to kill the thread and spawn a new one. OTOH it's a problem that is not solved in e.g. jack either: if an application decides not to return from a callback, jack completely messes up. Greets, Pieter > > Thanks again, > Albert > > > On Thu, 2008-04-24 at 09:28 -0400, Bjorn Roche wrote: >> Albert, >> >> I'm not sure I understand exactly what you're wanting to know, and >> I'm no longer an expert on the watchdog thread since I don't work on >> the platforms that use it anymore, so you'll have to take what I say >> with a grain of salt. The watchdog thread, IIRC, only kills the >> callback thread if the callback is overrunning the CPU, and seriously >> blocking lower priority threads from getting anything done at all for >> a significant period of time, as detected by the so-called "canary" >> thread. This is not the standard buffer underrun scenario. It's really >> a disaster-prevention scenario, eg if your callback gets stuck in a >> loop, making the computer completely unresponsive. The only time I've >> seen it kill my thread is when I've made a programming error resulting >> in a total system freeze up for three (?) seconds (including mouse >> movements), in which case it's a real godsend. It may not be necessary >> in the future, because of design improvements in Linux, which will >> hopefully be picked up by other OSes: >> >> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/scheduler/sched-rt-group.txt;h=1c6332f4543c350889eae9ba2b4c766270c1b65e;hb=HEAD#l38 >> >> As for what happens when an underrun occurs, it's possible that a new >> thread is launched on some platforms and the old one is killed, I >> don't know. This doesn't happen on Linux (OSS, ALSA or JACK) AFAIK, >> but I could be wrong. It's possible that this does happens on the mac >> OS -- I wrote the code and couldn't tell you because, AFAIK, it >> doesn't say in the Core Audio docs -- but creating a new thread is >> expensive and unbounded and I don't know why they would do it when >> they are already falling behind. Older platforms don't even use >> "threads", they use interrupts, so you should not expect each callback >> to occur on the same thread unless you know something about your >> platform. I imagine other techniques are possible as well, so I >> suspect newer OSes may not use threads either, but I am having a hard >> time imagining what that would be (still, I wouldn't rule it out >> unless an OS expert knows better). It seems to me that it's possible >> that on such platforms, you could have multiple simultaneous callbacks >> during an underrun condition, at least in theory, but I think I would >> consider such a platform broken. >> >> That said, it is widely known to be bad multithreaded programming to >> kill a thread at random (unless a seeming disaster has occurred, like >> a thread has caused your machine to deadlock, in which case you should >> probably exit right away because something really bad just happened) >> rather than wait for the thread to complete, so if an implementation >> was not waiting for your callback to complete for any reason other >> than disaster avoidance I would consider that a bug in the >> implementation. I can't say there are no bugs in any of the >> implementations, but my assumption has always been that callbacks will >> complete, because if they didn't I would file a bug report. >> >> I assume you are aware of the issues relating to using mutexes in a >> realtime thread. >> >> I hope that answers your question. >> >> bjorn >> >> >> On Apr 24, 2008, at 4:50 AM, Pau Arumí Albó wrote: >>> (This mail was already sent to mixxx-devel. I realized that portaudio >>> was also at the Cc when received an "subscribers-only" bounce. >>> So now resending it now after subscription) >>> >>> >>> El dc 23 de 04 del 2008 a les 10:11 -0400, en/na Albert Santoni va >>> escriure: >>>> Hi guys, >>>> >>>> I've got a question that I haven't been able to conclusively >>>> answer, and >>>> I was wondering if someone could shed some light on an answer. >>>> >>>> When a buffer underrun occurs, what happens to that instance of the >>>> callback thread? >>>> >>>> To elaborate, consider a case where the soundcard has requested >>>> audio, >>>> so the PA callback function gets called and your program runs off and >>>> processes whatever audio it has to as quickly as it can. If your >>>> program >>>> can't process quickly enough, what happens exactly? Does the initial >>>> callback thread get killed, and another one started immediately >>>> after? >>>> Does another callback thread simply get called? >>>> >>>> The reason this concerns me is because if the callback thread gets >>>> killed (if that's what happens during a buffer underrun) while it is >>>> waiting on a mutex, I'm afraid it could leave the mutex in some >>>> undetermined state, deadlocking my application. >>>> >>>> If anyone could offer any advice or insight, it would be much >>>> appreciated. >>>> >>>> Thanks, >>>> Albert >>> I've always guessed that in that case the audio process terminated >>> somehow. Being curious about it i've looked at PortAudio code to see >>> the >>> details. (this code from track corresponds to an old version, but i >>> guess that the same technique also applies to the trunk) >>> >>> http://www.portaudio.com/trac/browser/portaudio/trunk/pa_unix_oss/pa_unix_oss.c?rev=115#L563 >>> >>> So what happens is that a watchdog thread running with higher priority >>> is set up and it kills the audio thread ONLY if it is reading/writing >>> audio from 3 seconds behind the audio driver time. >>> >>> Ok, but during these 3 long seconds you can have underruns anyway. >>> What >>> i _deduce_ is that while in this 3 sec safety window callbacks are not >>> killed, and at termination, the new callback will contain the more >>> recent buffers. Then the callback flags will tell you if something >>> nasty >>> happened: skipped a writing deadline, skipped an input buffer... >>> >>> That's how i understand it - but a PortAudio developer could be more >>> assertive. >>> >>> So i believe you can be confident on the state of the mutex. But >>> anyway, >>> why to use a mutex inside a real-time thread?? Couldn't this be done >>> with lock-free techniques? >>> >>> Regards, >>> >>> Pau >>> >>> >>> >>> >>> _______________________________________________ >>> Portaudio mailing list >>> [EMAIL PROTECTED] >>> http://techweb.rfa.org/mailman/listinfo/portaudio >> ----------------------------- >> Bjorn Roche >> XO Wave >> Digital Audio Production and Post-Production Software >> http://www.xowave.com >> http://blog.bjornroche.com >> http://myspace.com/xowave >> >> > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference > Don't miss this year's exciting event. There's still time to save $100. > Use priority code J8TL2D2. > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone > _______________________________________________ > Mixxx-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/mixxx-devel ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ Mixxx-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mixxx-devel
