]> Cypherpunks repositories - gostls13.git/commitdiff
sync/atomic: use a better first-store-in-progress marker
authorKeith Randall <khr@golang.org>
Thu, 9 Jul 2020 16:13:34 +0000 (09:13 -0700)
committerKeith Randall <khr@golang.org>
Tue, 26 Oct 2021 20:41:32 +0000 (20:41 +0000)
Unlike what the comment says, the GC can see this pointer.
Might as well make it a real pointer, even though ^uintptr(0)
isn't currently causing problems.

Removed the comment about GC not seeing the pointer.

Change-Id: I04bc1fd4848698bec6afb79bd5fda671dfc9a073
Reviewed-on: https://go-review.googlesource.com/c/go/+/241661
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Colin Arnott <colin@urandom.co.uk>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Keith Randall <khr@golang.org>

src/sync/atomic/value.go

index 3500cd22f4e74e7991d4f9cfca1ea6856695b722..af6295de91e19ef858f943c31a79427a8cad7122 100644 (file)
@@ -28,7 +28,7 @@ type ifaceWords struct {
 func (v *Value) Load() (val interface{}) {
        vp := (*ifaceWords)(unsafe.Pointer(v))
        typ := LoadPointer(&vp.typ)
-       if typ == nil || uintptr(typ) == ^uintptr(0) {
+       if typ == nil || typ == unsafe.Pointer(&firstStoreInProgress) {
                // First store not yet completed.
                return nil
        }
@@ -39,6 +39,8 @@ func (v *Value) Load() (val interface{}) {
        return
 }
 
+var firstStoreInProgress byte
+
 // Store sets the value of the Value to x.
 // All calls to Store for a given Value must use values of the same concrete type.
 // Store of an inconsistent type panics, as does Store(nil).
@@ -53,10 +55,9 @@ func (v *Value) Store(val interface{}) {
                if typ == nil {
                        // Attempt to start first store.
                        // Disable preemption so that other goroutines can use
-                       // active spin wait to wait for completion; and so that
-                       // GC does not see the fake type accidentally.
+                       // active spin wait to wait for completion.
                        runtime_procPin()
-                       if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
+                       if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) {
                                runtime_procUnpin()
                                continue
                        }
@@ -66,7 +67,7 @@ func (v *Value) Store(val interface{}) {
                        runtime_procUnpin()
                        return
                }
-               if uintptr(typ) == ^uintptr(0) {
+               if typ == unsafe.Pointer(&firstStoreInProgress) {
                        // First store in progress. Wait.
                        // Since we disable preemption around the first store,
                        // we can wait with active spinning.