stdx.allocator.building_blocks.region

  • Declaration

    struct Region(ParentAllocator = NullAllocator, uint minAlign = platformAlignment, Flag!"growDownwards" growDownwards = No.growDownwards);

    A allocator allocates memory straight from one contiguous chunk. There is no deallocation, and once the region is full, allocation requests return . Therefore, s are often used (a) in conjunction with more sophisticated allocators; or (b) for batch-style very fast allocations that deallocate everything at once.

    Discussion

    The region only stores three pointers, corresponding to the current position in the store and the limits. One allocation entails rounding up the allocation size for alignment purposes, bumping the current pointer, and comparing it against the limit.

    If is different from , deallocates the chunk of memory during destruction.

    The parameter establishes alignment. If , the sizes of all allocation requests are rounded up to a multiple of . Applications aiming at maximum speed may want to choose and control alignment externally.

    Examples

    1. import std.algorithm.comparison : max; import stdx.allocator.building_blocks.allocator_list : AllocatorList; import stdx.allocator.mallocator : Mallocator; // Create a scalable list of regions. Each gets at least 1MB at a time by // using malloc. auto batchAllocator = AllocatorList!( (size_t n) => Region!Mallocator(max(n, 1024 * 1024)) )(); auto b = batchAllocator.allocate(101); assert(b.length == 101); // This will cause a second allocation b = batchAllocator.allocate(2 * 1024 * 1024); assert(b.length == 2 * 1024 * 1024); // Destructor will free the memory

    • Declaration

      ParentAllocator parent;

      The parent allocator. Depending on whether holds state or not, this is a member variable or an alias for ParentAllocator.instance.

    • Declaration

      this(ubyte[] store);
      this(size_t n);

      Constructs a region backed by a user-provided store. Assumes is aligned at . Also assumes the memory was allocated with (if different from ).

      Parameters

      ubyte[] store

      User-provided store backing up the region. must be aligned at (enforced with ). If is different from , memory is assumed to have been allocated with .

      size_t n

      Bytes to allocate using . This constructor is only defined If is different from . If returns , the region will be initialized as empty (correctly initialized but unable to allocate).

    • Declaration

      alias alignment = minAlign;

      Alignment offered.

    • Declaration

      void[] allocate(size_t n);

      Allocates bytes of memory. The shortest path involves an alignment adjustment (if ), an increment, and a comparison.

      Parameters

      size_t n

      number of bytes to allocate

      Return Value

      A properly-aligned buffer of size or if request could not be satisfied.

    • Declaration

      void[] alignedAllocate(size_t n, uint a);

      Allocates bytes of memory aligned at alignment .

      Parameters

      size_t n

      number of bytes to allocate

      uint a

      alignment for the allocated block

      Return Value

      Either a suitable block of bytes aligned at , or .

    • Declaration

      void[] allocateAll();

      Allocates and returns all memory available to this region.

    • Declaration

      bool expand(ref void[] b, size_t delta);

      Expands an allocated block in place. Expansion will succeed only if the block is the last allocated. Defined only if growDownwards is No.growDownwards.

    • Declaration

      bool deallocate(void[] b);

      Deallocates . This works only if was obtained as the last call to ; otherwise (i.e. another allocation has occurred since) it does nothing. This semantics is tricky and therefore is defined only if is instantiated with as the third template argument.

      Parameters

      void[] b

      Block previously obtained by a call to against this allocator ( is allowed).

    • Declaration

      bool deallocateAll();

      Deallocates all memory allocated by this region, which can be subsequently reused for new allocations.

    • Declaration

      const Ternary owns(void[] b);

      Queries whether has been allocated with this region.

      Parameters

      void[] b

      Arbitrary block of memory ( is allowed; returns ).

      Return Value

      if has been allocated with this region, otherwise.

    • Declaration

      const Ternary empty();

      Returns Ternary.yes if no memory has been allocated in this region, Ternary.no otherwise. (Never returns Ternary.unknown.)

    • Declaration

      const size_t available();

      Nonstandard property that returns bytes available for allocation.

  • Declaration

    struct InSituRegion(size_t size, size_t minAlign = platformAlignment);

    is a convenient region that carries its storage within itself (in the form of a statically-sized array).

    Discussion

    The first template argument is the size of the region and the second is the needed alignment. Depending on the alignment requested and platform details, the actual available storage may be smaller than the compile-time parameter. To make sure that at least bytes are available in the region, use .

    Given that the most frequent use of InSituRegion is as a stack allocator, it allocates starting at the end on systems where stack grows downwards, such that hot memory is used first.

    Examples

    1. // 128KB region, allocated to x86's cache line InSituRegion!(128 * 1024, 16) r1; auto a1 = r1.allocate(101); assert(a1.length == 101); // 128KB region, with fallback to the garbage collector. import stdx.allocator.building_blocks.fallback_allocator : FallbackAllocator; import stdx.allocator.building_blocks.free_list : FreeList; import stdx.allocator.building_blocks.bitmapped_block : BitmappedBlock; import stdx.allocator.gc_allocator : GCAllocator; FallbackAllocator!(InSituRegion!(128 * 1024), GCAllocator) r2; const a2 = r2.allocate(102); assert(a2.length == 102); // Reap with GC fallback. InSituRegion!(128 * 1024, 8) tmp3; FallbackAllocator!(BitmappedBlock!(64, 8), GCAllocator) r3; r3.primary = BitmappedBlock!(64, 8)(cast(ubyte[])(tmp3.allocateAll())); const a3 = r3.allocate(103); assert(a3.length == 103); // Reap/GC with a freelist for small objects up to 16 bytes. InSituRegion!(128 * 1024, 64) tmp4; FreeList!(FallbackAllocator!(BitmappedBlock!(64, 64), GCAllocator), 0, 16) r4; r4.parent.primary = BitmappedBlock!(64, 64)(cast(ubyte[])(tmp4.allocateAll())); const a4 = r4.allocate(104); assert(a4.length == 104);

    • Declaration

      alias alignment = minAlign;

      An alias for , which must be a valid alignment (nonzero power of 2). The start of the region and all allocation requests will be rounded up to a multiple of the alignment.

      Discussion

      1. InSituRegion!(4096) a1; assert(a1.alignment == platformAlignment); InSituRegion!(4096, 64) a2; assert(a2.alignment == 64);

    • Declaration

      void[] allocate(size_t n);

      Allocates and returns them, or if the region cannot accommodate the request. For efficiency reasons, if the function returns an empty non-null slice.

    • Declaration

      void[] alignedAllocate(size_t n, uint a);

      As above, but the memory allocated is aligned at bytes.

    • Declaration

      bool deallocate(void[] b);

      Deallocates . This works only if was obtained as the last call to ; otherwise (i.e. another allocation has occurred since) it does nothing. This semantics is tricky and therefore is defined only if is instantiated with as the third template argument.

      Parameters

      void[] b

      Block previously obtained by a call to against this allocator ( is allowed).

    • Declaration

      Ternary owns(void[] b);

      Returns Ternary.yes if b is the result of a previous allocation, Ternary.no otherwise.

    • Declaration

      bool expand(ref void[] b, size_t delta);

      Expands an allocated block in place. Expansion will succeed only if the block is the last allocated.

    • Declaration

      bool deallocateAll();

      Deallocates all memory allocated with this allocator.

    • Declaration

      void[] allocateAll();

      Allocates all memory available with this allocator.

    • Declaration

      size_t available();

      Nonstandard function that returns the bytes available for allocation.

  • Declaration

    struct SbrkRegion(uint minAlign = platformAlignment);

    Allocator backed by for Posix systems. Due to the fact that is not thread-safe , uses a mutex internally. This implies that uncontrolled calls to and may affect the workings of adversely.

    • Declaration

      static shared SbrkRegion instance;

      Instance shared by all callers.

    • Declaration

      enum uint alignment;
      shared void[] allocate(size_t bytes);
      shared void[] alignedAllocate(size_t bytes, uint a);

      Standard allocator primitives.

    • Declaration

      shared bool expand(ref void[] b, size_t delta);
      shared Ternary owns(void[] b);

      The method may only succeed if the argument is the last block allocated. In that case, attempts to push the break pointer to the right.

    • Declaration

      shared bool deallocate(void[] b);

      The method only works (and returns ) on systems that support reducing the break address (i.e. accept calls to with negative offsets). OSX does not accept such. In addition the argument must be the last block allocated.

    • Declaration

      shared bool deallocateAll();

      The method only works (and returns ) on systems that support reducing the break address (i.e. accept calls to with negative offsets). OSX does not accept such.

    • Declaration

      Ternary empty();

      Standard allocator API.