summaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorChangkun Ou <hi@changkun.de>2022-09-20 08:53:56 +0200
committerGopher Robot <gobot@golang.org>2022-10-31 20:12:59 +0000
commit7366b199c52f1c6ac6590bf126357bd2762ebc5b (patch)
tree9365b244c7674de3cd9d04228b9adb6060ffa20c /src/sync
parent3aebf682e4928ab490b64b3ba6729c78c9d066ba (diff)
downloadgo-git-7366b199c52f1c6ac6590bf126357bd2762ebc5b.tar.gz
sync: use atomic.Pointer for entry
Change-Id: Ie3b4bfe483d7ef43da29ea1dd73d423dac36cf39 Reviewed-on: https://go-review.googlesource.com/c/go/+/432055 Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Changkun Ou <mail@changkun.de>
Diffstat (limited to 'src/sync')
-rw-r--r--src/sync/map.go43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/sync/map.go b/src/sync/map.go
index bde78b8878..fa1cf7cee2 100644
--- a/src/sync/map.go
+++ b/src/sync/map.go
@@ -6,7 +6,6 @@ package sync
import (
"sync/atomic"
- "unsafe"
)
// Map is like a Go map[interface{}]interface{} but is safe for concurrent use
@@ -74,7 +73,7 @@ type readOnly struct {
// expunged is an arbitrary pointer that marks entries which have been deleted
// from the dirty map.
-var expunged = unsafe.Pointer(new(any))
+var expunged = new(any)
// An entry is a slot in the map corresponding to a particular key.
type entry struct {
@@ -97,11 +96,13 @@ type entry struct {
// p != expunged. If p == expunged, an entry's associated value can be updated
// only after first setting m.dirty[key] = e so that lookups using the dirty
// map find the entry.
- p unsafe.Pointer // *interface{}
+ p atomic.Pointer[any]
}
func newEntry(i any) *entry {
- return &entry{p: unsafe.Pointer(&i)}
+ e := &entry{}
+ e.p.Store(&i)
+ return e
}
func (m *Map) loadReadOnly() readOnly {
@@ -140,11 +141,11 @@ func (m *Map) Load(key any) (value any, ok bool) {
}
func (e *entry) load() (value any, ok bool) {
- p := atomic.LoadPointer(&e.p)
+ p := e.p.Load()
if p == nil || p == expunged {
return nil, false
}
- return *(*any)(p), true
+ return *p, true
}
// Store sets the value for a key.
@@ -183,11 +184,11 @@ func (m *Map) Store(key, value any) {
// unchanged.
func (e *entry) tryStore(i *any) bool {
for {
- p := atomic.LoadPointer(&e.p)
+ p := e.p.Load()
if p == expunged {
return false
}
- if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) {
+ if e.p.CompareAndSwap(p, i) {
return true
}
}
@@ -198,14 +199,14 @@ func (e *entry) tryStore(i *any) bool {
// If the entry was previously expunged, it must be added to the dirty map
// before m.mu is unlocked.
func (e *entry) unexpungeLocked() (wasExpunged bool) {
- return atomic.CompareAndSwapPointer(&e.p, expunged, nil)
+ return e.p.CompareAndSwap(expunged, nil)
}
// storeLocked unconditionally stores a value to the entry.
//
// The entry must be known not to be expunged.
func (e *entry) storeLocked(i *any) {
- atomic.StorePointer(&e.p, unsafe.Pointer(i))
+ e.p.Store(i)
}
// LoadOrStore returns the existing value for the key if present.
@@ -252,12 +253,12 @@ func (m *Map) LoadOrStore(key, value any) (actual any, loaded bool) {
// If the entry is expunged, tryLoadOrStore leaves the entry unchanged and
// returns with ok==false.
func (e *entry) tryLoadOrStore(i any) (actual any, loaded, ok bool) {
- p := atomic.LoadPointer(&e.p)
+ p := e.p.Load()
if p == expunged {
return nil, false, false
}
if p != nil {
- return *(*any)(p), true, true
+ return *p, true, true
}
// Copy the interface after the first load to make this method more amenable
@@ -265,15 +266,15 @@ func (e *entry) tryLoadOrStore(i any) (actual any, loaded, ok bool) {
// shouldn't bother heap-allocating.
ic := i
for {
- if atomic.CompareAndSwapPointer(&e.p, nil, unsafe.Pointer(&ic)) {
+ if e.p.CompareAndSwap(nil, &ic) {
return i, false, true
}
- p = atomic.LoadPointer(&e.p)
+ p = e.p.Load()
if p == expunged {
return nil, false, false
}
if p != nil {
- return *(*any)(p), true, true
+ return *p, true, true
}
}
}
@@ -310,12 +311,12 @@ func (m *Map) Delete(key any) {
func (e *entry) delete() (value any, ok bool) {
for {
- p := atomic.LoadPointer(&e.p)
+ p := e.p.Load()
if p == nil || p == expunged {
return nil, false
}
- if atomic.CompareAndSwapPointer(&e.p, p, nil) {
- return *(*any)(p), true
+ if e.p.CompareAndSwap(p, nil) {
+ return *p, true
}
}
}
@@ -389,12 +390,12 @@ func (m *Map) dirtyLocked() {
}
func (e *entry) tryExpungeLocked() (isExpunged bool) {
- p := atomic.LoadPointer(&e.p)
+ p := e.p.Load()
for p == nil {
- if atomic.CompareAndSwapPointer(&e.p, nil, expunged) {
+ if e.p.CompareAndSwap(nil, expunged) {
return true
}
- p = atomic.LoadPointer(&e.p)
+ p = e.p.Load()
}
return p == expunged
}