...
Source file src/pkg/sync/atomic/value.go
1
2
3
4
5 package atomic
6
7 import (
8 "unsafe"
9 )
10
11
12
13
14
15
16 type Value struct {
17 v interface{}
18 }
19
20
21 type ifaceWords struct {
22 typ unsafe.Pointer
23 data unsafe.Pointer
24 }
25
26
27
28 func (v *Value) Load() (x interface{}) {
29 vp := (*ifaceWords)(unsafe.Pointer(v))
30 typ := LoadPointer(&vp.typ)
31 if typ == nil || uintptr(typ) == ^uintptr(0) {
32
33 return nil
34 }
35 data := LoadPointer(&vp.data)
36 xp := (*ifaceWords)(unsafe.Pointer(&x))
37 xp.typ = typ
38 xp.data = data
39 return
40 }
41
42
43
44
45 func (v *Value) Store(x interface{}) {
46 if x == nil {
47 panic("sync/atomic: store of nil value into Value")
48 }
49 vp := (*ifaceWords)(unsafe.Pointer(v))
50 xp := (*ifaceWords)(unsafe.Pointer(&x))
51 for {
52 typ := LoadPointer(&vp.typ)
53 if typ == nil {
54
55
56
57
58 runtime_procPin()
59 if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
60 runtime_procUnpin()
61 continue
62 }
63
64 StorePointer(&vp.data, xp.data)
65 StorePointer(&vp.typ, xp.typ)
66 runtime_procUnpin()
67 return
68 }
69 if uintptr(typ) == ^uintptr(0) {
70
71
72
73 continue
74 }
75
76 if typ != xp.typ {
77 panic("sync/atomic: store of inconsistently typed value into Value")
78 }
79 StorePointer(&vp.data, xp.data)
80 return
81 }
82 }
83
84
85 func runtime_procPin()
86 func runtime_procUnpin()
87
View as plain text