// Copyright (C) 2011-2014 ChaosForge Ltd // This file is part of NV Libraries. // For conditions of distribution and use, see copyright notice in nv.hh #include "nv/core/time.hh" #include "nv/core/logging.hh" #include #if NV_COMPILER == NV_MSVC #define WIN32_LEAN_AND_MEAN #include #include #pragma intrinsic(__rdtsc) #else #if NV_COMPILER == NV_GNUC && NV_PLATFORM == NV_WINDOWS // mingw doesn't have usleep nor nanosleep... #include #endif // #include // #include // #include // #include #include #include #include #endif struct timer_impl { timer_impl() { clock_zero = clock(); #if NV_COMPILER == NV_MSVC QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&query_zero); #else gettimeofday(&timeval_zero, NULL); #endif } clock_t clock_zero; #if NV_COMPILER == NV_MSVC LARGE_INTEGER query_zero; LARGE_INTEGER frequency; #else struct timeval timeval_zero; #endif }; static timer_impl zero_timer; nv::uint64 nv::get_ticks() { #if NV_COMPILER == NV_MSVC return __rdtsc(); #else register long long ticks asm("eax") = 0; asm volatile (".byte 15, 49" : : : "eax", "edx"); return static_cast( ticks ); #endif } void nv::sleep( uint32 ms ) { #if NV_COMPILER == NV_MSVC Sleep( ms ); #else #if NV_COMPILER == NV_GNUC && NV_PLATFORM == NV_WINDOWS Sleep( ms ); #else struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = ms * 1000000; nanosleep(&ts, NULL); // usleep( ms * 1000 ); #endif #endif } nv::uint32 nv::get_cpu_ms() { return (uint32)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000.0 ) ) ; } nv::uint64 nv::get_cpu_us() { return (uint64)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000000.0 ) ) ; } nv::uint32 nv::get_system_ms() { #if NV_COMPILER == NV_MSVC LARGE_INTEGER now; QueryPerformanceCounter(&now); LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart; return (uint32) (1000.0 * result / (double) zero_timer.frequency.QuadPart); #else struct timeval now; gettimeofday(&now, NULL); return (uint32)( (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000+(now.tv_usec-zero_timer.timeval_zero.tv_usec)/1000 ); #endif } nv::uint64 nv::get_system_us() { #if NV_COMPILER == NV_MSVC LARGE_INTEGER now; QueryPerformanceCounter(&now); LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart; return (uint64) (1000000.0 * result / (double) zero_timer.frequency.QuadPart); #else struct timeval now; gettimeofday(&now, NULL); return (uint32)( (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000000+(now.tv_usec - zero_timer.timeval_zero.tv_usec) ); #endif }