Q: Hey, I'm spending a lot of time spinning in the graphics driver, waiting for a page flip, because I'm v-synced. Wouldn't it be better to Sleep() away that time, to give up some CPU to other applications?

A: That should work, with some caveats. I'm assuming Windows here (because otherwise you'd be talking about usleep() :-)

What you're doing is trying to make a time-sharing consumer OS do what's basically a real-time task. This isn't super easy, but can be done with some success.

Sleep()-ing is very jittery on DOS-based Windows. At best, you get +/- 20 ms precision, which is too low to use for interactive applications that want smooth frame rate. So detect Win98/ME and turn off sleeping, or have a check-box to turn it off.

Sleep() signals to the OS that you have nothing better to do, which will cause SpeedStep CPUs to slow down. Unfortunately, this means that your main loop will run at the slower speed, so you'll be falling behind, and won't be sleeping. Finally, the OS will notice you're not sleeping, and up the CPU speed. Then you'll start sleeping again, and the OS turns on SpeedStep... Detect SpeedStep and turn off sleeping, or have a check-box to turn it off.

Sleep() may wake up later than you tell it to (as I said, jitter), although it's pretty good on NT-based Windows (such as Windows XP). Thus, I'd set a wake-up point about 2 milliseconds before when I need to swap frames, and just accept that I'll be spinning for 2 milliseconds each frame (minus wake-up delay). If there's less than 2 ms left before flipping, don't sleep at all. You may find that wake-up precision is better if you raise the priority class of your application and the priority of your thread.

Sleep() does not wake up if there are windows events waiting for your window. For better interactivity, you may want to create an event that you never set, and then call MsgWaitForMultipleObjectsEx() with a time-out. This is known as an "alertable" sleep, and will wake you up if there are suddenly events delivered to your application (such as mouse movement). You could even run your Windows message pump that way: sleep and/or handle messages until 2 milliseconds before it's time to flip; then flip; then handle any remaining Windows messages before you go on to simulate and render the next frame.

Good luck!