68 lines
1.2 KiB
Go
68 lines
1.2 KiB
Go
package mrand
|
|
|
|
import (
|
|
"math/rand"
|
|
"sync"
|
|
)
|
|
|
|
// Everything in this file is taken from the math/rand package, which really
|
|
// ought to expose lockedSource publicly.
|
|
|
|
func read(p []byte, int63 func() int64, readVal *int64, readPos *int8) (n int, err error) {
|
|
pos := *readPos
|
|
val := *readVal
|
|
for n = 0; n < len(p); n++ {
|
|
if pos == 0 {
|
|
val = int63()
|
|
pos = 7
|
|
}
|
|
p[n] = byte(val)
|
|
val >>= 8
|
|
pos--
|
|
}
|
|
*readPos = pos
|
|
*readVal = val
|
|
return
|
|
}
|
|
|
|
type lockedSource struct {
|
|
lk sync.Mutex
|
|
src rand.Source64
|
|
}
|
|
|
|
func (r *lockedSource) Int63() (n int64) {
|
|
r.lk.Lock()
|
|
n = r.src.Int63()
|
|
r.lk.Unlock()
|
|
return
|
|
}
|
|
|
|
func (r *lockedSource) Uint64() (n uint64) {
|
|
r.lk.Lock()
|
|
n = r.src.Uint64()
|
|
r.lk.Unlock()
|
|
return
|
|
}
|
|
|
|
func (r *lockedSource) Seed(seed int64) {
|
|
r.lk.Lock()
|
|
r.src.Seed(seed)
|
|
r.lk.Unlock()
|
|
}
|
|
|
|
// seedPos implements Seed for a lockedSource without a race condition.
|
|
func (r *lockedSource) seedPos(seed int64, readPos *int8) {
|
|
r.lk.Lock()
|
|
r.src.Seed(seed)
|
|
*readPos = 0
|
|
r.lk.Unlock()
|
|
}
|
|
|
|
// read implements Read for a lockedSource without a race condition.
|
|
func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) {
|
|
r.lk.Lock()
|
|
n, err = read(p, r.src.Int63, readVal, readPos)
|
|
r.lk.Unlock()
|
|
return
|
|
}
|