github.com/tailscale/wireguard-go@v0.0.20201119-0.20210522003738-46b531feb08a/device/pools_test.go (about) 1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. 4 */ 5 6 package device 7 8 import ( 9 "math/rand" 10 "runtime" 11 "sync" 12 "sync/atomic" 13 "testing" 14 "time" 15 ) 16 17 func TestWaitPool(t *testing.T) { 18 t.Skip("Currently disabled") 19 var wg sync.WaitGroup 20 trials := int32(100000) 21 if raceEnabled { 22 // This test can be very slow with -race. 23 trials /= 10 24 } 25 workers := runtime.NumCPU() + 2 26 if workers-4 <= 0 { 27 t.Skip("Not enough cores") 28 } 29 p := NewWaitPool(uint32(workers-4), func() interface{} { return make([]byte, 16) }) 30 wg.Add(workers) 31 max := uint32(0) 32 updateMax := func() { 33 count := atomic.LoadUint32(&p.count) 34 if count > p.max { 35 t.Errorf("count (%d) > max (%d)", count, p.max) 36 } 37 for { 38 old := atomic.LoadUint32(&max) 39 if count <= old { 40 break 41 } 42 if atomic.CompareAndSwapUint32(&max, old, count) { 43 break 44 } 45 } 46 } 47 for i := 0; i < workers; i++ { 48 go func() { 49 defer wg.Done() 50 for atomic.AddInt32(&trials, -1) > 0 { 51 updateMax() 52 x := p.Get() 53 updateMax() 54 time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond) 55 updateMax() 56 p.Put(x) 57 updateMax() 58 } 59 }() 60 } 61 wg.Wait() 62 if max != p.max { 63 t.Errorf("Actual maximum count (%d) != ideal maximum count (%d)", max, p.max) 64 } 65 } 66 67 func BenchmarkWaitPool(b *testing.B) { 68 var wg sync.WaitGroup 69 trials := int32(b.N) 70 workers := runtime.NumCPU() + 2 71 if workers-4 <= 0 { 72 b.Skip("Not enough cores") 73 } 74 p := NewWaitPool(uint32(workers-4), func() interface{} { return make([]byte, 16) }) 75 wg.Add(workers) 76 b.ResetTimer() 77 for i := 0; i < workers; i++ { 78 go func() { 79 defer wg.Done() 80 for atomic.AddInt32(&trials, -1) > 0 { 81 x := p.Get() 82 time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond) 83 p.Put(x) 84 } 85 }() 86 } 87 wg.Wait() 88 }