summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2017-08-15 23:22:36 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2017-09-15 14:22:51 +0200
commit73bc364347fc8325a632f17fcda220ce7d6f5945 (patch)
treefd2ee517f8d15d3c5ffe2ef044aed12df89f9b47
parentcef9cf59f8064be99ce3b7d0738ab0775715112c (diff)
Add tools::Time::GetMonotonicTicks (us)
This moves a combination of tools::Time::GetSystemTicks(), canvas ElapsedTime::getSystemTime() and the opencl timing implementation into tools::Time::GetMonotonicTicks() as a monotonic microsecond time source. Change-Id: I5c9263540b8af55b2eeca6126e288129427f6e8e Reviewed-on: https://gerrit.libreoffice.org/41991 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r--canvas/Library_canvastools.mk6
-rw-r--r--canvas/source/tools/elapsedtime.cxx81
-rw-r--r--include/tools/time.hxx20
-rw-r--r--opencl/source/opencl_device.cxx73
-rw-r--r--tools/Library_tl.mk1
-rw-r--r--tools/source/datetime/ttime.cxx66
6 files changed, 74 insertions, 173 deletions
diff --git a/canvas/Library_canvastools.mk b/canvas/Library_canvastools.mk
index 50658b362f6b..a87e53fd1043 100644
--- a/canvas/Library_canvastools.mk
+++ b/canvas/Library_canvastools.mk
@@ -69,10 +69,4 @@ $(eval $(call gb_Library_add_defs,canvastools,\
endif
endif
-ifeq ($(OS),WNT)
-$(eval $(call gb_Library_use_system_win32_libs,canvastools,\
- winmm \
-))
-endif
-
# vim: set noet sw=4 ts=4:
diff --git a/canvas/source/tools/elapsedtime.cxx b/canvas/source/tools/elapsedtime.cxx
index e82df7dbe3fb..6cb7fd546a8e 100644
--- a/canvas/source/tools/elapsedtime.cxx
+++ b/canvas/source/tools/elapsedtime.cxx
@@ -19,28 +19,9 @@
#include <sal/config.h>
-#include <osl/time.h>
-
#include <canvas/elapsedtime.hxx>
-#if defined(_WIN32)
-
-#if defined _MSC_VER
-#pragma warning(push,1)
-#endif
-
-// TEMP!!!
-// Awaiting corresponding functionality in OSL
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winbase.h>
-#include <mmsystem.h>
-#endif
-
-#if defined _MSC_VER
-#pragma warning(pop)
-#endif
+#include <tools/time.hxx>
#include <algorithm>
#include <limits>
@@ -48,69 +29,11 @@
namespace canvas {
namespace tools {
-
-#if defined(_WIN32)
-// TODO(Q2): is 0 okay for the failure case here?
double ElapsedTime::getSystemTime()
{
- // TEMP!!!
- // Awaiting corresponding functionality in OSL
-
-
- // is there a performance counter available?
- static bool bTimeSetupDone( false );
- static bool bPerfTimerAvailable( false );
- static LONGLONG nPerfCountFreq;
-
- // TODO(F1): This _might_ cause problems, as it prevents correct
- // time handling for very long lifetimes of this class's
- // surrounding component in memory. When the difference between
- // current sys time and nInitialCount exceeds IEEE double's
- // mantissa, time will start to run jerky.
- static LONGLONG nInitialCount;
-
- if( !bTimeSetupDone )
- {
- if( QueryPerformanceFrequency(
- reinterpret_cast<LARGE_INTEGER *>(&nPerfCountFreq) ) )
- {
- // read initial time:
- QueryPerformanceCounter(
- reinterpret_cast<LARGE_INTEGER *>(&nInitialCount) );
- bPerfTimerAvailable = true;
- }
- bTimeSetupDone = true;
- }
-
- if( bPerfTimerAvailable )
- {
- LONGLONG nCurrCount;
- QueryPerformanceCounter(
- reinterpret_cast<LARGE_INTEGER *>(&nCurrCount) );
- nCurrCount -= nInitialCount;
- return double(nCurrCount) / nPerfCountFreq;
- }
- else
- {
- LONGLONG nCurrTime = timeGetTime();
- return double(nCurrTime) / 1000.0;
- }
+ return ::tools::Time::GetMonotonicTicks() / 1.0E6;
}
-#else // ! WNT
-
-// TODO(Q2): is 0 okay for the failure case here?
-double ElapsedTime::getSystemTime()
-{
- TimeValue aTimeVal;
- if( osl_getSystemTime( &aTimeVal ) )
- return ((aTimeVal.Nanosec * 10e-10) + aTimeVal.Seconds);
- else
- return 0.0;
-}
-
-#endif
-
ElapsedTime::ElapsedTime()
: m_pTimeBase(),
m_fLastQueriedTime( 0.0 ),
diff --git a/include/tools/time.hxx b/include/tools/time.hxx
index d8b4e6d06fc6..c6ada22a526d 100644
--- a/include/tools/time.hxx
+++ b/include/tools/time.hxx
@@ -121,9 +121,27 @@ public:
static Time GetUTCOffset();
- /// Elapsed time since epoch in milliseconds
+ /**
+ * Elapsed time in milliseconds (1e-3) since some unspecified starting point
+ *
+ * Convenience function, which just calls GetMonotonicTicks() / 1000.
+ */
static sal_uInt64 GetSystemTicks();
+ /**
+ * Elapsed time in microseconds (1e-6) since some unspecified starting point
+ *
+ * Uses the high-precision, monotonic time sources provided by the OS, if
+ * available. Don't try to relate it to the system time, and also it's long
+ * time accuracy is not the best.
+ *
+ * Currently used to measure the runtime of OpenCL shaders and to set a
+ * message creation timestamp to allow filtering of invalid timer messages.
+ *
+ * @return current system ticks in microseconds (1e-6s)
+ */
+ static sal_uInt64 GetMonotonicTicks();
+
tools::Time& operator =( const tools::Time& rTime );
Time operator -() const
{ return Time( -nTime ); }
diff --git a/opencl/source/opencl_device.cxx b/opencl/source/opencl_device.cxx
index 4f63e983ae3a..103236906592 100644
--- a/opencl/source/opencl_device.cxx
+++ b/opencl/source/opencl_device.cxx
@@ -7,16 +7,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifdef _WIN32
-#include <prewin.h>
-#include <postwin.h>
-#elif defined __MACH__
-#include <mach/mach_time.h>
-#else
-#include <sys/time.h>
-#endif
-
-#include <time.h>
#include <math.h>
#include <float.h>
#include <iostream>
@@ -30,6 +20,7 @@
#include <opencl/platforminfo.hxx>
#include <sal/log.hxx>
#include <rtl/math.hxx>
+#include <tools/time.hxx>
#include <opencl/OpenCLZone.hxx>
@@ -63,15 +54,6 @@ struct LibreOfficeDeviceEvaluationIO
unsigned long outputSize;
};
-struct timer
-{
-#ifdef _WIN32
- LARGE_INTEGER start;
-#else
- long long start;
-#endif
-};
-
const char* source = STRINGIFY(
\n#if defined(KHR_DP_EXTENSION)
\n#pragma OPENCL EXTENSION cl_khr_fp64 : enable
@@ -129,47 +111,6 @@ const char* source = STRINGIFY(
size_t sourceSize[] = { strlen(source) };
-/*************************************************************************/
-/* INTERNAL FUNCTIONS */
-/*************************************************************************/
-/* Timer functions - start timer */
-void timerStart(timer* mytimer)
-{
-#ifdef _WIN32
- QueryPerformanceCounter(&mytimer->start);
-#elif defined __MACH__
- mytimer->start = mach_absolute_time();
-#else
- struct timespec s;
- clock_gettime(CLOCK_MONOTONIC, &s);
- mytimer->start = (long long)s.tv_sec * (long long)1.0E6 + (long long)s.tv_nsec / (long long)1.0E3;
-#endif
-}
-
-/* Timer functions - get current value */
-double timerCurrent(timer const * mytimer)
-{
-#ifdef _WIN32
- LARGE_INTEGER stop, frequency;
- QueryPerformanceCounter(&stop);
- QueryPerformanceFrequency(&frequency);
- double time = ((double)(stop.QuadPart - mytimer->start.QuadPart) / frequency.QuadPart);
-#elif defined __MACH__
- static mach_timebase_info_data_t info = { 0, 0 };
- if (info.numer == 0)
- mach_timebase_info(&info);
- long long stop = mach_absolute_time();
- double time = ((stop - mytimer->start) * (double) info.numer / info.denom) / 1.0E9;
-#else
- struct timespec s;
- long long stop;
- clock_gettime(CLOCK_MONOTONIC, &s);
- stop = (long long)s.tv_sec * (long long)1.0E6 + (long long)s.tv_nsec / (long long)1.0E3;
- double time = ((double)(stop - mytimer->start) / 1.0E6);
-#endif
- return time;
-}
-
/* Random number generator */
double random(double min, double max)
{
@@ -283,8 +224,7 @@ ds_status evaluateScoreForDevice(ds_device& rDevice, std::unique_ptr<LibreOffice
else
{
/* Build program succeeded */
- timer kernelTime;
- timerStart(&kernelTime);
+ sal_uInt64 kernelTime = tools::Time::GetMonotonicTicks();
/* Run kernel */
cl_kernel clKernel = clCreateKernel(clProgram, "DynamicKernel", &clStatus);
@@ -321,7 +261,7 @@ ds_status evaluateScoreForDevice(ds_device& rDevice, std::unique_ptr<LibreOffice
clReleaseMemObject(clResult);
clReleaseKernel(clKernel);
- rDevice.fTime = timerCurrent(&kernelTime);
+ rDevice.fTime = tools::Time::GetMonotonicTicks() - kernelTime;
rDevice.bErrors = false;
}
@@ -334,8 +274,7 @@ ds_status evaluateScoreForDevice(ds_device& rDevice, std::unique_ptr<LibreOffice
{
/* Evaluating an Native CPU device */
SAL_INFO("opencl.device", "Device: \"CPU\" (Native) evaluation...");
- timer kernelTime;
- timerStart(&kernelTime);
+ sal_uInt64 kernelTime = tools::Time::GetMonotonicTicks();
unsigned long j;
for (j = 0; j < testData->outputSize; j++)
@@ -354,13 +293,13 @@ ds_status evaluateScoreForDevice(ds_device& rDevice, std::unique_ptr<LibreOffice
// Don't run for much longer than one second
if (j > 0 && j % 100 == 0)
{
- rDevice.fTime = timerCurrent(&kernelTime);
+ rDevice.fTime = tools::Time::GetMonotonicTicks() - kernelTime;
if (rDevice.fTime >= 1)
break;
}
}
- rDevice.fTime = timerCurrent(&kernelTime);
+ rDevice.fTime = tools::Time::GetMonotonicTicks() - kernelTime;
// Scale time to how long it would have taken to go all the way to outputSize
rDevice.fTime /= ((double) j / testData->outputSize);
diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk
index 040490ed7f05..f82338d746cf 100644
--- a/tools/Library_tl.mk
+++ b/tools/Library_tl.mk
@@ -107,6 +107,7 @@ $(eval $(call gb_Library_use_system_win32_libs,tl,\
ole32 \
shell32 \
uuid \
+ winmm \
))
endif
diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx
index 83812f72171a..4f469906118e 100644
--- a/tools/source/datetime/ttime.cxx
+++ b/tools/source/datetime/ttime.cxx
@@ -23,6 +23,7 @@
#if defined(_WIN32)
#include <windows.h>
+#include <mmsystem.h>
#elif defined UNX
#include <unistd.h>
#include <limits.h>
@@ -34,6 +35,7 @@
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
+#include <mach/mach_time.h>
#endif
#include <sal/log.hxx>
@@ -411,30 +413,54 @@ Time tools::Time::GetUTCOffset()
sal_uInt64 tools::Time::GetSystemTicks()
{
-#if defined(_WIN32)
- static LARGE_INTEGER nTicksPerSecond;
- static bool bTicksPerSecondInitialized = false;
- if (!bTicksPerSecondInitialized)
- {
- QueryPerformanceFrequency(&nTicksPerSecond);
- bTicksPerSecondInitialized = true;
- }
+ return tools::Time::GetMonotonicTicks() / 1000;
+}
- LARGE_INTEGER nPerformanceCount;
- QueryPerformanceCounter(&nPerformanceCount);
+#ifdef _WIN32
+static LARGE_INTEGER initPerformanceFrequency()
+{
+ LARGE_INTEGER nTicksPerSecond = { 0 };
+ if (!QueryPerformanceFrequency(&nTicksPerSecond))
+ nTicksPerSecond.QuadPart = 0;
+ return nTicksPerSecond;
+}
+#endif
- return static_cast<sal_uInt64>(
- (nPerformanceCount.QuadPart*1000)/nTicksPerSecond.QuadPart);
-#else
- timeval tv;
- int n = gettimeofday (&tv, nullptr);
- if (n == -1) {
- int e = errno;
- SAL_WARN("tools.datetime", "gettimeofday failed: " << e);
+sal_uInt64 tools::Time::GetMonotonicTicks()
+{
+#ifdef _WIN32
+ static const LARGE_INTEGER nTicksPerSecond = initPerformanceFrequency();
+ if (nTicksPerSecond.QuadPart > 0)
+ {
+ LARGE_INTEGER nPerformanceCount;
+ QueryPerformanceCounter(&nPerformanceCount);
+ return static_cast<sal_uInt64>(
+ ( nPerformanceCount.QuadPart * 1000 * 1000 ) / nTicksPerSecond.QuadPart );
}
- return static_cast<sal_uInt64>(tv.tv_sec) * 1000
- + static_cast<sal_uInt64>(tv.tv_usec) / 1000;
+ else
+ {
+ return static_cast<sal_uInt64>( timeGetTime() * 1000 );
+ }
+#else
+ sal_uInt64 nMicroSeconds;
+#ifdef __MACH__
+ static mach_timebase_info_data_t info = { 0, 0 };
+ if ( 0 == info.numer )
+ mach_timebase_info( &info );
+ nMicroSeconds = mach_absolute_time() * (double) (info.numer / info.denom) / 1000;
+#else
+#if defined(USE_CLOCK_GETTIME)
+ struct timespec currentTime;
+ clock_gettime( CLOCK_MONOTONIC, &currentTime );
+ nMicroSeconds = currentTime.tv_sec * 1000 * 1000 + currentTime.tv_nsec / 1000;
+#else
+ struct timeval currentTime;
+ gettimeofday( &currentTime, nullptr );
+ nMicroSeconds = currentTime.tv_sec * 1000 * 1000 + currentTime.tv_usec;
#endif
+#endif // __MACH__
+ return nMicroSeconds;
+#endif // _WIN32
}
} /* namespace tools */