Skip to content

Commit 3a0cd11

Browse files
committed
sync/atomic: use a better first-store-in-progress marker
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 <[email protected]> Reviewed-by: Colin Arnott <[email protected]> Reviewed-by: Dmitry Vyukov <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Keith Randall <[email protected]>
1 parent f8779b9 commit 3a0cd11

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

src/sync/atomic/value.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type ifaceWords struct {
2828
func (v *Value) Load() (val interface{}) {
2929
vp := (*ifaceWords)(unsafe.Pointer(v))
3030
typ := LoadPointer(&vp.typ)
31-
if typ == nil || uintptr(typ) == ^uintptr(0) {
31+
if typ == nil || typ == unsafe.Pointer(&firstStoreInProgress) {
3232
// First store not yet completed.
3333
return nil
3434
}
@@ -39,6 +39,8 @@ func (v *Value) Load() (val interface{}) {
3939
return
4040
}
4141

42+
var firstStoreInProgress byte
43+
4244
// Store sets the value of the Value to x.
4345
// All calls to Store for a given Value must use values of the same concrete type.
4446
// Store of an inconsistent type panics, as does Store(nil).
@@ -53,10 +55,9 @@ func (v *Value) Store(val interface{}) {
5355
if typ == nil {
5456
// Attempt to start first store.
5557
// Disable preemption so that other goroutines can use
56-
// active spin wait to wait for completion; and so that
57-
// GC does not see the fake type accidentally.
58+
// active spin wait to wait for completion.
5859
runtime_procPin()
59-
if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
60+
if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) {
6061
runtime_procUnpin()
6162
continue
6263
}
@@ -66,7 +67,7 @@ func (v *Value) Store(val interface{}) {
6667
runtime_procUnpin()
6768
return
6869
}
69-
if uintptr(typ) == ^uintptr(0) {
70+
if typ == unsafe.Pointer(&firstStoreInProgress) {
7071
// First store in progress. Wait.
7172
// Since we disable preemption around the first store,
7273
// we can wait with active spinning.

0 commit comments

Comments
 (0)