diff options
Diffstat (limited to 'tests/benchmarks/inverted-thundering-herd')
l--------- | tests/benchmarks/inverted-thundering-herd/main.go | 1 | ||||
-rw-r--r-- | tests/benchmarks/inverted-thundering-herd/stm.go | 74 |
2 files changed, 75 insertions, 0 deletions
diff --git a/tests/benchmarks/inverted-thundering-herd/main.go b/tests/benchmarks/inverted-thundering-herd/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/benchmarks/inverted-thundering-herd/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/benchmarks/inverted-thundering-herd/stm.go b/tests/benchmarks/inverted-thundering-herd/stm.go new file mode 100644 index 0000000..1f240db --- /dev/null +++ b/tests/benchmarks/inverted-thundering-herd/stm.go @@ -0,0 +1,74 @@ +package stm + +import ( + "flag" +) + + + +const maxTokens = 25 + +var nFlag = flag.Int( + "n", + 1_000, + "The number of iterations to execute", +) + +func MainTest() { + flag.Parse() + n := *nFlag + + for i := 0; i < n; i++ { + continue // FIXME + done := NewBuiltinEqVar(false) + tokens := NewBuiltinEqVar(0) + pending := NewVar(NewSet[*Var[bool]]()) + for i := 0; i < 1000; i++ { + ready := NewVar(false) + Atomically(VoidOperation(func(tx *Tx) { + pending.Set(tx, pending.Get(tx).Add(ready)) + })) + go func() { + Atomically(VoidOperation(func(tx *Tx) { + tx.Assert(ready.Get(tx)) + set := pending.Get(tx) + if !set.Contains(ready) { + panic("couldn't find ourselves in pending") + } + pending.Set(tx, set.Delete(ready)) + })) + //b.Log("waiter finished") + }() + } + go func() { + for Atomically(func(tx *Tx) bool { + if done.Get(tx) { + return false + } + tx.Assert(tokens.Get(tx) < maxTokens) + tokens.Set(tx, tokens.Get(tx)+1) + return true + }) { + } + }() + go func() { + for Atomically(func(tx *Tx) bool { + tx.Assert(tokens.Get(tx) > 0) + tokens.Set(tx, tokens.Get(tx)-1) + pending.Get(tx).Range(func(ready *Var[bool]) bool { + if !ready.Get(tx) { + ready.Set(tx, true) + return false + } + return true + }) + return !done.Get(tx) + }) { + } + }() + Atomically(VoidOperation(func(tx *Tx) { + tx.Assert(pending.Get(tx).(Lenner).Len() == 0) + })) + AtomicSet(done, true) + } +} |