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) } }