diff options
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/platform/time.go')
-rw-r--r-- | vendor/github.com/tetratelabs/wazero/internal/platform/time.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/time.go b/vendor/github.com/tetratelabs/wazero/internal/platform/time.go new file mode 100644 index 000000000..fa9da1acb --- /dev/null +++ b/vendor/github.com/tetratelabs/wazero/internal/platform/time.go @@ -0,0 +1,76 @@ +package platform + +import ( + "sync/atomic" + "time" + + "github.com/tetratelabs/wazero/sys" +) + +const ( + ms = int64(time.Millisecond) + // FakeEpochNanos is midnight UTC 2022-01-01 and exposed for testing + FakeEpochNanos = 1640995200000 * ms +) + +// NewFakeWalltime implements sys.Walltime with FakeEpochNanos that increases by 1ms each reading. +// See /RATIONALE.md +func NewFakeWalltime() sys.Walltime { + // AddInt64 returns the new value. Adjust so the first reading will be FakeEpochNanos + t := FakeEpochNanos - ms + return func() (sec int64, nsec int32) { + wt := atomic.AddInt64(&t, ms) + return wt / 1e9, int32(wt % 1e9) + } +} + +// NewFakeNanotime implements sys.Nanotime that increases by 1ms each reading. +// See /RATIONALE.md +func NewFakeNanotime() sys.Nanotime { + // AddInt64 returns the new value. Adjust so the first reading will be zero. + t := int64(0) - ms + return func() int64 { + return atomic.AddInt64(&t, ms) + } +} + +// FakeNanosleep implements sys.Nanosleep by returning without sleeping. +var FakeNanosleep = sys.Nanosleep(func(int64) {}) + +// FakeOsyield implements sys.Osyield by returning without yielding. +var FakeOsyield = sys.Osyield(func() {}) + +// Walltime implements sys.Walltime with time.Now. +// +// Note: This is only notably less efficient than it could be is reading +// runtime.walltime(). time.Now defensively reads nanotime also, just in case +// time.Since is used. This doubles the performance impact. However, wall time +// is likely to be read less frequently than Nanotime. Also, doubling the cost +// matters less on fast platforms that can return both in <=100ns. +func Walltime() (sec int64, nsec int32) { + t := time.Now() + return t.Unix(), int32(t.Nanosecond()) +} + +// nanoBase uses time.Now to ensure a monotonic clock reading on all platforms +// via time.Since. +var nanoBase = time.Now() + +// nanotimePortable implements sys.Nanotime with time.Since. +// +// Note: This is less efficient than it could be is reading runtime.nanotime(), +// Just to do that requires CGO. +func nanotimePortable() int64 { + return time.Since(nanoBase).Nanoseconds() +} + +// Nanotime implements sys.Nanotime with runtime.nanotime() if CGO is available +// and time.Since if not. +func Nanotime() int64 { + return nanotime() +} + +// Nanosleep implements sys.Nanosleep with time.Sleep. +func Nanosleep(ns int64) { + time.Sleep(time.Duration(ns)) +} |