yieldpoint

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2025 License: MIT Imports: 5 Imported by: 0

README

yieldpoint

A Go package for cooperative goroutine yielding with priority-aware scheduling.

Overview

yieldpoint enables goroutines to voluntarily yield execution when high-priority tasks are active, using atomic operations and condition variables for efficient synchronization.

Features

  • Priority-based Yielding: Voluntary yielding when high-priority tasks are active
  • Efficient Blocking: Uses sync.Cond for non-busy waiting
  • Context Support: Timeout-aware operations with context
  • Thread Safety: Atomic operations for high-priority counting
  • Performance Optimizations: Fast variants with spin-wait strategies
  • Configurable: Adjustable spin-wait iterations and yield durations

Installation

go get github.com/AlexsanderHamir/yieldpoint

Usage

Basic Usage
package main

import "github.com/AlexsanderHamir/yieldpoint"

func main() {
    // High-priority section
    yieldpoint.EnterHighPriority()
    defer yieldpoint.ExitHighPriority()

    go func() {
        // Standard variants
        yieldpoint.MaybeYield()      // Quick yield if high-priority active
        yieldpoint.WaitIfActive()    // Block until high-priority ends

        // Fast variant for performance-critical paths
        yieldpoint.WaitIfActiveFast() // Spin-wait before blocking
    }()
}
Context Support
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

// Non-blocking yield with timeout
if err := yieldpoint.MaybeYieldWithContext(ctx); err != nil {
    // Handle timeout/cancellation
}

// Blocking wait with timeout
if err := yieldpoint.WaitIfActiveWithContext(ctx); err != nil {
    // Handle timeout/cancellation
}
Nested High-Priority
// Reference counting for nested sections
yieldpoint.EnterHighPriority() // Count = 1
yieldpoint.EnterHighPriority() // Count = 2
defer yieldpoint.ExitHighPriority() // Count = 1
defer yieldpoint.ExitHighPriority() // Count = 0, signals waiters

API Reference

Core Functions
  • MaybeYield(): If high-priority tasks are active, it yields the current goroutine using runtime.Gosched(), allowing others to run. The goroutine will resume execution in a future time slice if MaybeYield() isn't called again.
  • WaitIfActive(): Blocks the calling goroutine using sync.Cond until there are no active high-priority tasks.
  • EnterHighPriority(): Begins high-priority section (reference counted)
  • ExitHighPriority(): Ends high-priority section, signals if last
  • IsHighPriorityActive(): Checks high-priority status
Performance Variants
  • WaitIfActiveFast(): Spin-wait strategy for short waits + sync.cond in case it the spin wasn't enough.
    • Configurable via SetSpinWaitIterations
    • Falls back to mutex-based waiting
Context Functions
  • MaybeYieldWithContext(ctx): Non-blocking yield with timeout
  • WaitIfActiveWithContext(ctx): Blocking wait with timeout
Configuration
  • SetSpinWaitIterations(n int): Configure spin-wait behavior for the fast variation of WaitIfActive, it attempts to yield without blocking, but falls back to the conditional variable if it exhausts n.
func WaitIfActiveFast() {
	// First try spin-waiting
	for range SpinWaitIterations {
		if HighPriorityCount.Load() == 0 {
			return
		}
		runtime.Gosched()
	}

	// Only fall back to mutex-based waiting if spin-wait didn't succeed
	for HighPriorityCount.Load() > 0 {
		Mu.Lock()
		Cond.Wait()
		Mu.Unlock()
	}
}

Performance

  • Use fast variants in performance-critical paths
  • Tune SpinWaitIterations based on wait duration:
    • Higher: Better for very short waits
    • Lower: Better for longer waits
  • Set appropriate timeouts for context operations

Thread Safety

  • Atomic high-priority counting
  • Mutex and condition variable for blocking
  • Safe for concurrent use

Contributing

We welcome contributions! Before you start contributing, please ensure you have:

  • Go 1.24.3 or later installed
  • Git for version control
  • Basic understanding of Go testing and benchmarking
Quick Setup
# Fork and clone the repository
git clone https://github.com/AlexsanderHamir/GenPool.git
cd GenPool

# Install dependencies
go mod download
go mod tidy

# Run tests to verify setup
go test -v ./...
go test -bench=. ./...
Development Guidelines
  • Write tests for new functionality
  • Run benchmarks to ensure no performance regressions
  • Follow Go code style guidelines
  • Update documentation for user-facing changes
  • Ensure all tests pass before submitting PRs

License

MIT License - see LICENSE

Documentation

Overview

Package yieldpoint provides cooperative goroutine yielding based on priority-aware scheduling.

Index

Constants

This section is empty.

Variables

View Source
var Cond = sync.NewCond(&Mu)

Cond is the condition variable used for efficient blocking

View Source
var DefaultYieldDuration = 1 * time.Millisecond

DefaultYieldDuration is the default duration to sleep when yielding

View Source
var HighPriorityCount atomic.Int32

HighPriorityCount tracks the number of active high-priority sections

Mu is the mutex used for efficient blocking in WaitIfActive

View Source
var SpinWaitIterations = 1000

SpinWaitIterations is the number of iterations to spin-wait before falling back to mutex-based waiting

Functions

func EnterHighPriority

func EnterHighPriority()

EnterHighPriority begins a high-priority section. Multiple calls are supported through reference counting.

func ExitHighPriority

func ExitHighPriority()

ExitHighPriority ends a high-priority section. If this is the last high-priority section, it will signal any waiting goroutines.

func IsHighPriorityActive

func IsHighPriorityActive() bool

IsHighPriorityActive returns true if any high-priority sections are currently active.

func MaybeYield

func MaybeYield()

MaybeYield voluntarily yields the current goroutine if any high-priority sections are active.

func MaybeYieldWithContext

func MaybeYieldWithContext(ctx context.Context) error

MaybeYieldWithContext is a context-aware version of MaybeYield

func SetSpinWaitIterations

func SetSpinWaitIterations(n int)

SetSpinWaitIterations sets the number of iterations to spin-wait before falling back to mutex-based waiting

func WaitIfActive

func WaitIfActive()

WaitIfActive blocks the current goroutine until no high-priority sections are active. This is an efficient blocking operation that uses sync.Cond to avoid busy waiting.

func WaitIfActiveFast

func WaitIfActiveFast()

WaitIfActiveFast is a high-performance version of WaitIfActive that uses a spin-wait strategy before falling back to mutex-based waiting. This is suitable for performance-critical code paths where the wait time is expected to be very short.

func WaitIfActiveWithContext

func WaitIfActiveWithContext(ctx context.Context) error

WaitIfActiveWithContext is a context-aware version of WaitIfActive

Types

This section is empty.

Directories

Path Synopsis
examples
basic_usage command
context_support command
fast_support command
nested_priority command
wait_if_active command

Jump to

Keyboard shortcuts

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