|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r49923 - in sandbox/chrono: boost/chrono libs/chrono/src libs/chrono/test/chrono_msvc/await_keystroke libs/chrono/test/chrono_msvc/time2_demo
From: bdawes_at_[hidden]
Date: 2008-11-24 15:59:54
Author: bemandawes
Date: 2008-11-24 15:59:53 EST (Mon, 24 Nov 2008)
New Revision: 49923
URL: http://svn.boost.org/trac/boost/changeset/49923
Log:
Chrono: add clock now() error_code& argument for error handling. No test cases yet.
Text files modified:
sandbox/chrono/boost/chrono/chrono.hpp | 38 +++++++++++++++++++++++++++++++++++---
sandbox/chrono/boost/chrono/timer.hpp | 6 ++----
sandbox/chrono/libs/chrono/src/chrono.cpp | 30 +++++++++++++++++++++---------
sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj | 4 ++++
sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj | 4 ++++
5 files changed, 66 insertions(+), 16 deletions(-)
Modified: sandbox/chrono/boost/chrono/chrono.hpp
==============================================================================
--- sandbox/chrono/boost/chrono/chrono.hpp (original)
+++ sandbox/chrono/boost/chrono/chrono.hpp 2008-11-24 15:59:53 EST (Mon, 24 Nov 2008)
@@ -25,6 +25,36 @@
Anthony Williams.
*/
+/*
+
+TODO:
+
+ * Fully implement error handling, with test cases.
+ * Use boost::throw_exception. (Currently not used because of an issue with Intel 11.0.)
+ * Consider issues raised by Michael Marcin:
+
+ > In the past I've seen QueryPerformanceCounter give incorrect results,
+ > especially with SpeedStep processors on laptops. This was many years ago and
+ > might have been fixed by service packs and drivers.
+ >
+ > Typically you check the results of QPC against GetTickCount to see if the
+ > results are reasonable.
+ > http://support.microsoft.com/kb/274323
+ >
+ > I've also heard of problems with QueryPerformanceCounter in multi-processor
+ > systems.
+ >
+ > I know some people SetThreadAffinityMask to 1 for the current thread call
+ > their QueryPerformance* functions then restore SetThreadAffinityMask. This
+ > seems horrible to me because it forces your program to jump to another
+ > physical processor if it isn't already on cpu0 but they claim it worked well
+ > in practice because they called the timing functions infrequently.
+ >
+ > In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for
+ > high resolution timers to avoid these issues.
+
+*/
+
#ifndef BOOST_CHRONO_HPP
#define BOOST_CHRONO_HPP
@@ -35,6 +65,7 @@
#include <boost/chrono/config.hpp>
#include <boost/ratio.hpp>
#include <boost/type_traits/common_type.hpp>
+#include <boost/system/error_code.hpp>
#include <boost/cstdint.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
@@ -403,7 +434,7 @@
|| (ratio_divide<Period2, period>::type::den == 1
&& !treat_as_floating_point<Rep2>::value)
>::type* = 0)
-#ifdef __GNUC__
+#ifdef __GNUC__
// GCC 4.2.4 refused to accept a definition at this point,
// yet both VC++ 9.0 SP1 and Intel ia32 11.0 accepted the definition
// without complaint. VC++ 9.0 SP1 refused to accept a later definition,
@@ -877,7 +908,7 @@
typedef chrono::time_point<system_clock> time_point;
static const bool is_monotonic = false;
- static time_point now();
+ static time_point now( system::error_code & ec = system::throws );
static std::time_t to_time_t(const time_point& t);
static time_point from_time_t(std::time_t t);
@@ -896,7 +927,7 @@
typedef chrono::time_point<monotonic_clock> time_point;
static const bool is_monotonic = true;
- static time_point now();
+ static time_point now( system::error_code & ec = system::throws );
};
//----------------------------------------------------------------------------//
@@ -909,6 +940,7 @@
//----------------------------------------------------------------------------//
// duration constructor implementation //
+// See comment in the class duration synopsis //
//----------------------------------------------------------------------------//
#ifdef __GNUC__
Modified: sandbox/chrono/boost/chrono/timer.hpp
==============================================================================
--- sandbox/chrono/boost/chrono/timer.hpp (original)
+++ sandbox/chrono/boost/chrono/timer.hpp 2008-11-24 15:59:53 EST (Mon, 24 Nov 2008)
@@ -22,8 +22,6 @@
// timer //
//---------------------------------------------------------------------------------//
-// TODO: enable commented out ec
-
template <class Clock>
class timer
{
@@ -38,10 +36,10 @@
~timer() {} // never throws
void start( system::error_code & ec = system::throws )
- { m_start = clock::now(/*ec*/); }
+ { m_start = clock::now( ec ); }
duration elapsed( system::error_code & ec = system::throws )
- { return clock::now(/*ec*/) - m_start; }
+ { return clock::now( ec ) - m_start; }
private:
time_point m_start;
Modified: sandbox/chrono/libs/chrono/src/chrono.cpp
==============================================================================
--- sandbox/chrono/libs/chrono/src/chrono.cpp (original)
+++ sandbox/chrono/libs/chrono/src/chrono.cpp 2008-11-24 15:59:53 EST (Mon, 24 Nov 2008)
@@ -29,18 +29,25 @@
namespace
{
- double get_nanosecs_per_tic()
+ double get_nanosecs_per_tic( boost::system::error_code & ec )
{
LARGE_INTEGER freq;
if ( !QueryPerformanceFrequency( &freq ) )
{
- throw
- std::runtime_error( "monotonic_clock: QueryPerformanceFrequency failed" );
+ if ( &ec == &boost::system::throws )
+ throw
+ std::runtime_error( "monotonic_clock: QueryPerformanceFrequency failed" );
+ return -1.0;
}
+ if ( &ec != &boost::system::throws ) ec.clear();
return 1000000000.0L / freq.QuadPart;
}
- double nanosecs_per_tic = get_nanosecs_per_tic();
+ inline double nanosecs_per_tic( boost::system::error_code & ec )
+ {
+ static double ns_per_tic = get_nanosecs_per_tic(ec);
+ return ns_per_tic;
+ }
}
namespace boost
@@ -48,24 +55,29 @@
namespace chrono
{
- monotonic_clock::time_point monotonic_clock::now()
+ monotonic_clock::time_point monotonic_clock::now( system::error_code & ec )
{
LARGE_INTEGER pcount;
+ pcount.QuadPart = 1LL; // just in case nanosecs_per_tic(ec) fails
if ( !QueryPerformanceCounter( &pcount ) )
{
+ if ( &ec == &system::throws )
throw
std::runtime_error( "monotonic_clock: QueryPerformanceCounter failed" );
- }
+ return time_point(duration(
+ static_cast<monotonic_clock::rep>(-1.0) ));
+ }
+ if ( &ec != &system::throws ) ec.clear();
return time_point(duration(
- static_cast<monotonic_clock::rep>(nanosecs_per_tic * pcount.QuadPart) ));
+ static_cast<monotonic_clock::rep>(nanosecs_per_tic(ec) * pcount.QuadPart) ));
}
-
- system_clock::time_point system_clock::now()
+ system_clock::time_point system_clock::now( system::error_code & ec )
{
FILETIME ft;
::GetSystemTimeAsFileTime( &ft ); // never fails
+ if ( &ec != &system::throws ) ec.clear();
return time_point(duration(
(static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime));
}
Modified: sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj
==============================================================================
--- sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj (original)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/await_keystroke/await_keystroke.vcproj 2008-11-24 15:59:53 EST (Mon, 24 Nov 2008)
@@ -176,6 +176,10 @@
RelativePath="..\..\..\src\chrono.cpp"
>
</File>
+ <File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Header Files"
Modified: sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj
==============================================================================
--- sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj (original)
+++ sandbox/chrono/libs/chrono/test/chrono_msvc/time2_demo/time2_demo.vcproj 2008-11-24 15:59:53 EST (Mon, 24 Nov 2008)
@@ -173,6 +173,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\system\src\error_code.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\example\time2_demo.cpp"
>
</File>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk