cryptocore: prefetch nonces in the background

Spawn a worker goroutine that reads the next 512-byte block
while the current one is being drained.

This should help reduce waiting times when /dev/urandom is very
slow (like on Linux 3.16 kernels).
This commit is contained in:
Jakob Unterwurzacher 2017-06-11 19:56:59 +02:00
parent f351c3c1ec
commit 9837cb0ddc
1 changed files with 18 additions and 2 deletions

View File

@ -22,9 +22,15 @@ Benchmark40960-2 10000000 147 ns/op 108.82 MB/s
*/
const prefetchN = 512
func init() {
randPrefetcher.refill = make(chan []byte)
go randPrefetcher.refillWorker()
}
type randPrefetcherT struct {
sync.Mutex
buf bytes.Buffer
buf bytes.Buffer
refill chan []byte
}
func (r *randPrefetcherT) read(want int) (out []byte) {
@ -37,8 +43,12 @@ func (r *randPrefetcherT) read(want int) (out []byte) {
return out
}
// Buffer was empty -> re-fill
fresh := <-r.refill
if len(fresh) != prefetchN {
log.Panicf("randPrefetcher: refill: got %d bytes instead of %d", len(fresh), prefetchN)
}
r.buf.Reset()
r.buf.Write(RandBytes(prefetchN))
r.buf.Write(fresh)
have, err = r.buf.Read(out)
if have != want || err != nil {
log.Panicf("randPrefetcher could not satisfy read: have=%d want=%d err=%v", have, want, err)
@ -47,4 +57,10 @@ func (r *randPrefetcherT) read(want int) (out []byte) {
return out
}
func (r *randPrefetcherT) refillWorker() {
for {
r.refill <- RandBytes(prefetchN)
}
}
var randPrefetcher randPrefetcherT