/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */ /* $Id: osaStopwatch.h,v 1.2 2007/04/26 19:33:57 anton Exp $ Author(s): Ofri Sadowsky Created on: 2005-02-17 (C) Copyright 2005-2007 Johns Hopkins University (JHU), All Rights Reserved. --- begin cisst license - do not edit --- This software is provided "as is" under an open source license, with no warranty. The complete license can be found in license.txt and http://www.cisst.org/cisst/license.txt. --- end cisst license --- */ #ifndef _osaStopwatch_h #define _osaStopwatch_h #include #if CISST_OS_IS_WINDOWS || (CISST_OS == CISST_CYGWIN) #include #elif (CISST_COMPILER == CISST_GCC) #include #endif /*! Implement a simple stopwatch mechanism, which is helpful in profiling, debugging, and performance estimation. The osaStopwatch class uses system calls to obtain time at the finest granularity available in the system. Note that a system call may sometimes invoke a context switch, and use them only when needed to interfere the least with the normal performance of the program. To reduce overhead (for mor efficient time polling), all the methods are inlined. */ class osaStopwatch { public: typedef unsigned long MillisecCounter; osaStopwatch() { Reset(); } /*! Return the granularity of time in the system, in seconds. The fraction part is the fraction of second that the system time granularity supports */ double GetTimeGranularity() const; /*! Reset all the counters to zero, and stop the watch */ void Reset() { RunningFlag = false; AccumulatedTime = 0; #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN) StartTicks = 0; #elif (CISST_COMPILER == CISST_GCC) StartTimeOfDay.tv_sec = 0; StartTimeOfDay.tv_usec = 0; #endif } /*! Start the stopwatch from its current counter state. If the watch is already running, do nothing */ inline void Start() { if (IsRunning()) return; #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN) if (HasHighPerformanceCounter) { LARGE_INTEGER ticks; ::QueryPerformanceCounter( &ticks ); StartTicks = static_cast( GetTimeGranularity() * static_cast(ticks.QuadPart) * 1000.0 ); } else { StartTicks = ::GetTickCount(); } #elif (CISST_COMPILER == CISST_GCC) gettimeofday(&StartTimeOfDay, 0); #endif RunningFlag = true; } /*! Stop the stopwatch so that its counter state is kept until a Start or a Reset */ inline void Stop() { if (!IsRunning()) return; RunningFlag = false; #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN) DWORD endTicks; MillisecCounter totalMillisec; if (HasHighPerformanceCounter) { LARGE_INTEGER ticks; QueryPerformanceCounter( &ticks ); endTicks = static_cast( GetTimeGranularity() * static_cast(ticks.QuadPart) * 1000.0 ); totalMillisec = endTicks - StartTicks; } else { endTicks = ::GetTickCount(); totalMillisec = endTicks - StartTicks; } #elif (CISST_COMPILER == CISST_GCC) timeval endTimeOfDay; gettimeofday(&endTimeOfDay, 0); timeval diffTime; timersub(&endTimeOfDay, &StartTimeOfDay, &diffTime); MillisecCounter totalMillisec = diffTime.tv_sec * 1000 + diffTime.tv_usec / 1000; #endif AccumulatedTime += totalMillisec; } /*! Returns true if the stopwatch is running and counting continues (i.e., if Start was called last). Returns false if the watch is stopped, i.e., if Stop or Reset was called last. */ bool IsRunning() const { return RunningFlag; } /*! Return the current read of the stopwatch without changing the running state. */ MillisecCounter GetCurrentRead() const { if (!IsRunning()) return AccumulatedTime; #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN) DWORD endTicks; MillisecCounter totalMillisec; if (HasHighPerformanceCounter) { LARGE_INTEGER ticks; QueryPerformanceCounter( &ticks ); endTicks = static_cast( GetTimeGranularity() * static_cast(ticks.QuadPart) * 1000.0 ); totalMillisec = endTicks - StartTicks; } else { endTicks = ::GetTickCount(); totalMillisec = endTicks - StartTicks; } #elif (CISST_COMPILER == CISST_GCC) timeval endTimeOfDay; gettimeofday(&endTimeOfDay, 0); timeval diffTime; timersub(&endTimeOfDay, &StartTimeOfDay, &diffTime); MillisecCounter totalMillisec = diffTime.tv_sec * 1000 + diffTime.tv_usec / 1000; #endif return AccumulatedTime + totalMillisec; } private: bool RunningFlag; MillisecCounter AccumulatedTime; static bool HasHighPerformanceCounter; #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN) DWORD StartTicks; #elif (CISST_COMPILER == CISST_GCC) timeval StartTimeOfDay; #endif }; #endif // _osaStopwatch_h // **************************************************************************** // Change History // **************************************************************************** // // $Log: osaStopwatch.h,v $ // Revision 1.2 2007/04/26 19:33:57 anton // All files in libraries: Applied new license text, separate copyright and // updated dates, added standard header where missing. // // Revision 1.1 2007/02/16 18:57:55 ofri // cisstOSAbstraction library: Added class osaStopwatch based on recent discussion // // Revision 1.3 2006/08/31 18:38:00 ofri // mscStopwatch : Rewritten to use Windows "high performance counter" directly. // // Revision 1.2 2005/04/23 02:41:39 ofri // mscStopwatch: Updated code to compile on Cygwin // // Revision 1.1 2005/02/24 16:21:27 ofri // Added classes mscDtopwatch and mscOutputFormatter // // // ****************************************************************************