12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- #
- #
- # Nim's Runtime Library
- # (c) Copyright 2017 Nim contributors
- #
- # See the file "copying.txt", included in this
- # distribution, for details about the copyright.
- #
- type
- AllocatorFlag* {.pure.} = enum ## flags describing the properties of the allocator
- ThreadLocal ## the allocator is thread local only.
- ZerosMem ## the allocator always zeros the memory on an allocation
- Allocator* = ptr AllocatorObj
- AllocatorObj* {.inheritable, compilerproc.} = object
- alloc*: proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall, raises: [], tags: [].}
- dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall, raises: [], tags: [].}
- realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall, raises: [], tags: [].}
- deallocAll*: proc (a: Allocator) {.nimcall, raises: [], tags: [].}
- flags*: set[AllocatorFlag]
- name*: cstring
- allocCount: int
- deallocCount: int
- var
- localAllocator {.threadvar.}: Allocator
- sharedAllocator: Allocator
- allocatorStorage {.threadvar.}: AllocatorObj
- when defined(useMalloc) and not defined(nimscript):
- import "system/ansi_c"
- import "system/memory"
- template `+!`(p: pointer, s: int): pointer =
- cast[pointer](cast[int](p) +% s)
- proc getLocalAllocator*(): Allocator =
- result = localAllocator
- if result == nil:
- result = addr allocatorStorage
- result.alloc = proc (a: Allocator; size: int; alignment: int = 8): pointer {.nimcall, raises: [].} =
- when defined(useMalloc) and not defined(nimscript):
- result = c_malloc(size)
- # XXX do we need this?
- nimZeroMem(result, size)
- else:
- result = system.alloc0(size)
- inc a.allocCount
- result.dealloc = proc (a: Allocator; p: pointer; size: int) {.nimcall, raises: [].} =
- when defined(useMalloc) and not defined(nimscript):
- c_free(p)
- else:
- system.dealloc(p)
- inc a.deallocCount
- result.realloc = proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall, raises: [].} =
- when defined(useMalloc) and not defined(nimscript):
- result = c_realloc(p, newSize)
- else:
- result = system.realloc(p, newSize)
- nimZeroMem(result +! oldSize, newSize - oldSize)
- result.deallocAll = nil
- result.flags = {ThreadLocal, ZerosMem}
- result.name = "nim_local"
- localAllocator = result
- proc setLocalAllocator*(a: Allocator) =
- localAllocator = a
- proc getSharedAllocator*(): Allocator =
- result = sharedAllocator
- proc setSharedAllocator*(a: Allocator) =
- sharedAllocator = a
- proc allocCounters*(): (int, int) =
- let a = getLocalAllocator()
- result = (a.allocCount, a.deallocCount)
|