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

The allocator proposal assumes an efficient `regionof` operation, most likely 
to be implemented via pointer masking with a compile-time constant (alignment 
by 64K seems to be good value for modern machines). Every allocator then must 
ensure that this pointer masking leads to an allocator control block:
    
    
    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.} = 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
    
    
    Run

The only downside is that most existing allocators do not adhere to this 
design. :-)

Reply via email to