Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
ForwardAllocator.cxx
Go to the documentation of this file.
1
38
39#include "utils/Buffer.hxx"
40
41// static
43 new DynamicPool(Bucket::init(sizeof(BufferType), 0));
44
45static constexpr unsigned MALLOC_OVERHEAD = sizeof(void *);
46
47#ifdef GTEST
48// static
49void ForwardAllocator::TEST_recreate_pool()
50{
51 delete kbytePool_;
53}
54#endif
55
56ForwardAllocator::ForwardAllocator()
57{
58}
59
60ForwardAllocator::~ForwardAllocator()
61{
63 while (!allocatedBlocks_.empty())
64 {
65 allocatedBlocks_.pop_front()->unref();
66 }
67}
68
69void *ForwardAllocator::allocate(size_t size, size_t align)
70{
71 HASSERT(align <= alignof(primitive_t));
72 if (size >= BLOCK_BYTE_SIZE)
73 {
74 // Large block. Allocate custom.
75 size_t head = sizeof(Buffer<uint64_t>);
76 head += size - sizeof(uint64_t);
77 HASSERT(head < 65535); // a bit left for buffer header.
78 auto *bufp =
80 HASSERT(bufp);
81 // Links the new buffer into the queue.
83 allocSize_ += head + MALLOC_OVERHEAD;
84 if (allocatedBlocks_.empty())
85 {
86 allocatedBlocks_.SimpleQueue::push_front(bufp);
88 }
89 else
90 {
91 auto it = allocatedBlocks_.SimpleQueue::begin();
92 ++it;
93 allocatedBlocks_.insert(it, bufp);
94 }
95 return bufp->data();
96 }
98 size_t pad = offsetInLast_ % align;
99 if (pad)
100 {
101 pad = (align - pad);
102 allocWasted_ += pad;
103 }
104 offsetInLast_ += pad;
105 if (offsetInLast_ + size > BLOCK_BYTE_SIZE)
106 {
109 // Does not fit. Allocate new block.
110 BufferType *new_block;
111 kbytePool_->alloc(&new_block);
112 allocSize_ += sizeof(BufferType) + MALLOC_OVERHEAD;
113 HASSERT(new_block);
114 allocatedBlocks_.push_front(new_block);
115 offsetInLast_ = 0;
116 }
117 auto *ret = head_ptr() + offsetInLast_;
118 offsetInLast_ += size;
119 return ret;
120}
DynamicPool * mainBufferPool
main buffer pool instance
Definition Buffer.cxx:37
static Bucket * init(int s,...)
Allocate a Bucket array off of the heap initialized with sizes.
Definition Buffer.hxx:406
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
A specialization of a pool which can allocate new elements dynamically upon request.
Definition Buffer.hxx:491
BufferBase * alloc_untyped(size_t size, Executable *flow) override
Get a free item out of the pool.
Definition Buffer.cxx:105
void * allocate(size_t size, size_t align)
Allocates a block of memory.
Buffer< AlignedPayload > BufferType
Buffer type that we will be allocating from the pool.
TypedQueue< BufferType > allocatedBlocks_
Holds all blocks that we allocated (ever).
OSMutex lock_
Lock that protects the offset in last variable and the queue of blocks.
size_t offsetInLast_
Points into the last allocated block to the next emtpy space.
static constexpr size_t BLOCK_BYTE_SIZE
Allocated blocks will be this size.
size_t allocWasted_
Number of bytes lost due to alignment and end-of-block chunks.
static DynamicPool * kbytePool_
This buffer pool will have one bucket to allocate 1kb objects each and kep them on a free list.
uint64_t primitive_t
A primitive type that has sufficient alignment to what we support.
size_t allocSize_
Total number of bytes allocated.
Class to allow convenient locking and unlocking of mutexes in a C context.
Definition OS.hxx:494
void alloc(Buffer< BufferType > **result, Executable *flow=NULL)
Get a free item out of the pool.
Definition Buffer.hxx:292
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138