1// run 2 3// Copyright 2022 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7package main 8 9import ( 10 "sync/atomic" 11 "unsafe" 12) 13 14var one interface{} = 1 15 16type eface struct { 17 typ unsafe.Pointer 18 data unsafe.Pointer 19} 20 21func f(c chan struct{}) { 22 var x atomic.Value 23 24 go func() { 25 x.Swap(one) // writing using the old marker 26 }() 27 for i := 0; i < 100000; i++ { 28 v := x.Load() // reading using the new marker 29 30 p := (*eface)(unsafe.Pointer(&v)).typ 31 if uintptr(p) == ^uintptr(0) { 32 // We read the old marker, which the new reader 33 // doesn't know is a case where it should retry 34 // instead of returning it. 35 panic("bad typ field") 36 } 37 } 38 c <- struct{}{} 39} 40 41func main() { 42 c := make(chan struct{}, 10) 43 for i := 0; i < 10; i++ { 44 go f(c) 45 } 46 for i := 0; i < 10; i++ { 47 <-c 48 } 49} 50