From 80ec29f423aeb8f7de75c057b12b2e5cd8cb35ba Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 4 Nov 2019 15:14:33 +1100 Subject: Use atomic pointers for Var data --- var.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'var.go') diff --git a/var.go b/var.go index bf48a41..2d0cb21 100644 --- a/var.go +++ b/var.go @@ -1,20 +1,40 @@ package stm -import "sync" +import ( + "sync/atomic" + "unsafe" +) // Holds an STM variable. type Var struct { - mu sync.Mutex + state *varSnapshot + watchers map[*Tx]struct{} +} + +func (v *Var) addr() *unsafe.Pointer { + return (*unsafe.Pointer)(unsafe.Pointer(&v.state)) +} + +func (v *Var) loadState() *varSnapshot { + return (*varSnapshot)(atomic.LoadPointer(v.addr())) +} + +func (v *Var) changeValue(new interface{}) { + version := v.loadState().version + atomic.StorePointer(v.addr(), unsafe.Pointer(&varSnapshot{version: version + 1, val: new})) +} + +type varSnapshot struct { val interface{} version uint64 - - watchers map[*Tx]struct{} } // Returns a new STM variable. func NewVar(val interface{}) *Var { return &Var{ - val: val, + state: &varSnapshot{ + val: val, + }, watchers: make(map[*Tx]struct{}), } } -- cgit v1.2.3