github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/sync2/spin/spin.go (about)

     1  package spin
     2  
     3  import (
     4  	"runtime"
     5  	"time"
     6  )
     7  
     8  // Default spintter
     9  type T = T256
    10  
    11  // Default limited spinner
    12  type L = L256_256
    13  
    14  // T256 is a spinner with Gosched every 256 iterations
    15  type T256 struct{ count int }
    16  
    17  func (s *T256) Spin() bool {
    18  	s.count++
    19  	if s.count > 256 {
    20  		runtime.Gosched()
    21  		s.count = 0
    22  	}
    23  	return true
    24  }
    25  
    26  // L256_256 is a limited spinner with Gosched every 256 iteration and maximum 1024 Gosched-s
    27  type L256_256 struct {
    28  	count int
    29  	total int
    30  }
    31  
    32  func (s *L256_256) Spin() bool {
    33  	s.count++
    34  	if s.count > 256 {
    35  		runtime.Gosched()
    36  		s.count = 0
    37  		s.total++
    38  	}
    39  	if s.total > 256 {
    40  		return false
    41  	}
    42  	return true
    43  }
    44  
    45  // Limited spinner with Gosched every 128 iteration and maximum 1024 Gosched-s
    46  type L128_1024 struct {
    47  	count int
    48  	total int
    49  }
    50  
    51  func (s *L128_1024) Spin() bool {
    52  	s.count++
    53  	if s.count > 128 {
    54  		runtime.Gosched()
    55  		s.count = 0
    56  		s.total++
    57  	}
    58  	if s.total > 1024 {
    59  		return false
    60  	}
    61  	return true
    62  }
    63  
    64  // Limited spinner upto 1 second
    65  type Second struct {
    66  	start time.Time
    67  	count int
    68  }
    69  
    70  func (s *Second) Spin() bool {
    71  	if s.count == 0 {
    72  		s.start = time.Now()
    73  	}
    74  	s.count++
    75  	runtime.Gosched()
    76  	if s.count > 512 {
    77  		if time.Since(s.start) > time.Second {
    78  			return false
    79  		}
    80  		s.count = 1
    81  	}
    82  	return true
    83  }