• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "memory_pool.h"
7 
8 #include <assert.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #define POOL_LARGE_ALLOC 4096
13 #define POOL_ALIGN       8
14 
15 struct memory_block {
16    struct memory_block *next;
17 };
18 
19 void
memory_pool_init(struct memory_pool * pool)20 memory_pool_init(struct memory_pool *pool)
21 {
22    memset(pool, 0, sizeof(struct memory_pool));
23 }
24 
25 void
memory_pool_destroy(struct memory_pool * pool)26 memory_pool_destroy(struct memory_pool *pool)
27 {
28    while (pool->blocks) {
29       struct memory_block *block = pool->blocks;
30       pool->blocks = block->next;
31       free(block);
32    }
33 }
34 
35 static void
refill_pool(struct memory_pool * pool)36 refill_pool(struct memory_pool *pool)
37 {
38    unsigned int blocksize = pool->total_allocated;
39    struct memory_block *newblock;
40 
41    if (!blocksize)
42       blocksize = 2 * POOL_LARGE_ALLOC;
43 
44    newblock = malloc(blocksize);
45    newblock->next = pool->blocks;
46    pool->blocks = newblock;
47 
48    pool->head = (unsigned char *)(newblock + 1);
49    pool->end = ((unsigned char *)newblock) + blocksize;
50    pool->total_allocated += blocksize;
51 }
52 
53 void *
memory_pool_malloc(struct memory_pool * pool,unsigned int bytes)54 memory_pool_malloc(struct memory_pool *pool, unsigned int bytes)
55 {
56    if (bytes < POOL_LARGE_ALLOC) {
57       void *ptr;
58 
59       if (pool->head + bytes > pool->end)
60          refill_pool(pool);
61 
62       assert(pool->head + bytes <= pool->end);
63 
64       ptr = pool->head;
65 
66       pool->head += bytes;
67       pool->head =
68          (unsigned char *)(((unsigned long)pool->head + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
69 
70       return ptr;
71    } else {
72       struct memory_block *block = malloc(bytes + sizeof(struct memory_block));
73 
74       block->next = pool->blocks;
75       pool->blocks = block;
76 
77       return (block + 1);
78    }
79 }
80