xmempool 1.0
A Simple Memory Pool Implementation
Loading...
Searching...
No Matches
xmempool.c File Reference
#include "xmempool.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

Go to the source code of this file.

Data Structures

struct  xmem_pool_block
 xmempool - A Simple Memory Pool Implementation More...
 
struct  xmem_pool
 

Macros

#define MIN_ALLOC_BLOCK_NODE_COUNT   (1024)
 
#define MAX_ALLOC_BLOCK_NODE_COUNT   (1024 << 2)
 
#define MIN_ALLOC_LENGTH   (1024)
 
#define MAX_ALLOC_LENGTH   (1024 << 2)
 

Functions

uint32_t size_count_with_4 (uint32_t size)
 
static void _alloc_block_nodes ()
 Allocate memory for new block nodes.
 
static xmem_pool_block * _get_next_block_node ()
 Get the next available block node.
 
static void _recover_block_node (xmem_pool_block *node)
 
static int _xmem_count_free_blocks (xmem_pool *pool)
 
xmem_pool_handle _create_pool (uint32_t block_size, uint32_t block_count)
 Create a new memory pool.
 
void xmem_print_info (xmem_pool_handle _pool)
 Print information about the memory pool.
 
xmem_pool_handle xmem_create_pool (unsigned int block_size)
 
void xmem_destroy_pool (xmem_pool_handle handle)
 Destroy a memory pool and free all associated resources.
 
char * xmem_alloc (xmem_pool_handle handle)
 Allocate a block from the memory pool.
 
int xmem_free (xmem_pool_handle handle, char *pointer)
 Free a block back to the memory pool.
 
void xmem_init ()
 
void xmem_clean_up ()
 Clean up global resources used by xmempool.
 

Variables

static uint32_t _xmem_pool_next_alloc_block_node_count
 
static xmem_pool_block * _free_block_ptr = 0
 
static xmem_pool_block * _free_block_ptr_end = 0
 
static int _xmem_page_size = 0
 
static uint32_t _block_size = sizeof(xmem_pool_block)
 

Macro Definition Documentation

◆ MAX_ALLOC_BLOCK_NODE_COUNT

#define MAX_ALLOC_BLOCK_NODE_COUNT   (1024 << 2)

Definition at line 48 of file xmempool.c.

◆ MAX_ALLOC_LENGTH

#define MAX_ALLOC_LENGTH   (1024 << 2)

Definition at line 50 of file xmempool.c.

◆ MIN_ALLOC_BLOCK_NODE_COUNT

#define MIN_ALLOC_BLOCK_NODE_COUNT   (1024)

Definition at line 47 of file xmempool.c.

◆ MIN_ALLOC_LENGTH

#define MIN_ALLOC_LENGTH   (1024)

Definition at line 49 of file xmempool.c.

Function Documentation

◆ _alloc_block_nodes()

static void _alloc_block_nodes ( )
inlinestatic

Allocate memory for new block nodes.

This function allocates a chunk of memory for new block nodes when the current pool is exhausted. It doubles the allocation size each time, up to a maximum defined by MAX_ALLOC_BLOCK_NODE_COUNT. The newly allocated nodes are then added to the free block list.

Definition at line 74 of file xmempool.c.

74 {
79 }
80
81#ifdef _WIN32
82 char* start = (char*)malloc(size_count);
83#else
84 char* start;
85 posix_memalign((void**)&start, _xmem_page_size, size_count);
86#endif
87 char* block_ptr = start;
88 char* end = start + size_count;
89
90 // Check if memory allocation was successful
91 if (!block_ptr) return;
92
93 for (; block_ptr < end; block_ptr += _block_size) {
94 xmem_pool_block* block = (xmem_pool_block*)block_ptr;
95 block->is_block_start = (block_ptr == start);
96 block->start = 0;
97
98 // Link the current block to the previous one, except for the first block
99 if (block_ptr != start) {
100 ((xmem_pool_block*)(block_ptr - _block_size))->next = block;
101 }
102
103 block->block_size = 0;
104 }
105 ((xmem_pool_block*)(end - _block_size))->next = 0;
106
107 // Add newly allocated blocks to the free list
109 // Append new blocks to the existing free list
111 } else {
112 // Initialize the free list with the new blocks
114 }
115
117}
xmempool - A Simple Memory Pool Implementation
Definition xmempool.c:26
struct xmem_pool_block * next
Definition xmempool.c:29
uint32_t block_size
Definition xmempool.c:28
uint32_t is_block_start
Definition xmempool.c:30
static uint32_t _xmem_pool_next_alloc_block_node_count
Definition xmempool.c:51
static int _xmem_page_size
Definition xmempool.c:55
static xmem_pool_block * _free_block_ptr
Definition xmempool.c:53
static uint32_t _block_size
Definition xmempool.c:56
#define MAX_ALLOC_BLOCK_NODE_COUNT
Definition xmempool.c:48
static xmem_pool_block * _free_block_ptr_end
Definition xmempool.c:54

◆ _create_pool()

xmem_pool_handle _create_pool ( uint32_t block_size,
uint32_t block_count )

Create a new memory pool.

This function creates a new memory pool with the specified block size and count. It allocates memory for the pool structure and the actual memory blocks, then initializes the free block list.

Parameters
block_sizeSize of each memory block in the pool
block_countNumber of blocks to allocate initially
Returns
Handle to the created pool, or NULL if creation failed

Definition at line 189 of file xmempool.c.

189 {
190 static uint32_t _pool_size = sizeof(xmem_pool);
191 xmem_pool* pool = (xmem_pool*)malloc(_pool_size);
192 uint32_t size_count = block_count * block_size;
193 uint32_t alloc_size = size_count_with_4(size_count);
194 char* space;
195
196#ifndef _WIN32
197 if (_xmem_page_size < alloc_size) {
198 posix_memalign((void**)&space, _xmem_page_size, alloc_size);
199 } else {
200#endif
201 space = (char*)malloc(size_count);
202#ifndef _WIN32
203 }
204#endif
205 xmem_pool_block* start_block = 0;
206 xmem_pool_block* end_block = 0;
207
208 // Allocate memory for the pool structure
209 if (!pool) return (char*)0;
210 if (!space) {
211 free(pool);
212 return (char*)0;
213 }
214
215 // Initialize pool properties
216 pool->start = space;
217 pool->end = space + (block_count * block_size);
218
219 pool->block_size = block_size;
220 pool->block_count = block_count;
221 pool->next = 0;
222
223 pool->next_alloc_length = block_count << 1;
226 }
227
228 // Initialize free blocks
229 for (; space < pool->end; space += block_size) {
231 if (!start_block) {
232 start_block = wrapper;
233 }
234
235 // Handle allocation failure
236 if (!wrapper) {
237 free(pool);
238 free(space);
239 while (start_block) {
240 xmem_pool_block* next = start_block->next;
241 _recover_block_node(start_block);
242 start_block = next;
243 }
244 return 0;
245 }
246
247 wrapper->block_size = block_size;
248 wrapper->start = space;
249 wrapper->next = 0;
250
251 // Link blocks in the free list
252 if (end_block) {
253 end_block->next = wrapper;
254 }
255 end_block = wrapper;
256 }
257
258 pool->free_blocks = start_block;
259 pool->free_blocks_tail = end_block;
260
261 return (char*)pool;
262}
char * start
Definition xmempool.c:37
struct xmem_pool * next
Definition xmempool.c:42
xmem_pool_block * free_blocks_tail
Definition xmempool.c:41
uint32_t block_count
Definition xmempool.c:35
uint32_t block_size
Definition xmempool.c:34
xmem_pool_block * free_blocks
Definition xmempool.c:40
char * end
Definition xmempool.c:38
uint32_t next_alloc_length
Definition xmempool.c:44
uint32_t size_count_with_4(uint32_t size)
Definition xmempool.c:58
static void _recover_block_node(xmem_pool_block *node)
Definition xmempool.c:149
#define MAX_ALLOC_LENGTH
Definition xmempool.c:50
static xmem_pool_block * _get_next_block_node()
Get the next available block node.
Definition xmempool.c:127

◆ _get_next_block_node()

static xmem_pool_block * _get_next_block_node ( )
inlinestatic

Get the next available block node.

This function returns the next available block node from the free list. If the free list is empty, it calls _alloc_block_nodes() to allocate more.

Returns
Pointer to the next available block node, or NULL if allocation fails

Definition at line 127 of file xmempool.c.

127 {
128 xmem_pool_block* should_return;
129
130 // If no more block node, generate a new block node list
131 if (!_free_block_ptr) {
133 }
134
135 // If still no more block node, return NULL to indicate error
136 if (!_free_block_ptr) return (xmem_pool_block*)0;
137
138 should_return = _free_block_ptr;
140
141 // If should_return is the last one, set the tail to NULL
142 if (should_return == _free_block_ptr_end) {
144 }
145
146 return should_return;
147}
static void _alloc_block_nodes()
Allocate memory for new block nodes.
Definition xmempool.c:74

◆ _recover_block_node()

static void _recover_block_node ( xmem_pool_block * node)
inlinestatic

Definition at line 149 of file xmempool.c.

149 {
150 node->block_size = 0;
151 node->next = NULL;
152 node->start = NULL;
153
156 _free_block_ptr_end = node;
157 } else {
159 }
160}

◆ _xmem_count_free_blocks()

static int _xmem_count_free_blocks ( xmem_pool * pool)
inlinestatic

Definition at line 162 of file xmempool.c.

162 {
163 xmem_pool_block* block;
164 int count;
165
166 if (!pool->free_blocks) return 0;
167 block = pool->free_blocks;
168 count = 1;
169
170 while (block != pool->free_blocks_tail) {
171 count++;
172 block = block->next;
173 }
174
175 return count;
176}

◆ size_count_with_4()

uint32_t size_count_with_4 ( uint32_t size)

Definition at line 58 of file xmempool.c.

58 {
59 if (size % 4 == 0) {
60 return size;
61 } else {
62 return size + (4 - size % 4);
63 }
64}

◆ xmem_alloc()

char * xmem_alloc ( xmem_pool_handle handle)

Allocate a block from the memory pool.

This function returns a pointer to a free block from the pool. If the current pool is full, it automatically creates and chains a new pool. The allocated block is always zero-initialized.

Parameters
handleHandle to the pool to allocate from
Returns
Pointer to the allocated block, or NULL if allocation failed

Definition at line 341 of file xmempool.c.

341 {
342 static uint32_t pool_element_size = sizeof(xmem_pool);
343 xmem_pool* pool = (xmem_pool*)handle;
344 xmem_pool temp_pool;
345 xmem_pool_block* block;
346 char* space;
347
348 // If no more free blocks, create a new pool
349 if (!pool->free_blocks) {
350 xmem_pool* new_pool =
352
353 if (!new_pool) {
354 return 0;
355 }
356
357 // Swap the new pool with the current one
358 memcpy(&temp_pool, pool, pool_element_size);
359 memcpy(pool, new_pool, pool_element_size);
360 memcpy(new_pool, &temp_pool, pool_element_size);
361
362 pool->next = new_pool;
363 }
364
365 // Allocate the first free block
366 block = pool->free_blocks;
367 pool->free_blocks = block->next;
368 space = block->start;
369
370 if (!pool->free_blocks) pool->free_blocks_tail = 0;
371
372 // Initialize allocated space and recover the block node
373 memset(space, 0, block->block_size);
374 _recover_block_node(block);
375
376 return space;
377}
xmem_pool_handle _create_pool(uint32_t block_size, uint32_t block_count)
Create a new memory pool.
Definition xmempool.c:189

◆ xmem_clean_up()

void xmem_clean_up ( )

Clean up global resources used by xmempool.

This function frees all global resources used by the xmempool system, particularly the memory used for managing block nodes. It should be called when the xmempool system is no longer needed.

Definition at line 408 of file xmempool.c.

408 {
410 xmem_pool_block* start = 0;
411 xmem_pool_block* end = 0;
412
413 // Reorganize the free block list
414 while (blk != 0) {
415 if (blk->is_block_start) {
416 if (end) {
417 end->next = blk;
418 } else {
419 start = blk;
420 }
421 end = blk;
422 }
423 blk = blk->next;
424 }
425 if (end) end->next = 0;
426
427 // Free all allocated block nodes
428 blk = start;
429 while (blk != 0) {
430 end = blk->next; // Temporary variable for the next block
431 free(blk);
432 blk = end;
433 }
434
435 // Reset global pointers
437}

◆ xmem_create_pool()

xmem_pool_handle xmem_create_pool ( unsigned int block_size)

Definition at line 292 of file xmempool.c.

292 {
293#ifndef _WIN32
294 // Initialize page size for non-Windows systems
295 if (_xmem_page_size == 0) {
296 _xmem_page_size = getpagesize();
297 }
298#endif
299
300#ifdef XMEM_DBG
301 // Debug mode: create pool and print creation message
302 char* pool = _create_pool(block_size, MIN_ALLOC_LENGTH);
303 printf("A new pool of [%d] is created!", block_size);
304 return pool;
305#endif
306
307 // Normal mode: create pool with minimum allocation length
308 return _create_pool(block_size, MIN_ALLOC_LENGTH);
309}
#define MIN_ALLOC_LENGTH
Definition xmempool.c:49

◆ xmem_destroy_pool()

void xmem_destroy_pool ( xmem_pool_handle pool)

Destroy a memory pool and free all associated resources.

This function frees all memory associated with the pool, including all chained pools and their blocks. It also recovers all block nodes used for managing free blocks.

Parameters
poolHandle to the pool to be destroyed

Definition at line 311 of file xmempool.c.

311 {
312 xmem_pool* pool = (xmem_pool*)handle;
313 xmem_pool* next_pool;
314
315 if (!handle) return;
316
317 // Iterate through all pools in the chain
318 while (pool) {
319 // Free the memory space allocated for blocks
320 free(pool->start);
321
322 // For the first pool, recover all free block nodes
323 if (pool == (xmem_pool*)handle) {
324 xmem_pool_block* block = pool->free_blocks;
325 xmem_pool_block* next_block;
326
327 while (block) {
328 next_block = block->next;
329 _recover_block_node(block);
330 block = next_block;
331 }
332 }
333
334 // Move to the next pool
335 next_pool = pool->next;
336 free(pool);
337 pool = next_pool;
338 }
339}

◆ xmem_free()

int xmem_free ( xmem_pool_handle handle,
char * pointer )

Free a block back to the memory pool.

This function returns a block to the free list of the first pool in the chain. It does not actually free memory, but makes the block available for future allocations.

Parameters
handleHandle to the pool
pointerPointer to the block to be freed
Returns
1 if successful, 0 if failed (e.g., if no free block nodes are available)

Definition at line 379 of file xmempool.c.

379 {
380 xmem_pool* pool = (xmem_pool*)handle;
381
382 // Get a new block node
384 if (!block) {
385 return 0;
386 }
387
388 // Initialize the new block and add it to the free list
389 block->block_size = pool->block_size;
390 block->start = pointer;
391 block->next = 0;
392
393 if (!pool->free_blocks && !pool->free_blocks_tail) {
394 pool->free_blocks = pool->free_blocks_tail = block;
395 return 1;
396 }
397
398 pool->free_blocks_tail->next = block;
399 pool->free_blocks_tail = block;
400
401 return 1;
402}

◆ xmem_init()

void xmem_init ( )

Definition at line 404 of file xmempool.c.

404 {
405 // Placeholder for potential initialization code
406}

◆ xmem_print_info()

void xmem_print_info ( xmem_pool_handle pool)

Print information about the memory pool.

This function prints detailed information about each pool in the chain, including its size, block count, memory range, and number of free blocks.

Parameters
poolHandle to the pool

Definition at line 264 of file xmempool.c.

264 {
265 xmem_pool* pool = (xmem_pool*)_pool;
266 int pool_id = 0;
267
268 if (!_pool) return;
269
270 while (pool) {
271 printf("----- POOL OF SIZE [%.4d] -----\n", pool->block_size);
272 printf(" + id: %d\n", pool_id++);
273 printf(" + count: %d\n", pool->block_count);
274
275#pragma GCC diagnostic push
276#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
277 printf(" + spaces: [0x%.8X, 0x%.8X)\n",
278 (unsigned int)pool->start,
279 (unsigned int)pool->end);
280#pragma GCC diagnostic pop
281
282 if (pool_id == 1) {
283 printf(" + free blocks: %d\n", _xmem_count_free_blocks(pool));
284 } else {
285 printf(" + free blocks: -\n");
286 }
287
288 pool = pool->next;
289 }
290}
static int _xmem_count_free_blocks(xmem_pool *pool)
Definition xmempool.c:162

Variable Documentation

◆ _block_size

uint32_t _block_size = sizeof(xmem_pool_block)
static

Definition at line 56 of file xmempool.c.

◆ _free_block_ptr

xmem_pool_block* _free_block_ptr = 0
static

Definition at line 53 of file xmempool.c.

◆ _free_block_ptr_end

xmem_pool_block* _free_block_ptr_end = 0
static

Definition at line 54 of file xmempool.c.

◆ _xmem_page_size

int _xmem_page_size = 0
static

Definition at line 55 of file xmempool.c.

◆ _xmem_pool_next_alloc_block_node_count

uint32_t _xmem_pool_next_alloc_block_node_count
static
Initial value:
=
(1024)

Definition at line 51 of file xmempool.c.