View source code
							
							
						
								Display the source code in std/experimental/allocator/building_blocks/bitmapped_block.d from which this
								page was generated on github.
							
						
							Report a bug
							
						
								If you spot a problem with this page, click here to create a
								Bugzilla issue.
							
						
							
								Improve this page
							
							
					
								Quickly fork, edit online, and submit a pull request for this page.
								Requires a signed-in GitHub account. This works well for small changes.
								If you'd like to make larger changes you may want to consider using
								local clone.
							
						Struct std.experimental.allocator.building_blocks.bitmapped_block.SharedBitmappedBlock
The threadsafe version of the BitmappedBlock.
The semantics of the SharedBitmappedBlock are identical to the regular BitmappedBlock.
						
				struct SharedBitmappedBlock(ulong theBlockSize, uint theAlignment = platformAlignment, ParentAllocator, Flag!("multiblock") f = Yes .multiblock)
				;
						
					
				Constructors
| Name | Description | 
|---|---|
								
									this
								
								(data)
							 | 
							Constructs a block allocator given a hunk of memory, or a desired capacity
        in bytes.
        
  | 
						
Fields
| Name | Type | Description | 
|---|---|---|
								parent
							 | 
							ParentAllocator | The parent allocator. Depending on whether ParentAllocator holds state
        or not, this is a member variable or an alias for
        ParentAllocator.
 | 
						
Methods
| Name | Description | 
|---|---|
								
									alignedAllocate
								
								(n, a)
							 | 
							Allocates a block with specified alignment a. The alignment must be a
        power of 2. If a <= alignment, function forwards to allocate.
        Otherwise, it attempts to overallocate and then adjust the result for
        proper alignment. In the worst case the slack memory is around two blocks.
 | 
						
								
									alignedReallocate
								
								(b, newSize, a)
							 | 
							Reallocates a block previously allocated with alignedAllocate. Contractions do not occur in place.
 | 
						
								
									allocate
								
								(s)
							 | 
							Allocates s bytes of memory and returns it, or null if memory
        could not be allocated.
 | 
						
								
									allocateAll
								
								()
							 | 
							If the SharedBitmappedBlock object is empty (has no active allocation), allocates
        all memory within and returns a slice to it. Otherwise, returns null
        (i.e. no attempt is made to allocate the largest available block).
 | 
						
								
									allocateFresh
								
								(s)
							 | 
							Allocates s bytes of memory and returns it, or null if memory could not be allocated.
        allocateFresh behaves just like allocate, the only difference being that this always
        returns unused(fresh) memory. Although there may still be available space in the SharedBitmappedBlock,
        allocateFresh could still return null, because all the available blocks have been previously deallocated.
 | 
						
								
									deallocate
								
								(b)
							 | 
							Deallocates the given buffer b, by atomically setting the corresponding
        bit to 0. b must be valid, and cannot contain multiple adjacent blocks.
 | 
						
								
									deallocateAll
								
								()
							 | 
							Forcibly deallocates all memory allocated by this allocator, making it
        available for further allocations. Does not return memory to ParentAllocator.
 | 
						
								
									empty
								
								()
							 | 
							Returns Ternary if no memory is currently allocated with this
        allocator, otherwise Ternary. This method never returns
        Ternary.
 | 
						
								
									expand
								
								(b, delta)
							 | 
							Expands in place a buffer previously allocated by SharedBitmappedBlock.
        Expansion fails if the new length exceeds the block size.
 | 
						
								
									goodAllocSize
								
								(n)
							 | 
							Returns the actual bytes allocated when n bytes are requested, i.e.
        n.
 | 
						
								
									owns
								
								(b)
							 | 
							Returns Ternary if b belongs to the SharedBitmappedBlock object,
        Ternary otherwise. Never returns Ternary. (This
        method is somewhat tolerant in that accepts an interior slice.)
 | 
						
								
									reallocate
								
								(b, newSize)
							 | 
							Reallocates a previously-allocated block. Contractions occur in place. | 
Aliases
| Name | Description | 
|---|---|
								
									alignment
								
							 | 
							The alignment offered is user-configurable statically through parameter
        theAlignment, defaulted to platformAlignment.
 | 
						
								
									blockSize
								
							 | 
							If blockSize == chooseAtRuntime, SharedBitmappedBlock offers a read/write
        property blockSize. It must be set before any use of the allocator.
        Otherwise (i.e. theBlockSize is a legit constant), blockSize is
        an alias for theBlockSize. Whether constant or variable, must also be
        a multiple of alignment. This constraint is asserted statically
        and dynamically.
 | 
						
Parameters
| Name | Description | 
|---|---|
| theBlockSize |  the length of a block, which must be a multiple of theAlignment
 | 
| theAlignment | alignment of each block | 
| ParentAllocator |  allocator from which the BitmappedBlock will draw memory.
        If set to NullAllocator, the storage must be passed via the constructor
 | 
| f |  Yes to support allocations spanning across multiple blocks and
        No to support single block allocations.
        Although limited by single block allocations, No will generally
        provide higher performance. | 
Example
import std .experimental .allocator .mallocator : Mallocator;
import std .experimental .allocator .common : platformAlignment;
import std .typecons : Flag, Yes, No;
// Create 'numThreads' threads, each allocating in parallel a chunk of memory
static void testAlloc(Allocator)(ref Allocator a, size_t allocSize)
{
    import core .thread : ThreadGroup;
    import std .algorithm .sorting : sort;
    import core .internal .spinlock : SpinLock;
    SpinLock lock = SpinLock(SpinLock .Contention .brief);
    enum numThreads = 10;
    void[][numThreads] buf;
    size_t count = 0;
    // Each threads allocates 'allocSize'
    void fun()
    {
        void[] b = a .allocate(allocSize);
        writeln(b .length); // allocSize
        lock .lock();
        scope(exit) lock .unlock();
        buf[count] = b;
        count++;
    }
    auto tg = new ThreadGroup;
    foreach (i; 0 .. numThreads)
    {
        tg .create(&fun);
    }
    tg .joinAll();
    // Sorting the allocations made by each thread, we expect the buffers to be
    // adjacent inside the SharedBitmappedBlock
    sort!((a, b) => a .ptr < b .ptr)(buf[0 .. numThreads]);
    foreach (i; 0 .. numThreads - 1)
    {
        assert(buf[i] .ptr + a .goodAllocSize(buf[i] .length) <= buf[i + 1] .ptr);
    }
    // Deallocate everything
    foreach (i; 0 .. numThreads)
    {
        assert(a .deallocate(buf[i]));
    }
}
enum blockSize = 64;
auto alloc1 = SharedBitmappedBlock!(blockSize, platformAlignment, Mallocator, Yes .multiblock)(1024 * 1024);
auto alloc2 = SharedBitmappedBlock!(blockSize, platformAlignment, Mallocator, No .multiblock)(1024 * 1024);
testAlloc(alloc1, 2 * blockSize);
testAlloc(alloc2, blockSize);
Authors
License
					Copyright © 1999-2024 by the D Language Foundation | Page generated by ddox.