data-structures-c
Loading...
Searching...
No Matches
pool.h
Go to the documentation of this file.
1/* pool.h
2 *
3 * Copyright (C) 2023 abxh
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 * See the file LICENSE included with this distribution for more
10 * information. */
11
20#include "align.h" // align, calc_alignment_padding
21
22#include <stdalign.h>
23#include <stddef.h>
24#include <string.h>
25
32
36struct pool {
37 size_t buf_len;
38 size_t chunk_size;
39 unsigned char *buf_ptr;
41};
42
44static inline void internal_pool_push_free_node(struct pool *self, struct pool_free_node *node)
45{
46 node->next_ptr = self->head_ptr;
47 self->head_ptr = node;
48}
50
56static inline void pool_deallocate_all(struct pool *self)
57{
58 assert(self);
59
60 const size_t chunk_count = self->buf_len / self->chunk_size;
61
62 for (size_t i = 0; i < chunk_count; i++) {
63 unsigned char *ptr = &self->buf_ptr[i * self->chunk_size];
64
65 struct pool_free_node *node = (struct pool_free_node *)ptr;
66
67 internal_pool_push_free_node(self, node);
68 }
69}
70
80static inline void pool_init(struct pool *self, const size_t len, unsigned char *backing_buf, const size_t data_size,
81 const size_t data_alignment)
82{
83 assert(self);
84 assert(backing_buf);
85
86 const uintptr_t padding = calc_alignment_padding(data_alignment, (uintptr_t)backing_buf);
87
88 size_t chunk_size = data_size >= sizeof(struct pool_free_node) ? data_size : sizeof(struct pool_free_node);
89
90 chunk_size = chunk_size + calc_alignment_padding(data_alignment, chunk_size);
91
92 assert(padding + chunk_size <= len);
93
94 self->buf_ptr = &backing_buf[padding];
95 self->buf_len = len - padding;
96 self->chunk_size = chunk_size;
97 self->head_ptr = NULL;
98
100}
101
109static inline void *pool_allocate(struct pool *self)
110{
111 struct pool_free_node *node = self->head_ptr;
112
113 if (node == NULL) {
114 return NULL;
115 }
116
117 self->head_ptr = node->next_ptr;
118
119 memset(node, 0, self->chunk_size);
120
121 return node;
122}
123
130static inline void pool_deallocate(struct pool *self, void *ptr)
131{
132 assert(self);
133 assert(ptr);
134 assert(&self->buf_ptr[0] <= (unsigned char *)ptr && (unsigned char *)ptr < &self->buf_ptr[self->buf_len]);
135
136 struct pool_free_node *node = (struct pool_free_node *)ptr;
137
138 internal_pool_push_free_node(self, node);
139}
Align memory.
static uintptr_t calc_alignment_padding(const size_t alignment, const uintptr_t ptr)
Calculate the alignment padding required to align a pointer.
Definition align.h:91
static void pool_init(struct pool *self, const size_t len, unsigned char *backing_buf, const size_t data_size, const size_t data_alignment)
Initialize pool for given data size and alignment.
Definition pool.h:80
static void pool_deallocate(struct pool *self, void *ptr)
Free a memory chunk for further reuse.
Definition pool.h:130
static void * pool_allocate(struct pool *self)
Get a pointer to a free block of previously given data size.
Definition pool.h:109
static void pool_deallocate_all(struct pool *self)
Deallocate pool and restore all free nodes.
Definition pool.h:56
Pool node struct.
Definition pool.h:29
struct pool_free_node * next_ptr
pointer to next node
Definition pool.h:30
Pool struct.
Definition pool.h:36
size_t chunk_size
Chunk size.
Definition pool.h:38
struct pool_free_node * head_ptr
Pointer to head node.
Definition pool.h:40
unsigned char * buf_ptr
Underlying buffer.
Definition pool.h:39
size_t buf_len
Underlying buffer length.
Definition pool.h:37