mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-14 00:51:12 +03:00
97 lines
1.7 KiB
Go
97 lines
1.7 KiB
Go
package kmutex
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// Number of unique resources to access
|
|
const number = 100
|
|
|
|
func makeIds(count int) []int {
|
|
ids := make([]int, count)
|
|
for i := 0; i < count; i++ {
|
|
ids[i] = i
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func TestKmutex(t *testing.T) {
|
|
km := New[int]()
|
|
ids := makeIds(number)
|
|
resources := make([]int, number)
|
|
wg := sync.WaitGroup{}
|
|
|
|
lc := make(chan int)
|
|
uc := make(chan int)
|
|
// Start 10n goroutines accessing n resources 10 times each
|
|
for i := 0; i < 10*number; i++ {
|
|
wg.Add(1)
|
|
go func(k int) {
|
|
for j := 0; j < 10; j++ {
|
|
lc <- k
|
|
km.Lock(ids[k])
|
|
// read and write resource to check for race
|
|
resources[k] = resources[k] + 1
|
|
km.Unlock(ids[k])
|
|
uc <- k
|
|
}
|
|
wg.Done()
|
|
}(i % len(ids))
|
|
}
|
|
|
|
to := time.After(time.Second)
|
|
counts := make(map[int]int)
|
|
var lCount, ulCount int
|
|
loop:
|
|
for {
|
|
select {
|
|
case k := <-lc:
|
|
counts[k] = counts[k] + 1
|
|
lCount++
|
|
case k := <-uc:
|
|
counts[k] = counts[k] - 1
|
|
ulCount++
|
|
case <-to:
|
|
t.Fatal("timed out waiting for results")
|
|
break loop
|
|
}
|
|
expectCount := 100 * number
|
|
if lCount == expectCount && ulCount == expectCount {
|
|
// Have all results
|
|
break
|
|
}
|
|
}
|
|
for k, c := range counts {
|
|
if c != 0 {
|
|
t.Errorf("Key %d count != 0: %d\n", k, c)
|
|
}
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
func BenchmarkKmutex1000(b *testing.B) {
|
|
km := New[int]()
|
|
ids := makeIds(number)
|
|
resources := make([]int, number)
|
|
wg := sync.WaitGroup{}
|
|
|
|
// Start 1000 goroutines accessing 100 resources N times each
|
|
b.ResetTimer()
|
|
for i := 0; i < 1000; i++ {
|
|
wg.Add(1)
|
|
go func(k int) {
|
|
for j := 0; j < b.N; j++ {
|
|
km.Lock(ids[k])
|
|
// read and write resource to check for race
|
|
resources[k] = resources[k] + 1
|
|
km.Unlock(ids[k])
|
|
}
|
|
wg.Done()
|
|
}(i % len(ids))
|
|
}
|
|
wg.Wait()
|
|
}
|