Thread::yield() performance OS X

I’m having to get a lot of MessageManagerLocks in my program and I noticed that my CPU usage is bouncing all over the place. I used the time profiler and found that sched_yield() is taking up lots of CPU. It is originating from MessageManagerLock::attemptLock when it calls Thread::yield().

I did some reading around and found that sched_yield() can take up CPU if there is nothing available to yield to. I simply switched the sched_yield() in Thread::yield() to a sleep (1) and I’m getting much better CPU usage:

[attachment=0]Screen Shot 2012-12-14 at 2.34.37 PM.png[/attachment]

EDIT: I’m using OS X 10.8.2

Better would be not to take the message manager lock. Is it absolutely necessary? Couldn’t it be done a different way?

I never really thought about trying to get rid of the MessageManagerLock. I will look into that right now.

That being said, would the yield function actually be better off with sched_yield() rather than a sleep function of whatever timing?

If you can explain why you’re taking the lock I will attempt to come up with an alternative.

No clue, really.

Looking over MessageManager::attemptLock…wow…I would stay far away from that function it is doing a hell of a lot! This is nothing like a CriticalSection, it is tying up the entire event loop by posting a custom message to the system queue.

I have some components that regularly request data from another thread that I want to avoid blocking. These components are requesting the data and then waiting for a response from the non blocking thread. They then need to draw themselves ASAP which is where I was waiting for the MessageManagerLock. I’m changing them now so that they call redraw on an async update instead to see how that works.

You should redraw on an async update :lol:

Alright, thanks for the suggestion.

Actually, now I remember that AsyncUpdater::triggerAsyncUpdate can block the audio thread / calling thread. The reason is that internally it calls SendMessage (on Windows at least). That’s why in VFLib, for the GuiCallQueue I use a separate thread for calling triggerAsyncUpdate, and use a vf::CallQueue to activate it.

I’ve been thinking about this in the context of audio plugins lately, so I thought I’d post my notes on this on a new thread here.

Dead link!

1 Like