27 lines
1.1 KiB
C#
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);
|
|
}
|