Re: multithreaded mixer
Re: multithreaded mixer
- Subject: Re: multithreaded mixer
- From: Jeff Moore <email@hidden>
- Date: Tue, 3 Feb 2004 15:56:37 -0800
Phiippe presents an excellent case, but unfortunately, it isn't going
to work too well when you push the machine hard. The reason why is that
there is no "politically correct" way to block the IO thread. No matter
how you do it, you are still suspending the IO thread. This mangles the
scheduler's notion of the behavior of the thread. It will appear like
it is running way more often than the scheduling parameters indicate it
should be running. This can cause things to not be pre-emptible when
they should be and will cause timing problems with other real time
threads, such as the IO thread of another device or the threads the
MIDI server and it's clients use.
In short, don't ever block the IO thread. It is number one on the list
of "bad things" you can do.
On Feb 3, 2004, at 12:10 PM, Philippe Wicker wrote:
On Thursday, February 3, 2005, at 05:56 PM, Stefan Werner wrote:
Hi Stefan,
The true question is not wether the IOProc thread may block or not but
how. This thread is already waiting each time it returns from the
IOProc on a lock (or whatever CoreAudio developers decided to use)
which is signaled by the HAL. I'm sure you are aware of this, I want
to remind this - just in case - to be sure that things are clear. The
IOProc thread may block as far as the conditions of this blocking are
totally under your control. For instance you should not call for a
dynamic memory allocation because the code which is then executed uses
a global lock and that a priority inversion may occur. But if you know
for sure that the thread which is currently holding the lock your
IOProc thread is trying to lock is 1) a high priority thread (in that
case a real time constrained thread would be better if not necessary),
2) that the code executed within the context of this thread is
"politically correct" from a real time point of view (no
"uncontrolled" possibly blocking calls while holding the lock), then
you can safely synchronize both threads using semaphores, POSIX
condition variables, etc...
In your case, assuming that you are running your app on a dual
processor machine, I would suggest that you split the AUs into two
groups, each one having its own mixer. One group of AU plus the mixer
constitute a subgraph with its root being the output of the mixer.
Then write a kind of "stub" with 2 inputs and one output. Each stub
input is connected to one mixer output. The stub output is connected
to the IOProc. Within the stub, you need to start 2 real time
constrained threads (let's call them the stub thread 1 and 2).
Rendering of each subgraph will be done in the context of these 2
threads. The synchronization between each stub thread and the IOProc
thread can be done with 2*2 mach semaphores: let's call them ReqSem1/2
and AckSem1/2. More about this later. When a stub thread is woken up,
it should pull the audio from the mixer output (by calling its render
callback) and copy to a local buffer. Now the tricky part. When the
stub "output callback" is called by the HAL, it should store somewhere
the parameters passed to the IOProc (so that they can be read by the
code of stub threads 1 and 2) and signal **both** ReqSem1 and ReqSem2
and then wait on, say, AckSem1. When ReqSem1 and 2 are signaled, stub
threads 1 and 2 are woken up immediately (they are real time
constrained) after IOProc thread call to the wait on AckSem1, and
executes each on one processor (provided than no other real time
thread is ready at the same moment). When stub thread 1 has finished
its rendering it signals AckSem1 and wait again on ReqSem1, same for
stub thread 2 which signals AckSem2 and goto wait on ReqSem2. The
IOProc thread is woken up when AckSem1 is signaled and goto wait on
AckSem2 which may have already been signaled (by stub thread 2) or
will be later when stub thread 2 has finished its rendering. Anyway,
when the IOProc thread returns from the wait on AckSem2 both subgraphs
have been rendered. The IOProc thread has then to mix audio coming
from both subgraphs and then return from its IOProc.
I didn't try this, so this is without any guarantee, but at first
glance it should work.
Philippe.
Hi,
On Tuesday, Feb 3, 2004, at 16:02 Europe/Berlin, David Duncan wrote:
Currently your going to have to spawn threads and buffer the output
yourself.
I was thinking about that, but how do I synchronize my threads when
I'm not supposed to block in IOProcs? Or should I just
assume/hope/wish my other thread gets called in time?
Stefan
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.
Philippe Wicker
email@hidden
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.
--
Jeff Moore
Core Audio
Apple
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.