/[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.4 - (hide annotations)
Tue Jun 17 13:25:50 2025 UTC (9 months ago) by sysadm
Branch: MAIN
Changes since 1.3: +3 -1 lines
Content type: text/x-csrc
Add conditional compile flag for debugging code

1 sysadm 1.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 sysadm 1.2 // For test and debug
152 sysadm 1.4 #ifdef _DEBUG
153     memory_pool_check_node(p_pool, p_node);
154     #endif
155 sysadm 1.2
156 sysadm 1.1 memcpy(p_node, &(p_pool->p_free), sizeof(p_pool->p_free));
157     p_pool->p_free = p_node;
158    
159     (p_pool->node_count_free)++;
160     (p_pool->node_count_allocated)--;
161     }
162    
163     int memory_pool_check_node(MEMORY_POOL *p_pool, void *p_node)
164     {
165     size_t chunk_size;
166     int i;
167    
168     if (p_pool == NULL || p_node == NULL)
169     {
170     log_error("NULL pointer error\n");
171     return -1;
172     }
173    
174     chunk_size = p_pool->node_size * p_pool->node_count_per_chunk;
175    
176     for (i = 0; i < p_pool->chunk_count; i++)
177     {
178     if (p_node >= p_pool->p_chunks[i] && p_node < p_pool->p_chunks[i] + chunk_size)
179     {
180     if ((size_t)(p_node - p_pool->p_chunks[i]) % p_pool->node_size == 0)
181     {
182     return 0; // OK
183     }
184     else
185     {
186     log_error("Address of node (%p) is not aligned with border of chunk %d [%p, %p)\n",
187     i, p_node >= p_pool->p_chunks[i], p_pool->p_chunks[i] + chunk_size);
188     return -3;
189     }
190     }
191     }
192    
193     log_error("Address of node is not in range of chunks\n");
194     return -2;
195     }

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