• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef MEMORY_POOL_H
7 #define MEMORY_POOL_H
8 
9 struct memory_block;
10 
11 /**
12  * Provides a pool of memory that can quickly be allocated from, at the
13  * cost of being unable to explicitly free one of the allocated blocks.
14  * Instead, the entire pool can be freed at once.
15  *
16  * The idea is to allow one to quickly allocate a flexible amount of
17  * memory during operations like shader compilation while avoiding
18  * reference counting headaches.
19  */
20 struct memory_pool {
21    unsigned char *head;
22    unsigned char *end;
23    unsigned int total_allocated;
24    struct memory_block *blocks;
25 };
26 
27 void memory_pool_init(struct memory_pool *pool);
28 void memory_pool_destroy(struct memory_pool *pool);
29 void *memory_pool_malloc(struct memory_pool *pool, unsigned int bytes);
30 
31 /**
32  * Generic helper for growing an array that has separate size/count
33  * and reserved counters to accommodate up to num new element.
34  *
35  *  type * Array;
36  *  unsigned int Size;
37  *  unsigned int Reserved;
38  *
39  * memory_pool_array_reserve(pool, type, Array, Size, Reserved, k);
40  * assert(Size + k < Reserved);
41  *
42  * \note Size is not changed by this macro.
43  *
44  * \warning Array, Size, Reserved have to be lvalues and may be evaluated
45  * several times.
46  */
47 #define memory_pool_array_reserve(pool, type, array, size, reserved, num)  \
48    do {                                                                    \
49       unsigned int _num = (num);                                           \
50       if ((size) + _num > (reserved)) {                                    \
51          unsigned int newreserve = (reserved) * 2;                         \
52          type *newarray;                                                   \
53          if (newreserve < _num)                                            \
54             newreserve = 4 * _num; /* arbitrary heuristic */               \
55          newarray = memory_pool_malloc((pool), newreserve * sizeof(type)); \
56          memcpy(newarray, (array), (size) * sizeof(type));                 \
57          (array) = newarray;                                               \
58          (reserved) = newreserve;                                          \
59       }                                                                    \
60    } while (0)
61 
62 #endif /* MEMORY_POOL_H */
63