Added new boost timer. Prepared fixes for removing players.

This commit is contained in:
lotodore
2007-05-05 21:14:23 +00:00
parent 363377b6a6
commit 82b5392ff5
18 changed files with 989 additions and 54 deletions
+31
View File
@@ -0,0 +1,31 @@
#ifndef BOOST_TIMER_DEVICES_HPP
#define BOOST_TIMER_DEVICES_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- Devices --------------------------
//! A device has 3 main member functions: start(), elapsed() & reset().
// -------------------------- Includes --------------------------
#include "boost/timer/devices/clock.hpp"
#include "boost/timer/devices/date_time.hpp"
#ifndef BOOST_WINDOWS
#include "boost/timer/devices/gettimeofday.hpp"
#else
#include "boost/timer/devices/QueryPerformanceCounter.hpp"
#include "boost/timer/devices/timeGetTime.hpp"
#include "boost/timer/devices/GetSystemTimeAsFileTime.hpp"
#include "boost/timer/devices/GetTickCount.hpp"
#endif
#endif // BOOST_TIMER_DEVICES_HPP
@@ -0,0 +1,96 @@
#ifndef BOOST_TIMER_DEVICES_GSTAFT_HPP
#define BOOST_TIMER_DEVICES_GSTAFT_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- GetSystemTimeAsFileTime() --------------------------
// Properties:
// - ??? ns resolution.
// - ??? ns overhead (6 clocks (64-bit load/store + synchronization (4))).
//
// Pros:
// - Low overhead.
//
// Cons:
// - Low resolution.
// -------------------------- Includes --------------------------
#ifndef BOOST_WINDOWS
#error "GetSystemTimeAsFileTime() can only be used on windows"
#else
// Boost headers
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
// Windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// -------------------------- Code --------------------------
namespace boost
{
//! The gstaft_device class is based on GetSystemTimeAsFileTime() to compute the time
class gstaft_device
{
public:
typedef posix_time::ptime time_type;
typedef time_type::time_duration_type time_duration_type;
explicit gstaft_device() : m_elapsed(0, 0, 0)
{
std::memset(&m_start, 0, sizeof(ULARGE_INTEGER));
}
void start()
{
if(!m_start.QuadPart)
GetSystemTimeAsFileTime(reinterpret_cast<LPFILETIME>(&m_start));
}
const time_duration_type& elapsed() const
{
if(m_start.QuadPart)
{
ULARGE_INTEGER current;
GetSystemTimeAsFileTime(reinterpret_cast<LPFILETIME>(&current));
uint64_t tmp = current.QuadPart - m_start.QuadPart;
m_elapsed += posix_time::milliseconds(tmp / 10000.0);
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_elapsed = time_duration_type(0,0,0);
std::memset(&m_start, 0, sizeof(ULARGE_INTEGER));
}
private:
mutable ULARGE_INTEGER m_start;
mutable time_duration_type m_elapsed;
};
} // namespace boost
#endif // BOOST_WINDOWS
#endif // BOOST_TIMER_DEVICES_GSTAFT_HPP
@@ -0,0 +1,92 @@
#ifndef BOOST_TIMER_DEVICES_GTC_HPP
#define BOOST_TIMER_DEVICES_GTC_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- GetTickCount() --------------------------
// Properties:
// - 5 to 55 ms resolution.
// - ??? ns overhead (8 clock (load, mul, shift)).
//
// Pros:
// - Very low overhead.
//
// Cons:
// - Very low resolution.
// -------------------------- Includes --------------------------
#ifndef BOOST_WINDOWS
#error "GetTickCount() can only be used on windows"
#else
// Boost headers
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
// Windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// -------------------------- Code --------------------------
namespace boost
{
//! The gtc_device class is based on GetTickCount() to compute the time
class gtc_device
{
public:
typedef posix_time::ptime time_type;
typedef time_type::time_duration_type time_duration_type;
explicit gtc_device() : m_start(0), m_elapsed(0, 0, 0)
{
}
void start()
{
if(!m_start)
m_start = GetTickCount();
}
const time_duration_type& elapsed() const
{
if(m_start)
{
uint32_t current = GetTickCount();
m_elapsed += posix_time::milliseconds(current - m_start);
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_elapsed = time_duration_type(0,0,0);
m_start = 0;
}
private:
mutable uint32_t m_start;
mutable time_duration_type m_elapsed;
};
} // namespace boost
#endif // BOOST_WINDOWS
#endif // BOOST_TIMER_DEVICES_GTC_HPP
@@ -0,0 +1,130 @@
#ifndef BOOST_TIMER_DEVICES_QPC_HPP
#define BOOST_TIMER_DEVICES_QPC_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- QueryPerformanceCounter() --------------------------
// Properties:
// Win2k (PIT):
// - 838 ns resolution.
// - ~3000 ns overhead.
// WinXP (PMT):
// - 279 ns resolution.
// - 700 ns overhead.
//
// Pros:
// - High resolution (usually the best one).
//
// Cons:
// - High overhead.
// - Not thread safe.
// - Multi core problems. To solve the issue you can #define BOOST_QPC_SET_AFFINITY which will call SetThreadAffinityMask() for you.
//
// Issues:
// 1) Q274323: may jump several seconds under heavy PCI bus load.
// not a problem, because the older systems on which this occurs
// have safe TSCs, so that is used instead.
// 2) "System clock problem can inflate benchmark scores":
// incorrect value if not polled every 4.5 seconds?
// -------------------------- Includes --------------------------
#ifndef BOOST_WINDOWS
#error "QueryPerformanceCounter() can only be used on windows"
#else
// Boost headers
#include <boost/throw_exception.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
// Windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// -------------------------- Code --------------------------
namespace boost
{
class qpc_device
{
public:
typedef posix_time::ptime time_type;
typedef time_type::time_duration_type time_duration_type;
explicit qpc_device() : m_elapsed(0, 0, 0)
{
#ifdef BOOST_QPC_SET_AFFINITY
m_affinity = SetThreadAffinityMask(GetCurrentThread(), 1);
#endif
m_start.QuadPart = 0;
if(!QueryPerformanceFrequency(&m_frequency))
throw_exception(std::runtime_error("qpc_device: QueryPerformanceFrequency() indicated there's no high-resolution performance counter"));
// Make it so we have the future results directly in milliseconds
m_frequency.QuadPart /= 1000;
}
~qpc_device()
{
#ifdef BOOST_QPC_SET_AFFINITY
SetThreadAffinityMask(GetCurrentThread(), m_affinity);
#endif
}
void start()
{
if(!m_start.QuadPart && !QueryPerformanceCounter(&m_start))
throw_exception(std::runtime_error("qpc_device: QueryPerformanceCounter() failed"));
}
const time_duration_type& elapsed() const
{
if(m_start.QuadPart)
{
LARGE_INTEGER current;
if(!QueryPerformanceCounter(&current))
throw_exception(std::runtime_error("qpc_device: QueryPerformanceCounter() failed"));
uint64_t milliseconds = (current.QuadPart - m_start.QuadPart) / m_frequency.QuadPart;
m_elapsed += posix_time::milliseconds(milliseconds);
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_elapsed = time_duration_type(0,0,0);
m_start.QuadPart = 0;
}
private:
LARGE_INTEGER m_frequency;
mutable LARGE_INTEGER m_start;
mutable time_duration_type m_elapsed;
#ifdef BOOST_QPC_SET_AFFINITY
DWORD_PTR m_affinity;
#endif
};
} // namespace boost
#endif // BOOST_WINDOWS
#endif // BOOST_TIMER_DEVICES_QPC_HPP
+85
View File
@@ -0,0 +1,85 @@
#ifndef BOOST_TIMER_DEVICES_CLOCK_HPP
#define BOOST_TIMER_DEVICES_CLOCK_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- std::clock() --------------------------
// Properties:
// - ??? ns resolution.
// - ??? ns overhead.
// - Is implemented with GetSystemTimeAsFileTime on windows.
//
// Pros:
// - Portable.
//
// Cons:
// - High resolution.
// -------------------------- Includes --------------------------
// Standard headers
#include <ctime>
// Boost headers
#include <boost/date_time/posix_time/posix_time.hpp>
// -------------------------- Code --------------------------
namespace boost
{
//! The clock_device class is based on std::clock() to compute the time
class clock_device
{
public:
typedef posix_time::ptime time_type;
typedef time_type::time_duration_type time_duration_type;
explicit clock_device() : m_start(0), m_elapsed(0, 0, 0)
{
}
void start()
{
if(!m_start)
m_start = std::clock();
}
const time_duration_type& elapsed() const
{
if(m_start)
{
std::clock_t current = std::clock();
m_elapsed += posix_time::milliseconds(static_cast<double>(current-m_start) / CLOCKS_PER_SEC * 1000.0);
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_elapsed = time_duration_type(0,0,0);
m_start = 0;
}
private:
mutable std::clock_t m_start;
mutable time_duration_type m_elapsed;
};
} // namespace boost
#endif // BOOST_TIMER_DEVICES_CLOCK_HPP
@@ -0,0 +1,84 @@
#ifndef BOOST_TIMER_DEVICES_DATE_TIME_HPP
#define BOOST_TIMER_DEVICES_DATE_TIME_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- date_time devices --------------------------
// Properties:
// - windows: uses GetSystemTimeAsFileTime()
// - POSIX: uses gettimeofday()
//
// Pros:
// - Portable.
// -------------------------- Includes --------------------------
#include <boost/date_time/posix_time/posix_time.hpp>
// -------------------------- Code --------------------------
namespace boost
{
//! The date_time device
template <class Clock, class Time = posix_time::ptime>
class date_time_device
{
public:
typedef Clock clock_type;
typedef Time time_type;
typedef typename clock_type::time_duration_type time_duration_type;
explicit date_time_device() : m_start(date_time::not_a_date_time), m_elapsed(0, 0, 0)
{
}
void start()
{
if(m_start.is_not_a_date_time())
m_start = clock_type::local_time();
}
const time_duration_type& elapsed() const
{
if(!m_start.is_not_a_date_time())
{
time_type current(clock_type::local_time());
m_elapsed += (current - m_start);
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_start = date_time::not_a_date_time;
m_elapsed = time_duration_type(0,0,0);
}
private:
mutable time_type m_start;
mutable time_duration_type m_elapsed;
};
// Convenience typedefs
typedef date_time_device<posix_time::microsec_clock> microsec_device;
typedef date_time_device<posix_time::second_clock> second_device;
} // namespace boost
#endif // BOOST_TIMER_DEVICES_DATE_TIME_HPP
@@ -0,0 +1,98 @@
#ifndef BOOST_TIMER_DEVICES_GTOD_HPP
#define BOOST_TIMER_DEVICES_GTOD_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- gettimeofday() --------------------------
// Properties:
// - ??? ns resolution.
// - ??? ns overhead.
//
// Pros:
// - Low overhead.
// - High resolution.
// -------------------------- Includes --------------------------
// Get config
#include <boost/config.hpp>
// Check we have gettimeofday()
#ifndef BOOST_HAS_GETTIMEOFDAY
#error "gettimeofday() can only be used on POSIX systems"
#else
// Boost headers
#include <boost/date_time/posix_time/posix_time.hpp>
// Linux headers
#include <sys/time.h>
// -------------------------- Code --------------------------
namespace boost
{
//! The gtod_device class is based on gettimeofday() to compute the time
class gtod_device
{
public:
typedef posix_time::ptime time_type;
typedef time_type::time_duration_type time_duration_type;
explicit gtod_device() : m_elapsed(0, 0, 0)
{
std::memset(&m_start, 0, sizeof(timeval));
}
void start()
{
if(!is_time(m_start))
gettimeofday(&m_start, 0);
}
const time_duration_type& elapsed() const
{
if(is_time(m_start))
{
timeval current;
gettimeofday(&current, 0);
m_elapsed += posix_time::milliseconds((current.tv_sec-m_start.tv_sec) * 1000 + ((current.tv_usec-m_start.tv_usec) / 1000.0));
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_elapsed = time_duration_type(0,0,0);
std::memset(&m_start, 0, sizeof(timeval));
}
private:
bool is_time(const timeval& value) const
{
return value.tv_sec || value.tv_usec;
}
mutable timeval m_start;
mutable time_duration_type m_elapsed;
};
} // namespace boost
#endif // BOOST_HAS_GETTIMEOFDAY
#endif // BOOST_TIMER_DEVICES_GTOD_HPP
@@ -0,0 +1,94 @@
#ifndef BOOST_TIMER_DEVICES_TGT_HPP
#define BOOST_TIMER_DEVICES_TGT_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- std::clock() --------------------------
// Properties:
// - 1 ms resolution.
// - ??? ns overhead.
//
// Pros:
// - Low overhead.
//
// Cons:
// - Low resolution.
// -------------------------- Includes --------------------------
#ifndef BOOST_WINDOWS
#error "timeGetTime() can only be used on windows"
#else
// Boost headers
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
// Windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Automagically link winmm.lib if we can
#pragma comment(lib, "winmm.lib")
// -------------------------- Code --------------------------
namespace boost
{
//! The tgt_device class is based on timeGetTime() to compute the time
class tgt_device
{
public:
typedef posix_time::ptime time_type;
typedef time_type::time_duration_type time_duration_type;
explicit tgt_device() : m_start(0), m_elapsed(0, 0, 0)
{
}
void start()
{
if(!m_start)
m_start = timeGetTime();
}
const time_duration_type& elapsed() const
{
if(m_start)
{
uint32_t current = timeGetTime();
m_elapsed += posix_time::milliseconds(current - m_start);
m_start = current;
}
return m_elapsed;
}
void reset()
{
m_elapsed = time_duration_type(0,0,0);
m_start = 0;
}
private:
mutable uint32_t m_start;
mutable time_duration_type m_elapsed;
};
} // namespace boost
#endif // BOOST_WINDOWS
#endif // BOOST_TIMER_DEVICES_TGT_HPP
+107
View File
@@ -0,0 +1,107 @@
#ifndef BOOST_TIMER_IMPLEMENTATION_HPP
#define BOOST_TIMER_IMPLEMENTATION_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- Code --------------------------
namespace boost
{
//! The timer class takes a device type that's used for the elapsed time computation.
//! Calling start(), pause() or resume() twice has no special effects.
template<class Device>
class timer
{
public:
typedef Device device_type;
typedef typename device_type::time_duration_type time_duration_type;
enum start_options { auto_start = 1, manual_start };
//! By default, start the timer without any time offset
explicit timer(time_duration_type initial_duration = time_duration_type(0, 0, 0), start_options start_op = auto_start)
: m_elapsed(initial_duration), m_running(false)
{
if(start_op == auto_start)
start();
}
//! Starts the timer
void start()
{
if(!m_running)
{
m_device.start();
m_running = true;
}
}
//! Restarts the timer
void restart()
{
reset();
start();
}
//! Returns the elapsed time
time_duration_type elapsed() const
{
return m_running ? (m_device.elapsed() + m_elapsed) : m_elapsed;
}
//! Pauses the timer
void pause()
{
if(m_running)
{
m_elapsed += m_device.elapsed();
m_device.reset();
m_running = false;
}
}
//! Resumes the timer
void resume()
{
if(!m_running)
{
m_device.start();
m_running = true;
}
}
//! Resets the timer
void reset()
{
m_elapsed = time_duration_type(0,0,0);
m_device.reset();
m_running = false;
}
//! Tells wether the timer is currently running or not
bool is_running() const
{
return m_running;
}
private:
mutable device_type m_device;
mutable time_duration_type m_elapsed;
bool m_running;
};
} // namespace boost
#endif // BOOST_TIMER_IMPLEMENTATION_HPP
+55
View File
@@ -0,0 +1,55 @@
#ifndef BOOST_TIMER_TYPEDEFS_HPP
#define BOOST_TIMER_TYPEDEFS_HPP
// (C) Copyright Vaucher Philippe 2006
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0. (See accompanying
// file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
// Author: Vaucher Philippe 2006
// -------------------------- Includes --------------------------
#include <boost/date_time/posix_time/posix_time.hpp>
#include "boost/timer/implementation.hpp"
#include "boost/timer/devices.hpp"
// -------------------------- Devices --------------------------
namespace boost
{
// boost::date_time devices
typedef timer<microsec_device> microsec_timer;
typedef timer<second_device> second_timer;
// std::clock() device
typedef timer<clock_device> clock_timer;
#ifndef BOOST_WINDOWS
// gettimeofday() device
typedef timer<gtod_device> gtod_timer;
#else
// QueryPerformanceCounter() device
typedef timer<qpc_device> qpc_timer;
// timeGetTime() device
typedef timer<tgt_device> tgt_timer;
// GetSystemTimeAsFileTime() device
typedef timer<gstaft_device> gstaft_timer;
// GetTickCount() device
typedef timer<gtc_device> gtc_timer;
#endif
} // namespace boost
#endif // BOOST_TIMER_TYPEDEFS_HPP