summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-06-11 19:56:59 +0200
committerJakob Unterwurzacher2017-06-11 21:29:50 +0200
commit9837cb0ddc5c38af9916a2a6a580092caf952e59 (patch)
treef699a605b9c60d1a1f24ea8c6b170a1a0a0bad79
parentf351c3c1ecf30bd88b9246d45ba39cd259047a3c (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).
-rw-r--r--internal/cryptocore/randprefetch.go20
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