github.com/CAFxX/fastrand@v0.1.0/pcg_atomic.go (about)

     1  package fastrand
     2  
     3  import (
     4  	"sync/atomic"
     5  )
     6  
     7  // AtomicPCG implements the PCG-XSH-RR generator with atomic state updates.
     8  //
     9  // This generator is safe for concurrent use by multiple goroutines.
    10  // The zero value is a valid state: Seed() can be called to set a custom seed.
    11  type AtomicPCG struct {
    12  	PCG
    13  }
    14  
    15  // Seed initializes the state with the provided seed.
    16  //
    17  // This function is safe for concurrent use by multiple goroutines.
    18  func (r *AtomicPCG) Seed(s uint64) {
    19  	var t PCG
    20  	t.Seed(s)
    21  	atomic.StoreUint64(&r.state, t.state)
    22  }
    23  
    24  // Uint32 returns a random uint32.
    25  //
    26  // This function is safe for concurrent use by multiple goroutines.
    27  func (r *AtomicPCG) Uint32() uint32 {
    28  	i := uint32(0)
    29  	for {
    30  		old := atomic.LoadUint64(&r.state)
    31  		var t PCG
    32  		t.state = old
    33  		n := t.Uint32()
    34  		if atomic.CompareAndSwapUint64(&r.state, old, t.state) {
    35  			return n
    36  		}
    37  		i += 30
    38  		cpuYield(i)
    39  	}
    40  }