Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
14e31b8e7f725afc98376c83bd750670c9df48a3
[simgrid.git] / src / mc / mc_liveness.c
1 /* Copyright (c) 2008-2012 Da SimGrid Team. All rights reserved.            */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "mc_private.h"
7 #include <unistd.h>
8
9 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc,
10                                 "Logging specific to algorithms for liveness properties verification");
11
12 xbt_dynar_t reached_pairs;
13 xbt_dynar_t reached_pairs_hash;
14 xbt_dynar_t visited_pairs;
15 xbt_dynar_t visited_pairs_hash;
16 xbt_dynar_t successors;
17
18 xbt_dynar_t hosts_table;
19
20
21 /* fast implementation of djb2 algorithm */
22 unsigned int hash_region(char *str, int str_len){
23
24   int c;
25   register unsigned int hash = 5381;
26
27   while (str_len--) {
28     c = *str++;
29     hash = ((hash << 5) + hash) + c;    /* hash * 33 + c */
30   }
31
32   return hash;
33
34 }
35
36 const char* get_memory_map_addr(void *addr){
37
38   FILE *fp;                     /* File pointer to process's proc maps file */
39   char *line = NULL;            /* Temporal storage for each line that is readed */
40   ssize_t read;                 /* Number of bytes readed */
41   size_t n = 0;                 /* Amount of bytes to read by getline */
42
43   fp = fopen("/proc/self/maps", "r");
44   
45   if(fp == NULL)
46     perror("fopen failed");
47
48   if(addr == NULL){
49     free(line);
50     fclose(fp);
51     return "nil";
52   }
53
54   xbt_dynar_t lfields = NULL;
55   xbt_dynar_t start_end  = NULL;
56   void *start_addr;
57   void *end_addr;
58
59   while ((read = getline(&line, &n, fp)) != -1) {
60
61     xbt_str_trim(line, NULL);
62     xbt_str_strip_spaces(line);
63     lfields = xbt_str_split(line,NULL);
64
65     start_end = xbt_str_split(xbt_dynar_get_as(lfields, 0, char*), "-");
66     start_addr = (void *) strtoul(xbt_dynar_get_as(start_end, 0, char*), NULL, 16);
67     end_addr = (void *) strtoul(xbt_dynar_get_as(start_end, 1, char*), NULL, 16);
68
69     if((addr > start_addr) && ( addr < end_addr)){
70       free(line);
71       fclose(fp);
72       if(start_addr == std_heap){
73         xbt_dynar_reset(lfields);
74         xbt_free(lfields);
75         xbt_dynar_reset(start_end);
76         xbt_free(start_end);
77         return "std_heap";
78       }
79       if(start_addr == raw_heap){
80         xbt_dynar_reset(lfields);
81         xbt_free(lfields);
82         xbt_dynar_reset(start_end);
83         xbt_free(start_end);
84         return "raw_heap";
85       }
86       if(xbt_dynar_length(lfields) == 6){
87         return xbt_dynar_get_as(lfields, xbt_dynar_length(lfields) - 1, char*);
88       }else{
89         xbt_dynar_reset(lfields);
90         xbt_free(lfields);
91         xbt_dynar_reset(start_end);
92         xbt_free(start_end);
93         return "Anonymous";
94       }
95     }
96
97   }
98
99   xbt_dynar_reset(lfields);
100   xbt_free(lfields);
101   xbt_dynar_reset(start_end);
102   xbt_free(start_end);
103   free(line);
104   fclose(fp);
105   return "Unknown area";
106
107 }
108
109 int data_program_region_compare(void *d1, void *d2, size_t size){
110   int distance = 0;
111   int pointer_align;
112   int i;
113   char *pointed_address1 = NULL, *pointed_address2 = NULL;
114   
115   for(i=0; i<size; i++){
116     if(memcmp(((char *)d1) + i, ((char *)d2) + i, 1) != 0){
117       fprintf(stderr,"Different byte (offset=%d) (%p - %p) in data program region\n", i, (char *)d1 + i, (char *)d2 + i);
118       distance++;
119       pointer_align = (i /sizeof(void *)) * sizeof(void *);
120       pointed_address1 = strdup(get_memory_map_addr(*((void **)((char *)d1 + pointer_align))));
121       pointed_address2 = strdup(get_memory_map_addr(*((void **)((char *)d2 + pointer_align))));
122       fprintf(stderr, "Pointed address : %p (in %s) - %p (in %s)\n", *((void **)((char *)d1 + pointer_align)), pointed_address1, *((void **)((char *)d2 + pointer_align)), pointed_address2);
123       /* FIXME : compare values in pointed address thanks to DWARF */
124     }
125   }
126   
127   fprintf(stderr, "Hamming distance between data program regions : %d\n", distance);
128
129   free(pointed_address1);
130   free(pointed_address2);
131
132   return distance;
133 }
134
135 int data_libsimgrid_region_compare(void *d1, void *d2, size_t size){
136   int distance = 0;
137   int pointer_align;
138   int i;
139   char *pointed_address1 = NULL, *pointed_address2 = NULL;
140   
141   for(i=0; i<size; i++){
142     if(memcmp(((char *)d1) + i, ((char *)d2) + i, 1) != 0){
143       fprintf(stderr, "Different byte (offset=%d) (%p - %p) in data libsimgrid region\n", i, (char *)d1 + i, (char *)d2 + i);
144       distance++;
145       pointer_align = (i /sizeof(void *)) * sizeof(void *);
146       pointed_address1 = strdup(get_memory_map_addr(*((void **)((char *)d1 + pointer_align))));
147       pointed_address2 = strdup(get_memory_map_addr(*((void **)((char *)d2 + pointer_align))));
148       fprintf(stderr, "Pointed address : %p (in %s) - %p (in %s)\n", *((void **)((char *)d1 + pointer_align)), pointed_address1, *((void **)((char *)d2 + pointer_align)), pointed_address2);
149       /* FIXME : compare values in pointed address thanks to DWARF */
150     }
151   }
152   
153   fprintf(stderr, "Hamming distance between data libsimgrid regions : %d\n", distance);
154
155   free(pointed_address1);
156   free(pointed_address2);
157   
158   return distance;
159 }
160
161 int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2, void* s_heap, void* r_heap){
162
163   
164   if(s1->num_reg != s2->num_reg){
165     XBT_INFO("Different num_reg (s1 = %u, s2 = %u)", s1->num_reg, s2->num_reg);
166     return 1;
167   }
168
169   int i;
170   int errors = 0;
171
172   for(i=0 ; i< s1->num_reg ; i++){
173
174     if(s1->regions[i]->type != s2->regions[i]->type){
175         XBT_INFO("Different type of region");
176         errors++;
177     }
178
179     switch(s1->regions[i]->type){
180       case 0:
181       if(s1->regions[i]->size != s2->regions[i]->size){
182         XBT_INFO("Different size of heap (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
183         errors++;
184       }
185       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
186         XBT_INFO("Different start addr of heap (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
187         errors++;
188       }
189       if(mmalloc_compare_heap(s1->regions[i]->data, s2->regions[i]->data, s_heap, r_heap)){
190         XBT_INFO("Different heap (mmalloc_compare)");
191         errors++; 
192       }
193       break;
194     case 1 :
195       if(s1->regions[i]->size != s2->regions[i]->size){
196         XBT_INFO("Different size of libsimgrid (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
197         errors++;
198       }
199       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
200         XBT_INFO("Different start addr of libsimgrid (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
201         errors++;
202       }
203       if(data_libsimgrid_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
204         XBT_INFO("Different memcmp for data in libsimgrid");
205         errors++;
206       }
207       break;
208     case 2 :
209       if(s1->regions[i]->size != s2->regions[i]->size){
210         XBT_INFO("Different size of data program (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
211         errors++;
212       }
213       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
214         XBT_INFO("Different start addr of data program (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
215         errors++;
216       }
217       if(data_program_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
218         XBT_INFO("Different memcmp for data in program");
219         errors++;
220       }
221       break;
222     default:
223       break;
224     }
225   }
226
227   return (errors > 0);
228   
229 }
230
231 int reached(xbt_state_t st){
232
233
234   if(xbt_dynar_is_empty(reached_pairs)){
235
236     return 0;
237
238   }else{
239
240     MC_SET_RAW_MEM;
241
242     mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
243     MC_take_snapshot_liveness(sn);    
244     
245     xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
246     int res;
247     int_f_void_t f;
248
249     /* Get values of propositional symbols */
250     unsigned int cursor = 0;
251     xbt_propositional_symbol_t ps = NULL;
252     xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
253       f = (int_f_void_t)ps->function;
254       res = (*f)();
255       xbt_dynar_push_as(prop_ato, int, res);
256     }
257
258     cursor = 0;
259     mc_pair_reached_t pair_test = NULL;
260
261     //xbt_dict_t current_rdv_points = SIMIX_get_rdv_points();
262      
263     xbt_dynar_foreach(reached_pairs, cursor, pair_test){
264       XBT_INFO("Pair reached #%d", pair_test->nb);
265       if(automaton_state_compare(pair_test->automaton_state, st) == 0){
266         if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
267           //XBT_INFO("Rdv points size %d - %d", xbt_dict_length(pair_test->rdv_points), xbt_dict_length(current_rdv_points));
268           //if(xbt_dict_length(pair_test->rdv_points) == xbt_dict_length(current_rdv_points)){
269           //if(rdv_points_compare(pair_test->rdv_points, current_rdv_points) == 0){
270           if(snapshot_compare(pair_test->system_state, sn, std_heap, raw_heap) == 0){
271            
272             MC_free_snapshot(sn);
273             xbt_dynar_reset(prop_ato);
274             xbt_free(prop_ato);
275             MC_UNSET_RAW_MEM;
276             return 1;
277           }
278           /* }
279           }else{
280             XBT_INFO("Different size of rdv points (%d - %d)",xbt_dict_length(pair_test->rdv_points), xbt_dict_length(current_rdv_points) );
281             }*/
282         }else{
283           XBT_INFO("Different values of propositional symbols");
284         }
285       }else{
286         XBT_INFO("Different automaton state");
287       }
288     }
289
290     MC_free_snapshot(sn);
291     xbt_dynar_reset(prop_ato);
292     xbt_free(prop_ato);
293     MC_UNSET_RAW_MEM;
294     return 0;
295     
296   }
297 }
298
299 int rdv_points_compare(xbt_dict_t d1, xbt_dict_t d2){ /* d1 = pair_test, d2 = current_pair */ 
300   
301    xbt_dict_cursor_t cursor_dict = NULL;
302    char *key;
303    char *data;
304    smx_rdv_t rdv1, rdv2;
305    xbt_fifo_item_t item1, item2;
306    smx_action_t action1, action2;
307    xbt_fifo_item_t item_req1, item_req2;
308    smx_simcall_t req1, req2;
309    int i=0;
310    int j=0;
311
312    xbt_dict_foreach(d1, cursor_dict, key, data){
313      rdv1 = (smx_rdv_t)data;
314      rdv2 = xbt_dict_get_or_null(d2, rdv1->name);
315      if(rdv2 == NULL){
316        XBT_INFO("Rdv point unknown");
317        return 1;
318      }else{
319        if(xbt_fifo_size(rdv1->comm_fifo) != xbt_fifo_size(rdv2->comm_fifo)){
320          XBT_INFO("Different total of actions in mailbox \"%s\" (%d - %d)", rdv1->name, xbt_fifo_size(rdv1->comm_fifo),xbt_fifo_size(rdv2->comm_fifo) );
321          return 1;
322        }else{
323          
324          XBT_INFO("Total of actions in mailbox \"%s\" : %d", rdv1->name, xbt_fifo_size(rdv1->comm_fifo)); 
325          
326          item1 = xbt_fifo_get_first_item(rdv1->comm_fifo);      
327          item2 = xbt_fifo_get_first_item(rdv2->comm_fifo);
328
329          while(i<xbt_fifo_size(rdv1->comm_fifo)){
330            action1 = (smx_action_t) xbt_fifo_get_item_content(item1);
331            action2 = (smx_action_t) xbt_fifo_get_item_content(item2);
332
333            if(action1->type != action2->type){
334              XBT_INFO("Different type of action");
335              return 1;
336            }
337
338            if(action1->state != action2->state){
339              XBT_INFO("Different state of action");
340              return 1;
341            }
342
343            if(xbt_fifo_size(action1->simcalls) != xbt_fifo_size(action2->simcalls)){
344              XBT_INFO("Different size of simcall list (%d - %d", xbt_fifo_size(action1->simcalls), xbt_fifo_size(action2->simcalls));
345              return 1;
346            }else{
347
348              item_req1 = xbt_fifo_get_first_item(action1->simcalls);    
349              item_req2 = xbt_fifo_get_first_item(action2->simcalls);
350
351              while(j<xbt_fifo_size(action1->simcalls)){
352
353                req1 = (smx_simcall_t) xbt_fifo_get_item_content(item_req1);
354                req2 = (smx_simcall_t) xbt_fifo_get_item_content(item_req2);
355                
356                if(req1->call != req2->call){
357                  XBT_INFO("Different simcall call in simcalls of action (%d - %d)", (int)req1->call, (int)req2->call);
358                  return 1;
359                }
360                if(req1->issuer->pid != req2->issuer->pid){
361                  XBT_INFO("Different simcall issuer in simcalls of action (%lu- %lu)", req1->issuer->pid, req2->issuer->pid);
362                  return 1;
363                }
364
365                item_req1 = xbt_fifo_get_next_item(item_req1);   
366                item_req2 = xbt_fifo_get_next_item(item_req2);
367                j++;
368                
369              }
370            }
371
372            switch(action1->type){
373            case 0: /* execution */
374            case 1: /* parallel execution */
375              if(strcmp(action1->execution.host->name, action2->execution.host->name) != 0)
376                return 1;
377              break;
378            case 2: /* comm */
379              if(action1->comm.type != action2->comm.type)
380                return 1;
381              //XBT_INFO("Type of comm : %d", action1->comm.type);
382              
383              switch(action1->comm.type){
384              case 0: /* SEND */
385                if(action1->comm.src_proc->pid != action2->comm.src_proc->pid)
386                  return 1;
387                if(strcmp(action1->comm.src_proc->smx_host->name, action2->comm.src_proc->smx_host->name) != 0)
388                  return 1;
389                break;
390              case 1: /* RECEIVE */
391                if(action1->comm.dst_proc->pid != action2->comm.dst_proc->pid)
392                  return 1;
393                if(strcmp(action1->comm.dst_proc->smx_host->name, action2->comm.dst_proc->smx_host->name) != 0)
394                  return 1;
395                break;
396              case 2: /* READY */
397                if(action1->comm.src_proc->pid != action2->comm.src_proc->pid)
398                  return 1;
399                if(strcmp(action1->comm.src_proc->smx_host->name, action2->comm.src_proc->smx_host->name) != 0)
400                  return 1;
401                if(action1->comm.dst_proc->pid != action2->comm.dst_proc->pid)
402                  return 1;
403                if(strcmp(action1->comm.dst_proc->smx_host->name, action2->comm.dst_proc->smx_host->name) != 0)
404                  return 1;
405                break;
406              case 3: /* DONE */
407                if(action1->comm.src_proc->pid != action2->comm.src_proc->pid)
408                  return 1;
409                if(strcmp(action1->comm.src_proc->smx_host->name, action2->comm.src_proc->smx_host->name) != 0)
410                  return 1;
411                if(action1->comm.dst_proc->pid != action2->comm.dst_proc->pid)
412                  return 1;
413                if(strcmp(action1->comm.dst_proc->smx_host->name, action2->comm.dst_proc->smx_host->name) != 0)
414                  return 1;
415                break;
416                
417              } /* end of switch on type of comm */
418              
419              if(action1->comm.refcount != action2->comm.refcount)
420                return 1;
421              if(action1->comm.detached != action2->comm.detached)
422                return 1;
423              if(action1->comm.rate != action2->comm.rate)
424                return 1;
425              if(action1->comm.task_size != action2->comm.task_size)
426                return 1;
427              if(action1->comm.src_buff != action2->comm.src_buff)
428                return 1;
429              if(action1->comm.dst_buff != action2->comm.dst_buff)
430                return 1;
431              if(action1->comm.src_data != action2->comm.src_data)
432                return 1;
433              if(action1->comm.dst_data != action2->comm.dst_data)
434                return 1;
435              
436              break;
437            case 3: /* sleep */
438              if(strcmp(action1->sleep.host->name, action2->sleep.host->name) != 0)
439                return 1;
440              break;
441            case 4: /* synchro */
442              
443              break;
444            default:
445              break;
446            }
447
448            item1 = xbt_fifo_get_next_item(item1);       
449            item2 = xbt_fifo_get_next_item(item2);
450            i++;
451          }
452        }
453      }
454    }
455
456    return 0;
457    
458 }
459
460 void set_pair_reached(xbt_state_t st){
461
462  
463   MC_SET_RAW_MEM;
464   
465   mc_pair_reached_t pair = NULL;
466   pair = xbt_new0(s_mc_pair_reached_t, 1);
467   pair->nb = xbt_dynar_length(reached_pairs) + 1;
468   pair->automaton_state = st;
469   pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
470   pair->system_state = xbt_new0(s_mc_snapshot_t, 1);
471   //pair->rdv_points = xbt_dict_new();  
472   MC_take_snapshot_liveness(pair->system_state);
473
474   /* Get values of propositional symbols */
475   unsigned int cursor = 0;
476   xbt_propositional_symbol_t ps = NULL;
477   int res;
478   int_f_void_t f;
479
480   xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
481     f = (int_f_void_t)ps->function;
482     res = (*f)();
483     xbt_dynar_push_as(pair->prop_ato, int, res);
484   }
485
486   /*xbt_dict_t rdv_points = SIMIX_get_rdv_points();
487
488   xbt_dict_cursor_t cursor_dict = NULL;
489   char *key;
490   char *data;
491   xbt_fifo_item_t item;
492   smx_action_t action;
493
494   xbt_dict_foreach(rdv_points, cursor_dict, key, data){
495     smx_rdv_t new_rdv = xbt_new0(s_smx_rvpoint_t, 1);
496     new_rdv->name = strdup(((smx_rdv_t)data)->name);
497     new_rdv->comm_fifo = xbt_fifo_new();
498     xbt_fifo_foreach(((smx_rdv_t)data)->comm_fifo, item, action, smx_action_t) {
499       smx_action_t a = xbt_new0(s_smx_action_t, 1);
500       memcpy(a, action, sizeof(s_smx_action_t));
501       xbt_fifo_push(new_rdv->comm_fifo, a);
502       XBT_INFO("New action (type = %d, state = %d) in mailbox \"%s\"", action->type, action->state, key);
503       if(action->type==2)
504         XBT_INFO("Type of communication : %d, Ref count = %d", action->comm.type, action->comm.refcount);
505     }
506     //new_rdv->comm_fifo = xbt_fifo_copy(((smx_rdv_t)data)->comm_fifo);
507     xbt_dict_set(pair->rdv_points, new_rdv->name, new_rdv, NULL);
508     }*/
509  
510   xbt_dynar_push(reached_pairs, &pair); 
511
512   MC_UNSET_RAW_MEM;
513   
514 }
515
516
517 int reached_hash(xbt_state_t st){
518
519
520   if(xbt_dynar_is_empty(reached_pairs_hash)){
521
522     return 0;
523
524   }else{
525
526     MC_SET_RAW_MEM;
527
528     mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
529     MC_take_snapshot_liveness(sn);
530
531     int j;
532     unsigned int hash_regions[sn->num_reg];
533     for(j=0; j<sn->num_reg; j++){
534       hash_regions[j] = hash_region(sn->regions[j]->data, sn->regions[j]->size);
535     }
536
537
538     /* Get values of propositional symbols */
539     xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
540     unsigned int cursor = 0;
541     xbt_propositional_symbol_t ps = NULL;
542     int res;
543     int_f_void_t f;
544
545     xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
546       f = (int_f_void_t)ps->function;
547       res = (*f)();
548       xbt_dynar_push_as(prop_ato, int, res);
549     }
550
551     mc_pair_reached_hash_t pair_test = NULL;
552
553     int region_diff = 0;
554
555     cursor = 0;
556
557     xbt_dynar_foreach(reached_pairs_hash, cursor, pair_test){
558
559       if(automaton_state_compare(pair_test->automaton_state, st) == 0){
560         if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
561           for(j=0 ; j< sn->num_reg ; j++){
562             if(hash_regions[j] != pair_test->hash_regions[j]){
563               region_diff++;
564             }
565           }
566           if(region_diff == 0){
567             MC_free_snapshot(sn);
568             xbt_dynar_reset(prop_ato);
569             xbt_free(prop_ato);
570             MC_UNSET_RAW_MEM;
571             return 1;
572           }else{
573             XBT_INFO("Different snapshot");
574           }
575         }else{
576           XBT_INFO("Different values of propositional symbols");
577         }
578       }else{
579         XBT_INFO("Different automaton state");
580       }
581
582       region_diff = 0;
583     }
584     
585     MC_free_snapshot(sn);
586     xbt_dynar_reset(prop_ato);
587     xbt_free(prop_ato);
588     MC_UNSET_RAW_MEM;
589     return 0;
590     
591   }
592 }
593
594 void set_pair_reached_hash(xbt_state_t st){
595  
596   MC_SET_RAW_MEM;
597
598   mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
599   MC_take_snapshot_liveness(sn);
600  
601   mc_pair_reached_hash_t pair = NULL;
602   pair = xbt_new0(s_mc_pair_reached_hash_t, 1);
603   pair->automaton_state = st;
604   pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
605   pair->hash_regions = malloc(sizeof(unsigned int) * sn->num_reg);
606   
607   int i;
608
609   for(i=0 ; i< sn->num_reg ; i++){
610     pair->hash_regions[i] = hash_region(sn->regions[i]->data, sn->regions[i]->size);
611   }
612   
613   /* Get values of propositional symbols */
614   unsigned int cursor = 0;
615   xbt_propositional_symbol_t ps = NULL;
616   int res;
617   int_f_void_t f;
618
619   xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
620     f = (int_f_void_t)ps->function;
621     res = (*f)();
622     xbt_dynar_push_as(pair->prop_ato, int, res);
623   }
624   
625   xbt_dynar_push(reached_pairs_hash, &pair);
626
627   MC_free_snapshot(sn);
628   
629   MC_UNSET_RAW_MEM;
630     
631 }
632
633
634 int visited(xbt_state_t st, int sc){
635
636
637   if(xbt_dynar_is_empty(visited_pairs)){
638
639     return 0;
640
641   }else{
642
643     MC_SET_RAW_MEM;
644
645     mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
646     MC_take_snapshot_liveness(sn);
647
648     xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
649
650     /* Get values of propositional symbols */
651     unsigned int cursor = 0;
652     xbt_propositional_symbol_t ps = NULL;
653     int res;
654     int_f_void_t f;
655
656     xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
657       f = (int_f_void_t)ps->function;
658       res = (*f)();
659       xbt_dynar_push_as(prop_ato, int, res);
660     }
661
662     cursor = 0;
663     mc_pair_visited_t pair_test = NULL;
664
665     xbt_dynar_foreach(visited_pairs, cursor, pair_test){
666       if(pair_test->search_cycle == sc) {
667         if(automaton_state_compare(pair_test->automaton_state, st) == 0){
668           if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
669             if(snapshot_compare(pair_test->system_state, sn, std_heap, raw_heap) == 0){
670             
671               MC_free_snapshot(sn);
672               xbt_dynar_reset(prop_ato);
673               xbt_free(prop_ato);
674               MC_UNSET_RAW_MEM;
675                 
676               return 1;
677         
678             }else{
679               XBT_INFO("Different snapshot");
680             }
681           }else{
682             XBT_INFO("Different values of propositional symbols"); 
683           }
684         }else{
685           XBT_INFO("Different automaton state");
686         }
687       }else{
688         XBT_INFO("Different value of search_cycle");
689       }
690     }
691
692
693     MC_free_snapshot(sn);
694     xbt_dynar_reset(prop_ato);
695     xbt_free(prop_ato);
696     MC_UNSET_RAW_MEM;
697     return 0;
698     
699   }
700 }
701
702
703 int visited_hash(xbt_state_t st, int sc){
704
705
706   if(xbt_dynar_is_empty(visited_pairs_hash)){
707
708     return 0;
709
710   }else{
711
712     MC_SET_RAW_MEM;
713
714     mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
715     MC_take_snapshot_liveness(sn);
716
717     int j;
718     unsigned int hash_regions[sn->num_reg];
719     for(j=0; j<sn->num_reg; j++){
720       hash_regions[j] = hash_region(sn->regions[j]->data, sn->regions[j]->size);
721     }
722
723     
724     /* Get values of propositional symbols */
725     xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
726     unsigned int cursor = 0;
727     xbt_propositional_symbol_t ps = NULL;
728     int res;
729     int_f_void_t f;
730
731     xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
732       f = (int_f_void_t)ps->function;
733       res = (*f)();
734       xbt_dynar_push_as(prop_ato, int, res);
735     }
736
737     mc_pair_visited_hash_t pair_test = NULL;
738
739     int region_diff = 0;
740     cursor = 0;
741
742     xbt_dynar_foreach(visited_pairs_hash, cursor, pair_test){
743   
744       if(pair_test->search_cycle == sc) {
745         if(automaton_state_compare(pair_test->automaton_state, st) == 0){
746           if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
747             for(j=0 ; j< sn->num_reg ; j++){
748               if(hash_regions[j] != pair_test->hash_regions[j]){
749                 region_diff++;
750               }
751             }
752             if(region_diff == 0){
753               MC_free_snapshot(sn);
754               xbt_dynar_reset(prop_ato);
755               xbt_free(prop_ato);
756               MC_UNSET_RAW_MEM;
757               return 1;
758             }else{
759               //XBT_INFO("Different snapshot");
760             }
761           }else{
762             //XBT_INFO("Different values of propositional symbols"); 
763           }
764         }else{
765           //XBT_INFO("Different automaton state");
766         }
767       }else{
768         //XBT_INFO("Different value of search_cycle");
769       }
770       
771       region_diff = 0;
772     }
773     
774     MC_free_snapshot(sn);
775     xbt_dynar_reset(prop_ato);
776     xbt_free(prop_ato);
777     MC_UNSET_RAW_MEM;
778     return 0;
779     
780   }
781 }
782
783 void set_pair_visited_hash(xbt_state_t st, int sc){
784  
785   MC_SET_RAW_MEM;
786
787   mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
788   MC_take_snapshot_liveness(sn);
789  
790   mc_pair_visited_hash_t pair = NULL;
791   pair = xbt_new0(s_mc_pair_visited_hash_t, 1);
792   pair->automaton_state = st;
793   pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
794   pair->search_cycle = sc;
795   pair->hash_regions = malloc(sizeof(unsigned int) * sn->num_reg);
796   
797   int i;
798
799   for(i=0 ; i< sn->num_reg ; i++){
800     pair->hash_regions[i] = hash_region(sn->regions[i]->data, sn->regions[i]->size);
801   }
802   
803   /* Get values of propositional symbols */
804   unsigned int cursor = 0;
805   xbt_propositional_symbol_t ps = NULL;
806   int res;
807   int_f_void_t f;
808
809   xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
810     f = (int_f_void_t)ps->function;
811     res = (*f)();
812     xbt_dynar_push_as(pair->prop_ato, int, res);
813   }
814   
815   xbt_dynar_push(visited_pairs_hash, &pair);
816
817   MC_free_snapshot(sn);
818   
819   MC_UNSET_RAW_MEM;
820     
821 }
822
823 void set_pair_visited(xbt_state_t st, int sc){
824
825  
826   MC_SET_RAW_MEM;
827  
828   mc_pair_visited_t pair = NULL;
829   pair = xbt_new0(s_mc_pair_visited_t, 1);
830   pair->automaton_state = st;
831   pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
832   pair->search_cycle = sc;
833   pair->system_state = xbt_new0(s_mc_snapshot_t, 1);
834   MC_take_snapshot_liveness(pair->system_state);
835
836
837   /* Get values of propositional symbols */
838   unsigned int cursor = 0;
839   xbt_propositional_symbol_t ps = NULL;
840   int res;
841   int_f_void_t f;
842
843   xbt_dynar_foreach(automaton->propositional_symbols, cursor, ps){
844     f = (int_f_void_t)ps->function;
845     res = (*f)();
846     xbt_dynar_push_as(pair->prop_ato, int, res);
847   }
848   
849   xbt_dynar_push(visited_pairs, &pair);
850   
851   MC_UNSET_RAW_MEM;
852   
853   
854 }
855
856 void MC_pair_delete(mc_pair_t pair){
857   xbt_free(pair->graph_state->proc_status);
858   xbt_free(pair->graph_state);
859   xbt_free(pair);
860 }
861
862
863
864 int MC_automaton_evaluate_label(xbt_exp_label_t l){
865   
866   switch(l->type){
867   case 0 : {
868     int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp);
869     int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp);
870     return (left_res || right_res);
871   }
872   case 1 : {
873     int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp);
874     int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp);
875     return (left_res && right_res);
876   }
877   case 2 : {
878     int res = MC_automaton_evaluate_label(l->u.exp_not);
879     return (!res);
880   }
881   case 3 : { 
882     unsigned int cursor = 0;
883     xbt_propositional_symbol_t p = NULL;
884     int_f_void_t f;
885     xbt_dynar_foreach(automaton->propositional_symbols, cursor, p){
886       if(strcmp(p->pred, l->u.predicat) == 0){
887         f = (int_f_void_t)p->function;
888         return (*f)();
889       }
890     }
891     return -1;
892   }
893   case 4 : {
894     return 2;
895   }
896   default : 
897     return -1;
898   }
899 }
900
901
902 /********************* Double-DFS stateless *******************/
903
904 void MC_pair_stateless_delete(mc_pair_stateless_t pair){
905   xbt_free(pair->graph_state->proc_status);
906   xbt_free(pair->graph_state);
907   xbt_free(pair);
908 }
909
910 mc_pair_stateless_t new_pair_stateless(mc_state_t sg, xbt_state_t st, int r){
911   mc_pair_stateless_t p = NULL;
912   p = xbt_new0(s_mc_pair_stateless_t, 1);
913   p->automaton_state = st;
914   p->graph_state = sg;
915   p->requests = r;
916   mc_stats_pair->expanded_pairs++;
917   return p;
918 }
919
920 void MC_ddfs_init(void){
921
922   XBT_INFO("**************************************************");
923   XBT_INFO("Double-DFS init");
924   XBT_INFO("**************************************************");
925
926   mc_pair_stateless_t mc_initial_pair = NULL;
927   mc_state_t initial_graph_state = NULL;
928   smx_process_t process; 
929
930  
931   MC_wait_for_requests();
932
933   MC_SET_RAW_MEM;
934
935   initial_graph_state = MC_state_pair_new();
936   xbt_swag_foreach(process, simix_global->process_list){
937     if(MC_process_is_enabled(process)){
938       MC_state_interleave_process(initial_graph_state, process);
939     }
940   }
941
942   reached_pairs = xbt_dynar_new(sizeof(mc_pair_reached_t), NULL);
943   //reached_pairs_hash = xbt_dynar_new(sizeof(mc_pair_reached_hash_t), NULL);
944   //visited_pairs = xbt_dynar_new(sizeof(mc_pair_visited_t), NULL);
945   visited_pairs_hash = xbt_dynar_new(sizeof(mc_pair_visited_hash_t), NULL);
946   successors = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
947
948   /* Save the initial state */
949   initial_snapshot_liveness = xbt_new0(s_mc_snapshot_t, 1);
950   MC_take_snapshot_liveness(initial_snapshot_liveness);
951
952   MC_UNSET_RAW_MEM; 
953
954   unsigned int cursor = 0;
955   xbt_state_t state;
956
957   xbt_dynar_foreach(automaton->states, cursor, state){
958     if(state->type == -1){
959       
960       MC_SET_RAW_MEM;
961       mc_initial_pair = new_pair_stateless(initial_graph_state, state, MC_state_interleave_size(initial_graph_state));
962       xbt_fifo_unshift(mc_stack_liveness, mc_initial_pair);
963       MC_UNSET_RAW_MEM;
964       
965       if(cursor != 0){
966         MC_restore_snapshot(initial_snapshot_liveness);
967         MC_UNSET_RAW_MEM;
968       }
969
970       MC_ddfs(0);
971
972     }else{
973       if(state->type == 2){
974       
975         MC_SET_RAW_MEM;
976         mc_initial_pair = new_pair_stateless(initial_graph_state, state, MC_state_interleave_size(initial_graph_state));
977         xbt_fifo_unshift(mc_stack_liveness, mc_initial_pair);
978         MC_UNSET_RAW_MEM;
979
980         set_pair_reached(state);
981         //set_pair_reached_hash(state);
982
983         if(cursor != 0){
984           MC_restore_snapshot(initial_snapshot_liveness);
985           MC_UNSET_RAW_MEM;
986         }
987         
988         MC_ddfs(1);
989         
990       }
991     }
992   } 
993
994 }
995
996
997 void MC_ddfs(int search_cycle){
998
999   smx_process_t process;
1000   mc_pair_stateless_t current_pair = NULL;
1001
1002   if(xbt_fifo_size(mc_stack_liveness) == 0)
1003     return;
1004
1005
1006   /* Get current pair */
1007   current_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness));
1008
1009   /* Update current state in buchi automaton */
1010   automaton->current_state = current_pair->automaton_state;
1011
1012  
1013   XBT_INFO("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness), search_cycle);
1014   XBT_INFO("Pair : graph=%p, automaton=%p(%s), %u interleave", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id, MC_state_interleave_size(current_pair->graph_state));
1015  
1016   mc_stats_pair->visited_pairs++;
1017
1018   //sleep(1);
1019
1020   int value;
1021   mc_state_t next_graph_state = NULL;
1022   smx_simcall_t req = NULL;
1023   char *req_str;
1024
1025   xbt_transition_t transition_succ;
1026   unsigned int cursor = 0;
1027   int res;
1028
1029   mc_pair_stateless_t next_pair = NULL;
1030   mc_pair_stateless_t pair_succ;
1031   
1032   if(xbt_fifo_size(mc_stack_liveness) < MAX_DEPTH_LIVENESS){
1033
1034     //set_pair_visited(current_pair->automaton_state, search_cycle);
1035     set_pair_visited_hash(current_pair->automaton_state, search_cycle);
1036
1037     //XBT_INFO("Visited pairs : %lu", xbt_dynar_length(visited_pairs));
1038     XBT_INFO("Visited pairs : %lu", xbt_dynar_length(visited_pairs_hash));
1039
1040     if(current_pair->requests > 0){
1041
1042       while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
1043    
1044         /* Debug information */
1045
1046         req_str = MC_request_to_string(req, value);
1047         XBT_INFO("Execute: %s", req_str);
1048         xbt_free(req_str);
1049
1050         MC_state_set_executed_request(current_pair->graph_state, req, value);   
1051
1052         /* Answer the request */
1053         SIMIX_simcall_pre(req, value);
1054
1055         /* Wait for requests (schedules processes) */
1056         MC_wait_for_requests();
1057
1058
1059         MC_SET_RAW_MEM;
1060
1061         /* Create the new expanded graph_state */
1062         next_graph_state = MC_state_pair_new();
1063
1064         /* Get enabled process and insert it in the interleave set of the next graph_state */
1065         xbt_swag_foreach(process, simix_global->process_list){
1066           if(MC_process_is_enabled(process)){
1067             MC_state_interleave_process(next_graph_state, process);
1068           }
1069         }
1070
1071         xbt_dynar_reset(successors);
1072
1073         MC_UNSET_RAW_MEM;
1074
1075
1076         cursor= 0;
1077         xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
1078
1079           res = MC_automaton_evaluate_label(transition_succ->label);
1080
1081           if(res == 1){ // enabled transition in automaton
1082             MC_SET_RAW_MEM;
1083             next_pair = new_pair_stateless(next_graph_state, transition_succ->dst, MC_state_interleave_size(next_graph_state));
1084             xbt_dynar_push(successors, &next_pair);
1085             MC_UNSET_RAW_MEM;
1086           }
1087
1088         }
1089
1090         cursor = 0;
1091    
1092         xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
1093       
1094           res = MC_automaton_evaluate_label(transition_succ->label);
1095         
1096           if(res == 2){ // true transition in automaton
1097             MC_SET_RAW_MEM;
1098             next_pair = new_pair_stateless(next_graph_state, transition_succ->dst, MC_state_interleave_size(next_graph_state));
1099             xbt_dynar_push(successors, &next_pair);
1100             MC_UNSET_RAW_MEM;
1101           }
1102
1103         }
1104
1105         cursor = 0; 
1106         
1107         xbt_dynar_foreach(successors, cursor, pair_succ){
1108
1109           if(search_cycle == 1){
1110
1111             if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){ 
1112                       
1113               if(reached(pair_succ->automaton_state)){
1114                 //if(reached_hash(pair_succ->automaton_state)){
1115               
1116                 XBT_INFO("Next pair (depth = %d, %u interleave) already reached !", xbt_fifo_size(mc_stack_liveness) + 1, MC_state_interleave_size(pair_succ->graph_state));
1117
1118                 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
1119                 XBT_INFO("|             ACCEPTANCE CYCLE            |");
1120                 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
1121                 XBT_INFO("Counter-example that violates formula :");
1122                 MC_show_stack_liveness(mc_stack_liveness);
1123                 MC_dump_stack_liveness(mc_stack_liveness);
1124                 MC_print_statistics_pairs(mc_stats_pair);
1125                 exit(0);
1126
1127               }else{
1128
1129                 XBT_INFO("Next pair (depth =%d) -> Acceptance pair : graph=%p, automaton=%p(%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
1130               
1131                 set_pair_reached(pair_succ->automaton_state);
1132                 //set_pair_reached_hash(pair_succ->automaton_state);
1133
1134                 XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
1135                 //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
1136
1137                 MC_SET_RAW_MEM;
1138                 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
1139                 MC_UNSET_RAW_MEM;
1140                 
1141                 MC_ddfs(search_cycle);
1142
1143               }
1144
1145             }else{
1146
1147               if(!visited_hash(pair_succ->automaton_state, search_cycle)){
1148                 //if(!visited(pair_succ->automaton_state, search_cycle)){
1149                 
1150                 MC_SET_RAW_MEM;
1151                 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
1152                 MC_UNSET_RAW_MEM;
1153                 
1154                 MC_ddfs(search_cycle);
1155                 
1156               }else{
1157
1158                 XBT_INFO("Next pair already visited ! ");
1159
1160               }
1161               
1162             }
1163
1164           }else{
1165           
1166             if(((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
1167
1168               XBT_INFO("Next pair (depth =%d) -> Acceptance pair : graph=%p, automaton=%p(%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
1169             
1170               set_pair_reached(pair_succ->automaton_state); 
1171               //set_pair_reached_hash(pair_succ->automaton_state);
1172
1173               search_cycle = 1;
1174
1175               XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
1176               //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
1177
1178             }
1179
1180             if(!visited_hash(pair_succ->automaton_state, search_cycle)){
1181               //if(!visited(pair_succ->automaton_state, search_cycle)){
1182               
1183               MC_SET_RAW_MEM;
1184               xbt_fifo_unshift(mc_stack_liveness, pair_succ);
1185               MC_UNSET_RAW_MEM;
1186               
1187               MC_ddfs(search_cycle);
1188               
1189             }else{
1190
1191               XBT_INFO("Next pair already visited ! ");
1192
1193             }
1194
1195           }
1196
1197          
1198           /* Restore system before checking others successors */
1199           if(cursor != (xbt_dynar_length(successors) - 1))
1200             MC_replay_liveness(mc_stack_liveness, 1);
1201         
1202           
1203         }
1204
1205         if(MC_state_interleave_size(current_pair->graph_state) > 0){
1206           XBT_INFO("Backtracking to depth %d", xbt_fifo_size(mc_stack_liveness));
1207           MC_replay_liveness(mc_stack_liveness, 0);
1208         }
1209       }
1210
1211  
1212     }else{  /*No request to execute, search evolution in Büchi automaton */
1213
1214       MC_SET_RAW_MEM;
1215
1216       /* Create the new expanded graph_state */
1217       next_graph_state = MC_state_pair_new();
1218
1219       xbt_dynar_reset(successors);
1220
1221       MC_UNSET_RAW_MEM;
1222
1223
1224       cursor= 0;
1225       xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
1226
1227         res = MC_automaton_evaluate_label(transition_succ->label);
1228
1229         if(res == 1){ // enabled transition in automaton
1230           MC_SET_RAW_MEM;
1231           next_pair = new_pair_stateless(next_graph_state, transition_succ->dst, MC_state_interleave_size(next_graph_state));
1232           xbt_dynar_push(successors, &next_pair);
1233           MC_UNSET_RAW_MEM;
1234         }
1235
1236       }
1237
1238       cursor = 0;
1239    
1240       xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
1241       
1242         res = MC_automaton_evaluate_label(transition_succ->label);
1243         
1244         if(res == 2){ // true transition in automaton
1245           MC_SET_RAW_MEM;
1246           next_pair = new_pair_stateless(next_graph_state, transition_succ->dst, MC_state_interleave_size(next_graph_state));
1247           xbt_dynar_push(successors, &next_pair);
1248           MC_UNSET_RAW_MEM;
1249         }
1250
1251       }
1252
1253       cursor = 0; 
1254      
1255       xbt_dynar_foreach(successors, cursor, pair_succ){
1256
1257         if(search_cycle == 1){
1258
1259           if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){ 
1260
1261             if(reached(pair_succ->automaton_state)){
1262               //if(reached_hash(pair_succ->automaton_state)){
1263
1264               XBT_INFO("Next pair (depth = %d) already reached !", xbt_fifo_size(mc_stack_liveness) + 1);
1265               
1266               XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
1267               XBT_INFO("|             ACCEPTANCE CYCLE            |");
1268               XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
1269               XBT_INFO("Counter-example that violates formula :");
1270               MC_show_stack_liveness(mc_stack_liveness);
1271               MC_dump_stack_liveness(mc_stack_liveness);
1272               MC_print_statistics_pairs(mc_stats_pair);
1273               exit(0);
1274
1275             }else{
1276
1277               XBT_INFO("Next pair (depth = %d) -> Acceptance pair : graph=%p, automaton=%p(%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
1278               
1279               set_pair_reached(pair_succ->automaton_state);
1280               //set_pair_reached_hash(pair_succ->automaton_state);
1281                 
1282               XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
1283               //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
1284
1285               MC_SET_RAW_MEM;
1286               xbt_fifo_unshift(mc_stack_liveness, pair_succ);
1287               MC_UNSET_RAW_MEM;
1288               
1289               MC_ddfs(search_cycle);
1290
1291             }
1292
1293           }else{
1294
1295             if(!visited_hash(pair_succ->automaton_state, search_cycle)){
1296               //if(!visited(pair_succ->automaton_state, search_cycle)){
1297
1298               MC_SET_RAW_MEM;
1299               xbt_fifo_unshift(mc_stack_liveness, pair_succ);
1300               MC_UNSET_RAW_MEM;
1301               
1302               MC_ddfs(search_cycle);
1303               
1304             }else{
1305
1306               XBT_INFO("Next pair already visited ! ");
1307
1308             }
1309           }
1310             
1311
1312         }else{
1313             
1314           if(((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
1315
1316             set_pair_reached(pair_succ->automaton_state);
1317             //set_pair_reached_hash(pair_succ->automaton_state);
1318                     
1319             search_cycle = 1;
1320
1321             XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
1322             //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
1323
1324           }
1325
1326           if(!visited_hash(pair_succ->automaton_state, search_cycle)){
1327             //if(!visited(pair_succ->automaton_state, search_cycle)){
1328
1329             MC_SET_RAW_MEM;
1330             xbt_fifo_unshift(mc_stack_liveness, pair_succ);
1331             MC_UNSET_RAW_MEM;
1332             
1333             MC_ddfs(search_cycle);
1334             
1335           }else{
1336
1337             XBT_INFO("Next pair already visited ! ");
1338
1339           }
1340
1341         }
1342
1343         /* Restore system before checking others successors */
1344         if(cursor != xbt_dynar_length(successors) - 1)
1345           MC_replay_liveness(mc_stack_liveness, 1);
1346
1347          
1348       }
1349            
1350     }
1351     
1352   }else{
1353     
1354     XBT_INFO("Max depth reached");
1355
1356   }
1357
1358   if(xbt_fifo_size(mc_stack_liveness) == MAX_DEPTH_LIVENESS ){
1359     XBT_INFO("Pair (graph=%p, automaton =%p, search_cycle = %d, depth = %d) shifted in stack, maximum depth reached", current_pair->graph_state, current_pair->automaton_state, search_cycle, xbt_fifo_size(mc_stack_liveness) );
1360   }else{
1361     XBT_INFO("Pair (graph=%p, automaton =%p, search_cycle = %d, depth = %d) shifted in stack", current_pair->graph_state, current_pair->automaton_state, search_cycle, xbt_fifo_size(mc_stack_liveness) );
1362   }
1363
1364   
1365   MC_SET_RAW_MEM;
1366   xbt_fifo_shift(mc_stack_liveness);
1367   if((current_pair->automaton_state->type == 1) || (current_pair->automaton_state->type == 2)){
1368     xbt_dynar_pop(reached_pairs, NULL);
1369     //xbt_dynar_pop(reached_pairs_hash, NULL);
1370   }
1371   MC_UNSET_RAW_MEM;
1372   
1373   
1374
1375 }