Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
On windows, try_compile may use another compiler than the one we want.
[simgrid.git] / src / mc / mc_compare.c
1 /* Copyright (c) 2012-2013. 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 #include "mc_private.h"
8
9 #include "xbt/mmalloc.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, mc,
12                                 "Logging specific to mc_compare");
13
14 typedef struct s_pointers_pair{
15   void *p1;
16   void *p2;
17 }s_pointers_pair_t, *pointers_pair_t;
18
19 __thread xbt_dynar_t compared_pointers;
20
21 /************************** Free functions ****************************/
22 /********************************************************************/
23
24 static void stack_region_free(stack_region_t s){
25   if(s){
26     xbt_free(s->process_name);
27     xbt_free(s);
28   }
29 }
30
31 static void stack_region_free_voidp(void *s){
32   stack_region_free((stack_region_t) * (void **) s);
33 }
34
35 static void pointers_pair_free(pointers_pair_t p){
36   xbt_free(p);
37 }
38
39 static void pointers_pair_free_voidp(void *p){
40   pointers_pair_free((pointers_pair_t) * (void **)p);
41 }
42
43 /************************** Snapshot comparison *******************************/
44 /******************************************************************************/
45
46 static int already_compared_pointers(void *p1, void *p2){
47
48   if(xbt_dynar_is_empty(compared_pointers))
49     return -1;
50
51   unsigned int cursor = 0;
52   int start = 0;
53   int end = xbt_dynar_length(compared_pointers) - 1;
54   pointers_pair_t pair;
55
56   while(start <= end){
57     cursor = (start + end) / 2;
58     pair = (pointers_pair_t)xbt_dynar_get_as(compared_pointers, cursor, pointers_pair_t);
59     if(pair->p1 == p1){
60       if(pair->p2 == p2)
61         return 0;
62       else if(pair->p2 < p2)
63         start = cursor + 1;
64       else
65         end = cursor - 1;
66     }else if(pair->p1 < p1){
67       start = cursor + 1;
68     }else{
69       end = cursor - 1 ;
70     }
71   }
72
73   return -1;
74
75 }
76
77 static void add_compared_pointers(void *p1, void *p2){
78
79   pointers_pair_t new_pair = xbt_new0(s_pointers_pair_t, 1);
80   new_pair->p1 = p1;
81   new_pair->p2 = p2;
82   
83   if(xbt_dynar_is_empty(compared_pointers)){
84     xbt_dynar_push(compared_pointers, &new_pair);
85     return;
86   }
87
88   unsigned int cursor = 0;
89   int start = 0;
90   int end = xbt_dynar_length(compared_pointers) - 1;
91   pointers_pair_t pair = NULL;
92
93   while(start <= end){
94     cursor = (start + end) / 2;
95     pair = (pointers_pair_t)xbt_dynar_get_as(compared_pointers, cursor, pointers_pair_t);
96     if(pair->p1 == p1){
97       if(pair->p2 == p2){
98         pointers_pair_free(new_pair);
99         return;
100       }else if(pair->p2 < p2)
101         start = cursor + 1;
102       else
103         end = cursor - 1;
104     }else if(pair->p1 < p1){
105       start = cursor + 1;
106     }else{
107       end = cursor - 1 ;
108     }
109   }
110
111   if(pair->p1 == p1){
112     if(pair->p2 < p2)
113       xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
114     else
115       xbt_dynar_insert_at(compared_pointers, cursor, &new_pair); 
116   }else{
117     if(pair->p1 < p1)
118       xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
119     else
120       xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);   
121   }
122
123 }
124
125 static int compare_areas_with_type(void *area1, void *area2, xbt_dict_t types, xbt_dict_t other_types, char *type_id, int region_size, int region_type, void *start_data, int pointer_level){
126
127   dw_type_t type = xbt_dict_get_or_null(types, type_id);;
128   unsigned int cursor = 0;
129   dw_type_t member, subtype, subsubtype;
130   int elm_size, i, res, switch_types = 0;
131   void *addr_pointed1, *addr_pointed2;
132
133   switch(type->type){
134   case e_dw_base_type:
135   case e_dw_enumeration_type:
136   case e_dw_union_type:
137     return (memcmp(area1, area2, type->size) != 0);
138     break;
139   case e_dw_typedef:
140   case e_dw_volatile_type:
141     return compare_areas_with_type(area1, area2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
142     break;
143   case e_dw_const_type: /* Const variable cannot be modified */
144     return -1;
145     break;
146   case e_dw_array_type:
147     subtype = xbt_dict_get_or_null(types, type->dw_type_id);
148     switch(subtype->type){
149     case e_dw_base_type:
150     case e_dw_enumeration_type:
151     case e_dw_pointer_type:
152     case e_dw_structure_type:
153     case e_dw_union_type:
154       if(subtype->size == 0){ /*declaration of the type, need the complete description */
155         subtype = xbt_dict_get_or_null(types, get_type_description(types, subtype->name));
156         if(subtype == NULL){
157           subtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subtype->name));
158           switch_types = 1;
159         }
160       }
161       elm_size = subtype->size;
162       break;
163     case e_dw_typedef:
164     case e_dw_volatile_type:
165       subsubtype = xbt_dict_get_or_null(types, subtype->dw_type_id);
166       if(subsubtype->size == 0){ /*declaration of the type, need the complete description */
167         subsubtype = xbt_dict_get_or_null(types, get_type_description(types, subsubtype->name));
168         if(subsubtype == NULL){
169           subsubtype = xbt_dict_get_or_null(other_types, get_type_description(other_types, subsubtype->name));
170           switch_types = 1;
171         }
172       }
173       elm_size = subsubtype->size;
174       break;
175     default : 
176       return 0;
177       break;
178     }
179     for(i=0; i<type->size; i++){
180       if(switch_types)
181         res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), other_types, types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
182       else
183         res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level);
184       if(res == 1)
185         return res;
186     }
187     break;
188   case e_dw_pointer_type: 
189     if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(types, type->dw_type_id))->type == e_dw_subroutine_type){
190       addr_pointed1 = *((void **)(area1)); 
191       addr_pointed2 = *((void **)(area2));
192       return (addr_pointed1 != addr_pointed2);
193     }else{
194       addr_pointed1 = *((void **)(area1)); 
195       addr_pointed2 = *((void **)(area2));
196       
197       if(addr_pointed1 == NULL && addr_pointed2 == NULL)
198         return 0;
199       if(already_compared_pointers(addr_pointed1, addr_pointed2) != -1)
200         return 0;
201       add_compared_pointers(addr_pointed1, addr_pointed2);
202
203       pointer_level++;
204       
205       if(addr_pointed1 > std_heap && (char *)addr_pointed1 < (char*) std_heap + STD_HEAP_SIZE && addr_pointed2 > std_heap && (char *)addr_pointed2 < (char*) std_heap + STD_HEAP_SIZE){
206         return compare_heap_area(addr_pointed1, addr_pointed2, NULL, types, other_types, type->dw_type_id, pointer_level); 
207       }else if(addr_pointed1 > start_data && (char*)addr_pointed1 <= (char *)start_data + region_size && addr_pointed2 > start_data && (char*)addr_pointed2 <= (char *)start_data + region_size){
208         if(type->dw_type_id == NULL)
209           return  (addr_pointed1 != addr_pointed2);
210         else
211           return  compare_areas_with_type(addr_pointed1, addr_pointed2, types, other_types, type->dw_type_id, region_size, region_type, start_data, pointer_level); 
212       }else{
213         return (addr_pointed1 != addr_pointed2);
214       }
215     }
216     break;
217   case e_dw_structure_type:
218     xbt_dynar_foreach(type->members, cursor, member){
219       res = compare_areas_with_type((char *)area1 + member->offset, (char *)area2 + member->offset, types, other_types, member->dw_type_id, region_size, region_type, start_data, pointer_level);
220       if(res == 1)
221         return res;
222     }
223     break;
224   case e_dw_subroutine_type:
225     return -1;
226     break;
227   default:
228     XBT_VERB("Unknown case : %d", type->type);
229     break;
230   }
231   
232   return 0;
233 }
234
235 static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_region_t r2){
236
237   if(!compared_pointers){
238     compared_pointers = xbt_dynar_new(sizeof(pointers_pair_t), pointers_pair_free_voidp);
239     MC_ignore_global_variable("compared_pointers");
240   }else{
241     xbt_dynar_reset(compared_pointers);
242   }
243
244   xbt_dynar_t variables;
245   xbt_dict_t types, other_types;
246   int res;
247   unsigned int cursor = 0;
248   dw_variable_t current_var;
249   size_t offset;
250   void *start_data;
251
252   if(region_type == 2){
253     variables = mc_global_variables_binary;
254     types = mc_variables_type_binary;
255     other_types = mc_variables_type_libsimgrid;
256     start_data = start_data_binary;
257   }else{
258     variables = mc_global_variables_libsimgrid;
259     types = mc_variables_type_libsimgrid;
260     other_types = mc_variables_type_binary;
261     start_data = start_data_libsimgrid;
262   }
263
264   xbt_dynar_foreach(variables, cursor, current_var){
265
266     if(region_type == 2)
267       offset = (char *)current_var->address.address - (char *)start_data_binary;
268     else
269       offset = (char *)current_var->address.address - (char *)start_data_libsimgrid;
270
271     res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, types, other_types, current_var->type_origin, r1->size, region_type, start_data, 0);
272     if(res == 1){
273       XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset);
274       xbt_dynar_free(&compared_pointers);
275       compared_pointers = NULL;
276       return 1;
277     }
278
279   }
280
281   xbt_dynar_free(&compared_pointers);
282   compared_pointers = NULL;
283
284   return 0;
285
286 }
287
288 static int compare_local_variables(mc_snapshot_stack_t stack1, mc_snapshot_stack_t stack2, void *heap1, void *heap2){
289
290   if(!compared_pointers){
291     compared_pointers = xbt_dynar_new(sizeof(pointers_pair_t), pointers_pair_free_voidp);
292     MC_ignore_global_variable("compared_pointers");
293   }else{
294     xbt_dynar_reset(compared_pointers);
295   }
296
297   if(xbt_dynar_length(stack1->local_variables) != xbt_dynar_length(stack2->local_variables)){
298     XBT_VERB("Different number of local variables");
299     xbt_dynar_free(&compared_pointers);
300     compared_pointers = NULL;
301     return 1;
302   }else{
303     unsigned int cursor = 0;
304     local_variable_t current_var1, current_var2;
305     int offset1, offset2, res;
306     while(cursor < xbt_dynar_length(stack1->local_variables)){
307       current_var1 = (local_variable_t)xbt_dynar_get_as(stack1->local_variables, cursor, local_variable_t);
308       current_var2 = (local_variable_t)xbt_dynar_get_as(stack2->local_variables, cursor, local_variable_t);
309       if(strcmp(current_var1->name, current_var2->name) != 0 || strcmp(current_var1->frame, current_var2->frame) != 0 || current_var1->ip != current_var2->ip){
310         xbt_dynar_free(&compared_pointers);
311         XBT_VERB("Different name of variable (%s - %s) or frame (%s - %s) or ip (%lu - %lu)", current_var1->name, current_var2->name, current_var1->frame, current_var2->frame, current_var1->ip, current_var2->ip);
312         return 1;
313       }
314       offset1 = (char *)current_var1->address - (char *)std_heap;
315       offset2 = (char *)current_var2->address - (char *)std_heap;
316       if(current_var1->region == 1)
317         res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_variables_type_libsimgrid, mc_variables_type_binary, current_var1->type, 0, 1, start_data_libsimgrid, 0);
318       else
319         res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_variables_type_binary, mc_variables_type_libsimgrid, current_var1->type, 0, 2, start_data_binary, 0);
320       if(res == 1){
321         XBT_VERB("Local variable %s (%p - %p) in frame %s  is different between snapshots", current_var1->name,(char *)heap1 + offset1, (char *)heap2 + offset2, current_var1->frame);
322         xbt_dynar_free(&compared_pointers);
323         compared_pointers = NULL;
324         return res;
325       }
326       cursor++;
327     }
328     xbt_dynar_free(&compared_pointers);
329     compared_pointers = NULL;
330     return 0;
331   }
332 }
333
334 int snapshot_compare(void *state1, void *state2){
335
336   mc_snapshot_t s1, s2;
337   int num1, num2;
338   
339   if(_sg_mc_property_file && _sg_mc_property_file[0] != '\0'){ /* Liveness MC */
340     s1 = ((mc_visited_pair_t)state1)->graph_state->system_state;
341     s2 = ((mc_visited_pair_t)state2)->graph_state->system_state;
342     num1 = ((mc_visited_pair_t)state1)->num;
343     num2 =  ((mc_visited_pair_t)state2)->num;
344     /* Firstly compare automaton state */
345     /*if(xbt_automaton_state_compare(((mc_pair_t)state1)->automaton_state, ((mc_pair_t)state2)->automaton_state) != 0)
346       return 1;
347     if(xbt_automaton_propositional_symbols_compare_value(((mc_pair_t)state1)->atomic_propositions, ((mc_pair_t)state2)->atomic_propositions) != 0)
348     return 1;*/
349   }else{ /* Safety MC */
350     s1 = ((mc_visited_state_t)state1)->system_state;
351     s2 = ((mc_visited_state_t)state2)->system_state;
352     num1 = ((mc_visited_state_t)state1)->num;
353     num2 = ((mc_visited_state_t)state2)->num;
354   }
355
356   int errors = 0;
357   int res_init;
358
359   xbt_os_timer_t global_timer = xbt_os_timer_new();
360   xbt_os_timer_t timer = xbt_os_timer_new();
361
362   xbt_os_walltimer_start(global_timer);
363
364   #ifdef MC_DEBUG
365     xbt_os_walltimer_start(timer);
366   #endif
367
368   /* Compare size of stacks */
369   int i = 0;
370   size_t size_used1, size_used2;
371   int is_diff = 0;
372   while(i < xbt_dynar_length(s1->stacks)){
373     size_used1 = s1->stack_sizes[i];
374     size_used2 = s2->stack_sizes[i];
375     if(size_used1 != size_used2){
376     #ifdef MC_DEBUG
377       if(is_diff == 0){
378         xbt_os_walltimer_stop(timer);
379         mc_comp_times->stacks_sizes_comparison_time = xbt_os_timer_elapsed(timer);
380       }
381       XBT_DEBUG("(%d - %d) Different size used in stacks : %zu - %zu", num1, num2, size_used1, size_used2);
382       errors++;
383       is_diff = 1;
384     #else
385       #ifdef MC_VERBOSE
386       XBT_VERB("(%d - %d) Different size used in stacks : %zu - %zu", num1, num2, size_used1, size_used2);
387       #endif
388
389       xbt_os_walltimer_stop(timer);
390       xbt_os_timer_free(timer);
391       xbt_os_walltimer_stop(global_timer);
392       mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
393       xbt_os_timer_free(global_timer);
394
395       return 1;
396     #endif  
397     }
398     i++;
399   }
400
401   #ifdef MC_DEBUG
402     if(is_diff == 0)
403       xbt_os_walltimer_stop(timer);
404     xbt_os_walltimer_start(timer);
405   #endif
406
407   /* Compare hash of global variables */
408   if(s1->hash_global != NULL && s2->hash_global != NULL){
409     if(strcmp(s1->hash_global, s2->hash_global) != 0){
410       #ifdef MC_DEBUG
411         xbt_os_walltimer_stop(timer);
412         mc_comp_times->hash_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
413         XBT_DEBUG("Different hash of global variables : %s - %s", s1->hash_global, s2->hash_global); 
414         errors++; 
415       #else
416         #ifdef MC_VERBOSE
417           XBT_VERB("Different hash of global variables : %s - %s", s1->hash_global, s2->hash_global); 
418         #endif
419
420         xbt_os_walltimer_stop(timer);
421         xbt_os_timer_free(timer);
422         xbt_os_walltimer_stop(global_timer);
423         mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
424         xbt_os_timer_free(global_timer);
425
426         return 1;
427       #endif
428     }
429   }
430
431   #ifdef MC_DEBUG
432     xbt_os_walltimer_start(timer);
433   #endif
434
435   /* Compare hash of local variables */
436   if(s1->hash_local != NULL && s2->hash_local != NULL){
437     if(strcmp(s1->hash_local, s2->hash_local) != 0){
438       #ifdef MC_DEBUG
439         xbt_os_walltimer_stop(timer);
440         mc_comp_times->hash_local_variables_comparison_time = xbt_os_timer_elapsed(timer);
441         XBT_DEBUG("Different hash of local variables : %s - %s", s1->hash_local, s2->hash_local); 
442         errors++; 
443       #else
444         #ifdef MC_VERBOSE
445           XBT_VERB("Different hash of local variables : %s - %s", s1->hash_local, s2->hash_local); 
446         #endif
447
448         xbt_os_walltimer_stop(timer);
449         xbt_os_timer_free(timer);
450         xbt_os_walltimer_stop(global_timer);
451         mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
452         xbt_os_timer_free(global_timer);
453
454         return 1;
455       #endif
456     }
457   }
458
459   #ifdef MC_DEBUG
460     xbt_os_walltimer_start(timer);
461   #endif
462
463   /* Init heap information used in heap comparison algorithm */
464   res_init = init_heap_information((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, s1->to_ignore, s2->to_ignore);
465   if(res_init == -1){
466      #ifdef MC_DEBUG
467     XBT_DEBUG("(%d - %d) Different heap information", num1, num2); 
468         errors++; 
469       #else
470         #ifdef MC_VERBOSE
471         XBT_VERB("(%d - %d) Different heap information", num1, num2); 
472         #endif
473
474         xbt_os_walltimer_stop(global_timer);
475         mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
476         xbt_os_timer_free(global_timer);
477
478         return 1;
479       #endif
480   }
481
482   #ifdef MC_DEBUG
483     xbt_os_walltimer_start(timer);
484   #endif
485
486   /* Stacks comparison */
487   unsigned int  cursor = 0;
488   int diff_local = 0;
489   is_diff = 0;
490   mc_snapshot_stack_t stack1, stack2;
491     
492   while(cursor < xbt_dynar_length(s1->stacks)){
493     stack1 = (mc_snapshot_stack_t)xbt_dynar_get_as(s1->stacks, cursor, mc_snapshot_stack_t);
494     stack2 = (mc_snapshot_stack_t)xbt_dynar_get_as(s2->stacks, cursor, mc_snapshot_stack_t);
495     diff_local = compare_local_variables(stack1, stack2, s1->regions[0]->data, s2->regions[0]->data);
496     if(diff_local > 0){
497       #ifdef MC_DEBUG
498         if(is_diff == 0){
499           xbt_os_walltimer_stop(timer);
500           mc_comp_times->stacks_comparison_time = xbt_os_timer_elapsed(timer);
501         }
502         XBT_DEBUG("(%d - %d) Different local variables between stacks %d", num1, num2, cursor + 1);
503         errors++;
504         is_diff = 1;
505       #else
506         
507         #ifdef MC_VERBOSE
508         XBT_VERB("(%d - %d) Different local variables between stacks %d", num1, num2, cursor + 1);
509         #endif
510           
511         reset_heap_information();
512         xbt_os_walltimer_stop(timer);
513         xbt_os_timer_free(timer);
514         xbt_os_walltimer_stop(global_timer);
515         mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
516         xbt_os_timer_free(global_timer);
517  
518         return 1;
519       #endif
520     }
521     cursor++;
522   }
523
524   #ifdef MC_DEBUG
525     if(is_diff == 0)
526       xbt_os_walltimer_stop(timer);
527     xbt_os_walltimer_start(timer);
528   #endif
529
530   /* Compare binary global variables */
531   is_diff = compare_global_variables(2, s1->regions[2], s2->regions[2]);
532   if(is_diff != 0){
533     #ifdef MC_DEBUG
534       xbt_os_walltimer_stop(timer);
535       mc_comp_times->binary_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
536       XBT_DEBUG("(%d - %d) Different global variables in binary", num1, num2);
537       errors++;
538     #else
539       #ifdef MC_VERBOSE
540       XBT_VERB("(%d - %d) Different global variables in binary", num1, num2);
541       #endif
542
543       reset_heap_information();
544       xbt_os_walltimer_stop(timer);
545       xbt_os_timer_free(timer);
546       xbt_os_walltimer_stop(global_timer);
547       mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
548       xbt_os_timer_free(global_timer);
549
550       return 1;
551     #endif
552   }
553
554   #ifdef MC_DEBUG
555     if(is_diff == 0)
556       xbt_os_walltimer_stop(timer);
557     xbt_os_walltimer_start(timer);
558   #endif
559
560   /* Compare libsimgrid global variables */
561   is_diff = compare_global_variables(1, s1->regions[1], s2->regions[1]);
562   if(is_diff != 0){
563     #ifdef MC_DEBUG
564       xbt_os_walltimer_stop(timer);
565       mc_comp_times->libsimgrid_global_variables_comparison_time = xbt_os_timer_elapsed(timer);
566       XBT_DEBUG("(%d - %d) Different global variables in libsimgrid", num1, num2);
567       errors++;
568     #else
569       #ifdef MC_VERBOSE
570       XBT_VERB("(%d - %d) Different global variables in libsimgrid", num1, num2);
571       #endif
572         
573       reset_heap_information();
574       xbt_os_walltimer_stop(timer);
575       xbt_os_timer_free(timer);
576       xbt_os_walltimer_stop(global_timer);
577       mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
578       xbt_os_timer_free(global_timer);
579
580       return 1;
581     #endif
582   }
583
584   #ifdef MC_DEBUG
585     xbt_os_walltimer_start(timer);
586   #endif
587
588   /* Compare heap */
589     if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, mc_variables_type_libsimgrid, mc_variables_type_binary) > 0){
590
591     #ifdef MC_DEBUG
592       xbt_os_walltimer_stop(timer);
593       mc_comp_times->heap_comparison_time = xbt_os_timer_elapsed(timer); 
594       XBT_DEBUG("(%d - %d) Different heap (mmalloc_compare)", num1, num2);
595       errors++;
596     #else
597  
598       #ifdef MC_VERBOSE
599       XBT_VERB("(%d - %d) Different heap (mmalloc_compare)", num1, num2);
600       #endif
601        
602       reset_heap_information();
603       xbt_os_walltimer_stop(timer);
604       xbt_os_timer_free(timer);
605       xbt_os_walltimer_stop(global_timer);
606       mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
607       xbt_os_timer_free(global_timer);
608
609       return 1;
610     #endif
611   }else{
612     #ifdef MC_DEBUG
613       xbt_os_walltimer_stop(timer);
614     #endif
615   }
616
617   reset_heap_information();
618   
619   xbt_os_walltimer_stop(timer);
620   xbt_os_timer_free(timer);
621
622   #ifdef MC_VERBOSE
623     xbt_os_walltimer_stop(global_timer);
624     mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
625   #endif
626
627   xbt_os_timer_free(global_timer);
628
629   #ifdef MC_DEBUG
630     print_comparison_times();
631   #endif
632
633   return errors > 0;
634   
635 }
636
637 /***************************** Statistics *****************************/
638 /*******************************************************************/
639
640 void print_comparison_times(){
641   XBT_DEBUG("*** Comparison times ***");
642   XBT_DEBUG("- Nb processes : %f", mc_comp_times->nb_processes_comparison_time);
643   XBT_DEBUG("- Nb bytes used : %f", mc_comp_times->bytes_used_comparison_time);
644   XBT_DEBUG("- Stacks sizes : %f", mc_comp_times->stacks_sizes_comparison_time);
645   XBT_DEBUG("- Binary global variables : %f", mc_comp_times->binary_global_variables_comparison_time);
646   XBT_DEBUG("- Libsimgrid global variables : %f", mc_comp_times->libsimgrid_global_variables_comparison_time);
647   XBT_DEBUG("- Heap : %f", mc_comp_times->heap_comparison_time);
648   XBT_DEBUG("- Stacks : %f", mc_comp_times->stacks_comparison_time);
649 }
650
651 /**************************** MC snapshot compare simcall **************************/
652 /***********************************************************************************/
653
654 int SIMIX_pre_mc_compare_snapshots(smx_simcall_t simcall,
655                                    mc_snapshot_t s1, mc_snapshot_t s2){
656   return snapshot_compare(s1, s2);
657 }
658
659 int MC_compare_snapshots(void *s1, void *s2){
660   
661   MC_ignore_local_variable("self", "simcall_BODY_mc_snapshot");
662   return simcall_mc_compare_snapshots(s1, s2);
663
664 }