1 /* 2 * Copyright 2009 Nicolai Hähnle <[email protected]> 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 28 void memory_pool_init(struct memory_pool * pool); 29 void memory_pool_destroy(struct memory_pool * pool); 30 void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes); 31 32 33 /** 34 * Generic helper for growing an array that has separate size/count 35 * and reserved counters to accommodate up to num new element. 36 * 37 * type * Array; 38 * unsigned int Size; 39 * unsigned int Reserved; 40 * 41 * memory_pool_array_reserve(pool, type, Array, Size, Reserved, k); 42 * assert(Size + k < Reserved); 43 * 44 * \note Size is not changed by this macro. 45 * 46 * \warning Array, Size, Reserved have to be lvalues and may be evaluated 47 * several times. 48 */ 49 #define memory_pool_array_reserve(pool, type, array, size, reserved, num) do { \ 50 unsigned int _num = (num); \ 51 if ((size) + _num > (reserved)) { \ 52 unsigned int newreserve = (reserved) * 2; \ 53 type * newarray; \ 54 if (newreserve < _num) \ 55 newreserve = 4 * _num; /* arbitrary heuristic */ \ 56 newarray = memory_pool_malloc((pool), newreserve * sizeof(type)); \ 57 memcpy(newarray, (array), (size) * sizeof(type)); \ 58 (array) = newarray; \ 59 (reserved) = newreserve; \ 60 } \ 61 } while(0) 62 63 #endif /* MEMORY_POOL_H */ 64