Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add smartptrs and atomics #5

Merged
merged 5 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
- name: Run tests
run: |
cd threading
nimble test
nimble --threads:on test

# - name: Build docs
# if: matrix.branch == 'devel'
Expand Down
1 change: 0 additions & 1 deletion tests/fake_test.nim

This file was deleted.

1 change: 1 addition & 0 deletions tests/nim.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--path:"../"
319 changes: 319 additions & 0 deletions tests/tatomics.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
import std/bitops, threading/atomics
# Atomic operations for trivial objects

block trivialLoad:
var location: Atomic[int]
location.store(1)
assert location.load == 1
location.store(2)
assert location.load(Relaxed) == 2
location.store(3)
assert location.load(Acquire) == 3

block trivialStore:
var location: Atomic[int]
location.store(1)
assert location.load == 1
location.store(2, Relaxed)
assert location.load == 2
location.store(3, Release)
assert location.load == 3

block trivialExchange:
var location: Atomic[int]
location.store(1)
assert location.exchange(2) == 1
assert location.exchange(3, Relaxed) == 2
assert location.exchange(4, Acquire) == 3
assert location.exchange(5, Release) == 4
assert location.exchange(6, AcqRel) == 5
assert location.load == 6

block trivialCompareExchangeDoesExchange:
var location: Atomic[int]
var expected = 1
location.store(1)
assert location.compareExchange(expected, 2)
assert expected == 1
assert location.load == 2
expected = 2
assert location.compareExchange(expected, 3, Relaxed)
assert expected == 2
assert location.load == 3
expected = 3
assert location.compareExchange(expected, 4, Acquire)
assert expected == 3
assert location.load == 4
expected = 4
assert location.compareExchange(expected, 5, Release)
assert expected == 4
assert location.load == 5
expected = 5
assert location.compareExchange(expected, 6, AcqRel)
assert expected == 5
assert location.load == 6

block trivialCompareExchangeDoesNotExchange:
var location: Atomic[int]
var expected = 10
location.store(1)
assert not location.compareExchange(expected, 2)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 3, Relaxed)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 4, Acquire)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 5, Release)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 6, AcqRel)
assert expected == 1
assert location.load == 1

block trivialCompareExchangeSuccessFailureDoesExchange:
var location: Atomic[int]
var expected = 1
location.store(1)
assert location.compareExchange(expected, 2, SeqCst, SeqCst)
assert expected == 1
assert location.load == 2
expected = 2
assert location.compareExchange(expected, 3, Relaxed, Relaxed)
assert expected == 2
assert location.load == 3
expected = 3
assert location.compareExchange(expected, 4, Acquire, Acquire)
assert expected == 3
assert location.load == 4
expected = 4
assert location.compareExchange(expected, 5, Release, Release)
assert expected == 4
assert location.load == 5
expected = 5
assert location.compareExchange(expected, 6, AcqRel, AcqRel)
assert expected == 5
assert location.load == 6

block trivialCompareExchangeSuccessFailureDoesNotExchange:
var location: Atomic[int]
var expected = 10
location.store(1)
assert not location.compareExchange(expected, 2, SeqCst, SeqCst)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 3, Relaxed, Relaxed)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 4, Acquire, Acquire)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 5, Release, Release)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchange(expected, 6, AcqRel, AcqRel)
assert expected == 1
assert location.load == 1

block trivialCompareExchangeWeakDoesExchange:
var location: Atomic[int]
var expected = 1
location.store(1)
assert location.compareExchangeWeak(expected, 2)
assert expected == 1
assert location.load == 2
expected = 2
assert location.compareExchangeWeak(expected, 3, Relaxed)
assert expected == 2
assert location.load == 3
expected = 3
assert location.compareExchangeWeak(expected, 4, Acquire)
assert expected == 3
assert location.load == 4
expected = 4
assert location.compareExchangeWeak(expected, 5, Release)
assert expected == 4
assert location.load == 5
expected = 5
assert location.compareExchangeWeak(expected, 6, AcqRel)
assert expected == 5
assert location.load == 6

block trivialCompareExchangeWeakDoesNotExchange:
var location: Atomic[int]
var expected = 10
location.store(1)
assert not location.compareExchangeWeak(expected, 2)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 3, Relaxed)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 4, Acquire)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 5, Release)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 6, AcqRel)
assert expected == 1
assert location.load == 1

block trivialCompareExchangeWeakSuccessFailureDoesExchange:
var location: Atomic[int]
var expected = 1
location.store(1)
assert location.compareExchangeWeak(expected, 2, SeqCst, SeqCst)
assert expected == 1
assert location.load == 2
expected = 2
assert location.compareExchangeWeak(expected, 3, Relaxed, Relaxed)
assert expected == 2
assert location.load == 3
expected = 3
assert location.compareExchangeWeak(expected, 4, Acquire, Acquire)
assert expected == 3
assert location.load == 4
expected = 4
assert location.compareExchangeWeak(expected, 5, Release, Release)
assert expected == 4
assert location.load == 5
expected = 5
assert location.compareExchangeWeak(expected, 6, AcqRel, AcqRel)
assert expected == 5
assert location.load == 6

block trivialCompareExchangeWeakSuccessFailureDoesNotExchange:
var location: Atomic[int]
var expected = 10
location.store(1)
assert not location.compareExchangeWeak(expected, 2, SeqCst, SeqCst)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 3, Relaxed, Relaxed)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 4, Acquire, Acquire)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 5, Release, Release)
assert expected == 1
assert location.load == 1
expected = 10
assert not location.compareExchangeWeak(expected, 6, AcqRel, AcqRel)
assert expected == 1
assert location.load == 1

# Numerical operations

block fetchAdd:
var location: Atomic[int]
assert location.fetchAdd(1) == 0
assert location.fetchAdd(1, Relaxed) == 1
assert location.fetchAdd(1, Release) == 2
assert location.load == 3

block fetchSub:
var location: Atomic[int]
assert location.fetchSub(1) == 0
assert location.fetchSub(1, Relaxed) == -1
assert location.fetchSub(1, Release) == -2
assert location.load == -3

block fetchAnd:
var location: Atomic[int]

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchAnd(j) == i)
assert(location.load == i.bitand(j))

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchAnd(j, Relaxed) == i)
assert(location.load == i.bitand(j))

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchAnd(j, Release) == i)
assert(location.load == i.bitand(j))

block fetchOr:
var location: Atomic[int]

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchOr(j) == i)
assert(location.load == i.bitor(j))

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchOr(j, Relaxed) == i)
assert(location.load == i.bitor(j))

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchOr(j, Release) == i)
assert(location.load == i.bitor(j))

block fetchXor:
var location: Atomic[int]

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchXor(j) == i)
assert(location.load == i.bitxor(j))

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchXor(j, Relaxed) == i)
assert(location.load == i.bitxor(j))

for i in 0..16:
for j in 0..16:
location.store(i)
assert(location.fetchXor(j, Release) == i)
assert(location.load == i.bitxor(j))

block atomicInc:
var location: Atomic[int]
location.atomicInc
assert location.load == 1
location.atomicInc(1)
assert location.load == 2
location += 1
assert location.load == 3

block atomicDec:
var location: Atomic[int]
location.atomicDec
assert location.load == -1
location.atomicDec(1)
assert location.load == -2
location -= 1
assert location.load == -3
63 changes: 63 additions & 0 deletions tests/tsmartptrs.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import threading/smartptrs

block:
var a1: UniquePtr[int]
var a2 = newUniquePtr(0)

assert $a1 == "nil"
assert a1.isNil
assert $a2 == "(val: 0)"
assert not a2.isNil
assert a2[] == 0

# UniquePtr can't be copied but can be moved
let a3 = move a2

assert $a2 == "nil"
assert a2.isNil

assert $a3 == "(val: 0)"
assert not a3.isNil
assert a3[] == 0

a1 = newUniquePtr(int)
a1[] = 1
assert a1[] == 1
var a4 = newUniquePtr(string)
a4[] = "hello world"
assert a4[] == "hello world"

block:
var a1: SharedPtr[int]
let a2 = newSharedPtr(0)
let a3 = a2

assert $a1 == "nil"
assert a1.isNil
assert $a2 == "(val: 0)"
assert not a2.isNil
assert a2[] == 0
assert $a3 == "(val: 0)"
assert not a3.isNil
assert a3[] == 0

a1 = newSharedPtr(int)
a1[] = 1
assert a1[] == 1
var a4 = newSharedPtr(string)
a4[] = "hello world"
assert a4[] == "hello world"

block:
var a1: ConstPtr[float]
let a2 = newConstPtr(0)
let a3 = a2

assert $a1 == "nil"
assert a1.isNil
assert $a2 == "(val: 0)"
assert not a2.isNil
assert a2[] == 0
assert $a3 == "(val: 0)"
assert not a3.isNil
assert a3[] == 0
Loading