From 41b71487af6b9f17aebbd9374d2fd00337fcf188 Mon Sep 17 00:00:00 2001 From: James Date: Thu, 20 Jan 2022 04:58:59 -0800 Subject: [PATCH] Resolve cross file resolution errors in atomics (#19422) [backport:1.6] * Resolve call undeclared routine testAndSet * Fix undeclared field atomicType (cherry picked from commit 851e515bbae6edf6b28cf6723b2c7a45acce1869) --- lib/pure/concurrency/atomics.nim | 17 +++++++---------- tests/stdlib/concurrency/atomicSample.nim | 9 +++++++++ tests/stdlib/concurrency/tatomic_import.nim | 11 +++++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 tests/stdlib/concurrency/atomicSample.nim create mode 100644 tests/stdlib/concurrency/tatomic_import.nim diff --git a/lib/pure/concurrency/atomics.nim b/lib/pure/concurrency/atomics.nim index b252789fb4..c0a122bf95 100644 --- a/lib/pure/concurrency/atomics.nim +++ b/lib/pure/concurrency/atomics.nim @@ -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 @@ -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): diff --git a/tests/stdlib/concurrency/atomicSample.nim b/tests/stdlib/concurrency/atomicSample.nim new file mode 100644 index 0000000000..d56d867df3 --- /dev/null +++ b/tests/stdlib/concurrency/atomicSample.nim @@ -0,0 +1,9 @@ +import atomics + +type + AtomicWithGeneric*[T] = object + value: Atomic[T] + +proc initAtomicWithGeneric*[T](value: T): AtomicWithGeneric[T] = + result.value.store(value) + diff --git a/tests/stdlib/concurrency/tatomic_import.nim b/tests/stdlib/concurrency/tatomic_import.nim new file mode 100644 index 0000000000..e8faaae204 --- /dev/null +++ b/tests/stdlib/concurrency/tatomic_import.nim @@ -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)