mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 11:42:33 +00:00
* stdlib tests now check refc too * typo * fixes line numbers * disable cpp * do not touch
636 lines
21 KiB
Nim
636 lines
21 KiB
Nim
discard """
|
|
matrix: "--mm:refc; --mm:orc"
|
|
"""
|
|
|
|
# test atomic operations
|
|
|
|
import std/[atomics, bitops]
|
|
import std/assertions
|
|
|
|
|
|
type
|
|
Object = object
|
|
val: int
|
|
|
|
|
|
# Atomic operations for trivial objects
|
|
|
|
|
|
block trivialLoad:
|
|
var location: Atomic[int]
|
|
location.store(1)
|
|
doAssert location.load == 1
|
|
location.store(2)
|
|
doAssert location.load(moRelaxed) == 2
|
|
location.store(3)
|
|
doAssert location.load(moAcquire) == 3
|
|
|
|
|
|
block trivialStore:
|
|
var location: Atomic[int]
|
|
location.store(1)
|
|
doAssert location.load == 1
|
|
location.store(2, moRelaxed)
|
|
doAssert location.load == 2
|
|
location.store(3, moRelease)
|
|
doAssert location.load == 3
|
|
|
|
|
|
block trivialExchange:
|
|
var location: Atomic[int]
|
|
location.store(1)
|
|
doAssert location.exchange(2) == 1
|
|
doAssert location.exchange(3, moRelaxed) == 2
|
|
doAssert location.exchange(4, moAcquire) == 3
|
|
doAssert location.exchange(5, moRelease) == 4
|
|
doAssert location.exchange(6, moAcquireRelease) == 5
|
|
doAssert location.load == 6
|
|
|
|
|
|
block trivialCompareExchangeDoesExchange:
|
|
var location: Atomic[int]
|
|
var expected = 1
|
|
location.store(1)
|
|
doAssert location.compareExchange(expected, 2)
|
|
doAssert expected == 1
|
|
doAssert location.load == 2
|
|
expected = 2
|
|
doAssert location.compareExchange(expected, 3, moRelaxed)
|
|
doAssert expected == 2
|
|
doAssert location.load == 3
|
|
expected = 3
|
|
doAssert location.compareExchange(expected, 4, moAcquire)
|
|
doAssert expected == 3
|
|
doAssert location.load == 4
|
|
expected = 4
|
|
doAssert location.compareExchange(expected, 5, moRelease)
|
|
doAssert expected == 4
|
|
doAssert location.load == 5
|
|
expected = 5
|
|
doAssert location.compareExchange(expected, 6, moAcquireRelease)
|
|
doAssert expected == 5
|
|
doAssert location.load == 6
|
|
|
|
|
|
block trivialCompareExchangeDoesNotExchange:
|
|
var location: Atomic[int]
|
|
var expected = 10
|
|
location.store(1)
|
|
doAssert not location.compareExchange(expected, 2)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 3, moRelaxed)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 4, moAcquire)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 5, moRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 6, moAcquireRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
|
|
|
|
block trivialCompareExchangeSuccessFailureDoesExchange:
|
|
var location: Atomic[int]
|
|
var expected = 1
|
|
location.store(1)
|
|
doAssert location.compareExchange(expected, 2, moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == 1
|
|
doAssert location.load == 2
|
|
expected = 2
|
|
doAssert location.compareExchange(expected, 3, moRelaxed, moRelaxed)
|
|
doAssert expected == 2
|
|
doAssert location.load == 3
|
|
expected = 3
|
|
doAssert location.compareExchange(expected, 4, moAcquire, moAcquire)
|
|
doAssert expected == 3
|
|
doAssert location.load == 4
|
|
expected = 4
|
|
doAssert location.compareExchange(expected, 5, moRelease, moRelease)
|
|
doAssert expected == 4
|
|
doAssert location.load == 5
|
|
expected = 5
|
|
doAssert location.compareExchange(expected, 6, moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == 5
|
|
doAssert location.load == 6
|
|
|
|
|
|
block trivialCompareExchangeSuccessFailureDoesNotExchange:
|
|
var location: Atomic[int]
|
|
var expected = 10
|
|
location.store(1)
|
|
doAssert not location.compareExchange(expected, 2, moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 3, moRelaxed, moRelaxed)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 4, moAcquire, moAcquire)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 5, moRelease, moRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchange(expected, 6, moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
|
|
|
|
block trivialCompareExchangeWeakDoesExchange:
|
|
var location: Atomic[int]
|
|
var expected = 1
|
|
location.store(1)
|
|
doAssert location.compareExchangeWeak(expected, 2)
|
|
doAssert expected == 1
|
|
doAssert location.load == 2
|
|
expected = 2
|
|
doAssert location.compareExchangeWeak(expected, 3, moRelaxed)
|
|
doAssert expected == 2
|
|
doAssert location.load == 3
|
|
expected = 3
|
|
doAssert location.compareExchangeWeak(expected, 4, moAcquire)
|
|
doAssert expected == 3
|
|
doAssert location.load == 4
|
|
expected = 4
|
|
doAssert location.compareExchangeWeak(expected, 5, moRelease)
|
|
doAssert expected == 4
|
|
doAssert location.load == 5
|
|
expected = 5
|
|
doAssert location.compareExchangeWeak(expected, 6, moAcquireRelease)
|
|
doAssert expected == 5
|
|
doAssert location.load == 6
|
|
|
|
|
|
block trivialCompareExchangeWeakDoesNotExchange:
|
|
var location: Atomic[int]
|
|
var expected = 10
|
|
location.store(1)
|
|
doAssert not location.compareExchangeWeak(expected, 2)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 3, moRelaxed)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 4, moAcquire)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 5, moRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 6, moAcquireRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
|
|
|
|
block trivialCompareExchangeWeakSuccessFailureDoesExchange:
|
|
var location: Atomic[int]
|
|
var expected = 1
|
|
location.store(1)
|
|
doAssert location.compareExchangeWeak(expected, 2, moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == 1
|
|
doAssert location.load == 2
|
|
expected = 2
|
|
doAssert location.compareExchangeWeak(expected, 3, moRelaxed, moRelaxed)
|
|
doAssert expected == 2
|
|
doAssert location.load == 3
|
|
expected = 3
|
|
doAssert location.compareExchangeWeak(expected, 4, moAcquire, moAcquire)
|
|
doAssert expected == 3
|
|
doAssert location.load == 4
|
|
expected = 4
|
|
doAssert location.compareExchangeWeak(expected, 5, moRelease, moRelease)
|
|
doAssert expected == 4
|
|
doAssert location.load == 5
|
|
expected = 5
|
|
doAssert location.compareExchangeWeak(expected, 6, moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == 5
|
|
doAssert location.load == 6
|
|
|
|
|
|
block trivialCompareExchangeWeakSuccessFailureDoesNotExchange:
|
|
var location: Atomic[int]
|
|
var expected = 10
|
|
location.store(1)
|
|
doAssert not location.compareExchangeWeak(expected, 2, moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 3, moRelaxed, moRelaxed)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 4, moAcquire, moAcquire)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 5, moRelease, moRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
expected = 10
|
|
doAssert not location.compareExchangeWeak(expected, 6, moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == 1
|
|
doAssert location.load == 1
|
|
|
|
|
|
# Atomic operations for non-trivial objects
|
|
|
|
|
|
block objectLoad:
|
|
var location: Atomic[Object]
|
|
location.store(Object(val: 1))
|
|
doAssert location.load == Object(val: 1)
|
|
location.store(Object(val: 2))
|
|
doAssert location.load(moRelaxed) == Object(val: 2)
|
|
location.store(Object(val: 3))
|
|
doAssert location.load(moAcquire) == Object(val: 3)
|
|
|
|
|
|
block objectStore:
|
|
var location: Atomic[Object]
|
|
location.store(Object(val: 1))
|
|
doAssert location.load == Object(val: 1)
|
|
location.store(Object(val: 2), moRelaxed)
|
|
doAssert location.load == Object(val: 2)
|
|
location.store(Object(val: 3), moRelease)
|
|
doAssert location.load == Object(val: 3)
|
|
|
|
|
|
block objectExchange:
|
|
var location: Atomic[Object]
|
|
location.store(Object(val: 1))
|
|
doAssert location.exchange(Object(val: 2)) == Object(val: 1)
|
|
doAssert location.exchange(Object(val: 3), moRelaxed) == Object(val: 2)
|
|
doAssert location.exchange(Object(val: 4), moAcquire) == Object(val: 3)
|
|
doAssert location.exchange(Object(val: 5), moRelease) == Object(val: 4)
|
|
doAssert location.exchange(Object(val: 6), moAcquireRelease) == Object(val: 5)
|
|
doAssert location.load == Object(val: 6)
|
|
|
|
|
|
block objectCompareExchangeDoesExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 1)
|
|
location.store(Object(val: 1))
|
|
doAssert location.compareExchange(expected, Object(val: 2))
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 2)
|
|
expected = Object(val: 2)
|
|
doAssert location.compareExchange(expected, Object(val: 3), moRelaxed)
|
|
doAssert expected == Object(val: 2)
|
|
doAssert location.load == Object(val: 3)
|
|
expected = Object(val: 3)
|
|
doAssert location.compareExchange(expected, Object(val: 4), moAcquire)
|
|
doAssert expected == Object(val: 3)
|
|
doAssert location.load == Object(val: 4)
|
|
expected = Object(val: 4)
|
|
doAssert location.compareExchange(expected, Object(val: 5), moRelease)
|
|
doAssert expected == Object(val: 4)
|
|
doAssert location.load == Object(val: 5)
|
|
expected = Object(val: 5)
|
|
doAssert location.compareExchange(expected, Object(val: 6), moAcquireRelease)
|
|
doAssert expected == Object(val: 5)
|
|
doAssert location.load == Object(val: 6)
|
|
|
|
|
|
block objectCompareExchangeDoesNotExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 10)
|
|
location.store(Object(val: 1))
|
|
doAssert not location.compareExchange(expected, Object(val: 2))
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 3), moRelaxed)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 4), moAcquire)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 5), moRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 6), moAcquireRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
|
|
|
|
block objectCompareExchangeSuccessFailureDoesExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 1)
|
|
location.store(Object(val: 1))
|
|
doAssert location.compareExchange(expected, Object(val: 2), moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 2)
|
|
expected = Object(val: 2)
|
|
doAssert location.compareExchange(expected, Object(val: 3), moRelaxed, moRelaxed)
|
|
doAssert expected == Object(val: 2)
|
|
doAssert location.load == Object(val: 3)
|
|
expected = Object(val: 3)
|
|
doAssert location.compareExchange(expected, Object(val: 4), moAcquire, moAcquire)
|
|
doAssert expected == Object(val: 3)
|
|
doAssert location.load == Object(val: 4)
|
|
expected = Object(val: 4)
|
|
doAssert location.compareExchange(expected, Object(val: 5), moRelease, moRelease)
|
|
doAssert expected == Object(val: 4)
|
|
doAssert location.load == Object(val: 5)
|
|
expected = Object(val: 5)
|
|
doAssert location.compareExchange(expected, Object(val: 6), moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == Object(val: 5)
|
|
doAssert location.load == Object(val: 6)
|
|
|
|
|
|
block objectCompareExchangeSuccessFailureDoesNotExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 10)
|
|
location.store(Object(val: 1))
|
|
doAssert not location.compareExchange(expected, Object(val: 2), moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 3), moRelaxed, moRelaxed)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 4), moAcquire, moAcquire)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 5), moRelease, moRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchange(expected, Object(val: 6), moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
|
|
|
|
block objectCompareExchangeWeakDoesExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 1)
|
|
location.store(Object(val: 1))
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 2))
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 2)
|
|
expected = Object(val: 2)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 3), moRelaxed)
|
|
doAssert expected == Object(val: 2)
|
|
doAssert location.load == Object(val: 3)
|
|
expected = Object(val: 3)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 4), moAcquire)
|
|
doAssert expected == Object(val: 3)
|
|
doAssert location.load == Object(val: 4)
|
|
expected = Object(val: 4)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 5), moRelease)
|
|
doAssert expected == Object(val: 4)
|
|
doAssert location.load == Object(val: 5)
|
|
expected = Object(val: 5)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 6), moAcquireRelease)
|
|
doAssert expected == Object(val: 5)
|
|
doAssert location.load == Object(val: 6)
|
|
|
|
|
|
block objectCompareExchangeWeakDoesNotExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 10)
|
|
location.store(Object(val: 1))
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 2))
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 3), moRelaxed)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 4), moAcquire)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 5), moRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 6), moAcquireRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
|
|
|
|
block objectCompareExchangeWeakSuccessFailureDoesExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 1)
|
|
location.store(Object(val: 1))
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 2), moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 2)
|
|
expected = Object(val: 2)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 3), moRelaxed, moRelaxed)
|
|
doAssert expected == Object(val: 2)
|
|
doAssert location.load == Object(val: 3)
|
|
expected = Object(val: 3)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 4), moAcquire, moAcquire)
|
|
doAssert expected == Object(val: 3)
|
|
doAssert location.load == Object(val: 4)
|
|
expected = Object(val: 4)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 5), moRelease, moRelease)
|
|
doAssert expected == Object(val: 4)
|
|
doAssert location.load == Object(val: 5)
|
|
expected = Object(val: 5)
|
|
doAssert location.compareExchangeWeak(expected, Object(val: 6), moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == Object(val: 5)
|
|
doAssert location.load == Object(val: 6)
|
|
|
|
|
|
block objectCompareExchangeWeakSuccessFailureDoesNotExchange:
|
|
var location: Atomic[Object]
|
|
var expected = Object(val: 10)
|
|
location.store(Object(val: 1))
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 2), moSequentiallyConsistent, moSequentiallyConsistent)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 3), moRelaxed, moRelaxed)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 4), moAcquire, moAcquire)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 5), moRelease, moRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
expected = Object(val: 10)
|
|
doAssert not location.compareExchangeWeak(expected, Object(val: 6), moAcquireRelease, moAcquireRelease)
|
|
doAssert expected == Object(val: 1)
|
|
doAssert location.load == Object(val: 1)
|
|
|
|
|
|
# Numerical operations
|
|
|
|
|
|
block fetchAdd:
|
|
var location: Atomic[int]
|
|
doAssert location.fetchAdd(1) == 0
|
|
doAssert location.fetchAdd(1, moRelaxed) == 1
|
|
doAssert location.fetchAdd(1, moRelease) == 2
|
|
doAssert location.load == 3
|
|
|
|
|
|
block fetchSub:
|
|
var location: Atomic[int]
|
|
doAssert location.fetchSub(1) == 0
|
|
doAssert location.fetchSub(1, moRelaxed) == -1
|
|
doAssert location.fetchSub(1, moRelease) == -2
|
|
doAssert location.load == -3
|
|
|
|
|
|
block fetchAnd:
|
|
var location: Atomic[int]
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchAnd(j) == i)
|
|
doAssert(location.load == i.bitand(j))
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchAnd(j, moRelaxed) == i)
|
|
doAssert(location.load == i.bitand(j))
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchAnd(j, moRelease) == i)
|
|
doAssert(location.load == i.bitand(j))
|
|
|
|
|
|
block fetchOr:
|
|
var location: Atomic[int]
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchOr(j) == i)
|
|
doAssert(location.load == i.bitor(j))
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchOr(j, moRelaxed) == i)
|
|
doAssert(location.load == i.bitor(j))
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchOr(j, moRelease) == i)
|
|
doAssert(location.load == i.bitor(j))
|
|
|
|
|
|
block fetchXor:
|
|
var location: Atomic[int]
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchXor(j) == i)
|
|
doAssert(location.load == i.bitxor(j))
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchXor(j, moRelaxed) == i)
|
|
doAssert(location.load == i.bitxor(j))
|
|
|
|
for i in 0..16:
|
|
for j in 0..16:
|
|
location.store(i)
|
|
doAssert(location.fetchXor(j, moRelease) == i)
|
|
doAssert(location.load == i.bitxor(j))
|
|
|
|
|
|
block atomicInc:
|
|
var location: Atomic[int]
|
|
location.atomicInc
|
|
doAssert location.load == 1
|
|
location.atomicInc(1)
|
|
doAssert location.load == 2
|
|
location += 1
|
|
doAssert location.load == 3
|
|
|
|
|
|
block atomicDec:
|
|
var location: Atomic[int]
|
|
location.atomicDec
|
|
doAssert location.load == -1
|
|
location.atomicDec(1)
|
|
doAssert location.load == -2
|
|
location -= 1
|
|
doAssert location.load == -3
|
|
|
|
|
|
# Flag operations
|
|
|
|
|
|
block testAndSet:
|
|
var location: AtomicFlag
|
|
doAssert not location.testAndSet
|
|
doAssert location.testAndSet
|
|
doAssert location.testAndSet
|
|
location.clear()
|
|
doAssert not location.testAndSet(moRelaxed)
|
|
doAssert location.testAndSet(moRelaxed)
|
|
doAssert location.testAndSet(moRelaxed)
|
|
location.clear()
|
|
doAssert not location.testAndSet(moRelease)
|
|
doAssert location.testAndSet(moRelease)
|
|
doAssert location.testAndSet(moRelease)
|
|
|
|
|
|
block clear:
|
|
var location: AtomicFlag
|
|
discard location.testAndSet
|
|
location.clear
|
|
doAssert not location.testAndSet
|
|
location.clear(moRelaxed)
|
|
doAssert not location.testAndSet
|
|
location.clear(moRelease)
|
|
doAssert not location.testAndSet
|
|
|
|
block: # bug #18844
|
|
when not defined(cpp): # cpp pending pr #18836
|
|
type
|
|
Deprivation = object of RootObj
|
|
memes: Atomic[int]
|
|
Zoomer = object
|
|
dopamine: Deprivation
|
|
|
|
block:
|
|
var x = Deprivation()
|
|
var y = Zoomer()
|
|
doAssert x.memes.load == 0
|
|
doAssert y.dopamine.memes.load == 0
|
|
|
|
block:
|
|
var x: Deprivation
|
|
var y: Zoomer
|
|
doAssert x.memes.load == 0
|
|
doAssert y.dopamine.memes.load == 0
|