diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-02-02 18:37:49 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-02-02 19:32:13 +0100 |
commit | 48460703229d73fbacdd0d6b0d0f01a54f7ce751 (patch) | |
tree | 991cf63384f64b206b3c82dbbb15532c6f011d4a /device/pools_test.go | |
parent | a9f80d8c587df99c6e8f57704aef3fe1ac62d0db (diff) |
device: use a waiting sync.Pool instead of a channel
Channels are FIFO which means we have guaranteed cache misses.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'device/pools_test.go')
-rw-r--r-- | device/pools_test.go | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/device/pools_test.go b/device/pools_test.go new file mode 100644 index 0000000..e6cbac5 --- /dev/null +++ b/device/pools_test.go @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. + */ + +package device + +import ( + "math/rand" + "runtime" + "sync" + "sync/atomic" + "testing" + "time" +) + +func TestWaitPool(t *testing.T) { + var wg sync.WaitGroup + trials := int32(100000) + workers := runtime.NumCPU() + 2 + if workers-4 <= 0 { + t.Skip("Not enough cores") + } + p := NewWaitPool(uint32(workers-4), func() interface{} { return make([]byte, 16) }) + wg.Add(workers) + max := uint32(0) + updateMax := func() { + count := atomic.LoadUint32(&p.count) + if count > p.max { + t.Errorf("count (%d) > max (%d)", count, p.max) + } + for { + old := atomic.LoadUint32(&max) + if count <= old { + break + } + if atomic.CompareAndSwapUint32(&max, old, count) { + break + } + } + } + for i := 0; i < workers; i++ { + go func() { + defer wg.Done() + for atomic.AddInt32(&trials, -1) > 0 { + updateMax() + x := p.Get() + updateMax() + time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond) + updateMax() + p.Put(x) + updateMax() + } + }() + } + wg.Wait() + if max != p.max { + t.Errorf("Actual maximum count (%d) != ideal maximum count (%d)", max, p.max) + } +} |