diff options
author | Araq <rumpf_a@web.de> | 2017-12-01 01:52:00 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2017-12-01 01:52:00 +0100 |
commit | fa92c519aa6ac04f10655b1ab6992701549d4aed (patch) | |
tree | 226ba271daccfc14af091df54ea83c30ca53fe16 /tests/destructor/tatomicptrs.nim | |
parent | 255902f9a5a9f92ce2d65996a43626eff4c3b52c (diff) | |
download | Nim-fa92c519aa6ac04f10655b1ab6992701549d4aed.tar.gz |
more progress on destructors; removed old destructor based code as it proved confusing
Diffstat (limited to 'tests/destructor/tatomicptrs.nim')
-rw-r--r-- | tests/destructor/tatomicptrs.nim | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim new file mode 100644 index 000000000..d20596415 --- /dev/null +++ b/tests/destructor/tatomicptrs.nim @@ -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() + |