aboutsummaryrefslogtreecommitdiff
path: root/tests/functional/usage/stm.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/usage/stm.go')
-rw-r--r--tests/functional/usage/stm.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/tests/functional/usage/stm.go b/tests/functional/usage/stm.go
new file mode 100644
index 0000000..dcc6736
--- /dev/null
+++ b/tests/functional/usage/stm.go
@@ -0,0 +1,76 @@
+package stm
+
+import (
+ g "gobang"
+)
+
+
+
+func MainTest() {
+ g.TestStart("Example of API usage")
+
+ g.Testing("operating on int variables", func() {
+ // create a shared variable
+ n := NewVar(3)
+
+ // read a variable
+ var v int
+ Atomically(VoidOperation(func(tx *Tx) {
+ v = n.Get(tx)
+ }))
+ g.TAssertEqual(v, 3)
+
+ // or:
+ v = Deref(n)
+ g.TAssertEqual(v, 3)
+
+ // write to a variable
+ Atomically(VoidOperation(func(tx *Tx) {
+ n.Set(tx, 12)
+ }))
+ g.TAssertEqual(Deref(n), 12)
+
+ // or:
+ AtomicSet(n, 11)
+ g.TAssertEqual(Deref(n), 11)
+
+ // update a variable
+ Atomically(VoidOperation(func(tx *Tx) {
+ cur := n.Get(tx)
+ n.Set(tx, cur+1)
+ }))
+ g.TAssertEqual(Deref(n), 12)
+
+ // block until a condition is met
+ Atomically(VoidOperation(func(tx *Tx) {
+ cur := n.Get(tx)
+ if cur == 0 {
+ tx.Retry()
+ }
+ n.Set(tx, 10)
+ }))
+ g.TAssertEqual(Deref(n), 10)
+
+ // or:
+ Atomically(VoidOperation(func(tx *Tx) {
+ cur := n.Get(tx)
+ tx.Assert(cur != 0)
+ n.Set(tx, 11)
+ }))
+ g.TAssertEqual(Deref(n), 11)
+
+ // select among multiple (potentially blocking) transactions
+ Atomically(Select(
+ // this function blocks forever, so it will be skipped
+ VoidOperation(func(tx *Tx) { tx.Retry() }),
+
+ // this function will always succeed without blocking
+ VoidOperation(func(tx *Tx) { n.Set(tx, 10) }),
+
+ // this function will never run, because the previous
+ // function succeeded
+ VoidOperation(func(tx *Tx) { n.Set(tx, 11) }),
+ ))
+ g.TAssertEqual(Deref(n), 10)
+ })
+}