From 9837cb0ddc5c38af9916a2a6a580092caf952e59 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 11 Jun 2017 19:56:59 +0200 Subject: [PATCH] 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). --- internal/cryptocore/randprefetch.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/internal/cryptocore/randprefetch.go b/internal/cryptocore/randprefetch.go index 8825a05..081559d 100644 --- a/internal/cryptocore/randprefetch.go +++ b/internal/cryptocore/randprefetch.go @@ -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