xref: /aosp_15_r20/external/coreboot/src/commonlib/include/commonlib/mem_pool.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _MEM_POOL_H_
4 #define _MEM_POOL_H_
5 
6 #include <assert.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 /*
11  * The memory pool allows one to allocate memory from a fixed size buffer that
12  * also allows freeing semantics for reuse. However, the current limitation is
13  * that only the two most recent allocations  can be freed (in exact reverse
14  * order). If one tries to free any allocation that isn't at the top of the
15  * allocation stack, or one allocates more than two buffers in a row without
16  * freeing, it will result in a leak within the memory pool. (Two allocations
17  * were chosen to optimize for the CBFS cache case which may need two buffers
18  * to map a single compressed file, and will free them in reverse order.)
19  *
20  * You must ensure the backing buffer is 'alignment' aligned.
21  */
22 
23 struct mem_pool {
24 	uint8_t *buf;
25 	size_t size;
26 	size_t alignment;
27 	uint8_t *last_alloc;
28 	uint8_t *second_to_last_alloc;
29 	size_t free_offset;
30 };
31 
32 #define MEM_POOL_INIT(buf_, size_, alignment_)	\
33 	{					\
34 		.buf = (buf_),			\
35 		.size = (size_),		\
36 		.alignment = (alignment_),	\
37 		.last_alloc = NULL,		\
38 		.second_to_last_alloc = NULL,	\
39 		.free_offset = 0,		\
40 	}
41 
mem_pool_reset(struct mem_pool * mp)42 static inline void mem_pool_reset(struct mem_pool *mp)
43 {
44 	mp->last_alloc = NULL;
45 	mp->second_to_last_alloc = NULL;
46 	mp->free_offset = 0;
47 }
48 
49 /* Initialize a memory pool. */
mem_pool_init(struct mem_pool * mp,void * buf,size_t sz,size_t alignment)50 static inline void mem_pool_init(struct mem_pool *mp, void *buf, size_t sz,
51 					 size_t alignment)
52 {
53 	assert(alignment);
54 	assert((uintptr_t)buf % alignment == 0);
55 
56 	mp->buf = buf;
57 	mp->size = sz;
58 	mp->alignment = alignment;
59 	mem_pool_reset(mp);
60 }
61 
62 /* Allocate requested size from the memory pool. NULL returned on error. */
63 void *mem_pool_alloc(struct mem_pool *mp, size_t sz);
64 
65 /* Free allocation from memory pool. */
66 void mem_pool_free(struct mem_pool *mp, void *alloc);
67 
68 #endif /* _MEM_POOL_H_ */
69