|
1 | | -// Copyright 2022 The Go Authors. All rights reserved. |
2 | | -// Use of this source code is governed by a BSD-style |
3 | | -// license that can be found in the LICENSE file. |
4 | | - |
5 | | -//go:build !go1.19 |
| 1 | +//go:build !go1.24 |
6 | 2 |
|
7 | 3 | package atomic |
8 | 4 |
|
9 | | -import ( |
10 | | - "sync/atomic" |
11 | | - "unsafe" |
12 | | -) |
13 | | - |
14 | | -// A Bool is an atomic boolean value. |
15 | | -// The zero value is false. |
16 | | -type Bool struct { |
17 | | - _ noCopy |
18 | | - v uint32 |
19 | | -} |
20 | | - |
21 | | -// Load atomically loads and returns the value stored in x. |
22 | | -func (x *Bool) Load() bool { return atomic.LoadUint32(&x.v) != 0 } |
23 | | - |
24 | | -// Store atomically stores val into x. |
25 | | -func (x *Bool) Store(val bool) { atomic.StoreUint32(&x.v, b32(val)) } |
26 | | - |
27 | | -// Swap atomically stores new into x and returns the previous value. |
28 | | -func (x *Bool) Swap(new bool) (old bool) { return atomic.SwapUint32(&x.v, b32(new)) != 0 } |
29 | | - |
30 | | -// CompareAndSwap executes the compare-and-swap operation for the boolean value x. |
31 | | -func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { |
32 | | - return atomic.CompareAndSwapUint32(&x.v, b32(old), b32(new)) |
33 | | -} |
34 | | - |
35 | | -// b32 returns a uint32 0 or 1 representing b. |
36 | | -func b32(b bool) uint32 { |
37 | | - if b { |
38 | | - return 1 |
39 | | - } |
40 | | - return 0 |
41 | | -} |
42 | | - |
43 | | -// A Pointer is an atomic pointer of type *T. The zero value is a nil *T. |
44 | | -type Pointer[T any] struct { |
45 | | - // Mention *T in a field to disallow conversion between Pointer types. |
46 | | - // See go.dev/issue/56603 for more details. |
47 | | - // Use *T, not T, to avoid spurious recursive type definition errors. |
48 | | - _ [0]*T |
49 | | - |
50 | | - _ noCopy |
51 | | - v unsafe.Pointer |
52 | | -} |
53 | | - |
54 | | -// Load atomically loads and returns the value stored in x. |
55 | | -func (x *Pointer[T]) Load() *T { return (*T)(atomic.LoadPointer(&x.v)) } |
56 | | - |
57 | | -// Store atomically stores val into x. |
58 | | -func (x *Pointer[T]) Store(val *T) { atomic.StorePointer(&x.v, unsafe.Pointer(val)) } |
59 | | - |
60 | | -// Swap atomically stores new into x and returns the previous value. |
61 | | -func (x *Pointer[T]) Swap(new *T) (old *T) { |
62 | | - return (*T)(atomic.SwapPointer(&x.v, unsafe.Pointer(new))) |
63 | | -} |
64 | | - |
65 | | -// CompareAndSwap executes the compare-and-swap operation for x. |
66 | | -func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { |
67 | | - return atomic.CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new)) |
68 | | -} |
69 | | - |
70 | | -// An Int32 is an atomic int32. The zero value is zero. |
71 | | -type Int32 struct { |
72 | | - _ noCopy |
73 | | - v int32 |
74 | | -} |
75 | | - |
76 | | -// Load atomically loads and returns the value stored in x. |
77 | | -func (x *Int32) Load() int32 { return atomic.LoadInt32(&x.v) } |
78 | | - |
79 | | -// Store atomically stores val into x. |
80 | | -func (x *Int32) Store(val int32) { atomic.StoreInt32(&x.v, val) } |
81 | | - |
82 | | -// Swap atomically stores new into x and returns the previous value. |
83 | | -func (x *Int32) Swap(new int32) (old int32) { return atomic.SwapInt32(&x.v, new) } |
84 | | - |
85 | | -// CompareAndSwap executes the compare-and-swap operation for x. |
86 | | -func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) { |
87 | | - return atomic.CompareAndSwapInt32(&x.v, old, new) |
88 | | -} |
89 | | - |
90 | | -// Add atomically adds delta to x and returns the new value. |
91 | | -func (x *Int32) Add(delta int32) (new int32) { return atomic.AddInt32(&x.v, delta) } |
92 | | - |
93 | | -// An Int64 is an atomic int64. The zero value is zero. |
94 | | -type Int64 struct { |
95 | | - _ noCopy |
96 | | - v int64 |
97 | | -} |
98 | | - |
99 | | -// Load atomically loads and returns the value stored in x. |
100 | | -func (x *Int64) Load() int64 { return atomic.LoadInt64(&x.v) } |
101 | | - |
102 | | -// Store atomically stores val into x. |
103 | | -func (x *Int64) Store(val int64) { atomic.StoreInt64(&x.v, val) } |
| 5 | +import "sync/atomic" |
104 | 6 |
|
105 | | -// Swap atomically stores new into x and returns the previous value. |
106 | | -func (x *Int64) Swap(new int64) (old int64) { return atomic.SwapInt64(&x.v, new) } |
107 | | - |
108 | | -// CompareAndSwap executes the compare-and-swap operation for x. |
109 | | -func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) { |
110 | | - return atomic.CompareAndSwapInt64(&x.v, old, new) |
111 | | -} |
112 | | - |
113 | | -// Add atomically adds delta to x and returns the new value. |
114 | | -func (x *Int64) Add(delta int64) (new int64) { return atomic.AddInt64(&x.v, delta) } |
115 | | - |
116 | | -// An Uint32 is an atomic uint32. The zero value is zero. |
117 | | -type Uint32 struct { |
118 | | - _ noCopy |
119 | | - v uint32 |
120 | | -} |
121 | | - |
122 | | -// Load atomically loads and returns the value stored in x. |
123 | | -func (x *Uint32) Load() uint32 { return atomic.LoadUint32(&x.v) } |
124 | | - |
125 | | -// Store atomically stores val into x. |
126 | | -func (x *Uint32) Store(val uint32) { atomic.StoreUint32(&x.v, val) } |
127 | | - |
128 | | -// Swap atomically stores new into x and returns the previous value. |
129 | | -func (x *Uint32) Swap(new uint32) (old uint32) { return atomic.SwapUint32(&x.v, new) } |
130 | | - |
131 | | -// CompareAndSwap executes the compare-and-swap operation for x. |
132 | | -func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { |
133 | | - return atomic.CompareAndSwapUint32(&x.v, old, new) |
134 | | -} |
135 | | - |
136 | | -// Add atomically adds delta to x and returns the new value. |
137 | | -func (x *Uint32) Add(delta uint32) (new uint32) { return atomic.AddUint32(&x.v, delta) } |
138 | | - |
139 | | -// An Uint64 is an atomic uint64. The zero value is zero. |
140 | | -type Uint64 struct { |
141 | | - _ noCopy |
142 | | - v uint64 |
143 | | -} |
144 | | - |
145 | | -// Load atomically loads and returns the value stored in x. |
146 | | -func (x *Uint64) Load() uint64 { return atomic.LoadUint64(&x.v) } |
147 | | - |
148 | | -// Store atomically stores val into x. |
149 | | -func (x *Uint64) Store(val uint64) { atomic.StoreUint64(&x.v, val) } |
150 | | - |
151 | | -// Swap atomically stores new into x and returns the previous value. |
152 | | -func (x *Uint64) Swap(new uint64) (old uint64) { return atomic.SwapUint64(&x.v, new) } |
153 | | - |
154 | | -// CompareAndSwap executes the compare-and-swap operation for x. |
155 | | -func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { |
156 | | - return atomic.CompareAndSwapUint64(&x.v, old, new) |
157 | | -} |
158 | | - |
159 | | -// Add atomically adds delta to x and returns the new value. |
160 | | -func (x *Uint64) Add(delta uint64) (new uint64) { return atomic.AddUint64(&x.v, delta) } |
161 | | - |
162 | | -// An Uintptr is an atomic uintptr. The zero value is zero. |
163 | | -type Uintptr struct { |
164 | | - _ noCopy |
165 | | - v uintptr |
166 | | -} |
167 | | - |
168 | | -// Load atomically loads and returns the value stored in x. |
169 | | -func (x *Uintptr) Load() uintptr { return atomic.LoadUintptr(&x.v) } |
170 | | - |
171 | | -// Store atomically stores val into x. |
172 | | -func (x *Uintptr) Store(val uintptr) { atomic.StoreUintptr(&x.v, val) } |
173 | | - |
174 | | -// Swap atomically stores new into x and returns the previous value. |
175 | | -func (x *Uintptr) Swap(new uintptr) (old uintptr) { return atomic.SwapUintptr(&x.v, new) } |
176 | | - |
177 | | -// CompareAndSwap executes the compare-and-swap operation for x. |
178 | | -func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { |
179 | | - return atomic.CompareAndSwapUintptr(&x.v, old, new) |
180 | | -} |
181 | | - |
182 | | -// Add atomically adds delta to x and returns the new value. |
183 | | -func (x *Uintptr) Add(delta uintptr) (new uintptr) { return atomic.AddUintptr(&x.v, delta) } |
184 | | - |
185 | | -// noCopy may be added to structs which must not be copied |
186 | | -// after the first use. |
187 | | -// |
188 | | -// See https://golang.org/issues/8005#issuecomment-190753527 |
189 | | -// for details. |
190 | | -// |
191 | | -// Note that it must not be embedded, due to the Lock and Unlock methods. |
192 | | -type noCopy struct{} |
193 | | - |
194 | | -// Lock is a no-op used by -copylocks checker from `go vet`. |
195 | | -func (*noCopy) Lock() {} |
196 | | -func (*noCopy) Unlock() {} |
| 7 | +type ( |
| 8 | + Bool = atomic.Bool |
| 9 | + Int32 = atomic.Int32 |
| 10 | + Int64 = atomic.Int64 |
| 11 | + Uint32 = atomic.Uint32 |
| 12 | + Uint64 = atomic.Uint64 |
| 13 | + Uintptr = atomic.Uintptr |
| 14 | + Value = atomic.Value |
| 15 | +) |
197 | 16 |
|
198 | | -type Value = atomic.Value |
| 17 | +type Pointer[T any] atomic.Pointer[T] |
0 commit comments