aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Joiner <anacrolix@gmail.com>2019-10-23 16:07:08 +1100
committerMatt Joiner <anacrolix@gmail.com>2019-10-23 16:07:08 +1100
commit9cef1afed06ef975209116e3dee5f6187ef16073 (patch)
treef26bc936bf0e1fe3d0cc747c5cdabc5e87ea65a4
parentBreak up the stm.go file (diff)
downloadstm-9cef1afed06ef975209116e3dee5f6187ef16073.tar.gz
stm-9cef1afed06ef975209116e3dee5f6187ef16073.tar.xz
Add PingPong test and benchmark
-rw-r--r--bench_test.go5
-rw-r--r--stm_test.go41
2 files changed, 46 insertions, 0 deletions
diff --git a/bench_test.go b/bench_test.go
index f87477e..3dbdf73 100644
--- a/bench_test.go
+++ b/bench_test.go
@@ -125,3 +125,8 @@ func BenchmarkReadVarChannel(b *testing.B) {
wg.Wait()
}
}
+
+func BenchmarkPingPong(b *testing.B) {
+ b.ReportAllocs()
+ testPingPong(b, b.N, func(string) {})
+}
diff --git a/stm_test.go b/stm_test.go
index 233dff8..f030a8a 100644
--- a/stm_test.go
+++ b/stm_test.go
@@ -216,3 +216,44 @@ func TestAtomicSetRetry(t *testing.T) {
t.Fatal("AtomicSet did not wake up a waiting transaction")
}
}
+
+func testPingPong(t testing.TB, n int, afterHit func(string)) {
+ ball := NewVar(false)
+ doneVar := NewVar(false)
+ hits := NewVar(0)
+ ready := NewVar(true) // The ball is ready for hitting.
+ bat := func(from, to interface{}, noise string) {
+ done := false
+ for {
+ Atomically(func(tx *Tx) {
+ if tx.Get(doneVar).(bool) {
+ done = true
+ return
+ }
+ tx.Assert(tx.Get(ready).(bool))
+ if tx.Get(ball) == from {
+ tx.Set(ball, to)
+ tx.Set(hits, tx.Get(hits).(int)+1)
+ tx.Set(ready, false)
+ return
+ }
+ tx.Retry()
+ })
+ if done {
+ break
+ }
+ afterHit(noise)
+ AtomicSet(ready, true)
+ }
+ }
+ go bat(false, true, "ping!")
+ go bat(true, false, "pong!")
+ Atomically(func(tx *Tx) {
+ tx.Assert(tx.Get(hits).(int) >= n)
+ tx.Set(doneVar, true)
+ })
+}
+
+func TestPingPong(t *testing.T) {
+ testPingPong(t, 42, func(s string) { t.Log(s) })
+}