Files
MoShiro/backend/shared/Monitor.Measurement/Core/MonoClock.cs
T
2026-10-04 21:46:39 +08:00

27 lines
1.1 KiB
C#

namespace Monitor.Measurement;
/// <summary>节点的单调时钟(微秒):t1…t4、t_send、t_recv 都用它;Probe 和 Agent 各自一个,块头里的时钟锚点把它对应到 UTC。</summary>
public sealed class MonoClock
{
private readonly TimeProvider _time;
public MonoClock(TimeProvider time)
{
_time = time;
}
public TimeProvider Time => _time;
public long NowUs()
{
long ticks = _time.GetTimestamp();
// 先除后乘会丢精度,先乘再除在 64 位内不会溢出(频率通常是 1e9 或 1e7)
return (ticks / _time.TimestampFrequency * 1_000_000) + (ticks % _time.TimestampFrequency * 1_000_000 / _time.TimestampFrequency);
}
public ClockAnchor Anchor() => new(NowUs(), _time.GetUtcNow().ToUnixTimeMilliseconds());
/// <summary>单调时钟读数 <paramref name="thenUs"/> 对应的 UTC 毫秒(只用于块的粗略起点,精确时间由块头的时钟锚点换算)。</summary>
public long UtcMsAt(long thenUs) => _time.GetUtcNow().ToUnixTimeMilliseconds() - (Math.Max(0, NowUs() - thenUs) / 1000);
}