/[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.11 - (hide annotations)
Sat Jan 3 10:27:14 2026 UTC (2 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.10: +1 -1 lines
Content type: text/x-csrc
Update copyright info

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    
84     if (p_pool->chunk_count >= p_pool->chunk_count_limit)
85     {
86 sysadm 1.10 log_error("Chunk count limit %d reached", p_pool->chunk_count);
87 sysadm 1.1 return NULL;
88     }
89     p_chunk = malloc(p_pool->node_size * p_pool->node_count_per_chunk);
90     if (p_chunk == NULL)
91     {
92 sysadm 1.10 log_error("malloc(%d * %d) error: OOM", p_pool->node_size, p_pool->node_count_per_chunk);
93 sysadm 1.1 return NULL;
94     }
95    
96     p_node = p_pool->p_free;
97 sysadm 1.6 memcpy((char *)p_chunk + (p_pool->node_count_per_chunk - 1) * p_pool->node_size, &p_node, sizeof(p_node));
98 sysadm 1.1 for (i = 0; i < p_pool->node_count_per_chunk - 1; i++)
99     {
100 sysadm 1.6 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 sysadm 1.1 }
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 sysadm 1.10 log_error("NULL pointer error");
121 sysadm 1.1 return NULL;
122     }
123    
124     if (p_pool->p_free == NULL && memory_pool_add_chunk(p_pool) == NULL)
125     {
126 sysadm 1.10 log_error("Add chunk error");
127 sysadm 1.1 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 sysadm 1.10 log_error("NULL pointer error");
144 sysadm 1.1 return;
145     }
146    
147 sysadm 1.2 // For test and debug
148 sysadm 1.4 #ifdef _DEBUG
149     memory_pool_check_node(p_pool, p_node);
150     #endif
151 sysadm 1.2
152 sysadm 1.1 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 sysadm 1.10 log_error("NULL pointer error");
167 sysadm 1.1 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 sysadm 1.6 if (p_node >= p_pool->p_chunks[i] && (char *)p_node < (char *)(p_pool->p_chunks[i]) + chunk_size)
175 sysadm 1.1 {
176 sysadm 1.6 if ((size_t)((char *)p_node - (char *)(p_pool->p_chunks[i])) % p_pool->node_size == 0)
177 sysadm 1.1 {
178     return 0; // OK
179     }
180     else
181     {
182 sysadm 1.10 log_error("Address of node (%p) is not aligned with border of chunk %d [%p, %p)",
183 sysadm 1.6 i, p_node >= p_pool->p_chunks[i], (char *)(p_pool->p_chunks[i]) + chunk_size);
184 sysadm 1.1 return -3;
185     }
186     }
187     }
188    
189 sysadm 1.10 log_error("Address of node is not in range of chunks");
190 sysadm 1.1 return -2;
191     }

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