Sign in to follow this  

[C++] Cross-platform timing / sleep functions?

This topic is 3662 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

I'm writing some code using boost::thread, and one thing I want is to make a thread sleep - for instance in a thread which runs a loop. boost::thread::sleep() looks good but apparently only has resolution of one second. I don't need nanosecond resolution, but a few milliseconds would be nice. So using standard C/C++ libraries, and boost, what is the simplest way to make a thread sleep? I am finding the boost documentation really unhelpful in layout as well as content so if you are able to provide code it would save me a bunch of time! Thanks.

Share this post


Link to post
Share on other sites
After poking around a bit in the cvs for boost::thread I saw that xtime structure supposedly has two fields: sec and nsec. However, what these values are filled with seems to depend on what clock boost decides to use. Basically here's the source. On a cursory glance it looks like it checks for if certain timers exist and then uses them. The first it checks for is a windows function and it looks like, in that case, it uses it (and is in the millisecond range). So if you haven't already tried using the nsec field of xtime go ahead and see if that helps. Be sure and check for overflow, though.

If that doesn't work you may need to rewrite the xtime_get function.

Hope that helps.

Share this post


Link to post
Share on other sites
time() is the closest thing to a standard timing function in C++.

Standard C++ doesn't recognise the existance of threads. If you are using threads you are by definition going beyond the standard libraries. Consequently there are no sleep functions.

I don't know enough about boost to know if it has a better solution than the one you found. One possible, if somewhat out there, solution might be to use select() from the socket API. This is probably portable enough - as in it's "in the box" and doesn't need a third-party library for virtually all modern OS's/compilers. The Windows case would require a small amount of non-portable initialization code.

Share this post


Link to post
Share on other sites
Quote:
Original post by nobodynews
After poking around a bit in the cvs for boost::thread I saw that xtime structure supposedly has two fields: sec and nsec.
I missed the nsec attribute, in fact I only found it looking at the non-official boost documentation!

I'll try it a bit later... I only have access to a windows pc though. However, cross-platform is not a requirement at this point, and if it tuns out to be a problem on linux/mac we'll solve it then.

I'll report back if it works as expected...

Share this post


Link to post
Share on other sites
I haven't checked the newest version of boost, but in the version 1.33.1, timers used for threading were barely usable for real time applications. Windows implementation was based on GetSystemTimeAsFileTime which is unable to sleep for less than 15 ms.

That xtime structure comes from Linux high performance counter gettimeofday and it is the best possible timer on Linux platform but on Windows they chose to ignore timeGetTime (1 ms precision) and QueryPerformanceCounter (which is the equivalent to Linux gettimeofday) because of various issues (QPC has problems with multicore CPUs, timeGetTime isn't any better than GetSystemTimeAsFileTime without manual setup through timeBeginPeriod). The choice of xtime is quite unfortunate for Windows users, because it requires additional conversion from that structure's fields to those expected by GetSystemTimeAsFileTime.

The upcoming C++0x has a very nice timing library but who knows when it will become widely supported. For our application, the best choice was to ignore boost timers and implement our own platform specific timing code.

Share this post


Link to post
Share on other sites
Actually QueryPerformanceCounter is fine on Intel chips with multiple cores, only problem I ran into was with AMD chips. But if you run one high precision timer on a dedicated core your times will be stable without major issues (from being bounced between cores).

I fall back to timeGetTime() which is great for 1-3ms resolution depending on what you set timeBeginPeriod() too. Which I don't see the big deal, you call it once on application start and once on finish (works for me)

Share this post


Link to post
Share on other sites
Well using the latest Windows boost libs, 1.34.1, boost::xtime seems to give me a resolution of about 15ms. I'm not sure if that is adequate for my use.

However I wondered how the boost sleeping works. If I do:
boost::xtime xt;
boost::xtime_get(&xt,boost::TIME_UTC);
xt.nsec += 1;
boost::thread::sleep(xt);


Then presumably it will sleep until the time is AT LEAST xt - in other words instead of sleeping for 1ns it will sleep for 15ms?

Share this post


Link to post
Share on other sites
Take a look at 'thread.cpp' from the boost thread library sources (the source code of boost thread library is quite easy to follow, unlike many other boost libs).

It reads the current time, subtracting it from the xtime you provided to gain deltatime and then it uses Win32 API Sleep call. So there are a lot of conversions going on in the background from GetSystemTimeAsFileTime data to xtime data and the timer is invoked twice, once by you to specify sleep period and once again by boost::thread::sleep call.

However, everything works out nicely if you are using it on Linux platform. You'll also notice that boost thread library was designed to be more akin to POSIX threads than Windows threads.

Share this post


Link to post
Share on other sites

This topic is 3662 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this