Skip to content

Commit

Permalink
Resolve cross file resolution errors in atomics (#19422) [backport:1.6]
Browse files Browse the repository at this point in the history
* Resolve call undeclared routine testAndSet

* Fix undeclared field atomicType
  • Loading branch information
Nycto authored Jan 20, 2022
1 parent 4a38092 commit 851e515
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
17 changes: 7 additions & 10 deletions lib/pure/concurrency/atomics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -293,19 +293,16 @@ else:
AtomicInt32 {.importc: "_Atomic NI32".} = int32
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
AtomicFlag* {.importc: "atomic_flag", size: 1.} = object

Atomic*[T] = object
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:
nonAtomicValue: T
guard: AtomicFlag
Expand Down Expand Up @@ -364,11 +361,11 @@ else:
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 =
while location.guard.testAndSet(moAcquire): discard
while testAndSet(location.guard, moAcquire): discard
try:
body
finally:
location.guard.clear(moRelease)
clear(location.guard, moRelease)

proc load*[T: not Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {.inline.} =
withLock(location, order):
Expand Down
9 changes: 9 additions & 0 deletions tests/stdlib/concurrency/atomicSample.nim
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions tests/stdlib/concurrency/tatomic_import.nim
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 851e515

Please sign in to comment.