Skip to content

Atomic symbol resolution: unable to use std/atomics #12695

@mratsim

Description

@mratsim

I manage to reach an atomic dead-end with the long series of symbol resolution issues #8677

The code snippet at the bottom triggers on devel and 1.0.2 the following error messages:

.../debug/file1.nim(18, 15) template/generic instantiation of `trySend` from here
.../debug/file1.nim(12, 12) template/generic instantiation of `store` from here
.../.choosenim/toolchains/nim-#devel/lib/pure/concurrency/atomics.nim(302, 42) Error: undeclared field: 'value'

The relevant atomics are:

Atomic*[T] = object
when T is Trivial:
value: T.atomicType
else:
nonAtomicValue: T
guard: AtomicFlag
#proc init*[T](location: var Atomic[T]; value: T): T {.importcpp: "atomic_init(@)".}
proc atomic_load_explicit[T, A](location: ptr A; order: MemoryOrder): T {.importc.}
proc atomic_store_explicit[T, A](location: ptr A; desired: T; order: MemoryOrder = moSequentiallyConsistent) {.importc.}
proc atomic_exchange_explicit[T, A](location: ptr A; desired: T; order: MemoryOrder = moSequentiallyConsistent): T {.importc.}
proc atomic_compare_exchange_strong_explicit[T, A](location: ptr A; expected: ptr T; desired: T; success, failure: MemoryOrder): bool {.importc.}
proc atomic_compare_exchange_weak_explicit[T, A](location: ptr A; expected: ptr T; desired: T; success, failure: MemoryOrder): bool {.importc.}
# Numerical operations
proc atomic_fetch_add_explicit[T, A](location: ptr A; value: T; order: MemoryOrder = moSequentiallyConsistent): T {.importc.}
proc atomic_fetch_sub_explicit[T, A](location: ptr A; value: T; order: MemoryOrder = moSequentiallyConsistent): T {.importc.}
proc atomic_fetch_and_explicit[T, A](location: ptr A; value: T; order: MemoryOrder = moSequentiallyConsistent): T {.importc.}
proc atomic_fetch_or_explicit[T, A](location: ptr A; value: T; order: MemoryOrder = moSequentiallyConsistent): T {.importc.}
proc atomic_fetch_xor_explicit[T, A](location: ptr A; value: T; order: MemoryOrder = moSequentiallyConsistent): T {.importc.}
# Flag operations
# var ATOMIC_FLAG_INIT {.importc, nodecl.}: AtomicFlag
# proc init*(location: var AtomicFlag) {.inline.} = location = ATOMIC_FLAG_INIT
proc testAndSet*(location: var AtomicFlag; order: MemoryOrder = moSequentiallyConsistent): bool {.importc: "atomic_flag_test_and_set_explicit".}
proc clear*(location: var AtomicFlag; order: MemoryOrder = moSequentiallyConsistent) {.importc: "atomic_flag_clear_explicit".}
proc fence*(order: MemoryOrder) {.importc: "atomic_thread_fence".}
proc signalFence*(order: MemoryOrder) {.importc: "atomic_signal_fence".}
{.pop.}
proc load*[T: Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {.inline.} =
cast[T](atomic_load_explicit[nonAtomicType(T), type(location.value)](addr(location.value), order))
proc store*[T: Trivial](location: var Atomic[T]; desired: T; order: MemoryOrder = moSequentiallyConsistent) {.inline.} =
atomic_store_explicit(addr(location.value), cast[nonAtomicType(T)](desired), order)

Value is defined at line 269, exporting or mixin or bind don't work

import std/atomics

type
  MyType* = ptr object
    next*: Atomic[MyType]

  ChannelFoo*[T] = object
    front: T
    back: Atomic[T]

proc trySend*[T](chan: var ChannelFoo[T], src: sink T): bool =
  chan.back.store(nil, moRelaxed)


var x = createShared(typeof(default(MyType)[]))
var c = createShared(ChannelFoo[MyType])

let done = c[].trySend(x)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions