aboutsummaryrefslogtreecommitdiff
path: root/tests/benchmarks/inverted-thundering-herd
diff options
context:
space:
mode:
Diffstat (limited to 'tests/benchmarks/inverted-thundering-herd')
l---------tests/benchmarks/inverted-thundering-herd/main.go1
-rw-r--r--tests/benchmarks/inverted-thundering-herd/stm.go74
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)
+ }
+}