diff options
-rw-r--r-- | canvas/Library_canvastools.mk | 6 | ||||
-rw-r--r-- | canvas/source/tools/elapsedtime.cxx | 81 | ||||
-rw-r--r-- | include/tools/time.hxx | 20 | ||||
-rw-r--r-- | opencl/source/opencl_device.cxx | 73 | ||||
-rw-r--r-- | tools/Library_tl.mk | 1 | ||||
-rw-r--r-- | tools/source/datetime/ttime.cxx | 66 |
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, ¤tTime ); + nMicroSeconds = currentTime.tv_sec * 1000 * 1000 + currentTime.tv_nsec / 1000; +#else + struct timeval currentTime; + gettimeofday( ¤tTime, nullptr ); + nMicroSeconds = currentTime.tv_sec * 1000 * 1000 + currentTime.tv_usec; #endif +#endif // __MACH__ + return nMicroSeconds; +#endif // _WIN32 } } /* namespace tools */ |