Documentation
¶
Overview ¶
Package spin provides minimal spin-based primitives for performance-critical code paths:
- Lock — non-fair spinlock for extremely short critical sections
- Wait — adaptive spin-wait helper for tight polling loops
- Pause — architecture-specific CPU hint for busy-wait loops
- Yield — cooperative yield/sleep for non-hot paths
Design notes
- Hot paths should prefer Pause (light CPU hint) and Wait (adaptive backoff) instead of ad-hoc loops with runtime.Gosched().
- Lock is intentionally non-fair and intended only for very short critical sections where OS mutex overhead is prohibitive.
- No allocations in hot paths; functions return immediately and never block unless explicitly documented (Yield with a positive sleep duration).
Architectures: amd64, arm64, 386, arm, riscv64, ppc64le, s390x, loong64, wasm.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Pause ¶
func Pause(cycles ...int)
Pause executes CPU pause instructions to reduce energy consumption in spin-wait loops. It must not block or yield the scheduler.
Defaults to 30 cycles if not specified. Uses optimized assembly on amd64/arm64.
Usage:
Pause() // 30 cycles (default) Pause(1) // 1 cycle Pause(50) // 50 cycles
func SetYieldDuration ¶
SetYieldDuration sets the base duration unit for Yield(). Recommended: 50-250 microseconds for real-time systems, 1-4 ms for general workloads.
func Yield ¶
Yield cooperatively yields execution to reduce CPU burn in tight loops.
By default, Yield sleeps for a small duration (configured by SetYieldDuration) to give other goroutines and the OS scheduler a chance to run.
If an explicit duration is provided, it overrides the default for this call. A non-positive duration disables sleeping and falls back to runtime.Gosched() (a purely cooperative yield without a timer sleep).
For automatic adaptive backoff in tight loops, use Wait instead.
Example ¶
package main
import (
"fmt"
"time"
"code.hybscloud.com/spin"
)
func main() {
spin.Yield(10 * time.Millisecond)
fmt.Println("yielded")
}
Types ¶
type Lock ¶
type Lock struct {
// contains filtered or unexported fields
}
Lock is a minimal, non-fair spin lock intended for very short critical sections on hot paths. It avoids allocations and OS mutex overhead but should not be used as a general-purpose lock.
Example ¶
package main
import (
"fmt"
"code.hybscloud.com/spin"
)
func main() {
var lk spin.Lock
lk.Lock()
// critical section
lk.Unlock()
fmt.Println("locked")
}
Output: locked
func (*Lock) Lock ¶
func (sl *Lock) Lock()
Lock acquires the lock, spinning with an adaptive backoff.
type Wait ¶
type Wait struct {
// contains filtered or unexported fields
}
Wait is a lightweight adaptive spin-wait helper used in tight polling loops.
It escalates from a short CPU pause to a cooperative scheduler yield based on the recent history of calls. The zero value is ready to use.
Example ¶
package main
import (
"fmt"
"sync/atomic"
"time"
"code.hybscloud.com/spin"
)
func main() {
var sw spin.Wait
var ready atomic.Bool
go func() {
time.Sleep(50 * time.Microsecond)
ready.Store(true)
}()
for !ready.Load() {
sw.Once()
}
fmt.Println("ready")
}
Output: ready