/[LeafOK_CVS]/lbbs/src/memory_pool.c
ViewVC logotype

Contents of /lbbs/src/memory_pool.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Fri Dec 19 06:16:27 2025 UTC (2 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.9: +12 -12 lines
Content type: text/x-csrc
Append \n to the end of logging message by log_...()
Remove ending \n from each logging message

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * memory_pool
4 * - memory pool
5 *
6 * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "log.h"
14 #include "memory_pool.h"
15 #include <stdlib.h>
16 #include <string.h>
17
18 MEMORY_POOL *memory_pool_init(size_t node_size, size_t node_count_per_chunk, int chunk_count_limit)
19 {
20 MEMORY_POOL *p_pool;
21
22 if (node_size < sizeof(void *))
23 {
24 log_error("Error: node_size < sizeof(void *)");
25 return NULL;
26 }
27
28 p_pool = malloc(sizeof(MEMORY_POOL));
29 if (p_pool == NULL)
30 {
31 log_error("malloc(MEMORY_POOL) error: OOM");
32 return NULL;
33 }
34
35 p_pool->node_size = node_size;
36 p_pool->node_count_per_chunk = node_count_per_chunk;
37 p_pool->chunk_count_limit = chunk_count_limit;
38 p_pool->chunk_count = 0;
39 p_pool->p_free = NULL;
40
41 p_pool->p_chunks = malloc(sizeof(void *) * (size_t)chunk_count_limit);
42 if (p_pool->p_chunks == NULL)
43 {
44 log_error("malloc(sizeof(void *) * %d) error: OOM", chunk_count_limit);
45 free(p_pool);
46 return NULL;
47 }
48
49 p_pool->node_count_allocated = 0;
50 p_pool->node_count_free = 0;
51 p_pool->node_count_total = 0;
52
53 return p_pool;
54 }
55
56 void memory_pool_cleanup(MEMORY_POOL *p_pool)
57 {
58 if (p_pool == NULL)
59 {
60 return;
61 }
62
63 if (p_pool->node_count_allocated > 0)
64 {
65 log_error("Still have %d in-use nodes", p_pool->node_count_allocated);
66 }
67
68 while (p_pool->chunk_count > 0)
69 {
70 (p_pool->chunk_count)--;
71 free(p_pool->p_chunks[p_pool->chunk_count]);
72 }
73
74 free(p_pool->p_chunks);
75 free(p_pool);
76 }
77
78 inline static void *memory_pool_add_chunk(MEMORY_POOL *p_pool)
79 {
80 void *p_chunk;
81 void *p_node;
82 size_t i;
83
84 if (p_pool->chunk_count >= p_pool->chunk_count_limit)
85 {
86 log_error("Chunk count limit %d reached", p_pool->chunk_count);
87 return NULL;
88 }
89 p_chunk = malloc(p_pool->node_size * p_pool->node_count_per_chunk);
90 if (p_chunk == NULL)
91 {
92 log_error("malloc(%d * %d) error: OOM", p_pool->node_size, p_pool->node_count_per_chunk);
93 return NULL;
94 }
95
96 p_node = p_pool->p_free;
97 memcpy((char *)p_chunk + (p_pool->node_count_per_chunk - 1) * p_pool->node_size, &p_node, sizeof(p_node));
98 for (i = 0; i < p_pool->node_count_per_chunk - 1; i++)
99 {
100 p_node = (char *)p_chunk + (i + 1) * p_pool->node_size;
101 memcpy((char *)p_chunk + i * p_pool->node_size, &p_node, sizeof(p_node));
102 }
103
104 p_pool->p_chunks[p_pool->chunk_count] = p_chunk;
105 (p_pool->chunk_count)++;
106 p_pool->node_count_total += (int)p_pool->node_count_per_chunk;
107 p_pool->node_count_free += (int)p_pool->node_count_per_chunk;
108
109 p_pool->p_free = p_chunk;
110
111 return p_chunk;
112 }
113
114 void *memory_pool_alloc(MEMORY_POOL *p_pool)
115 {
116 void *p_node;
117
118 if (p_pool == NULL)
119 {
120 log_error("NULL pointer error");
121 return NULL;
122 }
123
124 if (p_pool->p_free == NULL && memory_pool_add_chunk(p_pool) == NULL)
125 {
126 log_error("Add chunk error");
127 return NULL;
128 }
129
130 p_node = p_pool->p_free;
131 memcpy(&(p_pool->p_free), p_node, sizeof(p_pool->p_free));
132
133 (p_pool->node_count_free)--;
134 (p_pool->node_count_allocated)++;
135
136 return p_node;
137 }
138
139 void memory_pool_free(MEMORY_POOL *p_pool, void *p_node)
140 {
141 if (p_pool == NULL)
142 {
143 log_error("NULL pointer error");
144 return;
145 }
146
147 // For test and debug
148 #ifdef _DEBUG
149 memory_pool_check_node(p_pool, p_node);
150 #endif
151
152 memcpy(p_node, &(p_pool->p_free), sizeof(p_pool->p_free));
153 p_pool->p_free = p_node;
154
155 (p_pool->node_count_free)++;
156 (p_pool->node_count_allocated)--;
157 }
158
159 int memory_pool_check_node(MEMORY_POOL *p_pool, void *p_node)
160 {
161 size_t chunk_size;
162 int i;
163
164 if (p_pool == NULL || p_node == NULL)
165 {
166 log_error("NULL pointer error");
167 return -1;
168 }
169
170 chunk_size = p_pool->node_size * p_pool->node_count_per_chunk;
171
172 for (i = 0; i < p_pool->chunk_count; i++)
173 {
174 if (p_node >= p_pool->p_chunks[i] && (char *)p_node < (char *)(p_pool->p_chunks[i]) + chunk_size)
175 {
176 if ((size_t)((char *)p_node - (char *)(p_pool->p_chunks[i])) % p_pool->node_size == 0)
177 {
178 return 0; // OK
179 }
180 else
181 {
182 log_error("Address of node (%p) is not aligned with border of chunk %d [%p, %p)",
183 i, p_node >= p_pool->p_chunks[i], (char *)(p_pool->p_chunks[i]) + chunk_size);
184 return -3;
185 }
186 }
187 }
188
189 log_error("Address of node is not in range of chunks");
190 return -2;
191 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1