diff options
author | Jakob Unterwurzacher | 2017-06-11 19:56:59 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2017-06-11 21:29:50 +0200 |
commit | 9837cb0ddc5c38af9916a2a6a580092caf952e59 (patch) | |
tree | f699a605b9c60d1a1f24ea8c6b170a1a0a0bad79 /internal | |
parent | f351c3c1ecf30bd88b9246d45ba39cd259047a3c (diff) |
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).
Diffstat (limited to 'internal')
-rw-r--r-- | internal/cryptocore/randprefetch.go | 20 |
1 files 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 |