of WaitNextEvent and Thread Priorities and Ceiling Whacks

In 9 everything is easy: don't call WNE unless your life depends on it .

But I remember hearing a while back on mac-games-dev that in X, not calling WNE results in the thread scheduler downgrading your thread's priority. IIRC the outcome of this whole discussion was that when in X, unless you're using CarbonEvents, you should call WaitNextEvent with a sleep time of 1. Does anyone have supporting evidence for this?

It was never quite cleared up precisely what happens to you if you don't give the OS time, but enough people report enough bad stuff happening for me to believe them . One thing you can rely on is getting a spinning beach-ball cursor.

On OS 9, calling WaitNextEvent(0) was also a reasonable option -- the system got time, but you got control back ASAP. Many games successfully used this route. OS X, however, has a special case on WNE(0) to replace the 0 with a much longer sleep time. This was an attempt to "fix" many older applications' CPU usage without forcing a recompile.

If you call WNE(1), you should avoid the special case, and avoid any penalization for not giving the OS time. However, you will not, under any circumstances, be returned control before that 1/60th of a second is up, even if nobody else needs the CPU time.

The solution to all of this is, of course, Carbon Event timers. Set up a timer to fire every millisecond, so you'll be called back as often as the scheduler allows, and either pass a very long sleep time to WNE, or use RunApplicationEventLoop. The very high-frequency timer means that if nothing else requires the CPU, you will get it. Because you spend all the time you can blocked in RAEL, you won't be punished.

If you find that even with Carbon Event timers and RAEL you're still getting a jerky frame-rate when other programs are running, there is a way to put yourself on fixed-frequency scheduling. That means that, although you don't get any more CPU time than normal, you are guaranteed to get it regularly. Most people won't find this necessary, but some people have reported good success with it. You'll need to search the archives of the mac-games-dev list to find out how: http://lists.apple.com

There's also a very detailed discussion of precisely how the OS X scheduler works on that list.

This reports up to 100% usage in ProcessViewer while in front (basically uses as much as it needs), and 0-5% in the background. You can actually take it one step further and use a wait of "kEventDurationForever" if the app is hidden, but that could mess up stuff in the main loop that requires semi-regular updates (like networking). I've haven't seen any OSX scheduler "bullying" problems (or beachballs) using this loop.

I found that RAEL with a timer running frames is *too* generous to background tasks and generally unreliable. RAEL is easier to use however, and handles nitty-gritty stuff that you need to take care of manually with RNE (apple events, menus, etc.) so it should be fine for puzzle-type games where a consistant frame rate isn't that important.