diff options
author | Matt Joiner <anacrolix@gmail.com> | 2020-08-28 10:08:42 +1000 |
---|---|---|
committer | Matt Joiner <anacrolix@gmail.com> | 2020-08-28 10:08:42 +1000 |
commit | d6fb810e5e00ddbe5b7d06f49d8a08d25e54c723 (patch) | |
tree | ea68305be6fbc85af6965acfb7a768d506f6193d /tx.go | |
parent | Add thundering herd tests (diff) | |
download | stm-d6fb810e5e00ddbe5b7d06f49d8a08d25e54c723.tar.gz stm-d6fb810e5e00ddbe5b7d06f49d8a08d25e54c723.tar.xz |
Dedicated tx locks type
Reduces allocations
Diffstat (limited to 'tx.go')
-rw-r--r-- | tx.go | 43 |
1 files changed, 33 insertions, 10 deletions
@@ -11,7 +11,7 @@ import ( type Tx struct { reads map[*Var]uint64 writes map[*Var]interface{} - locks []*sync.Mutex + locks txLocks mu sync.Mutex cond sync.Cond } @@ -50,7 +50,7 @@ func (tx *Tx) wait() { } expvars.Add("waits", 1) tx.cond.Wait() - firstWait=false + firstWait = false } tx.mu.Unlock() for v := range tx.reads { @@ -115,12 +115,12 @@ func (tx *Tx) lockAllVars() { } func (tx *Tx) resetLocks() { - tx.locks = tx.locks[:0] + tx.locks.clear() } func (tx *Tx) collectReadLocks() { for v := range tx.reads { - tx.locks = append(tx.locks, &v.mu) + tx.locks.append(&v.mu) } } @@ -128,25 +128,23 @@ func (tx *Tx) collectAllLocks() { tx.collectReadLocks() for v := range tx.writes { if _, ok := tx.reads[v]; !ok { - tx.locks = append(tx.locks, &v.mu) + tx.locks.append(&v.mu) } } } func (tx *Tx) sortLocks() { - sort.Slice(tx.locks, func(i, j int) bool { - return uintptr(unsafe.Pointer(tx.locks[i])) < uintptr(unsafe.Pointer(tx.locks[j])) - }) + sort.Sort(tx.locks) } func (tx *Tx) lock() { - for _, l := range tx.locks { + for _, l := range tx.locks.mus { l.Lock() } } func (tx *Tx) unlock() { - for _, l := range tx.locks { + for _, l := range tx.locks.mus { l.Unlock() } } @@ -154,3 +152,28 @@ func (tx *Tx) unlock() { func (tx *Tx) String() string { return fmt.Sprintf("%[1]T %[1]p", tx) } + +// Dedicated type avoids reflection in sort.Slice. +type txLocks struct { + mus []*sync.Mutex +} + +func (me txLocks) Len() int { + return len(me.mus) +} + +func (me txLocks) Less(i, j int) bool { + return uintptr(unsafe.Pointer(me.mus[i])) < uintptr(unsafe.Pointer(me.mus[j])) +} + +func (me txLocks) Swap(i, j int) { + me.mus[i], me.mus[j] = me.mus[j], me.mus[i] +} + +func (me *txLocks) clear() { + me.mus = me.mus[:0] +} + +func (me *txLocks) append(mu *sync.Mutex) { + me.mus = append(me.mus, mu) +} |