aboutsummaryrefslogtreecommitdiff
path: root/tests/benchmarks/thundering-herd/stm.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/benchmarks/thundering-herd/stm.go')
-rw-r--r--tests/benchmarks/thundering-herd/stm.go56
1 files changed, 56 insertions, 0 deletions
diff --git a/tests/benchmarks/thundering-herd/stm.go b/tests/benchmarks/thundering-herd/stm.go
new file mode 100644
index 0000000..fa31938
--- /dev/null
+++ b/tests/benchmarks/thundering-herd/stm.go
@@ -0,0 +1,56 @@
+package stm
+
+import (
+ "flag"
+)
+
+
+
+var nFlag = flag.Int(
+ "n",
+ 1_000,
+ "The number of iterations to execute",
+)
+
+func MainTest() {
+ flag.Parse()
+ n := *nFlag
+
+ const maxTokens = 25
+ for i := 0; i < n; i++ {
+ done := NewBuiltinEqVar(false)
+ tokens := NewBuiltinEqVar(0)
+ pending := NewBuiltinEqVar(0)
+ for i := 0; i < 1000; i++ {
+ Atomically(VoidOperation(func(tx *Tx) {
+ pending.Set(tx, pending.Get(tx)+1)
+ }))
+ go func() {
+ Atomically(VoidOperation(func(tx *Tx) {
+ t := tokens.Get(tx)
+ if t > 0 {
+ tokens.Set(tx, t-1)
+ pending.Set(tx, pending.Get(tx)-1)
+ } else {
+ tx.Retry()
+ }
+ }))
+ }()
+ }
+ 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
+ }) {
+ }
+ }()
+ Atomically(VoidOperation(func(tx *Tx) {
+ tx.Assert(pending.Get(tx) == 0)
+ }))
+ AtomicSet(done, true)
+ }
+}