Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
I don't need an extra file just to define calloc when it can be inlined that easily
[simgrid.git] / src / xbt / mmalloc / mm_legacy.c
1 /* Copyright (c) 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /* Redefine the classical malloc/free/realloc functions so that they fit well in the mmalloc framework */
8
9 #include "mmprivate.h"
10 #include "gras_config.h"
11 #include <math.h>
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_mm_legacy, xbt,
14                                 "Logging specific to mm_legacy in mmalloc");
15
16 /* The mmalloc() package can use a single implicit malloc descriptor
17    for mmalloc/mrealloc/mfree operations which do not supply an explicit
18    descriptor.  This allows mmalloc() to provide
19    backwards compatibility with the non-mmap'd version. */
20 xbt_mheap_t __mmalloc_default_mdp = NULL;
21
22
23 static xbt_mheap_t __mmalloc_current_heap = NULL;     /* The heap we are currently using. */
24
25 xbt_mheap_t mmalloc_get_current_heap(void)
26 {
27   return __mmalloc_current_heap;
28 }
29
30 void mmalloc_set_current_heap(xbt_mheap_t new_heap)
31 {
32   __mmalloc_current_heap = new_heap;
33 }
34
35 #ifdef MMALLOC_WANT_OVERIDE_LEGACY
36 void *malloc(size_t n)
37 {
38   xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
39
40   LOCK(mdp);
41   void *ret = mmalloc(mdp, n);
42   UNLOCK(mdp);
43
44   return ret;
45 }
46
47 void *calloc(size_t nmemb, size_t size)
48 {
49   xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
50
51   LOCK(mdp);
52   void *ret = mmalloc(mdp, nmemb*size);
53   UNLOCK(mdp);
54   memset(ret, 0, nmemb * size);
55
56
57   return ret;
58 }
59
60 void *realloc(void *p, size_t s)
61 {
62   void *ret = NULL;
63   xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
64
65   LOCK(mdp);
66   ret = mrealloc(mdp, p, s);
67   UNLOCK(mdp);
68
69   return ret;
70 }
71
72 void free(void *p)
73 {
74   xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
75
76   LOCK(mdp);
77   mfree(mdp, p);
78   UNLOCK(mdp);
79 }
80 #endif
81
82
83 int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
84
85   if(mdp1 == NULL && mdp2 == NULL){
86     XBT_DEBUG("Malloc descriptors null");
87     return 0;
88   }
89
90   /* Heapstats */
91
92   int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
93
94   return (errors > 0);
95
96 }
97
98 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr){
99
100   int errors = 0;
101
102   if(mdp1->headersize != mdp2->headersize){
103     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
104       XBT_DEBUG("Different size of the file header for the mapped files");
105       errors++;
106     }else{
107       return 1;
108     }
109   }
110
111   if(mdp1->refcount != mdp2->refcount){
112     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
113       XBT_DEBUG("Different number of processes that attached the heap");
114       errors++;
115     }else{
116       return 1;
117     }
118   }
119  
120   if(strcmp(mdp1->magic, mdp2->magic) != 0){
121     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
122       XBT_DEBUG("Different magic number");
123       errors++;
124     }else{
125       return 1;
126     }
127   }
128
129   if(mdp1->flags != mdp2->flags){
130     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
131       XBT_DEBUG("Different flags");
132       errors++;
133     }else{
134       return 1;
135     }
136   }
137
138   if(mdp1->heapsize != mdp2->heapsize){
139     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
140       XBT_DEBUG("Different number of info entries");
141       errors++;
142     }else{
143       return 1;
144     }
145   }
146
147   //XBT_DEBUG("Heap size : %zu", mdp1->heapsize);
148
149   if(mdp1->heapbase != mdp2->heapbase){
150     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
151       XBT_DEBUG("Different first block of the heap");
152       errors++;
153     }else{
154       return 1;
155     }
156   }
157
158
159   if(mdp1->heapindex != mdp2->heapindex){
160     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
161       XBT_DEBUG("Different index for the heap table : %zu - %zu", mdp1->heapindex, mdp2->heapindex);
162       errors++;
163     }else{
164       return 1;
165     }
166   }
167
168   //XBT_DEBUG("Heap index : %zu", mdp1->heapindex);
169
170   if(mdp1->base != mdp2->base){
171     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
172       XBT_DEBUG("Different base address of the memory region");
173       errors++;
174     }else{
175       return 1;
176     }
177   }
178
179   if(mdp1->breakval != mdp2->breakval){
180     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
181       XBT_DEBUG("Different current location in the memory region");
182       errors++;
183     }else{
184       return 1;
185     }
186   }
187
188   if(mdp1->top != mdp2->top){
189     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
190       XBT_DEBUG("Different end of the current location in the memory region");
191       errors++;
192     }else{
193       return 1;
194     }
195   }
196   
197   if(mdp1->heaplimit != mdp2->heaplimit){
198     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
199       XBT_DEBUG("Different limit of valid info table indices");
200       errors++;
201     }else{
202       return 1;
203     }
204   }
205
206   if(mdp1->fd != mdp2->fd){
207     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
208       XBT_DEBUG("Different file descriptor for the file to which this malloc heap is mapped");
209       errors++;
210     }else{
211       return 1;
212     }
213   }
214
215    if(mdp1->version != mdp2->version){
216     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
217       XBT_DEBUG("Different version of the mmalloc package");
218       errors++;
219     }else{
220       return 1;
221     }
222   }
223
224  
225   size_t block_free1, block_free2 , next_block_free, first_block_free, block_free ;
226   size_t i, j;
227   void *addr_block1, *addr_block2;
228   size_t frag_size;
229  
230
231   /* Search index of the first free block */
232
233   block_free1 = mdp1->heapindex; 
234   block_free2 = mdp2->heapindex;
235
236   while(mdp1->heapinfo[block_free1].free_block.prev != 0){
237     block_free1 = mdp1->heapinfo[block_free1].free_block.prev;
238   }
239
240   while(mdp2->heapinfo[block_free2].free_block.prev != 0){
241     block_free2 = mdp1->heapinfo[block_free2].free_block.prev;
242   }
243
244   if(block_free1 !=  block_free2){
245     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
246       XBT_DEBUG("Different first free block");
247       errors++;
248     }else{
249       return 1;
250     }
251   }
252
253   first_block_free = block_free1;
254
255   if(mdp1->heapinfo[first_block_free].free_block.size != mdp2->heapinfo[first_block_free].free_block.size){
256     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
257       XBT_DEBUG("Different size (in blocks) of the first free cluster");
258       errors++;
259     }else{
260       return 1;
261     }
262   }
263
264   /* Check busy blocks (circular checking)*/
265
266   i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size;
267
268   if(mdp1->heapinfo[first_block_free].free_block.next != mdp2->heapinfo[first_block_free].free_block.next){
269     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
270       XBT_DEBUG("Different next block free");
271       errors++;
272     }else{
273       return 1;
274     }
275   }
276   
277   block_free = first_block_free;
278   next_block_free = mdp1->heapinfo[first_block_free].free_block.next;
279
280   if(next_block_free == 0)
281     next_block_free = mdp1->heaplimit;
282
283   while(i != first_block_free){
284
285     while(i<next_block_free){
286
287       if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
288         if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
289           XBT_DEBUG("Different type of busy block");
290           errors++;
291         }else{
292           return 1;
293         }
294       }else{
295
296         addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
297         addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
298         
299         switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free
300         case 0 :
301           if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
302             if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
303               XBT_DEBUG("Different size of a large cluster");
304               errors++;
305             }else{
306               return 1;
307             }
308           }else{
309             if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
310               if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){           
311                 XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy_block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
312                 errors++;
313               }else{
314                 return 1;
315               }
316             } 
317           }
318           i = i+mdp1->heapinfo[i].busy_block.size;
319
320           break;
321         default :         
322           if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
323             if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
324               XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
325               errors++;
326             }else{
327               return 1;
328             }
329           }else{
330             if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
331               if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
332                 XBT_DEBUG("Different first free fragments in the block %zu", i);
333                 errors++;
334               }else{
335                 return 1;
336               } 
337             }else{
338               frag_size = pow(2,mdp1->heapinfo[i].type);
339               for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
340                 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
341                   if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
342                     XBT_DEBUG("Different data in fragment %zu (addr_frag1 = %p - addr_frag2 = %p) of block %zu", j + 1, (char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size),  i);
343                     errors++;
344                   }else{
345                     return 1;
346                   }
347                 } 
348               }
349             }
350           }
351
352           i++;
353
354           break;
355         }
356
357       }
358     }
359
360     if( i != first_block_free){
361
362       if(mdp1->heapinfo[block_free].free_block.next != mdp2->heapinfo[block_free].free_block.next){
363         if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
364           XBT_DEBUG("Different next block free");
365           errors++;
366         }else{
367           return 1;
368         }
369       }
370      
371       block_free = mdp1->heapinfo[block_free].free_block.next;
372       next_block_free = mdp1->heapinfo[block_free].free_block.next;
373
374       i = block_free + mdp1->heapinfo[block_free].free_block.size;
375
376       if((next_block_free == 0) && (i != mdp1->heaplimit)){
377
378         while(i < mdp1->heaplimit){
379
380           if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
381             if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
382               XBT_DEBUG("Different type of busy block");
383               errors++;
384             }else{
385               return 1;
386             }
387           }else{
388
389             addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
390             addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
391         
392             switch(mdp1->heapinfo[i].type){
393             case 0 :
394               if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
395                 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
396                   XBT_DEBUG("Different size of a large cluster");
397                   errors++;
398                 }else{
399                   return 1;
400                 }
401               }else{
402                 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
403                   if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){       
404                     XBT_DEBUG("Different data in block %zu (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
405                     errors++;
406                   }else{
407                     return 1;
408                   }
409                 } 
410               }
411             
412               i = i+mdp1->heapinfo[i].busy_block.size;
413
414               break;
415             default :     
416               if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
417                 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
418                   XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
419                   errors++;
420                 }else{
421                   return 1;
422                 }
423               }else{
424                 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
425                   if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
426                     XBT_DEBUG("Different first free fragments in the block %zu", i);
427                     errors++;
428                   }else{
429                     return 1;
430                   } 
431                 }else{
432                   frag_size = pow(2,mdp1->heapinfo[i].type);
433                   for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
434                     if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
435                       if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
436                         XBT_DEBUG("Different data in fragment %zu (addr_frag1 = %p - addr_frag2 = %p) of block %zu", j + 1, (char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size),  i);
437                         errors++;
438                       }else{
439                         return 1;
440                       }
441                     } 
442                   }
443                 }
444               }
445
446               i++;
447
448               break;
449             }
450           }
451         }
452
453       }
454
455     }
456   }
457   
458   return (errors>0);    
459 }
460
461  
462 void mmalloc_display_info_heap(xbt_mheap_t h){
463
464 }