Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7f898308cb2f37ca3cc6b24775ee033457399550
[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 = mcalloc(mdp, nmemb,size);
53   UNLOCK(mdp);
54
55   return ret;
56 }
57
58 void *realloc(void *p, size_t s)
59 {
60   void *ret = NULL;
61   xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
62
63   LOCK(mdp);
64   ret = mrealloc(mdp, p, s);
65   UNLOCK(mdp);
66
67   return ret;
68 }
69
70 void free(void *p)
71 {
72   xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
73
74   LOCK(mdp);
75   mfree(mdp, p);
76   UNLOCK(mdp);
77 }
78 #endif
79
80
81 int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
82
83   if(mdp1 == NULL && mdp2 == NULL){
84     XBT_DEBUG("Malloc descriptors null");
85     return 0;
86   }
87
88   /* Heapstats */
89
90   int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
91
92   return (errors > 0);
93
94 }
95
96 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr){
97
98   int errors = 0;
99
100   if(mdp1->headersize != mdp2->headersize){
101     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
102       XBT_DEBUG("Different size of the file header for the mapped files");
103       errors++;
104     }else{
105       return 1;
106     }
107   }
108
109   if(mdp1->refcount != mdp2->refcount){
110     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
111       XBT_DEBUG("Different number of processes that attached the heap");
112       errors++;
113     }else{
114       return 1;
115     }
116   }
117  
118   if(strcmp(mdp1->magic, mdp2->magic) != 0){
119     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
120       XBT_DEBUG("Different magic number");
121       errors++;
122     }else{
123       return 1;
124     }
125   }
126
127   if(mdp1->flags != mdp2->flags){
128     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
129       XBT_DEBUG("Different flags");
130       errors++;
131     }else{
132       return 1;
133     }
134   }
135
136   if(mdp1->heapsize != mdp2->heapsize){
137     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
138       XBT_DEBUG("Different number of info entries");
139       errors++;
140     }else{
141       return 1;
142     }
143   }
144
145   //XBT_DEBUG("Heap size : %zu", mdp1->heapsize);
146
147   if(mdp1->heapbase != mdp2->heapbase){
148     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
149       XBT_DEBUG("Different first block of the heap");
150       errors++;
151     }else{
152       return 1;
153     }
154   }
155
156
157   if(mdp1->heapindex != mdp2->heapindex){
158     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
159       XBT_DEBUG("Different index for the heap table : %zu - %zu", mdp1->heapindex, mdp2->heapindex);
160       errors++;
161     }else{
162       return 1;
163     }
164   }
165
166   //XBT_DEBUG("Heap index : %zu", mdp1->heapindex);
167
168   if(mdp1->base != mdp2->base){
169     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
170       XBT_DEBUG("Different base address of the memory region");
171       errors++;
172     }else{
173       return 1;
174     }
175   }
176
177   if(mdp1->breakval != mdp2->breakval){
178     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
179       XBT_DEBUG("Different current location in the memory region");
180       errors++;
181     }else{
182       return 1;
183     }
184   }
185
186   if(mdp1->top != mdp2->top){
187     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
188       XBT_DEBUG("Different end of the current location in the memory region");
189       errors++;
190     }else{
191       return 1;
192     }
193   }
194   
195   if(mdp1->heaplimit != mdp2->heaplimit){
196     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
197       XBT_DEBUG("Different limit of valid info table indices");
198       errors++;
199     }else{
200       return 1;
201     }
202   }
203
204   if(mdp1->fd != mdp2->fd){
205     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
206       XBT_DEBUG("Different file descriptor for the file to which this malloc heap is mapped");
207       errors++;
208     }else{
209       return 1;
210     }
211   }
212
213    if(mdp1->version != mdp2->version){
214     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
215       XBT_DEBUG("Different version of the mmalloc package");
216       errors++;
217     }else{
218       return 1;
219     }
220   }
221
222  
223   size_t block_free1, block_free2 , next_block_free, first_block_free, block_free ;
224   size_t i, j;
225   void *addr_block1, *addr_block2;
226   size_t frag_size;
227  
228
229   /* Search index of the first free block */
230
231   block_free1 = mdp1->heapindex; 
232   block_free2 = mdp2->heapindex;
233
234   while(mdp1->heapinfo[block_free1].free.prev != 0){
235     block_free1 = mdp1->heapinfo[block_free1].free.prev;
236   }
237
238   while(mdp2->heapinfo[block_free2].free.prev != 0){
239     block_free2 = mdp1->heapinfo[block_free2].free.prev;
240   }
241
242   if(block_free1 !=  block_free2){
243     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
244       XBT_DEBUG("Different first free block");
245       errors++;
246     }else{
247       return 1;
248     }
249   }
250
251   first_block_free = block_free1;
252
253   if(mdp1->heapinfo[first_block_free].free.size != mdp2->heapinfo[first_block_free].free.size){ 
254     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
255       XBT_DEBUG("Different size (in blocks) of the first free cluster");
256       errors++;
257     }else{
258       return 1;
259     }
260   }
261
262   /* Check busy blocks (circular checking)*/
263
264   i = first_block_free + mdp1->heapinfo[first_block_free].free.size;
265
266   if(mdp1->heapinfo[first_block_free].free.next != mdp2->heapinfo[first_block_free].free.next){
267     if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
268       XBT_DEBUG("Different next block free");
269       errors++;
270     }else{
271       return 1;
272     }
273   }
274   
275   block_free = first_block_free;
276   next_block_free = mdp1->heapinfo[first_block_free].free.next;
277
278   if(next_block_free == 0)
279     next_block_free = mdp1->heaplimit;
280
281   while(i != first_block_free){
282
283     while(i<next_block_free){
284
285       if(mdp1->heapinfo[i].busy.type != mdp2->heapinfo[i].busy.type){
286         if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
287           XBT_DEBUG("Different type of busy block");
288           errors++;
289         }else{
290           return 1;
291         }
292       }else{
293
294         addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
295         addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
296         
297         switch(mdp1->heapinfo[i].busy.type){
298         case 0 :
299           if(mdp1->heapinfo[i].busy.info.block.size != mdp2->heapinfo[i].busy.info.block.size){
300             if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
301               XBT_DEBUG("Different size of a large cluster");
302               errors++;
303             }else{
304               return 1;
305             }
306           }else{
307             if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy.info.block.size * BLOCKSIZE)) != 0){
308               if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){           
309                 XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy.info.block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
310                 errors++;
311               }else{
312                 return 1;
313               }
314             } 
315           }
316           i = i+mdp1->heapinfo[i].busy.info.block.size;
317
318           break;
319         default :         
320           if(mdp1->heapinfo[i].busy.info.frag.nfree != mdp2->heapinfo[i].busy.info.frag.nfree){
321             if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
322               XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
323               errors++;
324             }else{
325               return 1;
326             }
327           }else{
328             if(mdp1->heapinfo[i].busy.info.frag.first != mdp2->heapinfo[i].busy.info.frag.first){
329               if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
330                 XBT_DEBUG("Different first free fragments in the block %zu", i);
331                 errors++;
332               }else{
333                 return 1;
334               } 
335             }else{
336               frag_size = pow(2,mdp1->heapinfo[i].busy.type);
337               for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
338                 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
339                   if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
340                     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);
341                     errors++;
342                   }else{
343                     return 1;
344                   }
345                 } 
346               }
347             }
348           }
349
350           i++;
351
352           break;
353         }
354
355       }
356     }
357
358     if( i != first_block_free){
359
360       if(mdp1->heapinfo[block_free].free.next != mdp2->heapinfo[block_free].free.next){
361         if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
362           XBT_DEBUG("Different next block free");
363           errors++;
364         }else{
365           return 1;
366         }
367       }
368      
369       block_free = mdp1->heapinfo[block_free].free.next;
370       next_block_free = mdp1->heapinfo[block_free].free.next;
371
372       i = block_free + mdp1->heapinfo[block_free].free.size;
373
374       if((next_block_free == 0) && (i != mdp1->heaplimit)){
375
376         while(i < mdp1->heaplimit){
377
378           if(mdp1->heapinfo[i].busy.type != mdp2->heapinfo[i].busy.type){
379             if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
380               XBT_DEBUG("Different type of busy block");
381               errors++;
382             }else{
383               return 1;
384             }
385           }else{
386
387             addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
388             addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE); 
389         
390             switch(mdp1->heapinfo[i].busy.type){
391             case 0 :
392               if(mdp1->heapinfo[i].busy.info.block.size != mdp2->heapinfo[i].busy.info.block.size){
393                 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
394                   XBT_DEBUG("Different size of a large cluster");
395                   errors++;
396                 }else{
397                   return 1;
398                 }
399               }else{
400                 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy.info.block.size * BLOCKSIZE)) != 0){
401                   if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){       
402                     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);
403                     errors++;
404                   }else{
405                     return 1;
406                   }
407                 } 
408               }
409             
410               i = i+mdp1->heapinfo[i].busy.info.block.size;
411
412               break;
413             default :     
414               if(mdp1->heapinfo[i].busy.info.frag.nfree != mdp2->heapinfo[i].busy.info.frag.nfree){
415                 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
416                   XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
417                   errors++;
418                 }else{
419                   return 1;
420                 }
421               }else{
422                 if(mdp1->heapinfo[i].busy.info.frag.first != mdp2->heapinfo[i].busy.info.frag.first){
423                   if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
424                     XBT_DEBUG("Different first free fragments in the block %zu", i);
425                     errors++;
426                   }else{
427                     return 1;
428                   } 
429                 }else{
430                   frag_size = pow(2,mdp1->heapinfo[i].busy.type);
431                   for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
432                     if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
433                       if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
434                         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);
435                         errors++;
436                       }else{
437                         return 1;
438                       }
439                     } 
440                   }
441                 }
442               }
443
444               i++;
445
446               break;
447             }
448           }
449         }
450
451       }
452
453     }
454   }
455   
456   return (errors>0);    
457 }
458
459  
460 void mmalloc_display_info_heap(xbt_mheap_t h){
461
462 }  
463
464 /* Useless prototype to make gcc happy */
465 void *valloc(size_t size);
466
467 void *valloc(size_t size)
468 { //FIXME: won't work
469   return mvalloc(NULL, size);
470 }
471
472   
473