* Atomic refcounting:
<https://github.com/mratsim/weave/blob/e5a3701/weave/cross_thread_com/flow_events.nim#L176-L201>
proc `=destroy`*(event: var FlowEvent) =
if event.e.isNil:
return
let count = event.e.refCount.load(moRelaxed)
fence(moAcquire)
if count == 0:
# We have the last reference
if not event.e.isNil:
if event.e.kind == Iteration:
wv_free(event.e.union.iter.singles)
# Return memory to the memory pool
recycle(event.e)
else:
discard fetchSub(event.e.refCount, 1, moRelease)
event.e = nil
proc `=sink`*(dst: var FlowEvent, src: FlowEvent) {.inline.} =
# Don't pay for atomic refcounting when compiler can prove there is no
ref change
`=destroy`(dst)
system.`=sink`(dst.e, src.e)
proc `=`*(dst: var FlowEvent, src: FlowEvent) {.inline.} =
`=destroy`(dst)
discard fetchAdd(src.e.refCount, 1, moRelaxed)
dst.e = src.e
Run
* Channels:
* Single-Producer Single-Consumer for stack object
<https://github.com/mratsim/weave/blob/e5a3701/weave/cross_thread_com/channels_spsc_single.nim>
* Single-Producer Single-Consumer for pointers (i.e. ownership transfer):
<https://github.com/mratsim/weave/blob/e5a3701/weave/cross_thread_com/channels_spsc_single_ptr.nim>
* Multi-Producer Single-Consumer for pointers with intrusive linked lists
(i.e. ownership transfer) and batching support:
<https://github.com/mratsim/weave/blob/e5a3701/weave/cross_thread_com/channels_mpsc_unbounded_batch.nim>
Note: they weren't tried with seq/strings/ref types but plain objects are
working well.