99 lines
2.5 KiB
C++
99 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include "XNCore_global.h"
|
|
#include "XNString.h"
|
|
#include "XNType.h"
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <time.h>
|
|
|
|
namespace XNSim {
|
|
|
|
// 系统时间点类型别名
|
|
using XNTimePoint = std::chrono::system_clock::time_point;
|
|
|
|
/**
|
|
* @brief 将ISO格式的时间字符串转换为系统时间点
|
|
* @param timeStr ISO格式的时间字符串 (YYYY-MM-DDTHH:mm:ss)
|
|
* @return 系统时间点
|
|
*/
|
|
FORCEINLINE XNTimePoint parseISOTime(const XN_STRING &timeStr) {
|
|
std::tm tm = {};
|
|
std::istringstream ss(timeStr);
|
|
ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
|
|
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
|
|
return tp;
|
|
}
|
|
|
|
struct PERIOD_INFO;
|
|
|
|
#ifdef XN_WINDOWS
|
|
using XN_TIMESPEC = LARGE_INTEGER;
|
|
|
|
FORCEINLINE void getCurrentRTTime(XN_TIMESPEC *time) {
|
|
QueryPerformanceCounter(time);
|
|
}
|
|
|
|
FORCEINLINE double calculateRTTime(XN_TIMESPEC *now, XN_TIMESPEC *last) {
|
|
XN_TIMESPEC freq;
|
|
QueryPerformanceFrequency(&freq);
|
|
XN_INT64 ns = (now->QuadPart - last->QuadPart) * 1000000LL / freq.QuadPart;
|
|
return (double)ns / 1.0E9;
|
|
}
|
|
|
|
FORCEINLINE void sleepToNextRTTime(PERIOD_INFO *pinfo) {
|
|
XN_TIMESPEC freq;
|
|
QueryPerformanceFrequency(&freq);
|
|
auto now = pinfo->next_period;
|
|
pinfo->next_period.QuadPart += (pinfo->period_ns * freq.QuadPart) / 1000000LL;
|
|
XN_INT64 ns =
|
|
(pinfo->next_period.QuadPart - now.QuadPart) * 1000000LL / freq.QuadPart;
|
|
Sleep(ns / 1000);
|
|
}
|
|
#endif
|
|
|
|
#ifdef XN_LINUX
|
|
using XN_TIMESPEC = timespec;
|
|
|
|
FORCEINLINE void getCurrentRTTime(XN_TIMESPEC *time) {
|
|
clock_gettime(CLOCK_MONOTONIC, time);
|
|
}
|
|
|
|
FORCEINLINE double calculateRTTime(XN_TIMESPEC *now, XN_TIMESPEC *last) {
|
|
double seconds = (double)(now->tv_sec - last->tv_sec) +
|
|
(double)(now->tv_nsec - last->tv_nsec) / 1.0E9;
|
|
return seconds;
|
|
}
|
|
|
|
FORCEINLINE void sleepToNextRTTime(PERIOD_INFO *pinfo) {
|
|
// 睡眠时间步进
|
|
pinfo->next_period.tv_nsec += pinfo->period_ns;
|
|
|
|
// 睡眠时间整理
|
|
while (pinfo->next_period.tv_nsec >= 1000000000) {
|
|
pinfo->next_period.tv_sec++;
|
|
pinfo->next_period.tv_nsec -= 1000000000;
|
|
}
|
|
|
|
// 执行纳秒睡眠
|
|
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &pinfo->next_period, NULL);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @brief 纳秒睡眠相关时间结构体
|
|
* @details 用于线程睡眠时间控制
|
|
*/
|
|
struct PERIOD_INFO {
|
|
/**
|
|
* @brief 系统提供的时间记录结构体,精确到纳秒
|
|
*/
|
|
XN_TIMESPEC next_period;
|
|
/**
|
|
* @brief 睡眠时长,单位纳秒
|
|
*/
|
|
XN_INT64 period_ns;
|
|
};
|
|
|
|
} // namespace XNSim
|