How to sleep accurately

BCS ao at pathlink.com
Thu Jun 28 10:14:51 PDT 2007


Reply to Jason,

> I've been trying for a while now to get a sleep routine that actually
> works as I expect it to (sleeping for the time specified within a
> practical error margin).
> 
> Let's say you want to sleep for 0.1 seconds (wall clock).
> 
> msleep(100); // Not available under linux
> 
> usleep(100000); // Not guaranteed to be reentrant...
> 
> timespec ts;
> ts.sec = 0;
> ts.nsec = 100000000;
> nanosleep(ts,cast(timespec)null); // Thread safe
> Unfortunately, all of those can be interrupted by signals (such as the
> garbage collector running).  Ignoring the reentrant issue (which seems
> to not affect stuff in practice), I tried the following:
> 
> time_t now = clock();
> time_t stop = now + 100000/CLOCKS_PER_SECOND;
> while(now<stop){
> usleep(stop-now);
> now = clock();
> }
> On windows, that seemed to work.  Under linux, clock() keeps returning
> zero!  It appears that it returns the process time that elapsed since
> the last call to clock rather than using any kind of absolute
> reference and is useless.
> 
> Does anyone have a good way of doing this?
> 

if you are on x86 and if you can get the clock speed and if you don't mind 
asm you can get a clock cycle resolution busy wait using:

|long first,stop;
|asm
|{
|  rdtsc;
|  mov first, EAX;
|  mov 4+first, EDX;
|}
|
|stop = first + TimeInCPUCycles();
|
|while(first < stop)
|  asm
|  {
|    rdtsc;
|    mov first, EAX;
|    mov 4+first, EDX;
|  }




More information about the Digitalmars-d-learn mailing list