Skip to content

Commit d0c3573

Browse files
authored
Merge pull request nim-lang#5 from planetis-m/smartptrs
Add smartptrs and atomics
2 parents 71ffdc5 + 726e2ca commit d0c3573

File tree

8 files changed

+713
-6
lines changed

8 files changed

+713
-6
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ jobs:
135135
- name: Run tests
136136
run: |
137137
cd threading
138-
nimble test
138+
nimble --threads:on test
139139
140140
# - name: Build docs
141141
# if: matrix.branch == 'devel'

tests/fake_test.nim

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/nim.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--path:"../"

tests/tatomics.nim

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
import std/bitops, threading/atomics
2+
# Atomic operations for trivial objects
3+
4+
block trivialLoad:
5+
var location: Atomic[int]
6+
location.store(1)
7+
assert location.load == 1
8+
location.store(2)
9+
assert location.load(Relaxed) == 2
10+
location.store(3)
11+
assert location.load(Acquire) == 3
12+
13+
block trivialStore:
14+
var location: Atomic[int]
15+
location.store(1)
16+
assert location.load == 1
17+
location.store(2, Relaxed)
18+
assert location.load == 2
19+
location.store(3, Release)
20+
assert location.load == 3
21+
22+
block trivialExchange:
23+
var location: Atomic[int]
24+
location.store(1)
25+
assert location.exchange(2) == 1
26+
assert location.exchange(3, Relaxed) == 2
27+
assert location.exchange(4, Acquire) == 3
28+
assert location.exchange(5, Release) == 4
29+
assert location.exchange(6, AcqRel) == 5
30+
assert location.load == 6
31+
32+
block trivialCompareExchangeDoesExchange:
33+
var location: Atomic[int]
34+
var expected = 1
35+
location.store(1)
36+
assert location.compareExchange(expected, 2)
37+
assert expected == 1
38+
assert location.load == 2
39+
expected = 2
40+
assert location.compareExchange(expected, 3, Relaxed)
41+
assert expected == 2
42+
assert location.load == 3
43+
expected = 3
44+
assert location.compareExchange(expected, 4, Acquire)
45+
assert expected == 3
46+
assert location.load == 4
47+
expected = 4
48+
assert location.compareExchange(expected, 5, Release)
49+
assert expected == 4
50+
assert location.load == 5
51+
expected = 5
52+
assert location.compareExchange(expected, 6, AcqRel)
53+
assert expected == 5
54+
assert location.load == 6
55+
56+
block trivialCompareExchangeDoesNotExchange:
57+
var location: Atomic[int]
58+
var expected = 10
59+
location.store(1)
60+
assert not location.compareExchange(expected, 2)
61+
assert expected == 1
62+
assert location.load == 1
63+
expected = 10
64+
assert not location.compareExchange(expected, 3, Relaxed)
65+
assert expected == 1
66+
assert location.load == 1
67+
expected = 10
68+
assert not location.compareExchange(expected, 4, Acquire)
69+
assert expected == 1
70+
assert location.load == 1
71+
expected = 10
72+
assert not location.compareExchange(expected, 5, Release)
73+
assert expected == 1
74+
assert location.load == 1
75+
expected = 10
76+
assert not location.compareExchange(expected, 6, AcqRel)
77+
assert expected == 1
78+
assert location.load == 1
79+
80+
block trivialCompareExchangeSuccessFailureDoesExchange:
81+
var location: Atomic[int]
82+
var expected = 1
83+
location.store(1)
84+
assert location.compareExchange(expected, 2, SeqCst, SeqCst)
85+
assert expected == 1
86+
assert location.load == 2
87+
expected = 2
88+
assert location.compareExchange(expected, 3, Relaxed, Relaxed)
89+
assert expected == 2
90+
assert location.load == 3
91+
expected = 3
92+
assert location.compareExchange(expected, 4, Acquire, Acquire)
93+
assert expected == 3
94+
assert location.load == 4
95+
expected = 4
96+
assert location.compareExchange(expected, 5, Release, Release)
97+
assert expected == 4
98+
assert location.load == 5
99+
expected = 5
100+
assert location.compareExchange(expected, 6, AcqRel, AcqRel)
101+
assert expected == 5
102+
assert location.load == 6
103+
104+
block trivialCompareExchangeSuccessFailureDoesNotExchange:
105+
var location: Atomic[int]
106+
var expected = 10
107+
location.store(1)
108+
assert not location.compareExchange(expected, 2, SeqCst, SeqCst)
109+
assert expected == 1
110+
assert location.load == 1
111+
expected = 10
112+
assert not location.compareExchange(expected, 3, Relaxed, Relaxed)
113+
assert expected == 1
114+
assert location.load == 1
115+
expected = 10
116+
assert not location.compareExchange(expected, 4, Acquire, Acquire)
117+
assert expected == 1
118+
assert location.load == 1
119+
expected = 10
120+
assert not location.compareExchange(expected, 5, Release, Release)
121+
assert expected == 1
122+
assert location.load == 1
123+
expected = 10
124+
assert not location.compareExchange(expected, 6, AcqRel, AcqRel)
125+
assert expected == 1
126+
assert location.load == 1
127+
128+
block trivialCompareExchangeWeakDoesExchange:
129+
var location: Atomic[int]
130+
var expected = 1
131+
location.store(1)
132+
assert location.compareExchangeWeak(expected, 2)
133+
assert expected == 1
134+
assert location.load == 2
135+
expected = 2
136+
assert location.compareExchangeWeak(expected, 3, Relaxed)
137+
assert expected == 2
138+
assert location.load == 3
139+
expected = 3
140+
assert location.compareExchangeWeak(expected, 4, Acquire)
141+
assert expected == 3
142+
assert location.load == 4
143+
expected = 4
144+
assert location.compareExchangeWeak(expected, 5, Release)
145+
assert expected == 4
146+
assert location.load == 5
147+
expected = 5
148+
assert location.compareExchangeWeak(expected, 6, AcqRel)
149+
assert expected == 5
150+
assert location.load == 6
151+
152+
block trivialCompareExchangeWeakDoesNotExchange:
153+
var location: Atomic[int]
154+
var expected = 10
155+
location.store(1)
156+
assert not location.compareExchangeWeak(expected, 2)
157+
assert expected == 1
158+
assert location.load == 1
159+
expected = 10
160+
assert not location.compareExchangeWeak(expected, 3, Relaxed)
161+
assert expected == 1
162+
assert location.load == 1
163+
expected = 10
164+
assert not location.compareExchangeWeak(expected, 4, Acquire)
165+
assert expected == 1
166+
assert location.load == 1
167+
expected = 10
168+
assert not location.compareExchangeWeak(expected, 5, Release)
169+
assert expected == 1
170+
assert location.load == 1
171+
expected = 10
172+
assert not location.compareExchangeWeak(expected, 6, AcqRel)
173+
assert expected == 1
174+
assert location.load == 1
175+
176+
block trivialCompareExchangeWeakSuccessFailureDoesExchange:
177+
var location: Atomic[int]
178+
var expected = 1
179+
location.store(1)
180+
assert location.compareExchangeWeak(expected, 2, SeqCst, SeqCst)
181+
assert expected == 1
182+
assert location.load == 2
183+
expected = 2
184+
assert location.compareExchangeWeak(expected, 3, Relaxed, Relaxed)
185+
assert expected == 2
186+
assert location.load == 3
187+
expected = 3
188+
assert location.compareExchangeWeak(expected, 4, Acquire, Acquire)
189+
assert expected == 3
190+
assert location.load == 4
191+
expected = 4
192+
assert location.compareExchangeWeak(expected, 5, Release, Release)
193+
assert expected == 4
194+
assert location.load == 5
195+
expected = 5
196+
assert location.compareExchangeWeak(expected, 6, AcqRel, AcqRel)
197+
assert expected == 5
198+
assert location.load == 6
199+
200+
block trivialCompareExchangeWeakSuccessFailureDoesNotExchange:
201+
var location: Atomic[int]
202+
var expected = 10
203+
location.store(1)
204+
assert not location.compareExchangeWeak(expected, 2, SeqCst, SeqCst)
205+
assert expected == 1
206+
assert location.load == 1
207+
expected = 10
208+
assert not location.compareExchangeWeak(expected, 3, Relaxed, Relaxed)
209+
assert expected == 1
210+
assert location.load == 1
211+
expected = 10
212+
assert not location.compareExchangeWeak(expected, 4, Acquire, Acquire)
213+
assert expected == 1
214+
assert location.load == 1
215+
expected = 10
216+
assert not location.compareExchangeWeak(expected, 5, Release, Release)
217+
assert expected == 1
218+
assert location.load == 1
219+
expected = 10
220+
assert not location.compareExchangeWeak(expected, 6, AcqRel, AcqRel)
221+
assert expected == 1
222+
assert location.load == 1
223+
224+
# Numerical operations
225+
226+
block fetchAdd:
227+
var location: Atomic[int]
228+
assert location.fetchAdd(1) == 0
229+
assert location.fetchAdd(1, Relaxed) == 1
230+
assert location.fetchAdd(1, Release) == 2
231+
assert location.load == 3
232+
233+
block fetchSub:
234+
var location: Atomic[int]
235+
assert location.fetchSub(1) == 0
236+
assert location.fetchSub(1, Relaxed) == -1
237+
assert location.fetchSub(1, Release) == -2
238+
assert location.load == -3
239+
240+
block fetchAnd:
241+
var location: Atomic[int]
242+
243+
for i in 0..16:
244+
for j in 0..16:
245+
location.store(i)
246+
assert(location.fetchAnd(j) == i)
247+
assert(location.load == i.bitand(j))
248+
249+
for i in 0..16:
250+
for j in 0..16:
251+
location.store(i)
252+
assert(location.fetchAnd(j, Relaxed) == i)
253+
assert(location.load == i.bitand(j))
254+
255+
for i in 0..16:
256+
for j in 0..16:
257+
location.store(i)
258+
assert(location.fetchAnd(j, Release) == i)
259+
assert(location.load == i.bitand(j))
260+
261+
block fetchOr:
262+
var location: Atomic[int]
263+
264+
for i in 0..16:
265+
for j in 0..16:
266+
location.store(i)
267+
assert(location.fetchOr(j) == i)
268+
assert(location.load == i.bitor(j))
269+
270+
for i in 0..16:
271+
for j in 0..16:
272+
location.store(i)
273+
assert(location.fetchOr(j, Relaxed) == i)
274+
assert(location.load == i.bitor(j))
275+
276+
for i in 0..16:
277+
for j in 0..16:
278+
location.store(i)
279+
assert(location.fetchOr(j, Release) == i)
280+
assert(location.load == i.bitor(j))
281+
282+
block fetchXor:
283+
var location: Atomic[int]
284+
285+
for i in 0..16:
286+
for j in 0..16:
287+
location.store(i)
288+
assert(location.fetchXor(j) == i)
289+
assert(location.load == i.bitxor(j))
290+
291+
for i in 0..16:
292+
for j in 0..16:
293+
location.store(i)
294+
assert(location.fetchXor(j, Relaxed) == i)
295+
assert(location.load == i.bitxor(j))
296+
297+
for i in 0..16:
298+
for j in 0..16:
299+
location.store(i)
300+
assert(location.fetchXor(j, Release) == i)
301+
assert(location.load == i.bitxor(j))
302+
303+
block atomicInc:
304+
var location: Atomic[int]
305+
location.atomicInc
306+
assert location.load == 1
307+
location.atomicInc(1)
308+
assert location.load == 2
309+
location += 1
310+
assert location.load == 3
311+
312+
block atomicDec:
313+
var location: Atomic[int]
314+
location.atomicDec
315+
assert location.load == -1
316+
location.atomicDec(1)
317+
assert location.load == -2
318+
location -= 1
319+
assert location.load == -3

tests/tsmartptrs.nim

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import threading/smartptrs
2+
3+
block:
4+
var a1: UniquePtr[int]
5+
var a2 = newUniquePtr(0)
6+
7+
assert $a1 == "nil"
8+
assert a1.isNil
9+
assert $a2 == "(val: 0)"
10+
assert not a2.isNil
11+
assert a2[] == 0
12+
13+
# UniquePtr can't be copied but can be moved
14+
let a3 = move a2
15+
16+
assert $a2 == "nil"
17+
assert a2.isNil
18+
19+
assert $a3 == "(val: 0)"
20+
assert not a3.isNil
21+
assert a3[] == 0
22+
23+
a1 = newUniquePtr(int)
24+
a1[] = 1
25+
assert a1[] == 1
26+
var a4 = newUniquePtr(string)
27+
a4[] = "hello world"
28+
assert a4[] == "hello world"
29+
30+
block:
31+
var a1: SharedPtr[int]
32+
let a2 = newSharedPtr(0)
33+
let a3 = a2
34+
35+
assert $a1 == "nil"
36+
assert a1.isNil
37+
assert $a2 == "(val: 0)"
38+
assert not a2.isNil
39+
assert a2[] == 0
40+
assert $a3 == "(val: 0)"
41+
assert not a3.isNil
42+
assert a3[] == 0
43+
44+
a1 = newSharedPtr(int)
45+
a1[] = 1
46+
assert a1[] == 1
47+
var a4 = newSharedPtr(string)
48+
a4[] = "hello world"
49+
assert a4[] == "hello world"
50+
51+
block:
52+
var a1: ConstPtr[float]
53+
let a2 = newConstPtr(0)
54+
let a3 = a2
55+
56+
assert $a1 == "nil"
57+
assert a1.isNil
58+
assert $a2 == "(val: 0)"
59+
assert not a2.isNil
60+
assert a2[] == 0
61+
assert $a3 == "(val: 0)"
62+
assert not a3.isNil
63+
assert a3[] == 0

0 commit comments

Comments
 (0)