/[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.1 - (show annotations)
Thu Jun 12 09:46:42 2025 UTC (9 months ago) by sysadm
Branch: MAIN
Content type: text/x-csrc
Add memory pool

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

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