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

Annotation of /lbbs/src/memory_pool.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (hide annotations)
Tue Jan 6 13:59:21 2026 UTC (2 months, 1 week ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.11: +6 -3 lines
Content type: text/x-csrc
Bug fix

1 sysadm 1.7 /* SPDX-License-Identifier: GPL-3.0-or-later */
2     /*
3     * memory_pool
4     * - memory pool
5     *
6 sysadm 1.11 * Copyright (C) 2004-2026 Leaflet <leaflet@leafok.com>
7 sysadm 1.7 */
8 sysadm 1.1
9 sysadm 1.9 #ifdef HAVE_CONFIG_H
10     #include "config.h"
11     #endif
12    
13 sysadm 1.5 #include "log.h"
14 sysadm 1.1 #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 sysadm 1.10 log_error("Error: node_size < sizeof(void *)");
25 sysadm 1.1 return NULL;
26     }
27    
28     p_pool = malloc(sizeof(MEMORY_POOL));
29     if (p_pool == NULL)
30     {
31 sysadm 1.10 log_error("malloc(MEMORY_POOL) error: OOM");
32 sysadm 1.1 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 sysadm 1.10 log_error("malloc(sizeof(void *) * %d) error: OOM", chunk_count_limit);
45 sysadm 1.1 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 sysadm 1.10 log_error("Still have %d in-use nodes", p_pool->node_count_allocated);
66 sysadm 1.1 }
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 sysadm 1.12 size_t chunk_size;
84 sysadm 1.1
85     if (p_pool->chunk_count >= p_pool->chunk_count_limit)
86     {
87 sysadm 1.10 log_error("Chunk count limit %d reached", p_pool->chunk_count);
88 sysadm 1.1 return NULL;
89     }
90 sysadm 1.12
91     chunk_size = p_pool->node_size * p_pool->node_count_per_chunk;
92     p_chunk = malloc(chunk_size);
93 sysadm 1.1 if (p_chunk == NULL)
94     {
95 sysadm 1.12 log_error("malloc(%zu) error: OOM", chunk_size);
96 sysadm 1.1 return NULL;
97     }
98    
99     p_node = p_pool->p_free;
100 sysadm 1.6 memcpy((char *)p_chunk + (p_pool->node_count_per_chunk - 1) * p_pool->node_size, &p_node, sizeof(p_node));
101 sysadm 1.1 for (i = 0; i < p_pool->node_count_per_chunk - 1; i++)
102     {
103 sysadm 1.6 p_node = (char *)p_chunk + (i + 1) * p_pool->node_size;
104     memcpy((char *)p_chunk + i * p_pool->node_size, &p_node, sizeof(p_node));
105 sysadm 1.1 }
106    
107     p_pool->p_chunks[p_pool->chunk_count] = p_chunk;
108     (p_pool->chunk_count)++;
109     p_pool->node_count_total += (int)p_pool->node_count_per_chunk;
110     p_pool->node_count_free += (int)p_pool->node_count_per_chunk;
111    
112     p_pool->p_free = p_chunk;
113    
114     return p_chunk;
115     }
116    
117     void *memory_pool_alloc(MEMORY_POOL *p_pool)
118     {
119     void *p_node;
120    
121     if (p_pool == NULL)
122     {
123 sysadm 1.10 log_error("NULL pointer error");
124 sysadm 1.1 return NULL;
125     }
126    
127     if (p_pool->p_free == NULL && memory_pool_add_chunk(p_pool) == NULL)
128     {
129 sysadm 1.10 log_error("Add chunk error");
130 sysadm 1.1 return NULL;
131     }
132    
133     p_node = p_pool->p_free;
134     memcpy(&(p_pool->p_free), p_node, sizeof(p_pool->p_free));
135    
136     (p_pool->node_count_free)--;
137     (p_pool->node_count_allocated)++;
138    
139     return p_node;
140     }
141    
142     void memory_pool_free(MEMORY_POOL *p_pool, void *p_node)
143     {
144     if (p_pool == NULL)
145     {
146 sysadm 1.10 log_error("NULL pointer error");
147 sysadm 1.1 return;
148     }
149    
150 sysadm 1.2 // For test and debug
151 sysadm 1.4 #ifdef _DEBUG
152     memory_pool_check_node(p_pool, p_node);
153     #endif
154 sysadm 1.2
155 sysadm 1.1 memcpy(p_node, &(p_pool->p_free), sizeof(p_pool->p_free));
156     p_pool->p_free = p_node;
157    
158     (p_pool->node_count_free)++;
159     (p_pool->node_count_allocated)--;
160     }
161    
162     int memory_pool_check_node(MEMORY_POOL *p_pool, void *p_node)
163     {
164     size_t chunk_size;
165     int i;
166    
167     if (p_pool == NULL || p_node == NULL)
168     {
169 sysadm 1.10 log_error("NULL pointer error");
170 sysadm 1.1 return -1;
171     }
172    
173     chunk_size = p_pool->node_size * p_pool->node_count_per_chunk;
174    
175     for (i = 0; i < p_pool->chunk_count; i++)
176     {
177 sysadm 1.6 if (p_node >= p_pool->p_chunks[i] && (char *)p_node < (char *)(p_pool->p_chunks[i]) + chunk_size)
178 sysadm 1.1 {
179 sysadm 1.6 if ((size_t)((char *)p_node - (char *)(p_pool->p_chunks[i])) % p_pool->node_size == 0)
180 sysadm 1.1 {
181     return 0; // OK
182     }
183     else
184     {
185 sysadm 1.10 log_error("Address of node (%p) is not aligned with border of chunk %d [%p, %p)",
186 sysadm 1.12 p_node, i, p_pool->p_chunks[i], (char *)(p_pool->p_chunks[i]) + chunk_size);
187 sysadm 1.1 return -3;
188     }
189     }
190     }
191    
192 sysadm 1.10 log_error("Address of node is not in range of chunks");
193 sysadm 1.1 return -2;
194     }

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