I've been writing multithreaded apps for quite a bit, and i'm of the opinion that sleep does a fine job of passing control away from a thread, thus allowing others to get to it.

There is however one major downside to using it. It's very inacurate. Sleep(1) will return 1-15ms later, rarely 1. With nothing else happening on the system, the average on my fast computer is 2-3ms, but as soon as something else is going on, it's 10-15ms.

Here's some code to try it out, if you feel like it, start another thread that does something and watch the numbers soar:

Code:
program Project1;

uses
 windows,sysutils;

procedure go_test;
var
 start_tick,end_tick,now_tick,switches,avg_ticks:longint;
begin
 switches:=0;
 start_tick:=gettickcount;
 end_tick:=start_tick+5000;

 repeat
  sleep(1);
  inc(switches);
  now_tick:=gettickcount;
 until now_tick>=end_tick;

 avg_ticks:=(now_tick-start_tick) div switches;

 messagebox(0,pchar('Each 1ms switch took on average '+inttostr(avg_ticks)+'ms'),'Result',mb_ok);
end;

begin
 go_test;
end.