238 lines
6.5 KiB
C++
238 lines
6.5 KiB
C++
// timeval_demo.cpp ----------------------------------------------------------//
|
|
|
|
// Copyright 2008 Howard Hinnant
|
|
// Copyright 2008 Beman Dawes
|
|
// Copyright 2009 Vicente J. Botet Escriba
|
|
// Copyright (c) Microsoft Corporation 2014
|
|
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// See http://www.boost.org/LICENSE_1_0.txt
|
|
|
|
/*
|
|
This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
|
|
was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
|
|
Many thanks to Howard for making his code available under the Boost license.
|
|
The original code was modified to conform to Boost conventions and to section
|
|
20.9 Time utilities [time] of the C++ committee's working paper N2798.
|
|
See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
|
|
|
|
time2_demo contained this comment:
|
|
|
|
Much thanks to Andrei Alexandrescu,
|
|
Walter Brown,
|
|
Peter Dimov,
|
|
Jeff Garland,
|
|
Terry Golubiewski,
|
|
Daniel Krugler,
|
|
Anthony Williams.
|
|
*/
|
|
#define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness
|
|
|
|
#include <boost/chrono/chrono.hpp>
|
|
#include <boost/type_traits.hpp>
|
|
|
|
#include <iostream>
|
|
|
|
#if defined(BOOST_CHRONO_MAC_API)
|
|
#include <sys/time.h> //for gettimeofday and timeval
|
|
#endif
|
|
|
|
#if defined(BOOST_CHRONO_WINDOWS_API)
|
|
# include <windows.h>
|
|
#endif
|
|
|
|
#if defined(BOOST_CHRONO_WINDOWS_API)
|
|
|
|
namespace
|
|
{
|
|
#if defined UNDER_CE || BOOST_PLAT_WINDOWS_RUNTIME
|
|
// Windows CE and Windows store does not define timeval
|
|
struct timeval {
|
|
long tv_sec; /* seconds */
|
|
long tv_usec; /* and microseconds */
|
|
};
|
|
#endif
|
|
|
|
int gettimeofday(struct timeval * tp, void *)
|
|
{
|
|
FILETIME ft;
|
|
#if defined(UNDER_CE)
|
|
// Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
|
|
SYSTEMTIME st;
|
|
::GetSystemTime( &st );
|
|
::SystemTimeToFileTime( &st, &ft );
|
|
#else
|
|
::GetSystemTimeAsFileTime( &ft ); // never fails
|
|
#endif
|
|
long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
|
|
# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
|
|
t -= 116444736000000000LL;
|
|
# else
|
|
t -= 116444736000000000;
|
|
# endif
|
|
t /= 10; // microseconds
|
|
tp->tv_sec = static_cast<long>( t / 1000000UL);
|
|
tp->tv_usec = static_cast<long>( t % 1000000UL);
|
|
return 0;
|
|
}
|
|
} // unnamed namespace
|
|
|
|
#endif
|
|
|
|
// timeval clock demo
|
|
// Demonstrate the use of a timeval-like struct to be used as the representation
|
|
// type for both duraiton and time_point.
|
|
|
|
namespace timeval_demo
|
|
{
|
|
|
|
class xtime {
|
|
private:
|
|
long tv_sec;
|
|
long tv_usec;
|
|
|
|
void fixup() {
|
|
if (tv_usec < 0) {
|
|
tv_usec += 1000000;
|
|
--tv_sec;
|
|
}
|
|
}
|
|
|
|
public:
|
|
|
|
explicit xtime(long sec, long usec) {
|
|
tv_sec = sec;
|
|
tv_usec = usec;
|
|
if (tv_usec < 0 || tv_usec >= 1000000) {
|
|
tv_sec += tv_usec / 1000000;
|
|
tv_usec %= 1000000;
|
|
fixup();
|
|
}
|
|
}
|
|
|
|
explicit xtime(long long usec)
|
|
{
|
|
tv_usec = static_cast<long>(usec % 1000000);
|
|
tv_sec = static_cast<long>(usec / 1000000);
|
|
fixup();
|
|
}
|
|
|
|
// explicit
|
|
operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
|
|
|
|
xtime& operator += (xtime rhs) {
|
|
tv_sec += rhs.tv_sec;
|
|
tv_usec += rhs.tv_usec;
|
|
if (tv_usec >= 1000000) {
|
|
tv_usec -= 1000000;
|
|
++tv_sec;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
xtime& operator -= (xtime rhs) {
|
|
tv_sec -= rhs.tv_sec;
|
|
tv_usec -= rhs.tv_usec;
|
|
fixup();
|
|
return *this;
|
|
}
|
|
|
|
xtime& operator %= (xtime rhs) {
|
|
long long t = tv_sec * 1000000 + tv_usec;
|
|
long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
|
|
t %= r;
|
|
tv_sec = static_cast<long>(t / 1000000);
|
|
tv_usec = static_cast<long>(t % 1000000);
|
|
fixup();
|
|
return *this;
|
|
}
|
|
|
|
friend xtime operator+(xtime x, xtime y) {return x += y;}
|
|
friend xtime operator-(xtime x, xtime y) {return x -= y;}
|
|
friend xtime operator%(xtime x, xtime y) {return x %= y;}
|
|
|
|
friend bool operator==(xtime x, xtime y)
|
|
{ return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
|
|
|
|
friend bool operator<(xtime x, xtime y) {
|
|
if (x.tv_sec == y.tv_sec)
|
|
return (x.tv_usec < y.tv_usec);
|
|
return (x.tv_sec < y.tv_sec);
|
|
}
|
|
|
|
friend bool operator!=(xtime x, xtime y) { return !(x == y); }
|
|
friend bool operator> (xtime x, xtime y) { return y < x; }
|
|
friend bool operator<=(xtime x, xtime y) { return !(y < x); }
|
|
friend bool operator>=(xtime x, xtime y) { return !(x < y); }
|
|
|
|
friend std::ostream& operator<<(std::ostream& os, xtime x)
|
|
{return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
|
|
};
|
|
|
|
class xtime_clock
|
|
{
|
|
public:
|
|
typedef xtime rep;
|
|
typedef boost::micro period;
|
|
typedef boost::chrono::duration<rep, period> duration;
|
|
typedef boost::chrono::time_point<xtime_clock> time_point;
|
|
|
|
static time_point now();
|
|
};
|
|
|
|
|
|
xtime_clock::time_point
|
|
xtime_clock::now()
|
|
{
|
|
#if defined(BOOST_CHRONO_WINDOWS_API)
|
|
timeval tv;
|
|
gettimeofday(&tv, 0);
|
|
xtime xt( tv.tv_sec, tv.tv_usec);
|
|
return time_point(duration(xt));
|
|
|
|
#elif defined(BOOST_CHRONO_MAC_API)
|
|
|
|
timeval tv;
|
|
gettimeofday(&tv, 0);
|
|
xtime xt( tv.tv_sec, tv.tv_usec);
|
|
return time_point(duration(xt));
|
|
|
|
#elif defined(BOOST_CHRONO_POSIX_API)
|
|
//time_point t(0,0);
|
|
|
|
timespec ts;
|
|
::clock_gettime( CLOCK_REALTIME, &ts );
|
|
|
|
xtime xt( ts.tv_sec, ts.tv_nsec/1000);
|
|
return time_point(duration(xt));
|
|
#endif // POSIX
|
|
|
|
}
|
|
|
|
void test_xtime_clock()
|
|
{
|
|
using namespace boost::chrono;
|
|
std::cout << "timeval_demo system clock test\n";
|
|
std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
|
|
std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
|
|
std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
|
|
xtime_clock::duration delay(milliseconds(5));
|
|
xtime_clock::time_point start = xtime_clock::now();
|
|
|
|
while (xtime_clock::now() - start <= delay)
|
|
{
|
|
}
|
|
xtime_clock::time_point stop = xtime_clock::now();
|
|
xtime_clock::duration elapsed = stop - start;
|
|
std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
|
|
}
|
|
|
|
} // timeval_demo
|
|
|
|
int main()
|
|
{
|
|
timeval_demo::test_xtime_clock();
|
|
return 0;
|
|
}
|
|
|