"Fossies" - the Fresh Open Source Software Archive 
Member "FunctionCheck-3.2.0/src/fcmanager/fc_memory_manager.c" (26 May 2012, 7683 Bytes) of package /linux/privat/old/FunctionCheck-3.2.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2 * FunctionCheck profiler
3 * (C) Copyright 2000-2012 Yannick Perret
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the FC_NU FC_eneral Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FC_NU
13 * FC_eneral Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /** fc_memory.c: **/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <limits.h>
24 #include "fc_memory_manager.h"
25 #include "fc_com.h"
26 #include "fc_global.h"
27 #include "fc_hash.h"
28 #include "fc_tools.h"
29
30 /* indicate the call-stack requested for memory actions */
31 int fc_memory_stack_size = 4;
32
33 /* set the call-stack size requested */
34 int fc_memory_set_stack_size(int size)
35 {
36 if (size < FC_MAX_CALLSTACK)
37 fc_memory_stack_size = size;
38 else
39 fc_memory_stack_size = FC_MAX_CALLSTACK;
40
41 return (1);
42 }
43
44 /* create a memory */
45 FC_Memory *fc_memory_create(int entry_size)
46 {
47 FC_Memory *tmp;
48 int i;
49
50 tmp = malloc(sizeof (FC_Memory));
51 if (tmp == NULL)
52 {
53 fc_message("cannot allocate %d bytes (memory)", sizeof (FC_Memory));
54 return (NULL);
55 }
56
57 /* allocate the list of entries */
58 tmp->max_elements = entry_size;
59 tmp->nb_elements = 0;
60 tmp->entry = 0;
61 tmp->list = malloc(sizeof (FC_MEl) * entry_size);
62 if (tmp->list == NULL)
63 {
64 fc_message("cannot allocate %d bytes (memory/list)", sizeof (FC_MEl) * entry_size);
65 free(tmp);
66 return (NULL);
67 }
68
69 /* initialize the entry list */
70 for (i = 0; i < entry_size; i++)
71 {
72 /* link for free entries */
73 tmp->list[i].next = i + 1;
74 tmp->list[i].self = i;
75 tmp->list[i].set = 0;
76 tmp->list[i].alloc_stack[0] = NULL;
77 tmp->list[i].pointer = NULL;
78 }
79
80 /* create the hash-table for access */
81 tmp->hash = fc_hash_new();
82 /* I need to check the NULL result ? */
83
84 return (tmp);
85 }
86
87 /* destroy a memory */
88 int fc_memory_delete(FC_Memory *mem)
89 {
90 if (mem == NULL)
91 return 0;
92
93 /* free the list of elements */
94 if (mem->list != NULL)
95 free(mem->list);
96 /* remove the hash-table */
97 if (mem->hash != NULL)
98 fc_hash_destroy(mem->hash);
99 free(mem);
100
101 return 1;
102 }
103
104 /* add an element in a memory/list (with reallocation if needed) and
105 return the address of the element for the hash-table */
106 FC_MEl *fc_memory_list_add(FC_Memory *mem)
107 {
108 int i;
109
110 /* with have to reallocate */
111 if (mem->nb_elements == mem->max_elements)
112 {
113 mem->list = realloc(mem->list, sizeof (FC_MEl)*2 * mem->max_elements);
114 if (mem->list == NULL)
115 {
116 /* argl! */
117 mem->nb_elements = 0;
118 mem->max_elements = 0;
119 mem->entry = 0;
120 fc_message("cannot reallocate entry list for memory managment");
121 fc_message("memory profile data lost.");
122 return (NULL);
123 }
124
125 /* init the available links */
126 for (i = mem->max_elements; i < mem->max_elements * 2; i++)
127 {
128 mem->list[i].next = i + 1;
129 mem->list[i].self = i;
130 mem->list[i].set = 0;
131 mem->list[i].alloc_stack[0] = NULL;
132 mem->list[i].pointer = NULL;
133 }
134
135 mem->max_elements *= 2;
136 }
137
138 /* now the entry is 'entry' */
139 i = mem->entry;
140 /* next available */
141 mem->entry = mem->list[mem->entry].next;
142 mem->nb_elements++;
143
144 mem->list[i].set = 1;
145
146 return (&(mem->list[i]));
147 }
148
149 /* remove an element from the memory/list */
150 int fc_memory_list_remove(FC_Memory *mem, FC_MEl *el)
151 {
152 /* still removed */
153 if (el->pointer == NULL)
154 return (0);
155
156 /* remove the element */
157 el->pointer = NULL;
158 el->set = 0;
159 el->next = mem->entry; /* next free is the actual entry */
160 mem->entry = el->self; /* new entry */
161
162 return (1);
163 }
164
165 /* record a 'malloc' entry */
166 int fc_memory_add_malloc(void *ctx, void *ptr, unsigned int size, void *where)
167 {
168 FC_MEl *el;
169 FC_Memory *mem;
170 void *tmp, *b;
171 int ret, a;
172
173 mem = ((FC_Context*) ctx)->memory;
174
175 /* allocation failed */
176 if (ptr == NULL)
177 {
178 /* nothing to record */
179 return 1;
180 }
181
182 /* first check if this pointer is available */
183 ret = fc_hash_lookup(mem->hash, ptr, &a, &tmp, &b);
184 if (ret)
185 {
186 fc_message("warning: pointer %p is still present as an active block!");
187 fc_message(" overwriting previous entry.");
188 el = (FC_MEl*) tmp;
189 }
190 else
191 {
192 /* prepare a new entry */
193 el = fc_memory_list_add(mem);
194 /* add the reference in the hash-table */
195 fc_hash_insert(mem->hash, ptr, 0, (void*) el, NULL);
196 }
197
198 /* now set the fields */
199 el->pointer = ptr;
200 el->size = size;
201 el->alloc_place = where;
202 fc_get_top_stack(((FC_Context*) ctx)->stack, fc_memory_stack_size, el->alloc_stack);
203 el->realloc_place = NULL;
204
205 return 1;
206 }
207
208 /* record a 'memalign' entry */
209 int fc_memory_add_memalign(void *ctx, void *ptr, unsigned int align, unsigned int size, void *where)
210 {
211 /* we treat it as a malloc action (align info is dropped) */
212 return (fc_memory_add_malloc(ctx, ptr, size, where));
213 }
214
215 /* record a 'free' action */
216 int fc_memory_add_free(void *ctx, void *ptr, void *where)
217 {
218 FC_MEl *el;
219 FC_Memory *mem;
220 int ret, a;
221 void *tmp, *b;
222
223 mem = ((FC_Context*) ctx)->memory;
224
225 /* search the entry */
226 ret = fc_hash_lookup(mem->hash, ptr, &a, &tmp, &b);
227 if (!ret)
228 {
229 /* free on a unreferenced pointer */
230 /* prepare a new entry */
231 el = fc_memory_list_add(mem);
232 el->pointer = ptr;
233 el->alloc_place = where;
234 el->realloc_place = NULL;
235 fc_get_top_stack(((FC_Context*) ctx)->stack, fc_memory_stack_size, el->alloc_stack);
236 el->size = UINT_MAX;
237 /* remove the original from the hash-table */
238 fc_hash_remove(mem->hash, ptr);
239 return 1;
240 }
241
242 /* no more needs of this entry. remove */
243 el = (FC_MEl*) tmp;
244 fc_hash_remove(mem->hash, ptr);
245 el->pointer = NULL;
246 el->size = 0;
247 el->set = 0;
248 el->alloc_place = NULL;
249 el->realloc_place = NULL;
250 fc_memory_list_remove(mem, el);
251
252 return 1;
253 }
254
255 /* record a 'realloc' entry */
256 int fc_memory_add_realloc(void *ctx, void *ptr, void *inc, unsigned int size, void *where)
257 {
258 FC_MEl *el;
259 FC_Memory *mem;
260 void *tmp, *b;
261 int a, ret;
262
263 mem = ((FC_Context*) ctx)->memory;
264
265 /* search the entry */
266 ret = fc_hash_lookup(mem->hash, inc, &a, &tmp, &b);
267 if (!ret)
268 {/* realloc on a unreferenced pointer */
269 /* prepare a new entry */
270 el = fc_memory_list_add(mem);
271 el->pointer = inc;
272 el->realloc_place = where;
273 fc_get_top_stack(((FC_Context*) ctx)->stack, fc_memory_stack_size, el->alloc_stack);
274 el->alloc_place = NULL;
275 el->size = UINT_MAX;
276 return 1;
277 }
278
279 /* update the data */
280 el = (FC_MEl*) tmp;
281 el->realloc_place = where;
282 el->pointer = ptr;
283 /* just modify the hash-table entry */
284 if (inc != ptr)
285 {
286 fc_hash_remove(mem->hash, inc);
287 fc_hash_insert(mem->hash, ptr, 0, (void *) el, NULL);
288 }
289
290 return 1;
291 }
292