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