Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Buffer.cxx
Go to the documentation of this file.
1
34#include "utils/Buffer.hxx"
35#include "utils/ByteBuffer.hxx"
36
39
41{
42 if (!rawBufferPool)
43 {
45 }
46 if (!mainBufferPool)
47 {
50 }
51 return mainBufferPool;
52}
53
58{
59 size_t total = 0;
60 for (Bucket *current = buckets; current->size() != 0; ++current)
61 {
62 total += current->pending();
63 }
64 return total;
65}
66
71size_t DynamicPool::free_items(size_t size)
72{
73 for (Bucket *current = buckets; current->size() != 0; ++current)
74 {
75 if (current->size() >= size)
76 {
77 return current->pending();
78 }
79 }
80 return 0;
81}
82
83#ifdef DEBUG_BUFFER_MEMORY
84/* key: buffer pointer. Value: instruction pointer for allocation caller. */
85std::map<BufferBase*, void*> g_alloc_source;
86Atomic g_alloc_atomic;
87void* g_current_alloc;
88#endif
89
90extern "C" {
96extern void *buffer_malloc(size_t length);
97}
98
106{
107 BufferBase *result = NULL;
108
109 for (Bucket *current = buckets; current->size() != 0; ++current)
110 {
111 if (size <= current->size())
112 {
113 result = static_cast<BufferBase*>(current->next().item);
114 if (result == NULL)
115 {
116 result = (BufferBase*)buffer_malloc(current->size());
117 {
118 AtomicHolder h(this);
119 if (0 && totalSize < 5000 && totalSize + current->size() >= 5000) {
120 HASSERT(0);
121 }
122 current->allocCount_++;
123 totalSize += current->size();
124 }
125 }
126 new (result) BufferBase(size, this);
127 break;
128 }
129 }
130
131 if (!result)
132 {
133 /* big items are just malloc'd freely */
134 result = (BufferBase*)alloc_large(size);
135 new (result) BufferBase(size, this);
136 {
137 AtomicHolder h(this);
138 totalSize += size;
139 }
140 }
141#ifdef DEBUG_BUFFER_MEMORY
142 {
143 AtomicHolder h(&g_alloc_atomic);
144 g_alloc_source[result] = g_current_alloc;
145 }
146#endif
147 if (flow)
148 {
149 flow->alloc_result(result);
150 }
151 return result;
152}
153
154void* DynamicPool::alloc_large(size_t size) {
155 return malloc(size);
156}
157
158void DynamicPool::free_large(void* buffer) {
159 ::free(buffer);
160}
161
166{
167#ifdef DEBUG_BUFFER_MEMORY
168 {
169 AtomicHolder h(&g_alloc_atomic);
170 g_alloc_source.erase(item);
171 }
172#endif
173 for (Bucket *current = buckets; current->size() != 0; ++current)
174 {
175 if (item->size() <= current->size())
176 {
177 current->insert(item);
178 return;
179 }
180 }
181 /* big items are just freed */
182 {
183 AtomicHolder h(this);
184 totalSize -= item->size();
185 }
186 free_large(item);
187}
188
198{
199 BufferBase *result = NULL;
200
201 {
202 AtomicHolder h(this);
203 if (empty == false)
204 {
205 result = static_cast<BufferBase *>(queue.next(0));
206 if (result)
207 {
208 new (result) BufferBase(size, this);
210 }
211 else
212 {
213 empty = true;
214 }
215 }
216 if (flow && empty)
217 {
218 queue.insert(flow);
219 }
220 }
221 if (result && flow)
222 {
223 flow->alloc_result(result);
224 }
225 return result;
226}
227
232{
233 HASSERT(valid(item));
234 HASSERT(item->size() <= itemSize);
235
236 Executable *waiting = NULL;
237 {
238 AtomicHolder h(this);
239 if (empty == true)
240 {
241 waiting = static_cast<Executable *>(queue.next().item);
242 if (queue.empty())
243 {
244 empty = false;
245 }
246 if (!waiting)
247 {
248 queue.insert(item);
250 }
251 }
252 else
253 {
254 queue.insert(item);
256 }
257 }
258 if (waiting)
259 {
260 waiting->alloc_result(item);
261 }
262
263}
void * buffer_malloc(size_t length)
malloc implementation used for allocating buffer space.
Pool * rawBufferPool
Use this BufferPool to allocate raw buffers.
Definition Buffer.cxx:38
Pool * init_main_buffer_pool()
Initializes the main buffer pool.
Definition Buffer.cxx:40
DynamicPool * mainBufferPool
main buffer pool instance
Definition Buffer.cxx:37
void * g_current_alloc
This pointer will be saved for debugging the current allocation source.
const unsigned LARGEST_BUFFERPOOL_BUCKET
Ensures that the largest bucket in the main buffer pool is exactly the size of a GenMessage.
Definition If.cxx:40
See OSMutexLock in os/OS.hxx.
Definition Atomic.hxx:153
Lightweight locking class for protecting small critical sections.
Definition Atomic.hxx:130
This is a struct for storing info about a specific size item in the DynamicPool.
Definition Buffer.hxx:397
size_t size()
Get the size of the bucket.
Definition Buffer.hxx:450
static Bucket * init(int s,...)
Allocate a Bucket array off of the heap initialized with sizes.
Definition Buffer.hxx:406
Abstract base class for all Buffers.
Definition Buffer.hxx:85
size_t size()
Definition Buffer.hxx:121
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
void free(BufferBase *item) override
Releases an item back to the free pool.
Definition Buffer.cxx:165
size_t free_items() override
Number of free items in the pool.
Definition Buffer.cxx:57
BufferBase * alloc_untyped(size_t size, Executable *flow) override
Get a free item out of the pool.
Definition Buffer.cxx:105
void * alloc_large(size_t size)
Allocates a large memory block directly from the heap.
Definition Buffer.cxx:154
Bucket * buckets
Free buffer queue.
Definition Buffer.hxx:536
void free_large(void *block)
Frees a large memory block allocated by alloc_large.
Definition Buffer.cxx:158
An object that can be scheduled on an executor to run.
virtual void alloc_result(QMember *item)
Return the result of an alloc_async() from a memory Pool.
void free(BufferBase *item) override
Release an item back to the free pool.
Definition Buffer.cxx:231
bool valid(QMember *item)
Used in static pools to tell if this item is a member of the pool.
Definition Buffer.hxx:579
BufferBase * alloc_untyped(size_t size, Executable *flow) override
Get a free item out of the pool.
Definition Buffer.cxx:197
size_t itemSize
item Size for fixed pools
Definition Buffer.hxx:642
bool empty
is the pool empty
Definition Buffer.hxx:648
Q queue
Free buffer queue.
Definition Buffer.hxx:636
Pool of previously allocated, but currently unused, items.
Definition Buffer.hxx:278
friend class BufferBase
Allow BufferBase to access this class.
Definition Buffer.hxx:381
size_t totalSize
keep track of total allocated size of memory
Definition Buffer.hxx:377
void insert(QMember *item, unsigned index=0)
Add an item to the back of the queue.
Definition Queue.hxx:124
bool empty(unsigned index)
Test if the queue is empty.
Definition Queue.hxx:225
QMember * next(unsigned index)
Get an item from the front of the queue.
Definition Queue.hxx:167
void * buffer_malloc(size_t length)
Allocates a buffer.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138