> The atomic RCing can be done like so:
proc incRef(x: ptr ObjectHeader) =
let allocator = regionof(x)
if allocator.isShared: atomicInc(x.rc)
else: inc(x.rc)
Run
@Araq, I see the Allocator definition but the above method of determining
whether to use atomic ref counts or not is pretty costly as a runtime check in
at least requiring a branch instruction and reading a field of a heap object on
every ref count.
Using a default of just doing atomic ref counts wouldn't be much slower even
when the allocator is not shared.
So the default could be to use atomic ref counts as in
x.rc.atomicInc/x.rc.atomicDec when threading is enabled but if there exists a
(unowned) refNonAtomic T which is the same except that it uses non-atomic
inc/dec (this version is the one used when threading is disabled), and when one
can guarantee single thread access as in having Lock'ed access or by other
means, then this the alternate distinct type can be used as follows:
let myref = bitcopy cast[refObjNonAtomic[aref.type]](aref)
# now using myref, everything is the same except non atomic ref counting
# we can assign and move non owned refs freely and quickly as required
myref = bitcopy nil # to cancel the normal destruction when it goes out of
scope
# we obtained it by a bit copy cast, so we need to get rid of it as cheaply
Run
The scheme depends on trusting the programmer not to use this when there is a
chance of multi-threaded access, but those are the joys of multi-threaded
programming...