more progress on destructors; removed old destructor based code as it proved confusing
This commit is contained in:
parent
255902f9a5
commit
fa92c519aa
9 changed files with 152 additions and 270 deletions
101
tests/destructor/tatomicptrs.nim
Normal file
101
tests/destructor/tatomicptrs.nim
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
discard """
|
||||
output: '''allocating
|
||||
allocating
|
||||
allocating
|
||||
55
|
||||
60
|
||||
99
|
||||
deallocating
|
||||
deallocating
|
||||
deallocating
|
||||
'''
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
"""
|
||||
|
||||
type
|
||||
SharedPtr*[T] = object
|
||||
x: ptr T
|
||||
|
||||
#proc isNil[T](s: SharedPtr[T]): bool {.inline.} = s.x.isNil
|
||||
|
||||
template incRef(x) =
|
||||
atomicInc(x.refcount)
|
||||
|
||||
template decRef(x): untyped = atomicDec(x.refcount)
|
||||
|
||||
proc makeShared*[T](x: T): SharedPtr[T] =
|
||||
# XXX could benefit from 'sink' parameter.
|
||||
# XXX could benefit from a macro that generates it.
|
||||
result = cast[SharedPtr[T]](allocShared(sizeof(x)))
|
||||
result.x[] = x
|
||||
echo "allocating"
|
||||
|
||||
proc `=destroy`*[T](dest: var SharedPtr[T]) =
|
||||
var s = dest.x
|
||||
if s != nil and decRef(s) == 0:
|
||||
`=destroy`(s[])
|
||||
deallocShared(s)
|
||||
echo "deallocating"
|
||||
dest.x = nil
|
||||
|
||||
proc `=`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
|
||||
var s = src.x
|
||||
if s != nil: incRef(s)
|
||||
#atomicSwap(dest, s)
|
||||
# XXX use an atomic store here:
|
||||
swap(dest.x, s)
|
||||
if s != nil and decRef(s) == 0:
|
||||
`=destroy`(s[])
|
||||
deallocShared(s)
|
||||
echo "deallocating"
|
||||
|
||||
proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
|
||||
## XXX make this an atomic store:
|
||||
if dest.x != src.x:
|
||||
let s = dest.x
|
||||
if s != nil:
|
||||
`=destroy`(s[])
|
||||
deallocShared(s)
|
||||
echo "deallocating"
|
||||
dest.x = src.x
|
||||
|
||||
template `.`*[T](s: SharedPtr[T]; field: untyped): untyped =
|
||||
s.x.field
|
||||
|
||||
template `.=`*[T](s: SharedPtr[T]; field, value: untyped) =
|
||||
s.x.field = value
|
||||
|
||||
from macros import unpackVarargs
|
||||
|
||||
template `.()`*[T](s: SharedPtr[T]; field: untyped, args: varargs[untyped]): untyped =
|
||||
unpackVarargs(s.x.field, args)
|
||||
|
||||
|
||||
type
|
||||
Tree = SharedPtr[TreeObj]
|
||||
TreeObj = object
|
||||
refcount: int
|
||||
le, ri: Tree
|
||||
data: int
|
||||
|
||||
proc takesTree(a: Tree) =
|
||||
if not a.isNil:
|
||||
takesTree(a.le)
|
||||
echo a.data
|
||||
takesTree(a.ri)
|
||||
|
||||
proc createTree(data: int): Tree =
|
||||
result = makeShared(TreeObj(refcount: 1, data: data))
|
||||
|
||||
proc createTree(data: int; le, ri: Tree): Tree =
|
||||
result = makeShared(TreeObj(refcount: 1, le: le, ri: ri, data: data))
|
||||
|
||||
|
||||
proc main =
|
||||
let le = createTree(55)
|
||||
let ri = createTree(99)
|
||||
let t = createTree(60, le, ri)
|
||||
takesTree(t)
|
||||
|
||||
main()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue