diff options
author | Matt Joiner <anacrolix@gmail.com> | 2019-10-31 19:07:45 +1100 |
---|---|---|
committer | Matt Joiner <anacrolix@gmail.com> | 2019-10-31 19:07:45 +1100 |
commit | 28b37142a55f8f105475ac4380b4e49f3a160e93 (patch) | |
tree | 1d1f813d25432712fc13128e7dcf4b56674eb5cd | |
parent | Merge branch 'master' into var-conds (diff) | |
download | stm-28b37142a55f8f105475ac4380b4e49f3a160e93.tar.gz stm-28b37142a55f8f105475ac4380b4e49f3a160e93.tar.xz |
Optimize a bunch of stuff
-rw-r--r-- | funcs.go | 25 | ||||
-rw-r--r-- | tx.go | 19 | ||||
-rw-r--r-- | var.go | 11 |
3 files changed, 42 insertions, 13 deletions
@@ -1,14 +1,26 @@ package stm +import ( + "sync" +) + +var ( + txPool = sync.Pool{New: func() interface{} { + tx := &Tx{ + reads: make(map[*Var]uint64), + writes: make(map[*Var]interface{}), + } + tx.cond.L = &globalLock + return tx + }} +) + // Atomically executes the atomic function fn. func Atomically(fn func(*Tx)) interface{} { -retry: // run the transaction - tx := &Tx{ - reads: make(map[*Var]uint64), - writes: make(map[*Var]interface{}), - } - tx.cond.L = &globalLock + tx := txPool.Get().(*Tx) +retry: + tx.reset() var ret interface{} if func() (retry bool) { defer func() { @@ -40,6 +52,7 @@ retry: // commit the write log and broadcast that variables have changed tx.commit() globalLock.Unlock() + tx.recycle() return ret } @@ -24,16 +24,17 @@ func (tx *Tx) verify() bool { return true } -// commit writes the values in the transaction log to their respective Vars. +// Writes the values in the transaction log to their respective Vars. func (tx *Tx) commit() { for v, val := range tx.writes { v.mu.Lock() v.val = val v.version++ + v.mu.Unlock() for tx := range v.watchers { tx.cond.Broadcast() + delete(v.watchers, tx) } - v.mu.Unlock() } } @@ -95,3 +96,17 @@ func (tx *Tx) Return(v interface{}) { type _return struct { value interface{} } + +func (tx *Tx) reset() { + for k := range tx.reads { + delete(tx.reads, k) + } + for k := range tx.writes { + delete(tx.writes, k) + } +} + +func (tx *Tx) recycle() { + tx.reset() + txPool.Put(tx) +} @@ -2,15 +2,16 @@ package stm import "sync" -// A Var holds an STM variable. +// Holds an STM variable. type Var struct { - val interface{} - version uint64 - mu sync.Mutex + mu sync.Mutex + val interface{} + version uint64 + watchers map[*Tx]struct{} } -// NewVar returns a new STM variable. +// Returns a new STM variable. func NewVar(val interface{}) *Var { return &Var{ val: val, |