[chuck-dev] Big Nasty Mutex (tm) + Jack + ChucK evilness

Dave Robillard drobilla at connect.carleton.ca
Mon Mar 14 23:35:59 EST 2005


On Mon, 2005-14-03 at 03:05 -0500, Ge Wang wrote:
> I must confess.  I don't know Jack.
> 
> So...
> 
> Before we, heh, re-implement ChucK and RtAudio, I would like to
> know the following, at least:
> 
> 1. Why is the mutex actually bad?  More specifically, how exactly
> does it cause Jack to fail or zombie?  ChucK does not call RtAudio
> from multiple threads, so the mutex shouldn't be blocking at all.
> 
> 2. If the concern is things taking too long in the callback, how does
> putting audio synthesis in the callback help?  The current scheme
> has the audio pre-computed before the callback.  Putting the most
> time consuming part of ChucK inside the callback will more likely
> delay the callback.
> 
> Dave, you said that replacing blocking I/O with computing audio in
> callback makes things robust, regardless of load.   How does Jack
> know the difference between the callback blocking versus just taking
> a long time computing audio?  I am clearly missing something here.
> 
> Related question:
> 
> 3.  Under what conditions does Jack decide to boot a process?
> 
> 4. If our blocking scheme is the problem, then why doesn't sndpeek
> work?  The callback just copies the input buffer and returns.

I think sndpeek might have seperate issues.   I've never even managed to
get a window to display for any amount of time, realtime or no.


> The current scheme
> has the audio pre-computed before the callback.  Putting the most
> time consuming part of ChucK inside the callback will more likely
> delay the callback.

I would rephrase it: "The current scheme MIGHT have the audio
pre-computed before the callback".  This is one of those things best
explained with questions:

- How do you know your thread is going fast enough?  Or even too fast?
- How do you know how much audio is actually demanded of you?
- What about offline processing?  (in theory)
- Who gets more scheduling priority?  Your thread?  Jack thread?
- Will usleep() return on time?  Will pthread_mutex_lock()?  Will the
synthesis thread get back in time?
- What does "in time" mean anyway?  How much time do we really have?

The answer to every one of these question is "I dunno".  It's all about
determinism.  Not really a specific Jack thing, it's just hard realtime
requirements.

pthread_mutex_lock is not deterministic.  usleep() isn't deterministic
(it is perfectly acceptable for usleep(1) to sleep for 10 /seconds/ if
it wants to).  Whether or not the other thread makes it back in time is
not deterministic.

The problem with attempting to wait on the other thread is - how long
can you wait?  You have no way of knowing what an acceptable time to
wait is.  Jack does, but you don't.  So, if you don't wait long enough,
you won't get your audio.  If you wait too long, jack will kick you out.
Having the other realtime thread running in parallel causes a whole
whack of scheduling problems too, which might be a cause of a lot of the
problems (I'm no kernel hacker) - the idea behind Jack is that there
is /one/ realtime priority audio thread that does everything and knows
what is going on, that's where the robustness comes from.

I find the best way to think about it is in terms of offline processing,
ie everything moving reeally slowly - imagine the audio callback being
called every 5 seconds.  Everything should still function perfectly well
(gigantic queues of timestamped events aside).  Currently you'd have a
realtime thread going crazy, generating way, way too much audio with
nowhere to store it (of course, the opposite is what's happening right
now).  Everything is so, so much nicer when the audio callback just says
"compute and give me 64 samples now".

To be honest, I don't know exactly when jack will decide it's had enough
of misbehaving clients, I'm not a jack developer.  I understand what you
mean, time is time.  Unfortunately it doesn't work that way, but I
freely admit to not really knowing how jack itself knows the difference.
I assume the lack of determinism just rears it's ugly head the your
callback takes too much time, but there could be more clever things
going on.  No idea - I just know that making the audio callback
deterministic is what you have to do (ie it's a known requirement
documented alongside Jack's API), and that my personal experience (and
reading code) has backed that up.

It's easy to get bitter at Jack for being more picky about these things,
but realtime systems should be coded properly regardless - determinism
is king.  I'm sure that on OSX if you run ChucK alongside a few other
audio programs and really thrash the CPU, you'll get lots of dropouts as
well.  Ever tried it?  (I don't have a Mac)

Sorry if I don't understand this stuff very well at a super-low level, I
just know what I have to know as an app developer..  I learned all this
the hard way, that's for sure.

Cheers,

-DR-

P.S.  I unintentionally come off sounding really negative here..  I
really think ChucK is the greatest thing since sliced bread.  Bravo. :)



More information about the chuck-dev mailing list