diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2014-03-08 10:33:13 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2014-03-08 10:33:13 +0100 |
commit | aaa13c001161c6efac250ea4b3ccbeab21fb9635 (patch) | |
tree | 34f640fbc2693a9bf4ae05b608e8448b106a820b | |
parent | dd216755ff61901eb0b08c56965f58fcabdf4a0e (diff) | |
parent | 3147f7f6c2c8fc62d04d5b449df093f113935487 (diff) | |
download | Nim-aaa13c001161c6efac250ea4b3ccbeab21fb9635.tar.gz |
Merge pull request #979 from EXetoC/alloc-overloads
More updates to the allocation interface
-rw-r--r-- | lib/system.nim | 53 | ||||
-rw-r--r-- | tests/system/alloc.nim | 37 |
2 files changed, 53 insertions, 37 deletions
diff --git a/lib/system.nim b/lib/system.nim index 171c7b6b8..24ad50f97 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1164,13 +1164,13 @@ when not defined(nimrodVM): ## from it before writing to it is undefined behaviour! ## The allocated memory belongs to its allocating thread! ## Use `allocShared` to allocate from a shared heap. - proc alloc*(T: typedesc, size = 1): ptr T {.inline.} = + proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline.} = ## allocates a new memory block with at least ``T.sizeof * size`` - ## bytes. The block has to be freed with ``realloc(block, 0)`` or - ## ``dealloc(block)``. The block is not initialized, so reading + ## bytes. The block has to be freed with ``resize(block, 0)`` or + ## ``free(block)``. The block is not initialized, so reading ## from it before writing to it is undefined behaviour! ## The allocated memory belongs to its allocating thread! - ## Use `allocShared` to allocate from a shared heap. + ## Use `createSharedU` to allocate from a shared heap. cast[ptr T](alloc(T.sizeof * size)) proc alloc0*(size: int): pointer {.noconv, rtl, tags: [].} ## allocates a new memory block with at least ``size`` bytes. The @@ -1179,13 +1179,13 @@ when not defined(nimrodVM): ## containing zero, so it is somewhat safer than ``alloc``. ## The allocated memory belongs to its allocating thread! ## Use `allocShared0` to allocate from a shared heap. - proc alloc0*(T: typedesc, size = 1): ptr T {.inline.} = + proc create*(T: typedesc, size = 1.Positive): ptr T {.inline.} = ## allocates a new memory block with at least ``T.sizeof * size`` - ## bytes. The block has to be freed with ``realloc(block, 0)`` or - ## ``dealloc(block)``. The block is initialized with all bytes - ## containing zero, so it is somewhat safer than ``alloc``. + ## bytes. The block has to be freed with ``resize(block, 0)`` or + ## ``free(block)``. The block is initialized with all bytes + ## containing zero, so it is somewhat safer than ``createU``. ## The allocated memory belongs to its allocating thread! - ## Use `allocShared0` to allocate from a shared heap. + ## Use `createShared` to allocate from a shared heap. cast[ptr T](alloc0(T.sizeof * size)) proc realloc*(p: pointer, newSize: int): pointer {.noconv, rtl, tags: [].} ## grows or shrinks a given memory block. If p is **nil** then a new @@ -1195,14 +1195,14 @@ when not defined(nimrodVM): ## be freed with ``dealloc``. ## The allocated memory belongs to its allocating thread! ## Use `reallocShared` to reallocate from a shared heap. - proc reallocType*[T](p: ptr T, newSize: int): ptr T {.inline.} = + proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline.} = ## grows or shrinks a given memory block. If p is **nil** then a new ## memory block is returned. In either way the block has at least ## ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is not - ## **nil** ``realloc`` calls ``dealloc(p)``. In other cases the block - ## has to be freed with ``dealloc``. The allocated memory belongs to + ## **nil** ``resize`` calls ``free(p)``. In other cases the block + ## has to be freed with ``free``. The allocated memory belongs to ## its allocating thread! - ## Use `reallocShared` to reallocate from a shared heap. + ## Use `resizeShared` to reallocate from a shared heap. cast[ptr T](realloc(p, T.sizeof * newSize)) proc dealloc*(p: pointer) {.noconv, rtl, tags: [].} ## frees the memory allocated with ``alloc``, ``alloc0`` or @@ -1212,16 +1212,18 @@ when not defined(nimrodVM): ## or other memory may be corrupted. ## The freed memory must belong to its allocating thread! ## Use `deallocShared` to deallocate from a shared heap. + proc free*[T](p: ptr T) {.inline.} = + dealloc(p) proc allocShared*(size: int): pointer {.noconv, rtl.} ## allocates a new memory block on the shared heap with at ## least ``size`` bytes. The block has to be freed with ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block ## is not initialized, so reading from it before writing to it is ## undefined behaviour! - proc allocShared*(T: typedesc, size: int): ptr T {.inline.} = + proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline.} = ## allocates a new memory block on the shared heap with at ## least ``T.sizeof * size`` bytes. The block has to be freed with - ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block + ## ``resizeShared(block, 0)`` or ``freeShared(block)``. The block ## is not initialized, so reading from it before writing to it is ## undefined behaviour! cast[ptr T](allocShared(T.sizeof * size)) @@ -1231,25 +1233,25 @@ when not defined(nimrodVM): ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. ## The block is initialized with all bytes ## containing zero, so it is somewhat safer than ``allocShared``. - proc allocShared0*(T: typedesc, size: int): ptr T {.inline.} = + proc createShared*(T: typedesc, size = 1.Positive): ptr T {.inline.} = ## allocates a new memory block on the shared heap with at ## least ``T.sizeof * size`` bytes. The block has to be freed with - ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. + ## ``resizeShared(block, 0)`` or ``freeShared(block)``. ## The block is initialized with all bytes - ## containing zero, so it is somewhat safer than ``allocShared``. - cast[ptr T](allocShared(T.sizeof * size)) + ## containing zero, so it is somewhat safer than ``createSharedU``. + cast[ptr T](allocShared0(T.sizeof * size)) proc reallocShared*(p: pointer, newSize: int): pointer {.noconv, rtl.} ## grows or shrinks a given memory block on the heap. If p is **nil** ## then a new memory block is returned. In either way the block has at ## least ``newSize`` bytes. If ``newSize == 0`` and p is not **nil** ## ``reallocShared`` calls ``deallocShared(p)``. In other cases the ## block has to be freed with ``deallocShared``. - proc reallocSharedType*[T](p: ptr T, newSize: int): ptr T {.inline.} = + proc resizeShared*[T](p: ptr T, newSize: Natural): ptr T {.inline.} = ## grows or shrinks a given memory block on the heap. If p is **nil** ## then a new memory block is returned. In either way the block has at ## least ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is - ## not **nil** ``reallocShared`` calls ``deallocShared(p)``. In other - ## cases the block has to be freed with ``deallocShared``. + ## not **nil** ``resizeShared`` calls ``freeShared(p)``. In other + ## cases the block has to be freed with ``freeShared``. cast[ptr T](reallocShared(p, T.sizeof * newSize)) proc deallocShared*(p: pointer) {.noconv, rtl.} ## frees the memory allocated with ``allocShared``, ``allocShared0`` or @@ -1257,6 +1259,13 @@ when not defined(nimrodVM): ## free the memory a leak occurs; if one tries to access freed ## memory (or just freeing it twice!) a core dump may happen ## or other memory may be corrupted. + proc freeShared*[T](p: ptr T) {.inline.} = + ## frees the memory allocated with ``createShared``, ``createSharedU`` or + ## ``resizeShared``. This procedure is dangerous! If one forgets to + ## free the memory a leak occurs; if one tries to access freed + ## memory (or just freeing it twice!) a core dump may happen + ## or other memory may be corrupted. + deallocShared(p) proc swap*[T](a, b: var T) {.magic: "Swap", noSideEffect.} ## swaps the values `a` and `b`. This is often more efficient than diff --git a/tests/system/alloc.nim b/tests/system/alloc.nim index 665b448ac..7abefec2a 100644 --- a/tests/system/alloc.nim +++ b/tests/system/alloc.nim @@ -2,44 +2,51 @@ var x: ptr int x = cast[ptr int](alloc(7)) assert x != nil - -x = alloc(int, 3) +x = cast[ptr int](x.realloc(2)) assert x != nil x.dealloc() -x = alloc0(int, 4) +x = createU(int, 3) +assert x != nil +x.free() + +x = create(int, 4) assert cast[ptr array[4, int]](x)[0] == 0 assert cast[ptr array[4, int]](x)[1] == 0 assert cast[ptr array[4, int]](x)[2] == 0 assert cast[ptr array[4, int]](x)[3] == 0 -x = cast[ptr int](x.realloc(2)) -assert x != nil - -x = x.reallocType(4) +x = x.resize(4) assert x != nil -x.dealloc() +x.free() x = cast[ptr int](allocShared(100)) assert x != nil deallocShared(x) -x = allocShared(int, 3) +x = createSharedU(int, 3) assert x != nil -x.deallocShared() +x.freeShared() -x = allocShared0(int, 3) +x = createShared(int, 3) assert x != nil assert cast[ptr array[3, int]](x)[0] == 0 assert cast[ptr array[3, int]](x)[1] == 0 assert cast[ptr array[3, int]](x)[2] == 0 -x = cast[ptr int](reallocShared(x, 2)) assert x != nil +x = cast[ptr int](x.resizeShared(2)) +assert x != nil +x.freeShared() -x = reallocType(x, 12) +x = create(int, 10) assert x != nil +x = x.resize(12) +assert x != nil +x.dealloc() -x = reallocSharedType(x, 1) +x = createShared(int, 1) +assert x != nil +x = x.resizeShared(1) assert x != nil -x.deallocShared() +x.freeShared() |