diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..dab54a8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + go-version: ['1.11', 'stable'] + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go-version }} + + - name: Build + run: go build ./... + + - name: Test + run: go test -race ./... diff --git a/README.md b/README.md index 6c82894..5636029 100644 --- a/README.md +++ b/README.md @@ -1 +1,8 @@ -# monotick \ No newline at end of file +# monotick + +Monotonic timestamps as int64 nanoseconds. + +[![Go Reference](https://pkg.go.dev/badge/github.com/dengaleev/monotick.svg)](https://pkg.go.dev/github.com/dengaleev/monotick) +[![CI](https://github.com/dengaleev/monotick/actions/workflows/ci.yml/badge.svg)](https://github.com/dengaleev/monotick/actions/workflows/ci.yml) + +See [documentation](https://pkg.go.dev/github.com/dengaleev/monotick) for details. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dde23de --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/dengaleev/monotick + +go 1.11 diff --git a/monotick.go b/monotick.go new file mode 100644 index 0000000..2100430 --- /dev/null +++ b/monotick.go @@ -0,0 +1,40 @@ +// Package monotick provides monotonic timestamps as int64 nanoseconds. +// +// # Why int64? +// +// For measuring durations, you don't need wall clock time — just a counter. +// int64 nanoseconds can represent ~292 years, while int32 overflows in ~2 seconds. +// +// # How it works +// +// A reference time.Time is captured at package init. Now() returns +// time.Since(start) as int64 nanoseconds. This approach: +// +// - Uses only public Go APIs (no go:linkname or runtime internals) +// - Requires no CGO +// - Works on all platforms +// +// Timestamps are relative to process start, not system boot. This is +// sufficient for measuring durations within a process. +// +// # Example +// +// start := monotick.Now() +// // ... do work ... +// elapsed := monotick.Since(start) +package monotick + +import "time" + +var start = time.Now() + +// Now returns nanoseconds elapsed since process start (monotonic). +func Now() int64 { + return int64(time.Since(start)) +} + +// Since returns nanoseconds elapsed since t, where t is a value +// previously returned by Now. +func Since(t int64) int64 { + return Now() - t +}