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