Resolve cross file resolution errors in atomics (#19422) [backport:1.6]
* Resolve call undeclared routine testAndSet * Fix undeclared field atomicType
This commit is contained in:
parent
4a38092ac1
commit
851e515bba
3 changed files with 27 additions and 10 deletions
|
|
@ -293,19 +293,16 @@ else:
|
||||||
AtomicInt32 {.importc: "_Atomic NI32".} = int32
|
AtomicInt32 {.importc: "_Atomic NI32".} = int32
|
||||||
AtomicInt64 {.importc: "_Atomic NI64".} = int64
|
AtomicInt64 {.importc: "_Atomic NI64".} = int64
|
||||||
|
|
||||||
template atomicType*(T: typedesc[Trivial]): untyped =
|
|
||||||
# Maps the size of a trivial type to it's internal atomic type
|
|
||||||
when sizeof(T) == 1: AtomicInt8
|
|
||||||
elif sizeof(T) == 2: AtomicInt16
|
|
||||||
elif sizeof(T) == 4: AtomicInt32
|
|
||||||
elif sizeof(T) == 8: AtomicInt64
|
|
||||||
|
|
||||||
type
|
type
|
||||||
AtomicFlag* {.importc: "atomic_flag", size: 1.} = object
|
AtomicFlag* {.importc: "atomic_flag", size: 1.} = object
|
||||||
|
|
||||||
Atomic*[T] = object
|
Atomic*[T] = object
|
||||||
when T is Trivial:
|
when T is Trivial:
|
||||||
value: T.atomicType
|
# Maps the size of a trivial type to it's internal atomic type
|
||||||
|
when sizeof(T) == 1: value: AtomicInt8
|
||||||
|
elif sizeof(T) == 2: value: AtomicInt16
|
||||||
|
elif sizeof(T) == 4: value: AtomicInt32
|
||||||
|
elif sizeof(T) == 8: value: AtomicInt64
|
||||||
else:
|
else:
|
||||||
nonAtomicValue: T
|
nonAtomicValue: T
|
||||||
guard: AtomicFlag
|
guard: AtomicFlag
|
||||||
|
|
@ -364,11 +361,11 @@ else:
|
||||||
cast[T](atomic_fetch_xor_explicit(addr(location.value), cast[nonAtomicType(T)](value), order))
|
cast[T](atomic_fetch_xor_explicit(addr(location.value), cast[nonAtomicType(T)](value), order))
|
||||||
|
|
||||||
template withLock[T: not Trivial](location: var Atomic[T]; order: MemoryOrder; body: untyped): untyped =
|
template withLock[T: not Trivial](location: var Atomic[T]; order: MemoryOrder; body: untyped): untyped =
|
||||||
while location.guard.testAndSet(moAcquire): discard
|
while testAndSet(location.guard, moAcquire): discard
|
||||||
try:
|
try:
|
||||||
body
|
body
|
||||||
finally:
|
finally:
|
||||||
location.guard.clear(moRelease)
|
clear(location.guard, moRelease)
|
||||||
|
|
||||||
proc load*[T: not Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {.inline.} =
|
proc load*[T: not Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {.inline.} =
|
||||||
withLock(location, order):
|
withLock(location, order):
|
||||||
|
|
|
||||||
9
tests/stdlib/concurrency/atomicSample.nim
Normal file
9
tests/stdlib/concurrency/atomicSample.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import atomics
|
||||||
|
|
||||||
|
type
|
||||||
|
AtomicWithGeneric*[T] = object
|
||||||
|
value: Atomic[T]
|
||||||
|
|
||||||
|
proc initAtomicWithGeneric*[T](value: T): AtomicWithGeneric[T] =
|
||||||
|
result.value.store(value)
|
||||||
|
|
||||||
11
tests/stdlib/concurrency/tatomic_import.nim
Normal file
11
tests/stdlib/concurrency/tatomic_import.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import atomicSample
|
||||||
|
|
||||||
|
block crossFileObjectContainingAGenericWithAComplexObject:
|
||||||
|
discard initAtomicWithGeneric[string]("foo")
|
||||||
|
|
||||||
|
block crossFileObjectContainingAGenericWithAnInteger:
|
||||||
|
discard initAtomicWithGeneric[int](1)
|
||||||
|
discard initAtomicWithGeneric[int8](1)
|
||||||
|
discard initAtomicWithGeneric[int16](1)
|
||||||
|
discard initAtomicWithGeneric[int32](1)
|
||||||
|
discard initAtomicWithGeneric[int64](1)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue