time

package
v0.0.0-...-8940ca0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2023 License: Apache-2.0, MIT Imports: 11 Imported by: 0

Documentation

Overview

Package time provides a calibrated clock synchronized to a system reference clock.

Index

Constants

View Source
const (
	// ApproxUpdateInterval is the approximate interval that parameters
	// should be updated at.
	//
	// Error correction assumes that the next update will occur after this
	// much time.
	//
	// If an update occurs before ApproxUpdateInterval passes, it has no
	// adverse effect on error correction behavior.
	//
	// If an update occurs after ApproxUpdateInterval passes, the clock
	// will overshoot its error correction target and begin accumulating
	// error in the other direction.
	//
	// If updates occur after more than 2*ApproxUpdateInterval passes, the
	// clock becomes unstable, accumulating more error than it had
	// originally. Repeated updates after more than 2*ApproxUpdateInterval
	// will cause unbounded increases in error.
	//
	// These statements assume that the host clock does not change. Actual
	// error will depend upon host clock changes.
	//
	// TODO(b/68779214): make error correction more robust to delayed
	// updates.
	ApproxUpdateInterval = 1 * time.Second

	// MaxClockError is the maximum amount of error that the clocks will
	// try to correct.
	//
	// This limit:
	//
	//  * Puts a limit on cases of otherwise unbounded increases in error.
	//
	//  * Avoids unreasonably large frequency adjustments required to
	//    correct large errors over a single update interval.
	MaxClockError = ReferenceNS(ApproxUpdateInterval) / 4
)

Variables

This section is empty.

Functions

This section is empty.

Types

type CalibratedClock

type CalibratedClock struct {
	// contains filtered or unexported fields
}

CalibratedClock implements a clock that tracks a reference clock.

Users should call Update at regular intervals of around approxUpdateInterval to ensure that the clock does not drift significantly from the reference clock.

func NewCalibratedClock

func NewCalibratedClock(c ClockID) *CalibratedClock

NewCalibratedClock creates a CalibratedClock that tracks the given ClockID.

func (*CalibratedClock) Debugf

func (c *CalibratedClock) Debugf(format string, v ...any)

Debugf logs at debug level.

func (*CalibratedClock) GetTime

func (c *CalibratedClock) GetTime() (int64, error)

GetTime returns the current time based on the clock calibration.

func (*CalibratedClock) Infof

func (c *CalibratedClock) Infof(format string, v ...any)

Infof logs at debug level.

func (*CalibratedClock) Update

func (c *CalibratedClock) Update() (Parameters, bool)

Update runs the update step of the clock, updating its synchronization with the reference clock.

Update returns timekeeping and true with the new timekeeping parameters if the clock is calibrated. Update should be called regularly to prevent the clock from getting significantly out of sync from the reference clock.

The returned timekeeping parameters are invalidated on the next call to Update.

func (*CalibratedClock) Warningf

func (c *CalibratedClock) Warningf(format string, v ...any)

Warningf logs at debug level.

type CalibratedClocks

type CalibratedClocks struct {
	// contains filtered or unexported fields
}

CalibratedClocks contains calibrated monotonic and realtime clocks.

TODO(mpratt): We know that Linux runs the monotonic and realtime clocks at the same rate, so rather than tracking both individually, we could do one calibration for both clocks.

func NewCalibratedClocks

func NewCalibratedClocks() *CalibratedClocks

NewCalibratedClocks creates a CalibratedClocks.

func (*CalibratedClocks) GetTime

func (c *CalibratedClocks) GetTime(id ClockID) (int64, error)

GetTime implements Clocks.GetTime.

func (*CalibratedClocks) Update

func (c *CalibratedClocks) Update() (Parameters, bool, Parameters, bool)

Update implements Clocks.Update.

type ClockID

type ClockID int32

ClockID is a Linux clock identifier.

const (
	Realtime ClockID = iota
	Monotonic
)

These are the supported Linux clock identifiers.

func (ClockID) String

func (c ClockID) String() string

String implements fmt.Stringer.String.

type Clocks

type Clocks interface {
	// Update performs an update step, keeping the clocks in sync with the
	// reference host clocks, and returning the new timekeeping parameters.
	//
	// Update should be called at approximately ApproxUpdateInterval.
	Update() (monotonicParams Parameters, monotonicOk bool, realtimeParam Parameters, realtimeOk bool)

	// GetTime returns the current time in nanoseconds for the given clock.
	//
	// Clocks implementations must support at least Monotonic and
	// Realtime.
	GetTime(c ClockID) (int64, error)
}

Clocks represents a clock source that contains both a monotonic and realtime clock.

type Parameters

type Parameters struct {
	// BaseCycles was the TSC counter value when the time was BaseRef.
	BaseCycles TSCValue

	// BaseRef is the reference clock time in nanoseconds corresponding to
	// BaseCycles.
	BaseRef ReferenceNS

	// Frequency is the frequency of the cycle clock in Hertz.
	Frequency uint64
}

Parameters are the timekeeping parameters needed to compute the current time.

func SeqAtomicLoadParameters

func SeqAtomicLoadParameters(seq *sync.SeqCount, ptr *Parameters) Parameters

SeqAtomicLoad returns a copy of *ptr, ensuring that the read does not race with any writer critical sections in seq.

func SeqAtomicTryLoadParameters

func SeqAtomicTryLoadParameters(seq *sync.SeqCount, epoch sync.SeqCountEpoch, ptr *Parameters) (val Parameters, ok bool)

SeqAtomicTryLoad returns a copy of *ptr while in a reader critical section in seq initiated by a call to seq.BeginRead() that returned epoch. If the read would race with a writer critical section, SeqAtomicTryLoad returns (unspecified, false).

func (Parameters) ComputeTime

func (p Parameters) ComputeTime(nowCycles TSCValue) (int64, bool)

ComputeTime calculates the current time from a "now" TSC value.

time = ref + (now - base) / f

type ReferenceNS

type ReferenceNS int64

ReferenceNS are nanoseconds in the reference clock domain. int64 gives us ~290 years before this overflows.

func (ReferenceNS) Magnitude

func (r ReferenceNS) Magnitude() ReferenceNS

Magnitude returns the absolute value of r.

type TSCValue

type TSCValue int64

TSCValue is a value from the TSC.

func Rdtsc

func Rdtsc() TSCValue

Rdtsc reads the TSC.

Intel SDM, Vol 3, Ch 17.15: "The RDTSC instruction reads the time-stamp counter and is guaranteed to return a monotonically increasing unique value whenever executed, except for a 64-bit counter wraparound. Intel guarantees that the time-stamp counter will not wraparound within 10 years after being reset."

We use int64, so we have 5 years before wrap-around.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL