Initial commit
This commit is contained in:
142
srcs/RobotNet10/Commons/RobotNet10.Realtime/RealtimeClock.cs
Normal file
142
srcs/RobotNet10/Commons/RobotNet10.Realtime/RealtimeClock.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RobotNet10.Realtime;
|
||||
|
||||
/// <summary>
|
||||
/// Provides high-resolution clock access for real-time applications.
|
||||
/// </summary>
|
||||
public class RealtimeClock
|
||||
{
|
||||
private readonly RealtimeClockType _clockType;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of RealtimeClock.
|
||||
/// </summary>
|
||||
/// <param name="clockType">Type of clock to use</param>
|
||||
public RealtimeClock(RealtimeClockType clockType)
|
||||
{
|
||||
_clockType = clockType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current time from the clock.
|
||||
/// </summary>
|
||||
/// <returns>Current time</returns>
|
||||
public DateTime GetTime()
|
||||
{
|
||||
var tp = new LinuxNative.timespec();
|
||||
int result = LinuxNative.clock_gettime((int)_clockType, ref tp);
|
||||
if (result != 0)
|
||||
{
|
||||
LinuxNative.ThrowLastError("clock_gettime");
|
||||
}
|
||||
|
||||
if (_clockType == RealtimeClockType.Realtime)
|
||||
{
|
||||
return DateTimeOffset.FromUnixTimeSeconds(tp.tv_sec)
|
||||
.AddTicks(tp.tv_nsec / 100)
|
||||
.DateTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For monotonic clocks, return time since boot
|
||||
return DateTime.UtcNow; // Note: This is approximate for monotonic clocks
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time as a TimeSpan (for monotonic clocks, represents time since boot).
|
||||
/// </summary>
|
||||
/// <returns>TimeSpan representing the clock time</returns>
|
||||
public TimeSpan GetTimeSpan()
|
||||
{
|
||||
var tp = new LinuxNative.timespec();
|
||||
int result = LinuxNative.clock_gettime((int)_clockType, ref tp);
|
||||
if (result != 0)
|
||||
{
|
||||
LinuxNative.ThrowLastError("clock_gettime");
|
||||
}
|
||||
|
||||
return TimeSpan.FromSeconds(tp.tv_sec) + TimeSpan.FromTicks(tp.tv_nsec / 100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resolution of the clock.
|
||||
/// </summary>
|
||||
/// <returns>Clock resolution</returns>
|
||||
public TimeSpan GetResolution()
|
||||
{
|
||||
var res = new LinuxNative.timespec();
|
||||
int result = LinuxNative.clock_getres((int)_clockType, ref res);
|
||||
if (result != 0)
|
||||
{
|
||||
LinuxNative.ThrowLastError("clock_getres");
|
||||
}
|
||||
|
||||
return TimeSpan.FromSeconds(res.tv_sec) + TimeSpan.FromTicks(res.tv_nsec / 100);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the clock time (only for CLOCK_REALTIME).
|
||||
/// </summary>
|
||||
/// <param name="time">Time to set</param>
|
||||
public void SetTime(DateTime time)
|
||||
{
|
||||
if (_clockType != RealtimeClockType.Realtime)
|
||||
{
|
||||
throw new InvalidOperationException("Only CLOCK_REALTIME can be set");
|
||||
}
|
||||
|
||||
var tp = new LinuxNative.timespec
|
||||
{
|
||||
tv_sec = ((DateTimeOffset)time.ToUniversalTime()).ToUnixTimeSeconds(),
|
||||
tv_nsec = (time.Millisecond % 1000) * 1000000
|
||||
};
|
||||
|
||||
int result = LinuxNative.clock_settime((int)_clockType, ref tp);
|
||||
if (result != 0)
|
||||
{
|
||||
LinuxNative.ThrowLastError("clock_settime");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Linux clock types.
|
||||
/// </summary>
|
||||
public enum RealtimeClockType
|
||||
{
|
||||
/// <summary>
|
||||
/// System-wide real-time clock (wall clock time).
|
||||
/// Can be set by root.
|
||||
/// </summary>
|
||||
Realtime = LinuxNative.CLOCK_REALTIME,
|
||||
|
||||
/// <summary>
|
||||
/// Monotonic clock that cannot be set and represents monotonic time since some unspecified starting point.
|
||||
/// Best for measuring elapsed time.
|
||||
/// </summary>
|
||||
Monotonic = LinuxNative.CLOCK_MONOTONIC,
|
||||
|
||||
/// <summary>
|
||||
/// Monotonic raw clock (not subject to NTP adjustments).
|
||||
/// </summary>
|
||||
MonotonicRaw = LinuxNative.CLOCK_MONOTONIC_RAW,
|
||||
|
||||
/// <summary>
|
||||
/// Clock that measures CPU time consumed by the calling process.
|
||||
/// </summary>
|
||||
ProcessCpuTime = LinuxNative.CLOCK_PROCESS_CPUTIME_ID,
|
||||
|
||||
/// <summary>
|
||||
/// Clock that measures CPU time consumed by the calling thread.
|
||||
/// </summary>
|
||||
ThreadCpuTime = LinuxNative.CLOCK_THREAD_CPUTIME_ID,
|
||||
|
||||
/// <summary>
|
||||
/// Boot time clock (monotonic clock that includes time spent in suspend).
|
||||
/// </summary>
|
||||
BootTime = LinuxNative.CLOCK_BOOTTIME,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user