Archived

This topic is now archived and is closed to further replies.

A sleep function that works

This topic is 5146 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

You need to be a bit more specific about this,
e.g. which OS are you coding for?


// ANSI C - accuracy depending on OS


#include <time.h>

void sleep(int ms) {

clock_t delay = (((clock_t)ms) * CLOCKS_PER_SEC) / 1000;
clock_t start = clock();

while ((clock() - start) < delay);
}



[edit]
Wrong header...
[/edit]


[edited by - darookie on November 10, 2003 2:52:55 AM]

Share this post


Link to post
Share on other sites
It really depends on what exactly you want to do. If you just want the program to accurately pause for a specific amount of time, you can write a function using QueryPerformanceCounter that loops until the specified time has elapsed. Note that by using this method, you''ll be hogging much more CPU time than you would by using the Sleep method (if that matters to you).

Share this post


Link to post
Share on other sites

namespace timer {
int cTime, lTime;

void refresh()
{
lTime=cTime;
cTime=timeGetTime();
}

bool get(int delay)
{
if ((cTime%delay) < (lTime%delay))
return true;
else
return false;
}
}


and to use it its basically


timer::refresh();
if (timer::get(1000))
//do whatever

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ansi''s clock function won''t work since it doesn''t return the system time but rather the amount of time spent in a specific process.
anyway there''s no accurate way to sleep, except perhaps on rtos''s or singletasking systems.

Share this post


Link to post
Share on other sites
One thing you can do is sleep() for a smaller time than desired and then busy wait for the remaining time.


void MySleep(int sleepAmount)
{
Timer t;
t.start();

Sleep( max(0, sleepAmount - SLEEP_RESOLUTION) );

while (t.getTime() < sleepAmount);
}


The resolution of sleep() is about 10 ms for a normal priority thread on WinNT 4/5.

Edit: damn trailing ;

[edited by - jermz on November 10, 2003 12:44:08 PM]

Share this post


Link to post
Share on other sites
I''m programming it for linux, mac, windows.

Right now I just query performance counter, the only problem is that it hogs a bunch of CPU. The Sleep() method would be perfect on windows, except when I say Sleep(1) it doesn''t sleep for a millisecond, it sleeps for 34... it''s bizarre.

I''ve tested it a lot, and I can''t figure out why sleep doesn''t work for me...

Share this post


Link to post
Share on other sites
It is not bizarre, it''s the normal operation of Sleep() for a non-realtime OS. Whenever you call Sleep(X), you are telling the OS you no longer need execution time and would LIKE control back in X ms. The OS will give you control back when it gets the chance, after it takes care of processing all the other processes/threads on the system.

Now 34 ms does seem like a long time to wait for a Sleep(1) call. You could try Sleep(0) which relinquishes the rest of your time-slice but tries to get control back on the next one. Or you could increment the priority of whatever your calling thread is so that normal priority ones don''t interfere as much.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
SDL_Delay()


SDL_Delay:
Wait a specified number of milliseconds before returning. SDL_Delay will wait at least the specified time, but possible longer due to OS scheduling.

It doesn't feature a better resolution than if you'd make your own Sleep() function with clock(). Also, it's silly to include SDL headers just for that single function.

BillyBillyBilly, using a sleep() function isn't really the best way of making your program time-independent. Instead, use delta time to calculate movement (or whatever you need it for). Search the forum.

[edited by - Goldfish on November 11, 2003 7:52:26 AM]

Share this post


Link to post
Share on other sites
according to MSDN,
quote:

The Sleep function suspends the execution of the current thread for at least the specified interval.


I get the impression that the main purpose of the sleep function is to give up your time slice for other processes so that your otherwise CPU intensive programs are more multi-task friendly...

See what happens when you use SleepEx

EDIT: This assumes that you are really trying to create a delay for some reason and your aren't attempting to impliment frame-rate independence... if you're not doing a delay, do what Goldfish says

[edited by - tempuself on November 11, 2003 12:56:41 PM]

Share this post


Link to post
Share on other sites
Why not use a Sleep(0) inside a busy wait to avoid thrashing it too much...



while (clock() < clocksleep_end) { Sleep( 0 ); }


- Scott "me22" McMurray
( email/MSN me22@fastmail.ca ICQ 37213887 )

Share this post


Link to post
Share on other sites
quote:

Why not use a Sleep(0) inside a busy wait to avoid thrashing it too much...
while (clock() < clocksleep_end) { Sleep( 0 ); }



According to this:

quote:

Sleep(1) it doesn''t sleep for a millisecond, it sleeps for 34



clock() will be a good bit past clocksleep_end by the time it gets back.

Ro_Akira

Share this post


Link to post
Share on other sites
As far as I can tell...

a) Sleep(0) returns immediately
b) SleepEx behaves he same way as Sleep

I''m doing this to limit frame rate (my movement is based on elapsed time like it should be). Right now:

LONGLONG Time;
QueryPerformanceCounter((LARGE_INTEGER *)&Time);
ElapsedTime=(FLOAT)(Time-LastTime)*TimerFrequency;
if(ElapsedTime<1.0f/60.0f)
{
// Sleep function would be nice to use here to
// avoid hogging CPU.
continue;
}
LastTime=Time;

It''s not big deal if I can''t get it, it''d just be nice to have my program use 0% of he CPU instead of 99% :-)
-Billy

Share this post


Link to post
Share on other sites
quote:

Sleep(0) returns immediately



Not necessarily.

quote:

...a value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.... - MSDN



If there are other other threads ready to run, they'll eat your time slice.

In any case, how would sleep (0) returning immediately help you?

Ro_Akira

[edited by - Ro_Akira on November 11, 2003 4:41:31 PM]

Share this post


Link to post
Share on other sites
It''s not best to base movement on elapsed time, this is undeterministic and not repeatable. Consider what it takes to replay a saved ''demo''. All of the timing the second iteration must match the original in order for the exact same thing(s) to occur - this will not happen in practice.

To limit the frame-rate, measure the frame-rate and if/when the frame-rate exceeds your cut-off, do a Sleep(1).

You can improve the resolution of the sleep, by using the multi-media function timeBeginPeriod (and timeEndPeriod). You can try to set it as low as 1ms, but on the Compaq''s I work with, the lowest it will go now is ~2ms. Funny, as the computers are getting faster, this value is going up, not down.

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
It's not best to base movement on elapsed time, this is undeterministic and not repeatable. Consider what it takes to replay a saved 'demo'. All of the timing the second iteration must match the original in order for the exact same thing(s) to occur - this will not happen in practice.

To limit the frame-rate, measure the frame-rate and if/when the frame-rate exceeds your cut-off, do a Sleep(1).



I've been thinking about this sense I read it yesterday and I can't really see why it's the "best" method... I agree that the second iteration of a sequence probably would not match the original exactly, and that your method would solve that problem... but does it have any other advantages over frame-rate independent movement?

(correct me if I'm wrong but...) it seems to me that this Sleep(1) method would not work smoothly on as many machines as an elapsed time method would...

For example, in my cheap space invaders clone, all the laser blast movements are a function of time so that one blast will travel from the bottom of the window to the top (400 pixels) in one second (or close to a second)
On machines that are too slow, this will look jerky. However, there are no machines that are so fast that the laser blast will go by too fast to see.

Now, if I tried to implement the Sleep(1) method, my game still would not run on slower machines... But now, I've introduced the possibility of a machine being so fast that you can't see my laser at all... Or am I missing something?



[edited by - tempuself on November 12, 2003 4:11:36 PM]

Share this post


Link to post
Share on other sites
Hello,
It seems elapsed time movement is the best actually. Considering that if you play a game that is about 10 year old on a newer computer that can run it, sometimes the games runs so incredibly fast the player is dead before they''ve even been able to control.

As well, should games cap their frame rates say to...70 frames per second? Well as a lot of id software games show, you can have a demo that runs accurately for a game that runs hundreds of frames per second. It all depends on how you save, load, and replay the demo. It IS deterministic AND repeatable.

Frame rate dependent movement is not the way to go...sometimes though on making some clone game it works well...if you cap the frame rate....
As for repeatable motion, think about interpolation...like with animation. You pick the start and end points of movement, and the start and end points in time and interpolate if you hit different frames. Definitely not the most complex aspect of saving and reloading/replaying a demo.

-Aeroum

Share this post


Link to post
Share on other sites