aboutsummaryrefslogtreecommitdiff
path: root/stm_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'stm_test.go')
-rw-r--r--stm_test.go74
1 files changed, 37 insertions, 37 deletions
diff --git a/stm_test.go b/stm_test.go
index 5c0ae31..fdf7af2 100644
--- a/stm_test.go
+++ b/stm_test.go
@@ -11,17 +11,17 @@ import (
)
func TestDecrement(t *testing.T) {
- x := NewVar(1000)
+ x := NewVar[int](1000)
for i := 0; i < 500; i++ {
go Atomically(VoidOperation(func(tx *Tx) {
- cur := tx.Get(x).(int)
- tx.Set(x, cur-1)
+ cur := x.Get(tx)
+ x.Set(tx, cur-1)
}))
}
done := make(chan struct{})
go func() {
Atomically(VoidOperation(func(tx *Tx) {
- tx.Assert(tx.Get(x) == 500)
+ tx.Assert(x.Get(tx) == 500)
}))
close(done)
}()
@@ -35,7 +35,7 @@ func TestDecrement(t *testing.T) {
// read-only transaction aren't exempt from calling tx.inputsChanged
func TestReadVerify(t *testing.T) {
read := make(chan struct{})
- x, y := NewVar(1), NewVar(2)
+ x, y := NewVar[int](1), NewVar[int](2)
// spawn a transaction that writes to x
go func() {
@@ -50,10 +50,10 @@ func TestReadVerify(t *testing.T) {
// between the reads, causing this tx to retry.
var x2, y2 int
Atomically(VoidOperation(func(tx *Tx) {
- x2 = tx.Get(x).(int)
+ x2 = x.Get(tx)
read <- struct{}{}
<-read // wait for other tx to complete
- y2 = tx.Get(y).(int)
+ y2 = y.Get(tx)
}))
if x2 == 1 && y2 == 2 {
t.Fatal("read was not verified")
@@ -61,15 +61,15 @@ func TestReadVerify(t *testing.T) {
}
func TestRetry(t *testing.T) {
- x := NewVar(10)
+ x := NewVar[int](10)
// spawn 10 transactions, one every 10 milliseconds. This will decrement x
// to 0 over the course of 100 milliseconds.
go func() {
for i := 0; i < 10; i++ {
time.Sleep(10 * time.Millisecond)
Atomically(VoidOperation(func(tx *Tx) {
- cur := tx.Get(x).(int)
- tx.Set(x, cur-1)
+ cur := x.Get(tx)
+ x.Set(tx, cur-1)
}))
}
}()
@@ -77,7 +77,7 @@ func TestRetry(t *testing.T) {
// retry. This should result in no more than 1 retry per transaction.
retry := 0
Atomically(VoidOperation(func(tx *Tx) {
- cur := tx.Get(x).(int)
+ cur := x.Get(tx)
if cur != 0 {
retry++
tx.Retry()
@@ -93,16 +93,16 @@ func TestVerify(t *testing.T) {
type foo struct {
i int
}
- x := NewVar(&foo{3})
+ x := NewVar[*foo](&foo{3})
read := make(chan struct{})
// spawn a transaction that modifies x
go func() {
Atomically(VoidOperation(func(tx *Tx) {
<-read
- rx := tx.Get(x).(*foo)
+ rx := x.Get(tx)
rx.i = 7
- tx.Set(x, rx)
+ x.Set(tx, rx)
}))
read <- struct{}{}
// other tx should retry, so we need to read/send again
@@ -113,7 +113,7 @@ func TestVerify(t *testing.T) {
// between the reads, causing this tx to retry.
var i int
Atomically(VoidOperation(func(tx *Tx) {
- f := tx.Get(x).(*foo)
+ f := x.Get(tx)
i = f.i
read <- struct{}{}
<-read // wait for other tx to complete
@@ -128,9 +128,9 @@ func TestSelect(t *testing.T) {
require.Panics(t, func() { Atomically(Select()) })
// with one arg, Select adds no effect
- x := NewVar(2)
+ x := NewVar[int](2)
Atomically(Select(VoidOperation(func(tx *Tx) {
- tx.Assert(tx.Get(x).(int) == 2)
+ tx.Assert(x.Get(tx) == 2)
})))
picked := Atomically(Select(
@@ -146,7 +146,7 @@ func TestSelect(t *testing.T) {
func(tx *Tx) interface{} {
return 3
},
- )).(int)
+ ))
assert.EqualValues(t, 2, picked)
}
@@ -178,20 +178,20 @@ func TestPanic(t *testing.T) {
func TestReadWritten(t *testing.T) {
// reading a variable written in the same transaction should return the
// previously written value
- x := NewVar(3)
+ x := NewVar[int](3)
Atomically(VoidOperation(func(tx *Tx) {
- tx.Set(x, 5)
- tx.Assert(tx.Get(x).(int) == 5)
+ x.Set(tx, 5)
+ tx.Assert(x.Get(tx) == 5)
}))
}
func TestAtomicSetRetry(t *testing.T) {
// AtomicSet should cause waiting transactions to retry
- x := NewVar(3)
+ x := NewVar[int](3)
done := make(chan struct{})
go func() {
Atomically(VoidOperation(func(tx *Tx) {
- tx.Assert(tx.Get(x).(int) == 5)
+ tx.Assert(x.Get(tx) == 5)
}))
done <- struct{}{}
}()
@@ -206,21 +206,21 @@ func TestAtomicSetRetry(t *testing.T) {
func testPingPong(t testing.TB, n int, afterHit func(string)) {
ball := NewBuiltinEqVar(false)
- doneVar := NewVar(false)
- hits := NewVar(0)
- ready := NewVar(true) // The ball is ready for hitting.
+ doneVar := NewVar[bool](false)
+ hits := NewVar[int](0)
+ ready := NewVar[bool](true) // The ball is ready for hitting.
var wg sync.WaitGroup
- bat := func(from, to interface{}, noise string) {
+ bat := func(from, to bool, noise string) {
defer wg.Done()
for !Atomically(func(tx *Tx) interface{} {
- if tx.Get(doneVar).(bool) {
+ if doneVar.Get(tx) {
return true
}
- 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)
+ tx.Assert(ready.Get(tx))
+ if ball.Get(tx) == from {
+ ball.Set(tx, to)
+ hits.Set(tx, hits.Get(tx)+1)
+ ready.Set(tx, false)
return false
}
return tx.Retry()
@@ -233,8 +233,8 @@ func testPingPong(t testing.TB, n int, afterHit func(string)) {
go bat(false, true, "ping!")
go bat(true, false, "pong!")
Atomically(VoidOperation(func(tx *Tx) {
- tx.Assert(tx.Get(hits).(int) >= n)
- tx.Set(doneVar, true)
+ tx.Assert(hits.Get(tx) >= n)
+ doneVar.Set(tx, true)
}))
wg.Wait()
}
@@ -253,7 +253,7 @@ func TestSleepingBeauty(t *testing.T) {
}
//func TestRetryStack(t *testing.T) {
-// v := NewVar(nil)
+// v := NewVar[int](nil)
// go func() {
// i := 0
// for {
@@ -266,7 +266,7 @@ func TestSleepingBeauty(t *testing.T) {
// ret := func() {
// defer Atomically(nil)
// }
-// tx.Get(v)
+// v.Get(tx)
// tx.Assert(false)
// return ret
// })