/[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.7 - (hide 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 sysadm 1.7 /* 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 sysadm 1.1
9 sysadm 1.5 #include "log.h"
10 sysadm 1.1 #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 sysadm 1.6 memcpy((char *)p_chunk + (p_pool->node_count_per_chunk - 1) * p_pool->node_size, &p_node, sizeof(p_node));
94 sysadm 1.1 for (i = 0; i < p_pool->node_count_per_chunk - 1; i++)
95     {
96 sysadm 1.6 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 sysadm 1.1 }
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 sysadm 1.2 // For test and debug
144 sysadm 1.4 #ifdef _DEBUG
145     memory_pool_check_node(p_pool, p_node);
146     #endif
147 sysadm 1.2
148 sysadm 1.1 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 sysadm 1.6 if (p_node >= p_pool->p_chunks[i] && (char *)p_node < (char *)(p_pool->p_chunks[i]) + chunk_size)
171 sysadm 1.1 {
172 sysadm 1.6 if ((size_t)((char *)p_node - (char *)(p_pool->p_chunks[i])) % p_pool->node_size == 0)
173 sysadm 1.1 {
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 sysadm 1.6 i, p_node >= p_pool->p_chunks[i], (char *)(p_pool->p_chunks[i]) + chunk_size);
180 sysadm 1.1 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