/[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.7 - (show annotations)
Tue Nov 4 13:49:51 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.6: +7 -15 lines
Content type: text/x-csrc
Update file header information comments

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

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