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  }