Distribution_Service/CC_SDK/Include/basic/CCPrecisionClock
2025-12-03 18:08:23 +08:00

199 lines
4.2 KiB
Plaintext

#ifndef CTL_NANO_TIMER_H
#define CTL_NANO_TIMER_H
#define CTL_NOEXCEPT throw()
#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__)
#if _MSC_VER >= 1900
#undef CTL_NOEXCEPT
#define CTL_NOEXCEPT noexcept
#endif
#elif defined(__cplusplus) && __cplusplus >= 201103L
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__clang__) // If compiler is GCC/G++
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4
#undef CTL_NOEXCEPT
#define CTL_NOEXCEPT noexcept
#endif
#elif defined(__clang__)
#if __has_feature(cxx_noexcept)
#undef CTL_NOEXCEPT
#define CTL_NOEXCEPT noexcept
#endif
#else // Assume type traits and initializer support for other compilers and standard libraries
#undef CTL_NOEXCEPT
#define CTL_NOEXCEPT noexcept
#endif
#endif
#if defined(__MACH__)
#include <mach/clock.h>
#include <mach/mach.h>
namespace CTL
{
class nanotimer
{
private:
clock_serv_t system_clock;
mach_timespec_t time1, time2;
public:
nanotimer() CTL_NOEXCEPT
{
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &system_clock);
}
~nanotimer() CTL_NOEXCEPT
{
mach_port_deallocate(mach_task_self(), system_clock);
}
void start() CTL_NOEXCEPT
{
clock_get_time(system_clock, &time1);
}
double get_elapsed_ms() CTL_NOEXCEPT
{
return static_cast<double>(get_elapsed_ns()) / 1000000.0;
}
double get_elapsed_us() CTL_NOEXCEPT
{
return static_cast<double>(get_elapsed_ns()) / 1000.0;
}
double get_elapsed_ns() CTL_NOEXCEPT
{
clock_get_time(system_clock, &time2);
return ((1000000000.0 * static_cast<double>(time2.tv_sec - time1.tv_sec)) + static_cast<double>(time2.tv_nsec - time1.tv_nsec));
}
};
// Linux/BSD implementation:
#elif (defined(linux) || defined(__linux__) || defined(__linux)) || (defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) || defined(__OHOS__)
#include <time.h>
#include <sys/time.h>
namespace CTL
{
class nanotimer
{
private:
struct timespec time1, time2;
public:
nanotimer() CTL_NOEXCEPT {}
void start() CTL_NOEXCEPT
{
clock_gettime(CLOCK_MONOTONIC, &time1);
}
double get_elapsed_ms() CTL_NOEXCEPT
{
return get_elapsed_ns() / 1000000.0;
}
double get_elapsed_us() CTL_NOEXCEPT
{
return get_elapsed_ns() / 1000.0;
}
double get_elapsed_ns() CTL_NOEXCEPT
{
clock_gettime(CLOCK_MONOTONIC, &time2);
return ((1000000000.0 * static_cast<double>(time2.tv_sec - time1.tv_sec)) + static_cast<double>(time2.tv_nsec - time1.tv_nsec));
}
};
// Windows implementation:
#elif defined(_WIN32)
#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) && !defined(NOMINMAX)
#define NOMINMAX // Otherwise MS compilers act like idiots when using std::numeric_limits<>::max() and including windows.h
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#else
#include <windows.h>
#endif
namespace CTL
{
class nanotimer
{
private:
LARGE_INTEGER ticks1, ticks2;
double frequency;
public:
nanotimer() CTL_NOEXCEPT
{
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
frequency = static_cast<double>(freq.QuadPart);
}
void start() CTL_NOEXCEPT
{
QueryPerformanceCounter(&ticks1);
}
double get_elapsed_ms() CTL_NOEXCEPT
{
QueryPerformanceCounter(&ticks2);
return (static_cast<double>(ticks2.QuadPart - ticks1.QuadPart) * 1000.0) / frequency;
}
double get_elapsed_us() CTL_NOEXCEPT
{
return get_elapsed_ms() * 1000.0;
}
double get_elapsed_ns() CTL_NOEXCEPT
{
return get_elapsed_ms() * 1000000.0;
}
};
#endif
#if defined(__MACH__) || (defined(linux) || defined(__linux__) || defined(__linux)) || (defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) || defined(_WIN32) || defined(__OHOS__)
inline void nanosecond_delay(const double delay_ns) CTL_NOEXCEPT
{
nanotimer timer;
timer.start();
while(timer.get_elapsed_ns() < delay_ns)
{};
}
inline void microsecond_delay(const double delay_us) CTL_NOEXCEPT
{
nanosecond_delay(delay_us * 1000.0);
}
inline void millisecond_delay(const double delay_ms) CTL_NOEXCEPT
{
nanosecond_delay(delay_ms * 1000000.0);
}
}
#endif
#undef CTL_NOEXCEPT
#endif