From 30943ded71e123886291ad393e55bfb6aa837df3 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Wed, 8 Jun 2022 02:28:37 -0600 Subject: BIG change: generic Var[T], txVar, etc. --- funcs.go | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'funcs.go') diff --git a/funcs.go b/funcs.go index 53975e0..3336c71 100644 --- a/funcs.go +++ b/funcs.go @@ -2,7 +2,6 @@ package stm import ( "math/rand" - "reflect" "runtime/pprof" "sync" "time" @@ -12,9 +11,9 @@ var ( txPool = sync.Pool{New: func() interface{} { expvars.Add("new txs", 1) tx := &Tx{ - reads: make(map[*Var]VarValue), - writes: make(map[*Var]interface{}), - watching: make(map[*Var]struct{}), + reads: make(map[txVar]VarValue), + writes: make(map[txVar]interface{}), + watching: make(map[txVar]struct{}), } tx.cond.L = &tx.mu return tx @@ -104,12 +103,12 @@ retry: } // AtomicGet is a helper function that atomically reads a value. -func AtomicGet(v *Var) interface{} { - return v.value.Load().Get() +func AtomicGet[T any](v *Var[T]) T { + return v.value.Load().Get().(T) } // AtomicSet is a helper function that atomically writes a value. -func AtomicSet(v *Var, val interface{}) { +func AtomicSet[T any](v *Var[T], val interface{}) { v.mu.Lock() v.changeValue(val) v.mu.Unlock() @@ -140,7 +139,7 @@ func Select(fns ...Operation) Operation { return fns[0](tx) default: oldWrites := tx.writes - tx.writes = make(map[*Var]interface{}, len(oldWrites)) + tx.writes = make(map[txVar]interface{}, len(oldWrites)) for k, v := range oldWrites { tx.writes[k] = v } @@ -164,14 +163,8 @@ func VoidOperation(f func(*Tx)) Operation { } } -func AtomicModify(v *Var, f interface{}) { - r := reflect.ValueOf(f) +func AtomicModify[T any](v *Var[T], f func(T) T) { Atomically(VoidOperation(func(tx *Tx) { - cur := reflect.ValueOf(tx.Get(v)) - out := r.Call([]reflect.Value{cur}) - if lenOut := len(out); lenOut != 1 { - panic(lenOut) - } - tx.Set(v, out[0].Interface()) + v.Set(tx, f(v.Get(tx))) })) } -- cgit v1.2.3