Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'mc'
authorGabriel Corona <gabriel.corona@loria.fr>
Fri, 27 Jun 2014 10:41:21 +0000 (12:41 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Fri, 27 Jun 2014 11:06:36 +0000 (13:06 +0200)
Conflicts:
src/mc/mc_global.c

61 files changed:
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/Flags.cmake
buildtools/Cmake/MakeExe.cmake
examples/msg/mc/bugged1_liveness.tesh
examples/msg/ns3/ns3.tesh
examples/msg/pastry/pastry_crosstraffic.tesh
examples/smpi/mc/hostfile_bugged1
examples/smpi/mc/hostfile_bugged1_liveness
examples/smpi/mc/hostfile_bugged2
examples/smpi/mc/hostfile_mutual_exclusion
examples/smpi/mc/hostfile_non_deterministic
examples/smpi/mc/hostfile_send_deterministic
examples/smpi/mc/non_deterministic.c
examples/smpi/mc/non_deterministic.tesh [new file with mode: 0644]
examples/smpi/mc/send_deterministic.c
examples/smpi/mc/send_deterministic.tesh [new file with mode: 0644]
include/xbt/misc.h
include/xbt/mmalloc.h
include/xbt/sysdep.h
include/xbt/xbt_os_time.h
src/include/mc/mc.h
src/mc/mc_checkpoint.c
src/mc/mc_comm_determinism.c [new file with mode: 0644]
src/mc/mc_compare.c [deleted file]
src/mc/mc_compare.cpp [new file with mode: 0644]
src/mc/mc_diff.c [new file with mode: 0644]
src/mc/mc_dpor.c [deleted file]
src/mc/mc_dwarf.c
src/mc/mc_dwarf_expression.c
src/mc/mc_global.c
src/mc/mc_hash.c
src/mc/mc_ignore.c [new file with mode: 0644]
src/mc/mc_liveness.c
src/mc/mc_member.c
src/mc/mc_memory.c
src/mc/mc_mmu.h [new file with mode: 0644]
src/mc/mc_page_snapshot.cpp [new file with mode: 0644]
src/mc/mc_page_store.cpp [new file with mode: 0644]
src/mc/mc_page_store.h [new file with mode: 0644]
src/mc/mc_pair.c
src/mc/mc_private.h
src/mc/mc_request.c
src/mc/mc_safety.c [new file with mode: 0644]
src/mc/mc_snapshot.c [new file with mode: 0644]
src/mc/mc_state.c
src/mc/mc_visited.c [new file with mode: 0644]
src/simgrid/sg_config.c
src/simix/smx_global.c
src/smpi/smpi_global.c
src/xbt/log.c
src/xbt/mmalloc/mm.c
src/xbt/mmalloc/mm_diff.c [deleted file]
src/xbt/mmalloc/mm_legacy.c
src/xbt/mmalloc/mm_module.c
src/xbt/mmalloc/mmalloc.c
src/xbt/mmalloc/mmprivate.h
src/xbt/xbt_main.c
teshsuite/mc/CMakeLists.txt [new file with mode: 0644]
teshsuite/mc/page_store.cpp [new file with mode: 0644]
teshsuite/mc/page_store.tesh [new file with mode: 0644]

index 3435a49..8edb591 100644 (file)
@@ -98,6 +98,7 @@ IF(NOT enable_memcheck)
 
   ### MC ###
   IF(HAVE_MC)
+    ADD_TESH(page_store                          --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc page_store.tesh)
     ADD_TESH(tesh-mc-dwarf                       --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/dwarf --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/dwarf dwarf.tesh)
     ADD_TESH(tesh-mc-dwarf-expression            --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/dwarf_expression --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/dwarf_expression dwarf_expression.tesh)
 
@@ -448,6 +449,10 @@ IF(NOT enable_memcheck)
       ADD_TESH(smpi-tracing-ptp                  --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/tracing/smpi_traced.tesh)
       ADD_TESH(smpi-replay                       --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/replay/smpi_replay.tesh)
     ENDIF()
+    IF(HAVE_MC)
+      ADD_TESH(smpi-mc-non-determinism                  --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/mc --cd ${CMAKE_BINARY_DIR}/examples/smpi/mc ${CMAKE_HOME_DIRECTORY}/examples/smpi/mc/non_deterministic.tesh)
+      ADD_TESH(smpi-mc-send-determinism                  --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/mc --cd ${CMAKE_BINARY_DIR}/examples/smpi/mc ${CMAKE_HOME_DIRECTORY}/examples/smpi/mc/send_deterministic.tesh)
+    ENDIF()
     # END TESH TESTS
   ENDIF()
 
index aeefb87..7f3a592 100644 (file)
@@ -111,7 +111,6 @@ set(EXTRA_DIST
   src/xbt/mallocator_private.h
   src/xbt/mmalloc/mfree.c
   src/xbt/mmalloc/mm.c
-  src/xbt/mmalloc/mm_diff.c
   src/xbt/mmalloc/mm_legacy.c
   src/xbt/mmalloc/mm_module.c
   src/xbt/mmalloc/mmalloc.c
@@ -592,22 +591,29 @@ set(JEDULE_SRC
 
 set(MC_SRC
   src/mc/mc_checkpoint.c
-  src/mc/mc_compare.c
-  src/mc/mc_dpor.c
+  src/mc/mc_snapshot.c
+  src/mc/mc_page_store.cpp
+  src/mc/mc_page_snapshot.cpp
+  src/mc/mc_comm_determinism.c
+  src/mc/mc_compare.cpp
+  src/mc/mc_diff.c
   src/mc/mc_dwarf.c
   src/mc/mc_dwarf_attrnames.h
   src/mc/mc_dwarf_expression.c
   src/mc/mc_dwarf_tagnames.h
   src/mc/mc_global.c
   src/mc/mc_hash.c
+  src/mc/mc_ignore.c
   src/mc/mc_liveness.c
   src/mc/mc_member.c
   src/mc/mc_memory.c
   src/mc/mc_pair.c
   src/mc/mc_private.h
   src/mc/mc_request.c
+  src/mc/mc_safety.c
   src/mc/mc_set.cpp
   src/mc/mc_state.c
+  src/mc/mc_visited.c
   src/mc/memory_map.c
   )
 
index 675587b..a40d5ea 100644 (file)
@@ -28,7 +28,7 @@ endif()
 
 if(enable_compile_optimizations)
   set(optCFLAGS "-O3 -finline-functions -funroll-loops -fno-strict-aliasing ")
-  if(CMAKE_COMPILER_IS_GNUCC)
+  if(CMAKE_COMPILER_IS_GNUCC AND (NOT enable_model-checking))
     if(WIN32)
       if (COMPILER_C_VERSION_MAJOR_MINOR STRGREATER "4.7")
       # On windows, we need 4.8 or higher to enable lto because of http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50293
@@ -45,6 +45,25 @@ else()
   set(optCFLAGS "-O0 ")
 endif()
 
+if(enable_model-checking AND enable_compile_optimizations)
+  # Forget it, do not optimize the code (because it confuses the MC):
+  set(optCFLAGS "-O0 ")
+  # But you can still optimize this:
+  foreach(s
+      src/xbt/mmalloc/mm.c
+      src/xbt/snprintf.c src/xbt/log.c
+      # For some reason, this fails to work when optimizing dynar.c:
+      # src/xbt/dynar.c
+      src/xbt/set.c src/xbt/setset.c src/xbt/backtrace_linux.c
+      src/mc/mc_dwarf_expression.c src/mc/mc_dwarf.c src/mc/mc_member.c
+      src/mc/mc_snapshot.c src/mc/mc_page_store.cpp src/mc/mc_page_snapshot.cpp
+      src/mc/mc_compare.cpp src/mc/mc_diff.c
+      src/mc/mc_dwarf.c src/mc/mc_dwarf_attrnames.h src/mc/mc_dwarf_expression.c src/mc/mc_dwarf_tagnames.h
+      src/mc/mc_set.cpp)
+    set_source_files_properties(${s} PROPERTIES COMPILE_FLAGS "-O3 -finline-functions -funroll-loops -fno-strict-aliasing")
+  endforeach()
+endif()
+
 if(APPLE AND COMPILER_C_VERSION_MAJOR_MINOR MATCHES "4.6")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
   set(optCFLAGS "-O0 ")
@@ -96,7 +115,3 @@ if(NOT $ENV{LDFLAGS} STREQUAL "")
   message(STATUS "Add LDFLAGS: \"$ENV{LDFLAGS}\" to CMAKE_C_LINK_FLAGS")
   set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} $ENV{LDFLAGS}")
 endif()
-
-if(enable_model-checking AND enable_compile_optimizations)
-  message(WARNING "Sorry for now GCC optimizations does not work with model checking.\nPlease turn off optimizations with command:\ncmake -Denable_compile_optimizations=off .")
-endif()
index 0deddd1..b86b7e6 100644 (file)
@@ -80,6 +80,7 @@ add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f90)
 
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/xbt)
 
+add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/mc)
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/mc/dwarf)
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/mc/dwarf_expression)
 
index ff3cd79..dfa372b 100644 (file)
@@ -44,6 +44,3 @@ $ ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../msg_platform.xml ${srcdir:=.}/de
 > [  0.000000] (0:@) Visited pairs = 21
 > [  0.000000] (0:@) Executed transitions = 20
 > [  0.000000] (0:@) Counter-example depth : 20
-
-
-
index b2f9d85..036f806 100644 (file)
@@ -36,4 +36,4 @@ p Two clusters
 $ ns3/ns3 ${srcdir:=.}/examples/platforms/clusters_routing_full.xml ${srcdir:=.}/examples/msg/ns3/Two_clusters-d.xml --cfg=network/model:NS3
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'NS3'
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
-> [c-16.me:slave:(2) 0.012729] [msg_test/INFO] FLOW[1] : Receive 100 bytes from c-3.me to c-16.me
+> [node-16.acme.org:slave:(2) 0.012729] [msg_test/INFO] FLOW[1] : Receive 100 bytes from node-3.acme.org to c-16.me
index dce7b71..b46d7ef 100644 (file)
@@ -441,2579 +441,2579 @@ $ $SG_TEST_EXENV ${bindir:=.}/chord$EXEEXT -nb_bits=6 ${srcdir:=.}/../msg_platfo
 $ $SG_TEST_EXENV ${bindir:=.}/chord$EXEEXT ${srcdir:=.}/../../platforms/cluster.xml ${srcdir:=.}/chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant
 > [   0.000000] (0:@) Configuration change: Set 'network/model' to 'Constant'
 > [   0.000000] (0:@) Switching workstation model to compound since you changed the network and/or cpu model(s)
-> [   0.000000] (10:node@c-9.me) Joining the ring with id 2015253, knowing node 1319738
-> [   0.000000] (1:node@c-0.me) My finger table:
-> [   0.000000] (1:node@c-0.me) Start | Succ 
-> [   0.000000] (1:node@c-0.me)   43  |  42 
-> [   0.000000] (1:node@c-0.me)   44  |  42 
-> [   0.000000] (1:node@c-0.me)   46  |  42 
-> [   0.000000] (1:node@c-0.me)   50  |  42 
-> [   0.000000] (1:node@c-0.me)   58  |  42 
-> [   0.000000] (1:node@c-0.me)   74  |  42 
-> [   0.000000] (1:node@c-0.me)  106  |  42 
-> [   0.000000] (1:node@c-0.me)  170  |  42 
-> [   0.000000] (1:node@c-0.me)  298  |  42 
-> [   0.000000] (1:node@c-0.me)  554  |  42 
-> [   0.000000] (1:node@c-0.me)  1066  |  42 
-> [   0.000000] (1:node@c-0.me)  2090  |  42 
-> [   0.000000] (1:node@c-0.me)  4138  |  42 
-> [   0.000000] (1:node@c-0.me)  8234  |  42 
-> [   0.000000] (1:node@c-0.me)  16426  |  42 
-> [   0.000000] (1:node@c-0.me)  32810  |  42 
-> [   0.000000] (1:node@c-0.me)  65578  |  42 
-> [   0.000000] (1:node@c-0.me)  131114  |  42 
-> [   0.000000] (1:node@c-0.me)  262186  |  42 
-> [   0.000000] (1:node@c-0.me)  524330  |  42 
-> [   0.000000] (1:node@c-0.me)  1048618  |  42 
-> [   0.000000] (1:node@c-0.me)  2097194  |  42 
-> [   0.000000] (1:node@c-0.me)  4194346  |  42 
-> [   0.000000] (1:node@c-0.me)  8388650  |  42 
-> [   0.000000] (1:node@c-0.me) Predecessor: -1
-> [   0.000000] (2:node@c-1.me) Joining the ring with id 366680, knowing node 42
-> [   0.000000] (3:node@c-2.me) Joining the ring with id 533744, knowing node 366680
-> [   0.000000] (4:node@c-3.me) Joining the ring with id 1319738, knowing node 42
-> [   0.000000] (5:node@c-4.me) Joining the ring with id 16509405, knowing node 366680
-> [   0.000000] (6:node@c-5.me) Joining the ring with id 10874876, knowing node 533744
-> [   0.000000] (7:node@c-6.me) Joining the ring with id 16728096, knowing node 1319738
-> [   0.000000] (8:node@c-7.me) Joining the ring with id 10004760, knowing node 16509405
-> [   0.000000] (9:node@c-8.me) Joining the ring with id 6518808, knowing node 42
-> [   4.000000] (3:node@c-2.me) My finger table:
-> [   4.000000] (3:node@c-2.me) Start | Succ 
-> [   4.000000] (3:node@c-2.me)  533745  | 366680 
-> [   4.000000] (3:node@c-2.me)  533746  | 533744 
-> [   4.000000] (3:node@c-2.me)  533748  | 533744 
-> [   4.000000] (3:node@c-2.me)  533752  | 533744 
-> [   4.000000] (3:node@c-2.me)  533760  | 533744 
-> [   4.000000] (3:node@c-2.me)  533776  | 533744 
-> [   4.000000] (3:node@c-2.me)  533808  | 533744 
-> [   4.000000] (3:node@c-2.me)  533872  | 533744 
-> [   4.000000] (3:node@c-2.me)  534000  | 533744 
-> [   4.000000] (3:node@c-2.me)  534256  | 533744 
-> [   4.000000] (3:node@c-2.me)  534768  | 533744 
-> [   4.000000] (3:node@c-2.me)  535792  | 533744 
-> [   4.000000] (3:node@c-2.me)  537840  | 533744 
-> [   4.000000] (3:node@c-2.me)  541936  | 533744 
-> [   4.000000] (3:node@c-2.me)  550128  | 533744 
-> [   4.000000] (3:node@c-2.me)  566512  | 533744 
-> [   4.000000] (3:node@c-2.me)  599280  | 533744 
-> [   4.000000] (3:node@c-2.me)  664816  | 533744 
-> [   4.000000] (3:node@c-2.me)  795888  | 533744 
-> [   4.000000] (3:node@c-2.me)  1058032  | 533744 
-> [   4.000000] (3:node@c-2.me)  1582320  | 533744 
-> [   4.000000] (3:node@c-2.me)  2630896  | 533744 
-> [   4.000000] (3:node@c-2.me)  4728048  | 533744 
-> [   4.000000] (3:node@c-2.me)  8922352  | 533744 
-> [   4.000000] (3:node@c-2.me) Predecessor: -1
-> [   4.000000] (6:node@c-5.me) My finger table:
-> [   4.000000] (6:node@c-5.me) Start | Succ 
-> [   4.000000] (6:node@c-5.me)  10874877  | 533744 
-> [   4.000000] (6:node@c-5.me)  10874878  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10874880  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10874884  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10874892  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10874908  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [   4.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [   4.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [   4.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [   4.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [   4.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [   4.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [   4.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [   4.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [   4.000000] (6:node@c-5.me) Predecessor: -1
-> [   5.000000] (5:node@c-4.me) My finger table:
-> [   5.000000] (5:node@c-4.me) Start | Succ 
-> [   5.000000] (5:node@c-4.me)  16509406  | 366680 
-> [   5.000000] (5:node@c-4.me)  16509407  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509409  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509413  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509421  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [   5.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [   5.000000] (5:node@c-4.me)  256477  | 16509405 
-> [   5.000000] (5:node@c-4.me)  780765  | 16509405 
-> [   5.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [   5.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [   5.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [   5.000000] (5:node@c-4.me) Predecessor: -1
-> [   5.000000] (8:node@c-7.me) My finger table:
-> [   5.000000] (8:node@c-7.me) Start | Succ 
-> [   5.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [   5.000000] (8:node@c-7.me)  10004762  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10004764  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10004768  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10004776  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [   5.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [   5.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [   5.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [   5.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [   5.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [   5.000000] (8:node@c-7.me) Predecessor: -1
-> [   6.000000] (2:node@c-1.me) My finger table:
-> [   6.000000] (2:node@c-1.me) Start | Succ 
-> [   6.000000] (2:node@c-1.me)  366681  |  42 
-> [   6.000000] (2:node@c-1.me)  366682  | 366680 
-> [   6.000000] (2:node@c-1.me)  366684  | 366680 
-> [   6.000000] (2:node@c-1.me)  366688  | 366680 
-> [   6.000000] (2:node@c-1.me)  366696  | 366680 
-> [   6.000000] (2:node@c-1.me)  366712  | 366680 
-> [   6.000000] (2:node@c-1.me)  366744  | 366680 
-> [   6.000000] (2:node@c-1.me)  366808  | 366680 
-> [   6.000000] (2:node@c-1.me)  366936  | 366680 
-> [   6.000000] (2:node@c-1.me)  367192  | 366680 
-> [   6.000000] (2:node@c-1.me)  367704  | 366680 
-> [   6.000000] (2:node@c-1.me)  368728  | 366680 
-> [   6.000000] (2:node@c-1.me)  370776  | 366680 
-> [   6.000000] (2:node@c-1.me)  374872  | 366680 
-> [   6.000000] (2:node@c-1.me)  383064  | 366680 
-> [   6.000000] (2:node@c-1.me)  399448  | 366680 
-> [   6.000000] (2:node@c-1.me)  432216  | 366680 
-> [   6.000000] (2:node@c-1.me)  497752  | 366680 
-> [   6.000000] (2:node@c-1.me)  628824  | 366680 
-> [   6.000000] (2:node@c-1.me)  890968  | 366680 
-> [   6.000000] (2:node@c-1.me)  1415256  | 366680 
-> [   6.000000] (2:node@c-1.me)  2463832  | 366680 
-> [   6.000000] (2:node@c-1.me)  4560984  | 366680 
-> [   6.000000] (2:node@c-1.me)  8755288  | 366680 
-> [   6.000000] (2:node@c-1.me) Predecessor: -1
-> [   8.000000] (7:node@c-6.me) My finger table:
-> [   8.000000] (7:node@c-6.me) Start | Succ 
-> [   8.000000] (7:node@c-6.me)  16728097  | 1319738 
-> [   8.000000] (7:node@c-6.me)  16728098  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728100  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728104  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [   8.000000] (7:node@c-6.me)  16416  | 16728096 
-> [   8.000000] (7:node@c-6.me)  81952  | 16728096 
-> [   8.000000] (7:node@c-6.me)  213024  | 16728096 
-> [   8.000000] (7:node@c-6.me)  475168  | 16728096 
-> [   8.000000] (7:node@c-6.me)  999456  | 16728096 
-> [   8.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [   8.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [   8.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [   8.000000] (7:node@c-6.me) Predecessor: -1
-> [   9.000000] (10:node@c-9.me) My finger table:
-> [   9.000000] (10:node@c-9.me) Start | Succ 
-> [   9.000000] (10:node@c-9.me)  2015254  | 1319738 
-> [   9.000000] (10:node@c-9.me)  2015255  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015257  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015261  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015269  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015285  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [   9.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [   9.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [   9.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [   9.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [   9.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [   9.000000] (10:node@c-9.me) Predecessor: -1
-> [  11.000000] (4:node@c-3.me) My finger table:
-> [  11.000000] (4:node@c-3.me) Start | Succ 
-> [  11.000000] (4:node@c-3.me)  1319739  |  42 
-> [  11.000000] (4:node@c-3.me)  1319740  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319742  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [  11.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [  11.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [  11.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [  11.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [  11.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [  11.000000] (4:node@c-3.me) Predecessor: -1
-> [  16.000000] (9:node@c-8.me) My finger table:
-> [  16.000000] (9:node@c-8.me) Start | Succ 
-> [  16.000000] (9:node@c-8.me)  6518809  |  42 
-> [  16.000000] (9:node@c-8.me)  6518810  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6518812  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6518816  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [  16.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [  16.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [  16.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [  16.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [  16.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [  16.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [  16.000000] (9:node@c-8.me) Predecessor: -1
-> [  26.000000] (4:node@c-3.me) My finger table:
-> [  26.000000] (4:node@c-3.me) Start | Succ 
-> [  26.000000] (4:node@c-3.me)  1319739  |  42 
-> [  26.000000] (4:node@c-3.me)  1319740  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319742  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [  26.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [  26.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [  26.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [  26.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [  26.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [  26.000000] (4:node@c-3.me) Predecessor: 16728096
-> [  31.000000] (2:node@c-1.me) My finger table:
-> [  31.000000] (2:node@c-1.me) Start | Succ 
-> [  31.000000] (2:node@c-1.me)  366681  |  42 
-> [  31.000000] (2:node@c-1.me)  366682  | 366680 
-> [  31.000000] (2:node@c-1.me)  366684  | 366680 
-> [  31.000000] (2:node@c-1.me)  366688  | 366680 
-> [  31.000000] (2:node@c-1.me)  366696  | 366680 
-> [  31.000000] (2:node@c-1.me)  366712  | 366680 
-> [  31.000000] (2:node@c-1.me)  366744  | 366680 
-> [  31.000000] (2:node@c-1.me)  366808  | 366680 
-> [  31.000000] (2:node@c-1.me)  366936  | 366680 
-> [  31.000000] (2:node@c-1.me)  367192  | 366680 
-> [  31.000000] (2:node@c-1.me)  367704  | 366680 
-> [  31.000000] (2:node@c-1.me)  368728  | 366680 
-> [  31.000000] (2:node@c-1.me)  370776  | 366680 
-> [  31.000000] (2:node@c-1.me)  374872  | 366680 
-> [  31.000000] (2:node@c-1.me)  383064  | 366680 
-> [  31.000000] (2:node@c-1.me)  399448  | 366680 
-> [  31.000000] (2:node@c-1.me)  432216  | 366680 
-> [  31.000000] (2:node@c-1.me)  497752  | 366680 
-> [  31.000000] (2:node@c-1.me)  628824  | 366680 
-> [  31.000000] (2:node@c-1.me)  890968  | 366680 
-> [  31.000000] (2:node@c-1.me)  1415256  | 366680 
-> [  31.000000] (2:node@c-1.me)  2463832  | 366680 
-> [  31.000000] (2:node@c-1.me)  4560984  | 366680 
-> [  31.000000] (2:node@c-1.me)  8755288  | 366680 
-> [  31.000000] (2:node@c-1.me) Predecessor: 16509405
-> [  32.000000] (5:node@c-4.me) My finger table:
-> [  32.000000] (5:node@c-4.me) Start | Succ 
-> [  32.000000] (5:node@c-4.me)  16509406  | 366680 
-> [  32.000000] (5:node@c-4.me)  16509407  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509409  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509413  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509421  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [  32.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [  32.000000] (5:node@c-4.me)  256477  | 16509405 
-> [  32.000000] (5:node@c-4.me)  780765  | 16509405 
-> [  32.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [  32.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [  32.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [  32.000000] (5:node@c-4.me) Predecessor: 10004760
-> [  38.000000] (3:node@c-2.me) My finger table:
-> [  38.000000] (3:node@c-2.me) Start | Succ 
-> [  38.000000] (3:node@c-2.me)  533745  | 16509405 
-> [  38.000000] (3:node@c-2.me)  533746  | 533744 
-> [  38.000000] (3:node@c-2.me)  533748  | 533744 
-> [  38.000000] (3:node@c-2.me)  533752  | 533744 
-> [  38.000000] (3:node@c-2.me)  533760  | 533744 
-> [  38.000000] (3:node@c-2.me)  533776  | 533744 
-> [  38.000000] (3:node@c-2.me)  533808  | 533744 
-> [  38.000000] (3:node@c-2.me)  533872  | 533744 
-> [  38.000000] (3:node@c-2.me)  534000  | 533744 
-> [  38.000000] (3:node@c-2.me)  534256  | 533744 
-> [  38.000000] (3:node@c-2.me)  534768  | 533744 
-> [  38.000000] (3:node@c-2.me)  535792  | 533744 
-> [  38.000000] (3:node@c-2.me)  537840  | 533744 
-> [  38.000000] (3:node@c-2.me)  541936  | 533744 
-> [  38.000000] (3:node@c-2.me)  550128  | 533744 
-> [  38.000000] (3:node@c-2.me)  566512  | 533744 
-> [  38.000000] (3:node@c-2.me)  599280  | 533744 
-> [  38.000000] (3:node@c-2.me)  664816  | 533744 
-> [  38.000000] (3:node@c-2.me)  795888  | 533744 
-> [  38.000000] (3:node@c-2.me)  1058032  | 533744 
-> [  38.000000] (3:node@c-2.me)  1582320  | 533744 
-> [  38.000000] (3:node@c-2.me)  2630896  | 533744 
-> [  38.000000] (3:node@c-2.me)  4728048  | 533744 
-> [  38.000000] (3:node@c-2.me)  8922352  | 533744 
-> [  38.000000] (3:node@c-2.me) Predecessor: 10874876
-> [  50.000000] (1:node@c-0.me) My finger table:
-> [  50.000000] (1:node@c-0.me) Start | Succ 
-> [  50.000000] (1:node@c-0.me)   43  |  42 
-> [  50.000000] (1:node@c-0.me)   44  |  42 
-> [  50.000000] (1:node@c-0.me)   46  |  42 
-> [  50.000000] (1:node@c-0.me)   50  |  42 
-> [  50.000000] (1:node@c-0.me)   58  |  42 
-> [  50.000000] (1:node@c-0.me)   74  |  42 
-> [  50.000000] (1:node@c-0.me)  106  |  42 
-> [  50.000000] (1:node@c-0.me)  170  |  42 
-> [  50.000000] (1:node@c-0.me)  298  |  42 
-> [  50.000000] (1:node@c-0.me)  554  |  42 
-> [  50.000000] (1:node@c-0.me)  1066  |  42 
-> [  50.000000] (1:node@c-0.me)  2090  |  42 
-> [  50.000000] (1:node@c-0.me)  4138  |  42 
-> [  50.000000] (1:node@c-0.me)  8234  |  42 
-> [  50.000000] (1:node@c-0.me)  16426  |  42 
-> [  50.000000] (1:node@c-0.me)  32810  |  42 
-> [  50.000000] (1:node@c-0.me)  65578  |  42 
-> [  50.000000] (1:node@c-0.me)  131114  |  42 
-> [  50.000000] (1:node@c-0.me)  262186  |  42 
-> [  50.000000] (1:node@c-0.me)  524330  |  42 
-> [  50.000000] (1:node@c-0.me)  1048618  |  42 
-> [  50.000000] (1:node@c-0.me)  2097194  |  42 
-> [  50.000000] (1:node@c-0.me)  4194346  |  42 
-> [  50.000000] (1:node@c-0.me)  8388650  |  42 
-> [  50.000000] (1:node@c-0.me) Predecessor: 366680
-> [  60.000000] (1:node@c-0.me) My finger table:
-> [  60.000000] (1:node@c-0.me) Start | Succ 
-> [  60.000000] (1:node@c-0.me)   43  |  42 
-> [  60.000000] (1:node@c-0.me)   44  |  42 
-> [  60.000000] (1:node@c-0.me)   46  |  42 
-> [  60.000000] (1:node@c-0.me)   50  |  42 
-> [  60.000000] (1:node@c-0.me)   58  |  42 
-> [  60.000000] (1:node@c-0.me)   74  |  42 
-> [  60.000000] (1:node@c-0.me)  106  |  42 
-> [  60.000000] (1:node@c-0.me)  170  |  42 
-> [  60.000000] (1:node@c-0.me)  298  |  42 
-> [  60.000000] (1:node@c-0.me)  554  |  42 
-> [  60.000000] (1:node@c-0.me)  1066  |  42 
-> [  60.000000] (1:node@c-0.me)  2090  |  42 
-> [  60.000000] (1:node@c-0.me)  4138  |  42 
-> [  60.000000] (1:node@c-0.me)  8234  |  42 
-> [  60.000000] (1:node@c-0.me)  16426  |  42 
-> [  60.000000] (1:node@c-0.me)  32810  |  42 
-> [  60.000000] (1:node@c-0.me)  65578  |  42 
-> [  60.000000] (1:node@c-0.me)  131114  |  42 
-> [  60.000000] (1:node@c-0.me)  262186  |  42 
-> [  60.000000] (1:node@c-0.me)  524330  |  42 
-> [  60.000000] (1:node@c-0.me)  1048618  |  42 
-> [  60.000000] (1:node@c-0.me)  2097194  |  42 
-> [  60.000000] (1:node@c-0.me)  4194346  |  42 
-> [  60.000000] (1:node@c-0.me)  8388650  |  42 
-> [  60.000000] (1:node@c-0.me) Predecessor: 1319738
-> [  70.000000] (1:node@c-0.me) My finger table:
-> [  70.000000] (1:node@c-0.me) Start | Succ 
-> [  70.000000] (1:node@c-0.me)   43  | 1319738 
-> [  70.000000] (1:node@c-0.me)   44  |  42 
-> [  70.000000] (1:node@c-0.me)   46  |  42 
-> [  70.000000] (1:node@c-0.me)   50  |  42 
-> [  70.000000] (1:node@c-0.me)   58  |  42 
-> [  70.000000] (1:node@c-0.me)   74  |  42 
-> [  70.000000] (1:node@c-0.me)  106  |  42 
-> [  70.000000] (1:node@c-0.me)  170  |  42 
-> [  70.000000] (1:node@c-0.me)  298  |  42 
-> [  70.000000] (1:node@c-0.me)  554  |  42 
-> [  70.000000] (1:node@c-0.me)  1066  |  42 
-> [  70.000000] (1:node@c-0.me)  2090  |  42 
-> [  70.000000] (1:node@c-0.me)  4138  |  42 
-> [  70.000000] (1:node@c-0.me)  8234  |  42 
-> [  70.000000] (1:node@c-0.me)  16426  |  42 
-> [  70.000000] (1:node@c-0.me)  32810  |  42 
-> [  70.000000] (1:node@c-0.me)  65578  |  42 
-> [  70.000000] (1:node@c-0.me)  131114  |  42 
-> [  70.000000] (1:node@c-0.me)  262186  |  42 
-> [  70.000000] (1:node@c-0.me)  524330  |  42 
-> [  70.000000] (1:node@c-0.me)  1048618  |  42 
-> [  70.000000] (1:node@c-0.me)  2097194  |  42 
-> [  70.000000] (1:node@c-0.me)  4194346  |  42 
-> [  70.000000] (1:node@c-0.me)  8388650  |  42 
-> [  70.000000] (1:node@c-0.me) Predecessor: 6518808
-> [  85.000000] (4:node@c-3.me) My finger table:
-> [  85.000000] (4:node@c-3.me) Start | Succ 
-> [  85.000000] (4:node@c-3.me)  1319739  | 6518808 
-> [  85.000000] (4:node@c-3.me)  1319740  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319742  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [  85.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [  85.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [  85.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [  85.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [  85.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [  85.000000] (4:node@c-3.me) Predecessor: 42
-> [  86.000000] (8:node@c-7.me) My finger table:
-> [  86.000000] (8:node@c-7.me) Start | Succ 
-> [  86.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [  86.000000] (8:node@c-7.me)  10004762  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10004764  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10004768  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10004776  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [  86.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [  86.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [  86.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [  86.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [  86.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [  86.000000] (8:node@c-7.me) Predecessor: 533744
-> [  90.000000] (7:node@c-6.me) My finger table:
-> [  90.000000] (7:node@c-6.me) Start | Succ 
-> [  90.000000] (7:node@c-6.me)  16728097  | 1319738 
-> [  90.000000] (7:node@c-6.me)  16728098  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728100  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728104  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [  90.000000] (7:node@c-6.me)  16416  | 16728096 
-> [  90.000000] (7:node@c-6.me)  81952  | 16728096 
-> [  90.000000] (7:node@c-6.me)  213024  | 16728096 
-> [  90.000000] (7:node@c-6.me)  475168  | 16728096 
-> [  90.000000] (7:node@c-6.me)  999456  | 16728096 
-> [  90.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [  90.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [  90.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [  90.000000] (7:node@c-6.me) Predecessor: 2015253
-> [ 109.000000] (9:node@c-8.me) My finger table:
-> [ 109.000000] (9:node@c-8.me) Start | Succ 
-> [ 109.000000] (9:node@c-8.me)  6518809  |  42 
-> [ 109.000000] (9:node@c-8.me)  6518810  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6518812  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6518816  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 109.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 109.000000] (9:node@c-8.me) Predecessor: 366680
-> [ 110.000000] (9:node@c-8.me) My finger table:
-> [ 110.000000] (9:node@c-8.me) Start | Succ 
-> [ 110.000000] (9:node@c-8.me)  6518809  |  42 
-> [ 110.000000] (9:node@c-8.me)  6518810  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6518812  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6518816  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 110.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 110.000000] (9:node@c-8.me) Predecessor: 1319738
-> [ 145.000000] (1:node@c-0.me) My finger table:
-> [ 145.000000] (1:node@c-0.me) Start | Succ 
-> [ 145.000000] (1:node@c-0.me)   43  | 1319738 
-> [ 145.000000] (1:node@c-0.me)   44  |  42 
-> [ 145.000000] (1:node@c-0.me)   46  |  42 
-> [ 145.000000] (1:node@c-0.me)   50  |  42 
-> [ 145.000000] (1:node@c-0.me)   58  |  42 
-> [ 145.000000] (1:node@c-0.me)   74  |  42 
-> [ 145.000000] (1:node@c-0.me)  106  |  42 
-> [ 145.000000] (1:node@c-0.me)  170  |  42 
-> [ 145.000000] (1:node@c-0.me)  298  |  42 
-> [ 145.000000] (1:node@c-0.me)  554  |  42 
-> [ 145.000000] (1:node@c-0.me)  1066  |  42 
-> [ 145.000000] (1:node@c-0.me)  2090  |  42 
-> [ 145.000000] (1:node@c-0.me)  4138  |  42 
-> [ 145.000000] (1:node@c-0.me)  8234  |  42 
-> [ 145.000000] (1:node@c-0.me)  16426  |  42 
-> [ 145.000000] (1:node@c-0.me)  32810  |  42 
-> [ 145.000000] (1:node@c-0.me)  65578  |  42 
-> [ 145.000000] (1:node@c-0.me)  131114  |  42 
-> [ 145.000000] (1:node@c-0.me)  262186  |  42 
-> [ 145.000000] (1:node@c-0.me)  524330  |  42 
-> [ 145.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 145.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 145.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 145.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 145.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 157.000000] (4:node@c-3.me) My finger table:
-> [ 157.000000] (4:node@c-3.me) Start | Succ 
-> [ 157.000000] (4:node@c-3.me)  1319739  | 6518808 
-> [ 157.000000] (4:node@c-3.me)  1319740  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319742  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 157.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 157.000000] (4:node@c-3.me) Predecessor: 366680
-> [ 184.000000] (7:node@c-6.me) My finger table:
-> [ 184.000000] (7:node@c-6.me) Start | Succ 
-> [ 184.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 184.000000] (7:node@c-6.me)  16728098  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728100  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728104  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 184.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 184.000000] (7:node@c-6.me) Predecessor: 6518808
-> [ 202.000000] (2:node@c-1.me) My finger table:
-> [ 202.000000] (2:node@c-1.me) Start | Succ 
-> [ 202.000000] (2:node@c-1.me)  366681  | 1319738 
-> [ 202.000000] (2:node@c-1.me)  366682  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366684  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366688  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366696  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366712  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366744  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 202.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 202.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 202.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 202.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 202.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 202.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 202.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 202.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 202.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 202.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 202.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 202.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 202.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 202.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 202.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 202.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 202.000000] (2:node@c-1.me) Predecessor: 42
-> [ 221.000000] (9:node@c-8.me) My finger table:
-> [ 221.000000] (9:node@c-8.me) Start | Succ 
-> [ 221.000000] (9:node@c-8.me)  6518809  | 16728096 
-> [ 221.000000] (9:node@c-8.me)  6518810  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6518812  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6518816  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 221.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 221.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 240.000000] (6:node@c-5.me) My finger table:
-> [ 240.000000] (6:node@c-5.me) Start | Succ 
-> [ 240.000000] (6:node@c-5.me)  10874877  | 533744 
-> [ 240.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 240.000000] (6:node@c-5.me)  10874880  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10874884  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10874892  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10874908  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 240.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 240.000000] (6:node@c-5.me) Predecessor: -1
-> [ 247.000000] (5:node@c-4.me) My finger table:
-> [ 247.000000] (5:node@c-4.me) Start | Succ 
-> [ 247.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 247.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 247.000000] (5:node@c-4.me)  16509409  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509413  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509421  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 247.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 247.000000] (5:node@c-4.me) Predecessor: 10004760
-> [ 250.000000] (1:node@c-0.me) My finger table:
-> [ 250.000000] (1:node@c-0.me) Start | Succ 
-> [ 250.000000] (1:node@c-0.me)   43  | 366680 
-> [ 250.000000] (1:node@c-0.me)   44  | 366680 
-> [ 250.000000] (1:node@c-0.me)   46  |  42 
-> [ 250.000000] (1:node@c-0.me)   50  |  42 
-> [ 250.000000] (1:node@c-0.me)   58  |  42 
-> [ 250.000000] (1:node@c-0.me)   74  |  42 
-> [ 250.000000] (1:node@c-0.me)  106  |  42 
-> [ 250.000000] (1:node@c-0.me)  170  |  42 
-> [ 250.000000] (1:node@c-0.me)  298  |  42 
-> [ 250.000000] (1:node@c-0.me)  554  |  42 
-> [ 250.000000] (1:node@c-0.me)  1066  |  42 
-> [ 250.000000] (1:node@c-0.me)  2090  |  42 
-> [ 250.000000] (1:node@c-0.me)  4138  |  42 
-> [ 250.000000] (1:node@c-0.me)  8234  |  42 
-> [ 250.000000] (1:node@c-0.me)  16426  |  42 
-> [ 250.000000] (1:node@c-0.me)  32810  |  42 
-> [ 250.000000] (1:node@c-0.me)  65578  |  42 
-> [ 250.000000] (1:node@c-0.me)  131114  |  42 
-> [ 250.000000] (1:node@c-0.me)  262186  |  42 
-> [ 250.000000] (1:node@c-0.me)  524330  |  42 
-> [ 250.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 250.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 250.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 250.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 250.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 251.000000] (3:node@c-2.me) My finger table:
-> [ 251.000000] (3:node@c-2.me) Start | Succ 
-> [ 251.000000] (3:node@c-2.me)  533745  | 10004760 
-> [ 251.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 251.000000] (3:node@c-2.me)  533748  | 533744 
-> [ 251.000000] (3:node@c-2.me)  533752  | 533744 
-> [ 251.000000] (3:node@c-2.me)  533760  | 533744 
-> [ 251.000000] (3:node@c-2.me)  533776  | 533744 
-> [ 251.000000] (3:node@c-2.me)  533808  | 533744 
-> [ 251.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 251.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 251.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 251.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 251.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 251.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 251.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 251.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 251.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 251.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 251.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 251.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 251.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 251.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 251.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 251.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 251.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 251.000000] (3:node@c-2.me) Predecessor: 10874876
-> [ 253.000000] (8:node@c-7.me) My finger table:
-> [ 253.000000] (8:node@c-7.me) Start | Succ 
-> [ 253.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [ 253.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 253.000000] (8:node@c-7.me)  10004764  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10004768  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10004776  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 253.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 253.000000] (8:node@c-7.me) Predecessor: 533744
-> [ 263.000000] (2:node@c-1.me) My finger table:
-> [ 263.000000] (2:node@c-1.me) Start | Succ 
-> [ 263.000000] (2:node@c-1.me)  366681  | 1319738 
-> [ 263.000000] (2:node@c-1.me)  366682  | 1319738 
-> [ 263.000000] (2:node@c-1.me)  366684  | 366680 
-> [ 263.000000] (2:node@c-1.me)  366688  | 366680 
-> [ 263.000000] (2:node@c-1.me)  366696  | 366680 
-> [ 263.000000] (2:node@c-1.me)  366712  | 366680 
-> [ 263.000000] (2:node@c-1.me)  366744  | 366680 
-> [ 263.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 263.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 263.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 263.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 263.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 263.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 263.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 263.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 263.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 263.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 263.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 263.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 263.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 263.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 263.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 263.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 263.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 263.000000] (2:node@c-1.me) Predecessor: 42
-> [ 268.000000] (4:node@c-3.me) My finger table:
-> [ 268.000000] (4:node@c-3.me) Start | Succ 
-> [ 268.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 268.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 268.000000] (4:node@c-3.me)  1319742  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 268.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 268.000000] (4:node@c-3.me) Predecessor: 366680
-> [ 269.000000] (10:node@c-9.me) My finger table:
-> [ 269.000000] (10:node@c-9.me) Start | Succ 
-> [ 269.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 269.000000] (10:node@c-9.me)  2015255  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015257  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015261  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015269  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015285  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 269.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 269.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 274.000000] (10:node@c-9.me) My finger table:
-> [ 274.000000] (10:node@c-9.me) Start | Succ 
-> [ 274.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 274.000000] (10:node@c-9.me)  2015255  | 6518808 
-> [ 274.000000] (10:node@c-9.me)  2015257  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015261  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015269  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015285  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 274.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 274.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 274.000000] (9:node@c-8.me) My finger table:
-> [ 274.000000] (9:node@c-8.me) Start | Succ 
-> [ 274.000000] (9:node@c-8.me)  6518809  | 16728096 
-> [ 274.000000] (9:node@c-8.me)  6518810  | 16728096 
-> [ 274.000000] (9:node@c-8.me)  6518812  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6518816  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 274.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 274.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 275.000000] (7:node@c-6.me) My finger table:
-> [ 275.000000] (7:node@c-6.me) Start | Succ 
-> [ 275.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 275.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 275.000000] (7:node@c-6.me)  16728100  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728104  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 275.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 275.000000] (7:node@c-6.me) Predecessor: 6518808
-> [ 288.000000] (7:node@c-6.me) My finger table:
-> [ 288.000000] (7:node@c-6.me) Start | Succ 
-> [ 288.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 288.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 288.000000] (7:node@c-6.me)  16728100  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728104  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 288.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 288.000000] (7:node@c-6.me) Predecessor: 16509405
-> [ 361.000000] (8:node@c-7.me) My finger table:
-> [ 361.000000] (8:node@c-7.me) Start | Succ 
-> [ 361.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [ 361.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 361.000000] (8:node@c-7.me)  10004764  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10004768  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10004776  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 361.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 361.000000] (8:node@c-7.me) Predecessor: 6518808
-> [ 364.000000] (6:node@c-5.me) My finger table:
-> [ 364.000000] (6:node@c-5.me) Start | Succ 
-> [ 364.000000] (6:node@c-5.me)  10874877  | 533744 
-> [ 364.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 364.000000] (6:node@c-5.me)  10874880  | 533744 
-> [ 364.000000] (6:node@c-5.me)  10874884  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10874892  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10874908  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 364.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 364.000000] (6:node@c-5.me) Predecessor: -1
-> [ 371.000000] (3:node@c-2.me) My finger table:
-> [ 371.000000] (3:node@c-2.me) Start | Succ 
-> [ 371.000000] (3:node@c-2.me)  533745  | 10004760 
-> [ 371.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 371.000000] (3:node@c-2.me)  533748  | 10004760 
-> [ 371.000000] (3:node@c-2.me)  533752  | 533744 
-> [ 371.000000] (3:node@c-2.me)  533760  | 533744 
-> [ 371.000000] (3:node@c-2.me)  533776  | 533744 
-> [ 371.000000] (3:node@c-2.me)  533808  | 533744 
-> [ 371.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 371.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 371.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 371.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 371.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 371.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 371.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 371.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 371.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 371.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 371.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 371.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 371.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 371.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 371.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 371.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 371.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 371.000000] (3:node@c-2.me) Predecessor: 10874876
-> [ 372.000000] (1:node@c-0.me) My finger table:
-> [ 372.000000] (1:node@c-0.me) Start | Succ 
-> [ 372.000000] (1:node@c-0.me)   43  | 366680 
-> [ 372.000000] (1:node@c-0.me)   44  | 366680 
-> [ 372.000000] (1:node@c-0.me)   46  | 366680 
-> [ 372.000000] (1:node@c-0.me)   50  |  42 
-> [ 372.000000] (1:node@c-0.me)   58  |  42 
-> [ 372.000000] (1:node@c-0.me)   74  |  42 
-> [ 372.000000] (1:node@c-0.me)  106  |  42 
-> [ 372.000000] (1:node@c-0.me)  170  |  42 
-> [ 372.000000] (1:node@c-0.me)  298  |  42 
-> [ 372.000000] (1:node@c-0.me)  554  |  42 
-> [ 372.000000] (1:node@c-0.me)  1066  |  42 
-> [ 372.000000] (1:node@c-0.me)  2090  |  42 
-> [ 372.000000] (1:node@c-0.me)  4138  |  42 
-> [ 372.000000] (1:node@c-0.me)  8234  |  42 
-> [ 372.000000] (1:node@c-0.me)  16426  |  42 
-> [ 372.000000] (1:node@c-0.me)  32810  |  42 
-> [ 372.000000] (1:node@c-0.me)  65578  |  42 
-> [ 372.000000] (1:node@c-0.me)  131114  |  42 
-> [ 372.000000] (1:node@c-0.me)  262186  |  42 
-> [ 372.000000] (1:node@c-0.me)  524330  |  42 
-> [ 372.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 372.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 372.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 372.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 372.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 374.000000] (8:node@c-7.me) My finger table:
-> [ 374.000000] (8:node@c-7.me) Start | Succ 
-> [ 374.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [ 374.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 374.000000] (8:node@c-7.me)  10004764  | 16509405 
-> [ 374.000000] (8:node@c-7.me)  10004768  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10004776  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 374.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 374.000000] (8:node@c-7.me) Predecessor: 6518808
-> [ 375.000000] (5:node@c-4.me) My finger table:
-> [ 375.000000] (5:node@c-4.me) Start | Succ 
-> [ 375.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 375.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 375.000000] (5:node@c-4.me)  16509409  | 16728096 
-> [ 375.000000] (5:node@c-4.me)  16509413  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16509421  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 375.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 375.000000] (5:node@c-4.me) Predecessor: 10004760
-> [ 395.000000] (9:node@c-8.me) My finger table:
-> [ 395.000000] (9:node@c-8.me) Start | Succ 
-> [ 395.000000] (9:node@c-8.me)  6518809  | 10004760 
-> [ 395.000000] (9:node@c-8.me)  6518810  | 16728096 
-> [ 395.000000] (9:node@c-8.me)  6518812  | 10004760 
-> [ 395.000000] (9:node@c-8.me)  6518816  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 395.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 395.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 398.000000] (7:node@c-6.me) My finger table:
-> [ 398.000000] (7:node@c-6.me) Start | Succ 
-> [ 398.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 398.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 398.000000] (7:node@c-6.me)  16728100  |  42 
-> [ 398.000000] (7:node@c-6.me)  16728104  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 398.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 398.000000] (7:node@c-6.me) Predecessor: 16509405
-> [ 405.000000] (4:node@c-3.me) My finger table:
-> [ 405.000000] (4:node@c-3.me) Start | Succ 
-> [ 405.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 405.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 405.000000] (4:node@c-3.me)  1319742  | 2015253 
-> [ 405.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 405.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 405.000000] (4:node@c-3.me) Predecessor: 366680
-> [ 411.000000] (2:node@c-1.me) My finger table:
-> [ 411.000000] (2:node@c-1.me) Start | Succ 
-> [ 411.000000] (2:node@c-1.me)  366681  | 1319738 
-> [ 411.000000] (2:node@c-1.me)  366682  | 1319738 
-> [ 411.000000] (2:node@c-1.me)  366684  | 1319738 
-> [ 411.000000] (2:node@c-1.me)  366688  | 366680 
-> [ 411.000000] (2:node@c-1.me)  366696  | 366680 
-> [ 411.000000] (2:node@c-1.me)  366712  | 366680 
-> [ 411.000000] (2:node@c-1.me)  366744  | 366680 
-> [ 411.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 411.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 411.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 411.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 411.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 411.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 411.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 411.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 411.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 411.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 411.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 411.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 411.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 411.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 411.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 411.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 411.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 411.000000] (2:node@c-1.me) Predecessor: 42
-> [ 426.000000] (10:node@c-9.me) My finger table:
-> [ 426.000000] (10:node@c-9.me) Start | Succ 
-> [ 426.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 426.000000] (10:node@c-9.me)  2015255  | 6518808 
-> [ 426.000000] (10:node@c-9.me)  2015257  | 6518808 
-> [ 426.000000] (10:node@c-9.me)  2015261  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2015269  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2015285  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 426.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 426.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 486.000000] (6:node@c-5.me) My finger table:
-> [ 486.000000] (6:node@c-5.me) Start | Succ 
-> [ 486.000000] (6:node@c-5.me)  10874877  | 533744 
-> [ 486.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 486.000000] (6:node@c-5.me)  10874880  | 533744 
-> [ 486.000000] (6:node@c-5.me)  10874884  | 533744 
-> [ 486.000000] (6:node@c-5.me)  10874892  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10874908  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 486.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 486.000000] (6:node@c-5.me) Predecessor: -1
-> [ 491.000000] (4:node@c-3.me) My finger table:
-> [ 491.000000] (4:node@c-3.me) Start | Succ 
-> [ 491.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 491.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 491.000000] (4:node@c-3.me)  1319742  | 2015253 
-> [ 491.000000] (4:node@c-3.me)  1319746  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 491.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 491.000000] (4:node@c-3.me) Predecessor: 533744
-> [ 492.000000] (1:node@c-0.me) My finger table:
-> [ 492.000000] (1:node@c-0.me) Start | Succ 
-> [ 492.000000] (1:node@c-0.me)   43  | 366680 
-> [ 492.000000] (1:node@c-0.me)   44  | 366680 
-> [ 492.000000] (1:node@c-0.me)   46  | 366680 
-> [ 492.000000] (1:node@c-0.me)   50  | 366680 
-> [ 492.000000] (1:node@c-0.me)   58  |  42 
-> [ 492.000000] (1:node@c-0.me)   74  |  42 
-> [ 492.000000] (1:node@c-0.me)  106  |  42 
-> [ 492.000000] (1:node@c-0.me)  170  |  42 
-> [ 492.000000] (1:node@c-0.me)  298  |  42 
-> [ 492.000000] (1:node@c-0.me)  554  |  42 
-> [ 492.000000] (1:node@c-0.me)  1066  |  42 
-> [ 492.000000] (1:node@c-0.me)  2090  |  42 
-> [ 492.000000] (1:node@c-0.me)  4138  |  42 
-> [ 492.000000] (1:node@c-0.me)  8234  |  42 
-> [ 492.000000] (1:node@c-0.me)  16426  |  42 
-> [ 492.000000] (1:node@c-0.me)  32810  |  42 
-> [ 492.000000] (1:node@c-0.me)  65578  |  42 
-> [ 492.000000] (1:node@c-0.me)  131114  |  42 
-> [ 492.000000] (1:node@c-0.me)  262186  |  42 
-> [ 492.000000] (1:node@c-0.me)  524330  |  42 
-> [ 492.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 492.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 492.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 492.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 492.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 495.000000] (3:node@c-2.me) My finger table:
-> [ 495.000000] (3:node@c-2.me) Start | Succ 
-> [ 495.000000] (3:node@c-2.me)  533745  | 1319738 
-> [ 495.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 495.000000] (3:node@c-2.me)  533748  | 10004760 
-> [ 495.000000] (3:node@c-2.me)  533752  | 1319738 
-> [ 495.000000] (3:node@c-2.me)  533760  | 533744 
-> [ 495.000000] (3:node@c-2.me)  533776  | 533744 
-> [ 495.000000] (3:node@c-2.me)  533808  | 533744 
-> [ 495.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 495.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 495.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 495.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 495.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 495.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 495.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 495.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 495.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 495.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 495.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 495.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 495.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 495.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 495.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 495.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 495.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 495.000000] (3:node@c-2.me) Predecessor: 10874876
-> [ 502.000000] (8:node@c-7.me) My finger table:
-> [ 502.000000] (8:node@c-7.me) Start | Succ 
-> [ 502.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [ 502.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 502.000000] (8:node@c-7.me)  10004764  | 16509405 
-> [ 502.000000] (8:node@c-7.me)  10004768  | 16509405 
-> [ 502.000000] (8:node@c-7.me)  10004776  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 502.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 502.000000] (8:node@c-7.me) Predecessor: 6518808
-> [ 505.000000] (5:node@c-4.me) My finger table:
-> [ 505.000000] (5:node@c-4.me) Start | Succ 
-> [ 505.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 505.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 505.000000] (5:node@c-4.me)  16509409  | 16728096 
-> [ 505.000000] (5:node@c-4.me)  16509413  | 16728096 
-> [ 505.000000] (5:node@c-4.me)  16509421  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 505.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 505.000000] (5:node@c-4.me) Predecessor: 10004760
-> [ 521.000000] (7:node@c-6.me) My finger table:
-> [ 521.000000] (7:node@c-6.me) Start | Succ 
-> [ 521.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 521.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 521.000000] (7:node@c-6.me)  16728100  |  42 
-> [ 521.000000] (7:node@c-6.me)  16728104  |  42 
-> [ 521.000000] (7:node@c-6.me)  16728112  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 521.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 521.000000] (7:node@c-6.me) Predecessor: 16509405
-> [ 535.000000] (9:node@c-8.me) My finger table:
-> [ 535.000000] (9:node@c-8.me) Start | Succ 
-> [ 535.000000] (9:node@c-8.me)  6518809  | 10004760 
-> [ 535.000000] (9:node@c-8.me)  6518810  | 16728096 
-> [ 535.000000] (9:node@c-8.me)  6518812  | 10004760 
-> [ 535.000000] (9:node@c-8.me)  6518816  | 10004760 
-> [ 535.000000] (9:node@c-8.me)  6518824  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 535.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 535.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 537.000000] (4:node@c-3.me) My finger table:
-> [ 537.000000] (4:node@c-3.me) Start | Succ 
-> [ 537.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 537.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 537.000000] (4:node@c-3.me)  1319742  | 2015253 
-> [ 537.000000] (4:node@c-3.me)  1319746  | 2015253 
-> [ 537.000000] (4:node@c-3.me)  1319754  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 537.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 537.000000] (4:node@c-3.me) Predecessor: 533744
-> [ 539.000000] (2:node@c-1.me) My finger table:
-> [ 539.000000] (2:node@c-1.me) Start | Succ 
-> [ 539.000000] (2:node@c-1.me)  366681  | 533744 
-> [ 539.000000] (2:node@c-1.me)  366682  | 1319738 
-> [ 539.000000] (2:node@c-1.me)  366684  | 1319738 
-> [ 539.000000] (2:node@c-1.me)  366688  | 533744 
-> [ 539.000000] (2:node@c-1.me)  366696  | 366680 
-> [ 539.000000] (2:node@c-1.me)  366712  | 366680 
-> [ 539.000000] (2:node@c-1.me)  366744  | 366680 
-> [ 539.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 539.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 539.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 539.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 539.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 539.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 539.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 539.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 539.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 539.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 539.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 539.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 539.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 539.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 539.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 539.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 539.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 539.000000] (2:node@c-1.me) Predecessor: 42
-> [ 540.000000] (3:node@c-2.me) My finger table:
-> [ 540.000000] (3:node@c-2.me) Start | Succ 
-> [ 540.000000] (3:node@c-2.me)  533745  | 1319738 
-> [ 540.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 540.000000] (3:node@c-2.me)  533748  | 10004760 
-> [ 540.000000] (3:node@c-2.me)  533752  | 1319738 
-> [ 540.000000] (3:node@c-2.me)  533760  | 533744 
-> [ 540.000000] (3:node@c-2.me)  533776  | 533744 
-> [ 540.000000] (3:node@c-2.me)  533808  | 533744 
-> [ 540.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 540.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 540.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 540.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 540.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 540.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 540.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 540.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 540.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 540.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 540.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 540.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 540.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 540.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 540.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 540.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 540.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 540.000000] (3:node@c-2.me) Predecessor: 366680
-> [ 567.000000] (10:node@c-9.me) My finger table:
-> [ 567.000000] (10:node@c-9.me) Start | Succ 
-> [ 567.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 567.000000] (10:node@c-9.me)  2015255  | 6518808 
-> [ 567.000000] (10:node@c-9.me)  2015257  | 6518808 
-> [ 567.000000] (10:node@c-9.me)  2015261  | 6518808 
-> [ 567.000000] (10:node@c-9.me)  2015269  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2015285  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 567.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 567.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 613.000000] (1:node@c-0.me) My finger table:
-> [ 613.000000] (1:node@c-0.me) Start | Succ 
-> [ 613.000000] (1:node@c-0.me)   43  | 366680 
-> [ 613.000000] (1:node@c-0.me)   44  | 366680 
-> [ 613.000000] (1:node@c-0.me)   46  | 366680 
-> [ 613.000000] (1:node@c-0.me)   50  | 366680 
-> [ 613.000000] (1:node@c-0.me)   58  | 366680 
-> [ 613.000000] (1:node@c-0.me)   74  |  42 
-> [ 613.000000] (1:node@c-0.me)  106  |  42 
-> [ 613.000000] (1:node@c-0.me)  170  |  42 
-> [ 613.000000] (1:node@c-0.me)  298  |  42 
-> [ 613.000000] (1:node@c-0.me)  554  |  42 
-> [ 613.000000] (1:node@c-0.me)  1066  |  42 
-> [ 613.000000] (1:node@c-0.me)  2090  |  42 
-> [ 613.000000] (1:node@c-0.me)  4138  |  42 
-> [ 613.000000] (1:node@c-0.me)  8234  |  42 
-> [ 613.000000] (1:node@c-0.me)  16426  |  42 
-> [ 613.000000] (1:node@c-0.me)  32810  |  42 
-> [ 613.000000] (1:node@c-0.me)  65578  |  42 
-> [ 613.000000] (1:node@c-0.me)  131114  |  42 
-> [ 613.000000] (1:node@c-0.me)  262186  |  42 
-> [ 613.000000] (1:node@c-0.me)  524330  |  42 
-> [ 613.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 613.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 613.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 613.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 613.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 616.000000] (3:node@c-2.me) My finger table:
-> [ 616.000000] (3:node@c-2.me) Start | Succ 
-> [ 616.000000] (3:node@c-2.me)  533745  | 1319738 
-> [ 616.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 616.000000] (3:node@c-2.me)  533748  | 10004760 
-> [ 616.000000] (3:node@c-2.me)  533752  | 1319738 
-> [ 616.000000] (3:node@c-2.me)  533760  | 1319738 
-> [ 616.000000] (3:node@c-2.me)  533776  | 533744 
-> [ 616.000000] (3:node@c-2.me)  533808  | 533744 
-> [ 616.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 616.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 616.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 616.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 616.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 616.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 616.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 616.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 616.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 616.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 616.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 616.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 616.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 616.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 616.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 616.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 616.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 616.000000] (3:node@c-2.me) Predecessor: 366680
-> [ 620.000000] (6:node@c-5.me) My finger table:
-> [ 620.000000] (6:node@c-5.me) Start | Succ 
-> [ 620.000000] (6:node@c-5.me)  10874877  | 16728096 
-> [ 620.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 620.000000] (6:node@c-5.me)  10874880  | 533744 
-> [ 620.000000] (6:node@c-5.me)  10874884  | 533744 
-> [ 620.000000] (6:node@c-5.me)  10874892  | 16728096 
-> [ 620.000000] (6:node@c-5.me)  10874908  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 620.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 620.000000] (6:node@c-5.me) Predecessor: -1
-> [ 629.000000] (8:node@c-7.me) My finger table:
-> [ 629.000000] (8:node@c-7.me) Start | Succ 
-> [ 629.000000] (8:node@c-7.me)  10004761  | 16509405 
-> [ 629.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 629.000000] (8:node@c-7.me)  10004764  | 16509405 
-> [ 629.000000] (8:node@c-7.me)  10004768  | 16509405 
-> [ 629.000000] (8:node@c-7.me)  10004776  | 16509405 
-> [ 629.000000] (8:node@c-7.me)  10004792  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 629.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 629.000000] (8:node@c-7.me) Predecessor: 6518808
-> [ 630.000000] (5:node@c-4.me) My finger table:
-> [ 630.000000] (5:node@c-4.me) Start | Succ 
-> [ 630.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 630.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 630.000000] (5:node@c-4.me)  16509409  | 16728096 
-> [ 630.000000] (5:node@c-4.me)  16509413  | 16728096 
-> [ 630.000000] (5:node@c-4.me)  16509421  | 16728096 
-> [ 630.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 630.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 630.000000] (5:node@c-4.me) Predecessor: 10004760
-> [ 653.000000] (7:node@c-6.me) My finger table:
-> [ 653.000000] (7:node@c-6.me) Start | Succ 
-> [ 653.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 653.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 653.000000] (7:node@c-6.me)  16728100  |  42 
-> [ 653.000000] (7:node@c-6.me)  16728104  |  42 
-> [ 653.000000] (7:node@c-6.me)  16728112  |  42 
-> [ 653.000000] (7:node@c-6.me)  16728128  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 653.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 653.000000] (7:node@c-6.me) Predecessor: 16509405
-> [ 663.000000] (2:node@c-1.me) My finger table:
-> [ 663.000000] (2:node@c-1.me) Start | Succ 
-> [ 663.000000] (2:node@c-1.me)  366681  | 533744 
-> [ 663.000000] (2:node@c-1.me)  366682  | 1319738 
-> [ 663.000000] (2:node@c-1.me)  366684  | 1319738 
-> [ 663.000000] (2:node@c-1.me)  366688  | 533744 
-> [ 663.000000] (2:node@c-1.me)  366696  | 533744 
-> [ 663.000000] (2:node@c-1.me)  366712  | 366680 
-> [ 663.000000] (2:node@c-1.me)  366744  | 366680 
-> [ 663.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 663.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 663.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 663.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 663.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 663.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 663.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 663.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 663.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 663.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 663.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 663.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 663.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 663.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 663.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 663.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 663.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 663.000000] (2:node@c-1.me) Predecessor: 42
-> [ 668.000000] (4:node@c-3.me) My finger table:
-> [ 668.000000] (4:node@c-3.me) Start | Succ 
-> [ 668.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 668.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 668.000000] (4:node@c-3.me)  1319742  | 2015253 
-> [ 668.000000] (4:node@c-3.me)  1319746  | 2015253 
-> [ 668.000000] (4:node@c-3.me)  1319754  | 2015253 
-> [ 668.000000] (4:node@c-3.me)  1319770  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 668.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 668.000000] (4:node@c-3.me) Predecessor: 533744
-> [ 683.000000] (5:node@c-4.me) My finger table:
-> [ 683.000000] (5:node@c-4.me) Start | Succ 
-> [ 683.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 683.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 683.000000] (5:node@c-4.me)  16509409  | 16728096 
-> [ 683.000000] (5:node@c-4.me)  16509413  | 16728096 
-> [ 683.000000] (5:node@c-4.me)  16509421  | 16728096 
-> [ 683.000000] (5:node@c-4.me)  16509437  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 683.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 683.000000] (5:node@c-4.me) Predecessor: 10874876
-> [ 688.000000] (9:node@c-8.me) My finger table:
-> [ 688.000000] (9:node@c-8.me) Start | Succ 
-> [ 688.000000] (9:node@c-8.me)  6518809  | 10004760 
-> [ 688.000000] (9:node@c-8.me)  6518810  | 16728096 
-> [ 688.000000] (9:node@c-8.me)  6518812  | 10004760 
-> [ 688.000000] (9:node@c-8.me)  6518816  | 10004760 
-> [ 688.000000] (9:node@c-8.me)  6518824  | 10004760 
-> [ 688.000000] (9:node@c-8.me)  6518840  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 688.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 688.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 699.000000] (10:node@c-9.me) My finger table:
-> [ 699.000000] (10:node@c-9.me) Start | Succ 
-> [ 699.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 699.000000] (10:node@c-9.me)  2015255  | 6518808 
-> [ 699.000000] (10:node@c-9.me)  2015257  | 6518808 
-> [ 699.000000] (10:node@c-9.me)  2015261  | 6518808 
-> [ 699.000000] (10:node@c-9.me)  2015269  | 6518808 
-> [ 699.000000] (10:node@c-9.me)  2015285  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 699.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 699.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 733.000000] (6:node@c-5.me) My finger table:
-> [ 733.000000] (6:node@c-5.me) Start | Succ 
-> [ 733.000000] (6:node@c-5.me)  10874877  | 16509405 
-> [ 733.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 733.000000] (6:node@c-5.me)  10874880  | 533744 
-> [ 733.000000] (6:node@c-5.me)  10874884  | 533744 
-> [ 733.000000] (6:node@c-5.me)  10874892  | 16728096 
-> [ 733.000000] (6:node@c-5.me)  10874908  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 733.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 733.000000] (6:node@c-5.me) Predecessor: 10004760
-> [ 735.000000] (1:node@c-0.me) My finger table:
-> [ 735.000000] (1:node@c-0.me) Start | Succ 
-> [ 735.000000] (1:node@c-0.me)   43  | 366680 
-> [ 735.000000] (1:node@c-0.me)   44  | 366680 
-> [ 735.000000] (1:node@c-0.me)   46  | 366680 
-> [ 735.000000] (1:node@c-0.me)   50  | 366680 
-> [ 735.000000] (1:node@c-0.me)   58  | 366680 
-> [ 735.000000] (1:node@c-0.me)   74  | 366680 
-> [ 735.000000] (1:node@c-0.me)  106  |  42 
-> [ 735.000000] (1:node@c-0.me)  170  |  42 
-> [ 735.000000] (1:node@c-0.me)  298  |  42 
-> [ 735.000000] (1:node@c-0.me)  554  |  42 
-> [ 735.000000] (1:node@c-0.me)  1066  |  42 
-> [ 735.000000] (1:node@c-0.me)  2090  |  42 
-> [ 735.000000] (1:node@c-0.me)  4138  |  42 
-> [ 735.000000] (1:node@c-0.me)  8234  |  42 
-> [ 735.000000] (1:node@c-0.me)  16426  |  42 
-> [ 735.000000] (1:node@c-0.me)  32810  |  42 
-> [ 735.000000] (1:node@c-0.me)  65578  |  42 
-> [ 735.000000] (1:node@c-0.me)  131114  |  42 
-> [ 735.000000] (1:node@c-0.me)  262186  |  42 
-> [ 735.000000] (1:node@c-0.me)  524330  |  42 
-> [ 735.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 735.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 735.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 735.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 735.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 743.000000] (3:node@c-2.me) My finger table:
-> [ 743.000000] (3:node@c-2.me) Start | Succ 
-> [ 743.000000] (3:node@c-2.me)  533745  | 1319738 
-> [ 743.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 743.000000] (3:node@c-2.me)  533748  | 10004760 
-> [ 743.000000] (3:node@c-2.me)  533752  | 1319738 
-> [ 743.000000] (3:node@c-2.me)  533760  | 1319738 
-> [ 743.000000] (3:node@c-2.me)  533776  | 1319738 
-> [ 743.000000] (3:node@c-2.me)  533808  | 533744 
-> [ 743.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 743.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 743.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 743.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 743.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 743.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 743.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 743.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 743.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 743.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 743.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 743.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 743.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 743.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 743.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 743.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 743.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 743.000000] (3:node@c-2.me) Predecessor: 366680
-> [ 752.000000] (5:node@c-4.me) My finger table:
-> [ 752.000000] (5:node@c-4.me) Start | Succ 
-> [ 752.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 752.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 752.000000] (5:node@c-4.me)  16509409  | 16728096 
-> [ 752.000000] (5:node@c-4.me)  16509413  | 16728096 
-> [ 752.000000] (5:node@c-4.me)  16509421  | 16728096 
-> [ 752.000000] (5:node@c-4.me)  16509437  | 16728096 
-> [ 752.000000] (5:node@c-4.me)  16509469  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 752.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 752.000000] (5:node@c-4.me) Predecessor: 10874876
-> [ 753.000000] (6:node@c-5.me) My finger table:
-> [ 753.000000] (6:node@c-5.me) Start | Succ 
-> [ 753.000000] (6:node@c-5.me)  10874877  | 16509405 
-> [ 753.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 753.000000] (6:node@c-5.me)  10874880  | 533744 
-> [ 753.000000] (6:node@c-5.me)  10874884  | 533744 
-> [ 753.000000] (6:node@c-5.me)  10874892  | 16728096 
-> [ 753.000000] (6:node@c-5.me)  10874908  | 16509405 
-> [ 753.000000] (6:node@c-5.me)  10874940  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 753.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 753.000000] (6:node@c-5.me) Predecessor: 10004760
-> [ 765.000000] (8:node@c-7.me) My finger table:
-> [ 765.000000] (8:node@c-7.me) Start | Succ 
-> [ 765.000000] (8:node@c-7.me)  10004761  | 10874876 
-> [ 765.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 765.000000] (8:node@c-7.me)  10004764  | 16509405 
-> [ 765.000000] (8:node@c-7.me)  10004768  | 16509405 
-> [ 765.000000] (8:node@c-7.me)  10004776  | 16509405 
-> [ 765.000000] (8:node@c-7.me)  10004792  | 10874876 
-> [ 765.000000] (8:node@c-7.me)  10004824  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 765.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 765.000000] (8:node@c-7.me) Predecessor: 6518808
-> [ 774.000000] (7:node@c-6.me) My finger table:
-> [ 774.000000] (7:node@c-6.me) Start | Succ 
-> [ 774.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 774.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 774.000000] (7:node@c-6.me)  16728100  |  42 
-> [ 774.000000] (7:node@c-6.me)  16728104  |  42 
-> [ 774.000000] (7:node@c-6.me)  16728112  |  42 
-> [ 774.000000] (7:node@c-6.me)  16728128  |  42 
-> [ 774.000000] (7:node@c-6.me)  16728160  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 774.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 774.000000] (7:node@c-6.me) Predecessor: 16509405
-> [ 796.000000] (2:node@c-1.me) My finger table:
-> [ 796.000000] (2:node@c-1.me) Start | Succ 
-> [ 796.000000] (2:node@c-1.me)  366681  | 533744 
-> [ 796.000000] (2:node@c-1.me)  366682  | 1319738 
-> [ 796.000000] (2:node@c-1.me)  366684  | 1319738 
-> [ 796.000000] (2:node@c-1.me)  366688  | 533744 
-> [ 796.000000] (2:node@c-1.me)  366696  | 533744 
-> [ 796.000000] (2:node@c-1.me)  366712  | 533744 
-> [ 796.000000] (2:node@c-1.me)  366744  | 366680 
-> [ 796.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 796.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 796.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 796.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 796.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 796.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 796.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 796.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 796.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 796.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 796.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 796.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 796.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 796.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 796.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 796.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 796.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 796.000000] (2:node@c-1.me) Predecessor: 42
-> [ 808.000000] (9:node@c-8.me) My finger table:
-> [ 808.000000] (9:node@c-8.me) Start | Succ 
-> [ 808.000000] (9:node@c-8.me)  6518809  | 10004760 
-> [ 808.000000] (9:node@c-8.me)  6518810  | 16728096 
-> [ 808.000000] (9:node@c-8.me)  6518812  | 10004760 
-> [ 808.000000] (9:node@c-8.me)  6518816  | 10004760 
-> [ 808.000000] (9:node@c-8.me)  6518824  | 10004760 
-> [ 808.000000] (9:node@c-8.me)  6518840  | 10004760 
-> [ 808.000000] (9:node@c-8.me)  6518872  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 808.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 808.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 810.000000] (4:node@c-3.me) My finger table:
-> [ 810.000000] (4:node@c-3.me) Start | Succ 
-> [ 810.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 810.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 810.000000] (4:node@c-3.me)  1319742  | 2015253 
-> [ 810.000000] (4:node@c-3.me)  1319746  | 2015253 
-> [ 810.000000] (4:node@c-3.me)  1319754  | 2015253 
-> [ 810.000000] (4:node@c-3.me)  1319770  | 2015253 
-> [ 810.000000] (4:node@c-3.me)  1319802  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 810.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 810.000000] (4:node@c-3.me) Predecessor: 533744
-> [ 831.000000] (10:node@c-9.me) My finger table:
-> [ 831.000000] (10:node@c-9.me) Start | Succ 
-> [ 831.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 831.000000] (10:node@c-9.me)  2015255  | 6518808 
-> [ 831.000000] (10:node@c-9.me)  2015257  | 6518808 
-> [ 831.000000] (10:node@c-9.me)  2015261  | 6518808 
-> [ 831.000000] (10:node@c-9.me)  2015269  | 6518808 
-> [ 831.000000] (10:node@c-9.me)  2015285  | 6518808 
-> [ 831.000000] (10:node@c-9.me)  2015317  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 831.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 831.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 859.000000] (1:node@c-0.me) My finger table:
-> [ 859.000000] (1:node@c-0.me) Start | Succ 
-> [ 859.000000] (1:node@c-0.me)   43  | 366680 
-> [ 859.000000] (1:node@c-0.me)   44  | 366680 
-> [ 859.000000] (1:node@c-0.me)   46  | 366680 
-> [ 859.000000] (1:node@c-0.me)   50  | 366680 
-> [ 859.000000] (1:node@c-0.me)   58  | 366680 
-> [ 859.000000] (1:node@c-0.me)   74  | 366680 
-> [ 859.000000] (1:node@c-0.me)  106  | 366680 
-> [ 859.000000] (1:node@c-0.me)  170  |  42 
-> [ 859.000000] (1:node@c-0.me)  298  |  42 
-> [ 859.000000] (1:node@c-0.me)  554  |  42 
-> [ 859.000000] (1:node@c-0.me)  1066  |  42 
-> [ 859.000000] (1:node@c-0.me)  2090  |  42 
-> [ 859.000000] (1:node@c-0.me)  4138  |  42 
-> [ 859.000000] (1:node@c-0.me)  8234  |  42 
-> [ 859.000000] (1:node@c-0.me)  16426  |  42 
-> [ 859.000000] (1:node@c-0.me)  32810  |  42 
-> [ 859.000000] (1:node@c-0.me)  65578  |  42 
-> [ 859.000000] (1:node@c-0.me)  131114  |  42 
-> [ 859.000000] (1:node@c-0.me)  262186  |  42 
-> [ 859.000000] (1:node@c-0.me)  524330  |  42 
-> [ 859.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 859.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 859.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 859.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 859.000000] (1:node@c-0.me) Predecessor: 16728096
-> [ 873.000000] (5:node@c-4.me) My finger table:
-> [ 873.000000] (5:node@c-4.me) Start | Succ 
-> [ 873.000000] (5:node@c-4.me)  16509406  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509407  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509409  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509413  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509421  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509437  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509469  | 16728096 
-> [ 873.000000] (5:node@c-4.me)  16509533  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16509661  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16509917  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16510429  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16511453  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16513501  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16517597  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16525789  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16542173  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16574941  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16640477  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  16771549  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  256477  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  780765  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  1829341  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  3926493  | 16509405 
-> [ 873.000000] (5:node@c-4.me)  8120797  | 16509405 
-> [ 873.000000] (5:node@c-4.me) Predecessor: 10874876
-> [ 893.000000] (3:node@c-2.me) My finger table:
-> [ 893.000000] (3:node@c-2.me) Start | Succ 
-> [ 893.000000] (3:node@c-2.me)  533745  | 1319738 
-> [ 893.000000] (3:node@c-2.me)  533746  | 10004760 
-> [ 893.000000] (3:node@c-2.me)  533748  | 10004760 
-> [ 893.000000] (3:node@c-2.me)  533752  | 1319738 
-> [ 893.000000] (3:node@c-2.me)  533760  | 1319738 
-> [ 893.000000] (3:node@c-2.me)  533776  | 1319738 
-> [ 893.000000] (3:node@c-2.me)  533808  | 1319738 
-> [ 893.000000] (3:node@c-2.me)  533872  | 533744 
-> [ 893.000000] (3:node@c-2.me)  534000  | 533744 
-> [ 893.000000] (3:node@c-2.me)  534256  | 533744 
-> [ 893.000000] (3:node@c-2.me)  534768  | 533744 
-> [ 893.000000] (3:node@c-2.me)  535792  | 533744 
-> [ 893.000000] (3:node@c-2.me)  537840  | 533744 
-> [ 893.000000] (3:node@c-2.me)  541936  | 533744 
-> [ 893.000000] (3:node@c-2.me)  550128  | 533744 
-> [ 893.000000] (3:node@c-2.me)  566512  | 533744 
-> [ 893.000000] (3:node@c-2.me)  599280  | 533744 
-> [ 893.000000] (3:node@c-2.me)  664816  | 533744 
-> [ 893.000000] (3:node@c-2.me)  795888  | 533744 
-> [ 893.000000] (3:node@c-2.me)  1058032  | 533744 
-> [ 893.000000] (3:node@c-2.me)  1582320  | 533744 
-> [ 893.000000] (3:node@c-2.me)  2630896  | 533744 
-> [ 893.000000] (3:node@c-2.me)  4728048  | 533744 
-> [ 893.000000] (3:node@c-2.me)  8922352  | 533744 
-> [ 893.000000] (3:node@c-2.me) Predecessor: 366680
-> [ 896.000000] (7:node@c-6.me) My finger table:
-> [ 896.000000] (7:node@c-6.me) Start | Succ 
-> [ 896.000000] (7:node@c-6.me)  16728097  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728098  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728100  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728104  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728112  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728128  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728160  |  42 
-> [ 896.000000] (7:node@c-6.me)  16728224  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16728352  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16728608  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16729120  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16730144  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16732192  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16736288  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16744480  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16760864  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  16416  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  81952  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  213024  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  475168  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  999456  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  2048032  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  4145184  | 16728096 
-> [ 896.000000] (7:node@c-6.me)  8339488  | 16728096 
-> [ 896.000000] (7:node@c-6.me) Predecessor: 16509405
-> [ 899.000000] (6:node@c-5.me) My finger table:
-> [ 899.000000] (6:node@c-5.me) Start | Succ 
-> [ 899.000000] (6:node@c-5.me)  10874877  | 16509405 
-> [ 899.000000] (6:node@c-5.me)  10874878  | 533744 
-> [ 899.000000] (6:node@c-5.me)  10874880  | 533744 
-> [ 899.000000] (6:node@c-5.me)  10874884  | 533744 
-> [ 899.000000] (6:node@c-5.me)  10874892  | 16728096 
-> [ 899.000000] (6:node@c-5.me)  10874908  | 16509405 
-> [ 899.000000] (6:node@c-5.me)  10874940  | 16509405 
-> [ 899.000000] (6:node@c-5.me)  10875004  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10875132  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10875388  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10875900  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10876924  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10878972  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10883068  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10891260  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10907644  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  10940412  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  11005948  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  11137020  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  11399164  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  11923452  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  12972028  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  15069180  | 10874876 
-> [ 899.000000] (6:node@c-5.me)  2486268  | 10874876 
-> [ 899.000000] (6:node@c-5.me) Predecessor: 10004760
-> [ 899.000000] (8:node@c-7.me) My finger table:
-> [ 899.000000] (8:node@c-7.me) Start | Succ 
-> [ 899.000000] (8:node@c-7.me)  10004761  | 10874876 
-> [ 899.000000] (8:node@c-7.me)  10004762  | 16509405 
-> [ 899.000000] (8:node@c-7.me)  10004764  | 16509405 
-> [ 899.000000] (8:node@c-7.me)  10004768  | 16509405 
-> [ 899.000000] (8:node@c-7.me)  10004776  | 16509405 
-> [ 899.000000] (8:node@c-7.me)  10004792  | 10874876 
-> [ 899.000000] (8:node@c-7.me)  10004824  | 10874876 
-> [ 899.000000] (8:node@c-7.me)  10004888  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10005016  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10005272  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10005784  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10006808  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10008856  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10012952  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10021144  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10037528  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10070296  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10135832  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10266904  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  10529048  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  11053336  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  12101912  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  14199064  | 10004760 
-> [ 899.000000] (8:node@c-7.me)  1616152  | 10004760 
-> [ 899.000000] (8:node@c-7.me) Predecessor: 6518808
-> [ 921.000000] (2:node@c-1.me) My finger table:
-> [ 921.000000] (2:node@c-1.me) Start | Succ 
-> [ 921.000000] (2:node@c-1.me)  366681  | 533744 
-> [ 921.000000] (2:node@c-1.me)  366682  | 1319738 
-> [ 921.000000] (2:node@c-1.me)  366684  | 1319738 
-> [ 921.000000] (2:node@c-1.me)  366688  | 533744 
-> [ 921.000000] (2:node@c-1.me)  366696  | 533744 
-> [ 921.000000] (2:node@c-1.me)  366712  | 533744 
-> [ 921.000000] (2:node@c-1.me)  366744  | 533744 
-> [ 921.000000] (2:node@c-1.me)  366808  | 366680 
-> [ 921.000000] (2:node@c-1.me)  366936  | 366680 
-> [ 921.000000] (2:node@c-1.me)  367192  | 366680 
-> [ 921.000000] (2:node@c-1.me)  367704  | 366680 
-> [ 921.000000] (2:node@c-1.me)  368728  | 366680 
-> [ 921.000000] (2:node@c-1.me)  370776  | 366680 
-> [ 921.000000] (2:node@c-1.me)  374872  | 366680 
-> [ 921.000000] (2:node@c-1.me)  383064  | 366680 
-> [ 921.000000] (2:node@c-1.me)  399448  | 366680 
-> [ 921.000000] (2:node@c-1.me)  432216  | 366680 
-> [ 921.000000] (2:node@c-1.me)  497752  | 366680 
-> [ 921.000000] (2:node@c-1.me)  628824  | 366680 
-> [ 921.000000] (2:node@c-1.me)  890968  | 366680 
-> [ 921.000000] (2:node@c-1.me)  1415256  | 366680 
-> [ 921.000000] (2:node@c-1.me)  2463832  | 366680 
-> [ 921.000000] (2:node@c-1.me)  4560984  | 366680 
-> [ 921.000000] (2:node@c-1.me)  8755288  | 366680 
-> [ 921.000000] (2:node@c-1.me) Predecessor: 42
-> [ 928.000000] (9:node@c-8.me) My finger table:
-> [ 928.000000] (9:node@c-8.me) Start | Succ 
-> [ 928.000000] (9:node@c-8.me)  6518809  | 10004760 
-> [ 928.000000] (9:node@c-8.me)  6518810  | 16728096 
-> [ 928.000000] (9:node@c-8.me)  6518812  | 10004760 
-> [ 928.000000] (9:node@c-8.me)  6518816  | 10004760 
-> [ 928.000000] (9:node@c-8.me)  6518824  | 10004760 
-> [ 928.000000] (9:node@c-8.me)  6518840  | 10004760 
-> [ 928.000000] (9:node@c-8.me)  6518872  | 10004760 
-> [ 928.000000] (9:node@c-8.me)  6518936  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6519064  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6519320  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6519832  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6520856  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6522904  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6527000  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6535192  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6551576  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6584344  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6649880  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  6780952  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  7043096  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  7567384  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  8615960  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  10713112  | 6518808 
-> [ 928.000000] (9:node@c-8.me)  14907416  | 6518808 
-> [ 928.000000] (9:node@c-8.me) Predecessor: 2015253
-> [ 930.000000] (4:node@c-3.me) My finger table:
-> [ 930.000000] (4:node@c-3.me) Start | Succ 
-> [ 930.000000] (4:node@c-3.me)  1319739  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319740  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319742  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319746  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319754  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319770  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319802  | 2015253 
-> [ 930.000000] (4:node@c-3.me)  1319866  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1319994  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1320250  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1320762  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1321786  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1323834  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1327930  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1336122  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1352506  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1385274  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1450810  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1581882  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  1844026  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  2368314  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  3416890  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  5514042  | 1319738 
-> [ 930.000000] (4:node@c-3.me)  9708346  | 1319738 
-> [ 930.000000] (4:node@c-3.me) Predecessor: 533744
-> [ 962.000000] (10:node@c-9.me) My finger table:
-> [ 962.000000] (10:node@c-9.me) Start | Succ 
-> [ 962.000000] (10:node@c-9.me)  2015254  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015255  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015257  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015261  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015269  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015285  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015317  | 6518808 
-> [ 962.000000] (10:node@c-9.me)  2015381  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2015509  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2015765  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2016277  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2017301  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2019349  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2023445  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2031637  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2048021  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2080789  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2146325  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2277397  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  2539541  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  3063829  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  4112405  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  6209557  | 2015253 
-> [ 962.000000] (10:node@c-9.me)  10403861  | 2015253 
-> [ 962.000000] (10:node@c-9.me) Predecessor: 1319738
-> [ 982.000000] (1:node@c-0.me) My finger table:
-> [ 982.000000] (1:node@c-0.me) Start | Succ 
-> [ 982.000000] (1:node@c-0.me)   43  | 366680 
-> [ 982.000000] (1:node@c-0.me)   44  | 366680 
-> [ 982.000000] (1:node@c-0.me)   46  | 366680 
-> [ 982.000000] (1:node@c-0.me)   50  | 366680 
-> [ 982.000000] (1:node@c-0.me)   58  | 366680 
-> [ 982.000000] (1:node@c-0.me)   74  | 366680 
-> [ 982.000000] (1:node@c-0.me)  106  | 366680 
-> [ 982.000000] (1:node@c-0.me)  170  | 366680 
-> [ 982.000000] (1:node@c-0.me)  298  |  42 
-> [ 982.000000] (1:node@c-0.me)  554  |  42 
-> [ 982.000000] (1:node@c-0.me)  1066  |  42 
-> [ 982.000000] (1:node@c-0.me)  2090  |  42 
-> [ 982.000000] (1:node@c-0.me)  4138  |  42 
-> [ 982.000000] (1:node@c-0.me)  8234  |  42 
-> [ 982.000000] (1:node@c-0.me)  16426  |  42 
-> [ 982.000000] (1:node@c-0.me)  32810  |  42 
-> [ 982.000000] (1:node@c-0.me)  65578  |  42 
-> [ 982.000000] (1:node@c-0.me)  131114  |  42 
-> [ 982.000000] (1:node@c-0.me)  262186  |  42 
-> [ 982.000000] (1:node@c-0.me)  524330  |  42 
-> [ 982.000000] (1:node@c-0.me)  1048618  |  42 
-> [ 982.000000] (1:node@c-0.me)  2097194  |  42 
-> [ 982.000000] (1:node@c-0.me)  4194346  |  42 
-> [ 982.000000] (1:node@c-0.me)  8388650  |  42 
-> [ 982.000000] (1:node@c-0.me) Predecessor: 16728096
+> [   0.000000] (10:node@node-9.acme.org) Joining the ring with id 2015253, knowing node 1319738
+> [   0.000000] (1:node@node-0.acme.org) My finger table:
+> [   0.000000] (1:node@node-0.acme.org) Start | Succ 
+> [   0.000000] (1:node@node-0.acme.org)   43  |  42 
+> [   0.000000] (1:node@node-0.acme.org)   44  |  42 
+> [   0.000000] (1:node@node-0.acme.org)   46  |  42 
+> [   0.000000] (1:node@node-0.acme.org)   50  |  42 
+> [   0.000000] (1:node@node-0.acme.org)   58  |  42 
+> [   0.000000] (1:node@node-0.acme.org)   74  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  106  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  170  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  298  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  554  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [   0.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [   0.000000] (1:node@node-0.acme.org) Predecessor: -1
+> [   0.000000] (2:node@node-1.acme.org) Joining the ring with id 366680, knowing node 42
+> [   0.000000] (3:node@node-2.acme.org) Joining the ring with id 533744, knowing node 366680
+> [   0.000000] (4:node@node-3.acme.org) Joining the ring with id 1319738, knowing node 42
+> [   0.000000] (5:node@node-4.acme.org) Joining the ring with id 16509405, knowing node 366680
+> [   0.000000] (6:node@node-5.acme.org) Joining the ring with id 10874876, knowing node 533744
+> [   0.000000] (7:node@node-6.acme.org) Joining the ring with id 16728096, knowing node 1319738
+> [   0.000000] (8:node@node-7.acme.org) Joining the ring with id 10004760, knowing node 16509405
+> [   0.000000] (9:node@node-8.acme.org) Joining the ring with id 6518808, knowing node 42
+> [   4.000000] (3:node@node-2.acme.org) My finger table:
+> [   4.000000] (3:node@node-2.acme.org) Start | Succ 
+> [   4.000000] (3:node@node-2.acme.org)  533745  | 366680 
+> [   4.000000] (3:node@node-2.acme.org)  533746  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  533748  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  533752  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  533760  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [   4.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [   4.000000] (3:node@node-2.acme.org) Predecessor: -1
+> [   4.000000] (6:node@node-5.acme.org) My finger table:
+> [   4.000000] (6:node@node-5.acme.org) Start | Succ 
+> [   4.000000] (6:node@node-5.acme.org)  10874877  | 533744 
+> [   4.000000] (6:node@node-5.acme.org)  10874878  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10874880  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10874884  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10874892  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10874908  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [   4.000000] (6:node@node-5.acme.org) Predecessor: -1
+> [   5.000000] (5:node@node-4.acme.org) My finger table:
+> [   5.000000] (5:node@node-4.acme.org) Start | Succ 
+> [   5.000000] (5:node@node-4.acme.org)  16509406  | 366680 
+> [   5.000000] (5:node@node-4.acme.org)  16509407  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509409  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509413  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509421  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [   5.000000] (5:node@node-4.acme.org) Predecessor: -1
+> [   5.000000] (8:node@node-7.acme.org) My finger table:
+> [   5.000000] (8:node@node-7.acme.org) Start | Succ 
+> [   5.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [   5.000000] (8:node@node-7.acme.org)  10004762  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10004764  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10004768  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10004776  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [   5.000000] (8:node@node-7.acme.org) Predecessor: -1
+> [   6.000000] (2:node@node-1.acme.org) My finger table:
+> [   6.000000] (2:node@node-1.acme.org) Start | Succ 
+> [   6.000000] (2:node@node-1.acme.org)  366681  |  42 
+> [   6.000000] (2:node@node-1.acme.org)  366682  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366684  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366688  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366696  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [   6.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [   6.000000] (2:node@node-1.acme.org) Predecessor: -1
+> [   8.000000] (7:node@node-6.acme.org) My finger table:
+> [   8.000000] (7:node@node-6.acme.org) Start | Succ 
+> [   8.000000] (7:node@node-6.acme.org)  16728097  | 1319738 
+> [   8.000000] (7:node@node-6.acme.org)  16728098  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728100  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728104  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [   8.000000] (7:node@node-6.acme.org) Predecessor: -1
+> [   9.000000] (10:node@node-9.acme.org) My finger table:
+> [   9.000000] (10:node@node-9.acme.org) Start | Succ 
+> [   9.000000] (10:node@node-9.acme.org)  2015254  | 1319738 
+> [   9.000000] (10:node@node-9.acme.org)  2015255  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015257  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015261  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015269  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015285  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [   9.000000] (10:node@node-9.acme.org) Predecessor: -1
+> [  11.000000] (4:node@node-3.acme.org) My finger table:
+> [  11.000000] (4:node@node-3.acme.org) Start | Succ 
+> [  11.000000] (4:node@node-3.acme.org)  1319739  |  42 
+> [  11.000000] (4:node@node-3.acme.org)  1319740  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319742  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [  11.000000] (4:node@node-3.acme.org) Predecessor: -1
+> [  16.000000] (9:node@node-8.acme.org) My finger table:
+> [  16.000000] (9:node@node-8.acme.org) Start | Succ 
+> [  16.000000] (9:node@node-8.acme.org)  6518809  |  42 
+> [  16.000000] (9:node@node-8.acme.org)  6518810  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6518812  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6518816  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [  16.000000] (9:node@node-8.acme.org) Predecessor: -1
+> [  26.000000] (4:node@node-3.acme.org) My finger table:
+> [  26.000000] (4:node@node-3.acme.org) Start | Succ 
+> [  26.000000] (4:node@node-3.acme.org)  1319739  |  42 
+> [  26.000000] (4:node@node-3.acme.org)  1319740  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319742  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [  26.000000] (4:node@node-3.acme.org) Predecessor: 16728096
+> [  31.000000] (2:node@node-1.acme.org) My finger table:
+> [  31.000000] (2:node@node-1.acme.org) Start | Succ 
+> [  31.000000] (2:node@node-1.acme.org)  366681  |  42 
+> [  31.000000] (2:node@node-1.acme.org)  366682  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366684  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366688  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366696  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [  31.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [  31.000000] (2:node@node-1.acme.org) Predecessor: 16509405
+> [  32.000000] (5:node@node-4.acme.org) My finger table:
+> [  32.000000] (5:node@node-4.acme.org) Start | Succ 
+> [  32.000000] (5:node@node-4.acme.org)  16509406  | 366680 
+> [  32.000000] (5:node@node-4.acme.org)  16509407  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509409  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509413  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509421  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [  32.000000] (5:node@node-4.acme.org) Predecessor: 10004760
+> [  38.000000] (3:node@node-2.acme.org) My finger table:
+> [  38.000000] (3:node@node-2.acme.org) Start | Succ 
+> [  38.000000] (3:node@node-2.acme.org)  533745  | 16509405 
+> [  38.000000] (3:node@node-2.acme.org)  533746  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  533748  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  533752  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  533760  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [  38.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [  38.000000] (3:node@node-2.acme.org) Predecessor: 10874876
+> [  50.000000] (1:node@node-0.acme.org) My finger table:
+> [  50.000000] (1:node@node-0.acme.org) Start | Succ 
+> [  50.000000] (1:node@node-0.acme.org)   43  |  42 
+> [  50.000000] (1:node@node-0.acme.org)   44  |  42 
+> [  50.000000] (1:node@node-0.acme.org)   46  |  42 
+> [  50.000000] (1:node@node-0.acme.org)   50  |  42 
+> [  50.000000] (1:node@node-0.acme.org)   58  |  42 
+> [  50.000000] (1:node@node-0.acme.org)   74  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  106  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  170  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  298  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  554  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [  50.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [  50.000000] (1:node@node-0.acme.org) Predecessor: 366680
+> [  60.000000] (1:node@node-0.acme.org) My finger table:
+> [  60.000000] (1:node@node-0.acme.org) Start | Succ 
+> [  60.000000] (1:node@node-0.acme.org)   43  |  42 
+> [  60.000000] (1:node@node-0.acme.org)   44  |  42 
+> [  60.000000] (1:node@node-0.acme.org)   46  |  42 
+> [  60.000000] (1:node@node-0.acme.org)   50  |  42 
+> [  60.000000] (1:node@node-0.acme.org)   58  |  42 
+> [  60.000000] (1:node@node-0.acme.org)   74  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  106  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  170  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  298  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  554  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [  60.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [  60.000000] (1:node@node-0.acme.org) Predecessor: 1319738
+> [  70.000000] (1:node@node-0.acme.org) My finger table:
+> [  70.000000] (1:node@node-0.acme.org) Start | Succ 
+> [  70.000000] (1:node@node-0.acme.org)   43  | 1319738 
+> [  70.000000] (1:node@node-0.acme.org)   44  |  42 
+> [  70.000000] (1:node@node-0.acme.org)   46  |  42 
+> [  70.000000] (1:node@node-0.acme.org)   50  |  42 
+> [  70.000000] (1:node@node-0.acme.org)   58  |  42 
+> [  70.000000] (1:node@node-0.acme.org)   74  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  106  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  170  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  298  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  554  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [  70.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [  70.000000] (1:node@node-0.acme.org) Predecessor: 6518808
+> [  85.000000] (4:node@node-3.acme.org) My finger table:
+> [  85.000000] (4:node@node-3.acme.org) Start | Succ 
+> [  85.000000] (4:node@node-3.acme.org)  1319739  | 6518808 
+> [  85.000000] (4:node@node-3.acme.org)  1319740  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319742  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [  85.000000] (4:node@node-3.acme.org) Predecessor: 42
+> [  86.000000] (8:node@node-7.acme.org) My finger table:
+> [  86.000000] (8:node@node-7.acme.org) Start | Succ 
+> [  86.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [  86.000000] (8:node@node-7.acme.org)  10004762  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10004764  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10004768  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10004776  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [  86.000000] (8:node@node-7.acme.org) Predecessor: 533744
+> [  90.000000] (7:node@node-6.acme.org) My finger table:
+> [  90.000000] (7:node@node-6.acme.org) Start | Succ 
+> [  90.000000] (7:node@node-6.acme.org)  16728097  | 1319738 
+> [  90.000000] (7:node@node-6.acme.org)  16728098  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728100  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728104  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [  90.000000] (7:node@node-6.acme.org) Predecessor: 2015253
+> [ 109.000000] (9:node@node-8.acme.org) My finger table:
+> [ 109.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 109.000000] (9:node@node-8.acme.org)  6518809  |  42 
+> [ 109.000000] (9:node@node-8.acme.org)  6518810  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6518812  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6518816  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 109.000000] (9:node@node-8.acme.org) Predecessor: 366680
+> [ 110.000000] (9:node@node-8.acme.org) My finger table:
+> [ 110.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 110.000000] (9:node@node-8.acme.org)  6518809  |  42 
+> [ 110.000000] (9:node@node-8.acme.org)  6518810  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6518812  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6518816  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 110.000000] (9:node@node-8.acme.org) Predecessor: 1319738
+> [ 145.000000] (1:node@node-0.acme.org) My finger table:
+> [ 145.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 145.000000] (1:node@node-0.acme.org)   43  | 1319738 
+> [ 145.000000] (1:node@node-0.acme.org)   44  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)   46  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)   50  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)   58  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)   74  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  106  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 145.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 145.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 157.000000] (4:node@node-3.acme.org) My finger table:
+> [ 157.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 157.000000] (4:node@node-3.acme.org)  1319739  | 6518808 
+> [ 157.000000] (4:node@node-3.acme.org)  1319740  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319742  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 157.000000] (4:node@node-3.acme.org) Predecessor: 366680
+> [ 184.000000] (7:node@node-6.acme.org) My finger table:
+> [ 184.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 184.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 184.000000] (7:node@node-6.acme.org)  16728098  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728100  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728104  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 184.000000] (7:node@node-6.acme.org) Predecessor: 6518808
+> [ 202.000000] (2:node@node-1.acme.org) My finger table:
+> [ 202.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 202.000000] (2:node@node-1.acme.org)  366681  | 1319738 
+> [ 202.000000] (2:node@node-1.acme.org)  366682  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366684  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366688  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366696  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 202.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 221.000000] (9:node@node-8.acme.org) My finger table:
+> [ 221.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 221.000000] (9:node@node-8.acme.org)  6518809  | 16728096 
+> [ 221.000000] (9:node@node-8.acme.org)  6518810  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6518812  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6518816  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 221.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 240.000000] (6:node@node-5.acme.org) My finger table:
+> [ 240.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 240.000000] (6:node@node-5.acme.org)  10874877  | 533744 
+> [ 240.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 240.000000] (6:node@node-5.acme.org)  10874880  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10874884  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10874892  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10874908  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 240.000000] (6:node@node-5.acme.org) Predecessor: -1
+> [ 247.000000] (5:node@node-4.acme.org) My finger table:
+> [ 247.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 247.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 247.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 247.000000] (5:node@node-4.acme.org)  16509409  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509413  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509421  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 247.000000] (5:node@node-4.acme.org) Predecessor: 10004760
+> [ 250.000000] (1:node@node-0.acme.org) My finger table:
+> [ 250.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 250.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 250.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 250.000000] (1:node@node-0.acme.org)   46  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)   50  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)   58  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)   74  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  106  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 250.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 250.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 251.000000] (3:node@node-2.acme.org) My finger table:
+> [ 251.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 251.000000] (3:node@node-2.acme.org)  533745  | 10004760 
+> [ 251.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 251.000000] (3:node@node-2.acme.org)  533748  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  533752  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  533760  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 251.000000] (3:node@node-2.acme.org) Predecessor: 10874876
+> [ 253.000000] (8:node@node-7.acme.org) My finger table:
+> [ 253.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 253.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [ 253.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 253.000000] (8:node@node-7.acme.org)  10004764  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10004768  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10004776  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 253.000000] (8:node@node-7.acme.org) Predecessor: 533744
+> [ 263.000000] (2:node@node-1.acme.org) My finger table:
+> [ 263.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 263.000000] (2:node@node-1.acme.org)  366681  | 1319738 
+> [ 263.000000] (2:node@node-1.acme.org)  366682  | 1319738 
+> [ 263.000000] (2:node@node-1.acme.org)  366684  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  366688  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  366696  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 263.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 268.000000] (4:node@node-3.acme.org) My finger table:
+> [ 268.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 268.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 268.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 268.000000] (4:node@node-3.acme.org)  1319742  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 268.000000] (4:node@node-3.acme.org) Predecessor: 366680
+> [ 269.000000] (10:node@node-9.acme.org) My finger table:
+> [ 269.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 269.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 269.000000] (10:node@node-9.acme.org)  2015255  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015257  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015261  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015269  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015285  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 269.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 274.000000] (10:node@node-9.acme.org) My finger table:
+> [ 274.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 274.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 274.000000] (10:node@node-9.acme.org)  2015255  | 6518808 
+> [ 274.000000] (10:node@node-9.acme.org)  2015257  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015261  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015269  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015285  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 274.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 274.000000] (9:node@node-8.acme.org) My finger table:
+> [ 274.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 274.000000] (9:node@node-8.acme.org)  6518809  | 16728096 
+> [ 274.000000] (9:node@node-8.acme.org)  6518810  | 16728096 
+> [ 274.000000] (9:node@node-8.acme.org)  6518812  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6518816  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 274.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 275.000000] (7:node@node-6.acme.org) My finger table:
+> [ 275.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 275.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 275.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 275.000000] (7:node@node-6.acme.org)  16728100  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728104  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 275.000000] (7:node@node-6.acme.org) Predecessor: 6518808
+> [ 288.000000] (7:node@node-6.acme.org) My finger table:
+> [ 288.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 288.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 288.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 288.000000] (7:node@node-6.acme.org)  16728100  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728104  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 288.000000] (7:node@node-6.acme.org) Predecessor: 16509405
+> [ 361.000000] (8:node@node-7.acme.org) My finger table:
+> [ 361.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 361.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [ 361.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 361.000000] (8:node@node-7.acme.org)  10004764  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10004768  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10004776  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 361.000000] (8:node@node-7.acme.org) Predecessor: 6518808
+> [ 364.000000] (6:node@node-5.acme.org) My finger table:
+> [ 364.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 364.000000] (6:node@node-5.acme.org)  10874877  | 533744 
+> [ 364.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 364.000000] (6:node@node-5.acme.org)  10874880  | 533744 
+> [ 364.000000] (6:node@node-5.acme.org)  10874884  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10874892  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10874908  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 364.000000] (6:node@node-5.acme.org) Predecessor: -1
+> [ 371.000000] (3:node@node-2.acme.org) My finger table:
+> [ 371.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 371.000000] (3:node@node-2.acme.org)  533745  | 10004760 
+> [ 371.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 371.000000] (3:node@node-2.acme.org)  533748  | 10004760 
+> [ 371.000000] (3:node@node-2.acme.org)  533752  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  533760  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 371.000000] (3:node@node-2.acme.org) Predecessor: 10874876
+> [ 372.000000] (1:node@node-0.acme.org) My finger table:
+> [ 372.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 372.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 372.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 372.000000] (1:node@node-0.acme.org)   46  | 366680 
+> [ 372.000000] (1:node@node-0.acme.org)   50  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)   58  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)   74  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  106  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 372.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 372.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 374.000000] (8:node@node-7.acme.org) My finger table:
+> [ 374.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 374.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [ 374.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 374.000000] (8:node@node-7.acme.org)  10004764  | 16509405 
+> [ 374.000000] (8:node@node-7.acme.org)  10004768  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10004776  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 374.000000] (8:node@node-7.acme.org) Predecessor: 6518808
+> [ 375.000000] (5:node@node-4.acme.org) My finger table:
+> [ 375.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 375.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 375.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 375.000000] (5:node@node-4.acme.org)  16509409  | 16728096 
+> [ 375.000000] (5:node@node-4.acme.org)  16509413  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16509421  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 375.000000] (5:node@node-4.acme.org) Predecessor: 10004760
+> [ 395.000000] (9:node@node-8.acme.org) My finger table:
+> [ 395.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 395.000000] (9:node@node-8.acme.org)  6518809  | 10004760 
+> [ 395.000000] (9:node@node-8.acme.org)  6518810  | 16728096 
+> [ 395.000000] (9:node@node-8.acme.org)  6518812  | 10004760 
+> [ 395.000000] (9:node@node-8.acme.org)  6518816  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 395.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 398.000000] (7:node@node-6.acme.org) My finger table:
+> [ 398.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 398.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 398.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 398.000000] (7:node@node-6.acme.org)  16728100  |  42 
+> [ 398.000000] (7:node@node-6.acme.org)  16728104  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 398.000000] (7:node@node-6.acme.org) Predecessor: 16509405
+> [ 405.000000] (4:node@node-3.acme.org) My finger table:
+> [ 405.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 405.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 405.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 405.000000] (4:node@node-3.acme.org)  1319742  | 2015253 
+> [ 405.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 405.000000] (4:node@node-3.acme.org) Predecessor: 366680
+> [ 411.000000] (2:node@node-1.acme.org) My finger table:
+> [ 411.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 411.000000] (2:node@node-1.acme.org)  366681  | 1319738 
+> [ 411.000000] (2:node@node-1.acme.org)  366682  | 1319738 
+> [ 411.000000] (2:node@node-1.acme.org)  366684  | 1319738 
+> [ 411.000000] (2:node@node-1.acme.org)  366688  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  366696  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 411.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 426.000000] (10:node@node-9.acme.org) My finger table:
+> [ 426.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 426.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 426.000000] (10:node@node-9.acme.org)  2015255  | 6518808 
+> [ 426.000000] (10:node@node-9.acme.org)  2015257  | 6518808 
+> [ 426.000000] (10:node@node-9.acme.org)  2015261  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2015269  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2015285  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 426.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 486.000000] (6:node@node-5.acme.org) My finger table:
+> [ 486.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 486.000000] (6:node@node-5.acme.org)  10874877  | 533744 
+> [ 486.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 486.000000] (6:node@node-5.acme.org)  10874880  | 533744 
+> [ 486.000000] (6:node@node-5.acme.org)  10874884  | 533744 
+> [ 486.000000] (6:node@node-5.acme.org)  10874892  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10874908  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 486.000000] (6:node@node-5.acme.org) Predecessor: -1
+> [ 491.000000] (4:node@node-3.acme.org) My finger table:
+> [ 491.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 491.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 491.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 491.000000] (4:node@node-3.acme.org)  1319742  | 2015253 
+> [ 491.000000] (4:node@node-3.acme.org)  1319746  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 491.000000] (4:node@node-3.acme.org) Predecessor: 533744
+> [ 492.000000] (1:node@node-0.acme.org) My finger table:
+> [ 492.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 492.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 492.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 492.000000] (1:node@node-0.acme.org)   46  | 366680 
+> [ 492.000000] (1:node@node-0.acme.org)   50  | 366680 
+> [ 492.000000] (1:node@node-0.acme.org)   58  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)   74  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  106  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 492.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 492.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 495.000000] (3:node@node-2.acme.org) My finger table:
+> [ 495.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 495.000000] (3:node@node-2.acme.org)  533745  | 1319738 
+> [ 495.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 495.000000] (3:node@node-2.acme.org)  533748  | 10004760 
+> [ 495.000000] (3:node@node-2.acme.org)  533752  | 1319738 
+> [ 495.000000] (3:node@node-2.acme.org)  533760  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 495.000000] (3:node@node-2.acme.org) Predecessor: 10874876
+> [ 502.000000] (8:node@node-7.acme.org) My finger table:
+> [ 502.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 502.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [ 502.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 502.000000] (8:node@node-7.acme.org)  10004764  | 16509405 
+> [ 502.000000] (8:node@node-7.acme.org)  10004768  | 16509405 
+> [ 502.000000] (8:node@node-7.acme.org)  10004776  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 502.000000] (8:node@node-7.acme.org) Predecessor: 6518808
+> [ 505.000000] (5:node@node-4.acme.org) My finger table:
+> [ 505.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 505.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 505.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 505.000000] (5:node@node-4.acme.org)  16509409  | 16728096 
+> [ 505.000000] (5:node@node-4.acme.org)  16509413  | 16728096 
+> [ 505.000000] (5:node@node-4.acme.org)  16509421  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 505.000000] (5:node@node-4.acme.org) Predecessor: 10004760
+> [ 521.000000] (7:node@node-6.acme.org) My finger table:
+> [ 521.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 521.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 521.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 521.000000] (7:node@node-6.acme.org)  16728100  |  42 
+> [ 521.000000] (7:node@node-6.acme.org)  16728104  |  42 
+> [ 521.000000] (7:node@node-6.acme.org)  16728112  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 521.000000] (7:node@node-6.acme.org) Predecessor: 16509405
+> [ 535.000000] (9:node@node-8.acme.org) My finger table:
+> [ 535.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 535.000000] (9:node@node-8.acme.org)  6518809  | 10004760 
+> [ 535.000000] (9:node@node-8.acme.org)  6518810  | 16728096 
+> [ 535.000000] (9:node@node-8.acme.org)  6518812  | 10004760 
+> [ 535.000000] (9:node@node-8.acme.org)  6518816  | 10004760 
+> [ 535.000000] (9:node@node-8.acme.org)  6518824  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 535.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 537.000000] (4:node@node-3.acme.org) My finger table:
+> [ 537.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 537.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 537.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 537.000000] (4:node@node-3.acme.org)  1319742  | 2015253 
+> [ 537.000000] (4:node@node-3.acme.org)  1319746  | 2015253 
+> [ 537.000000] (4:node@node-3.acme.org)  1319754  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 537.000000] (4:node@node-3.acme.org) Predecessor: 533744
+> [ 539.000000] (2:node@node-1.acme.org) My finger table:
+> [ 539.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 539.000000] (2:node@node-1.acme.org)  366681  | 533744 
+> [ 539.000000] (2:node@node-1.acme.org)  366682  | 1319738 
+> [ 539.000000] (2:node@node-1.acme.org)  366684  | 1319738 
+> [ 539.000000] (2:node@node-1.acme.org)  366688  | 533744 
+> [ 539.000000] (2:node@node-1.acme.org)  366696  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 539.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 540.000000] (3:node@node-2.acme.org) My finger table:
+> [ 540.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 540.000000] (3:node@node-2.acme.org)  533745  | 1319738 
+> [ 540.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 540.000000] (3:node@node-2.acme.org)  533748  | 10004760 
+> [ 540.000000] (3:node@node-2.acme.org)  533752  | 1319738 
+> [ 540.000000] (3:node@node-2.acme.org)  533760  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 540.000000] (3:node@node-2.acme.org) Predecessor: 366680
+> [ 567.000000] (10:node@node-9.acme.org) My finger table:
+> [ 567.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 567.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 567.000000] (10:node@node-9.acme.org)  2015255  | 6518808 
+> [ 567.000000] (10:node@node-9.acme.org)  2015257  | 6518808 
+> [ 567.000000] (10:node@node-9.acme.org)  2015261  | 6518808 
+> [ 567.000000] (10:node@node-9.acme.org)  2015269  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2015285  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 567.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 613.000000] (1:node@node-0.acme.org) My finger table:
+> [ 613.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 613.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 613.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 613.000000] (1:node@node-0.acme.org)   46  | 366680 
+> [ 613.000000] (1:node@node-0.acme.org)   50  | 366680 
+> [ 613.000000] (1:node@node-0.acme.org)   58  | 366680 
+> [ 613.000000] (1:node@node-0.acme.org)   74  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  106  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 613.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 613.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 616.000000] (3:node@node-2.acme.org) My finger table:
+> [ 616.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 616.000000] (3:node@node-2.acme.org)  533745  | 1319738 
+> [ 616.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 616.000000] (3:node@node-2.acme.org)  533748  | 10004760 
+> [ 616.000000] (3:node@node-2.acme.org)  533752  | 1319738 
+> [ 616.000000] (3:node@node-2.acme.org)  533760  | 1319738 
+> [ 616.000000] (3:node@node-2.acme.org)  533776  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 616.000000] (3:node@node-2.acme.org) Predecessor: 366680
+> [ 620.000000] (6:node@node-5.acme.org) My finger table:
+> [ 620.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 620.000000] (6:node@node-5.acme.org)  10874877  | 16728096 
+> [ 620.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 620.000000] (6:node@node-5.acme.org)  10874880  | 533744 
+> [ 620.000000] (6:node@node-5.acme.org)  10874884  | 533744 
+> [ 620.000000] (6:node@node-5.acme.org)  10874892  | 16728096 
+> [ 620.000000] (6:node@node-5.acme.org)  10874908  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 620.000000] (6:node@node-5.acme.org) Predecessor: -1
+> [ 629.000000] (8:node@node-7.acme.org) My finger table:
+> [ 629.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 629.000000] (8:node@node-7.acme.org)  10004761  | 16509405 
+> [ 629.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 629.000000] (8:node@node-7.acme.org)  10004764  | 16509405 
+> [ 629.000000] (8:node@node-7.acme.org)  10004768  | 16509405 
+> [ 629.000000] (8:node@node-7.acme.org)  10004776  | 16509405 
+> [ 629.000000] (8:node@node-7.acme.org)  10004792  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 629.000000] (8:node@node-7.acme.org) Predecessor: 6518808
+> [ 630.000000] (5:node@node-4.acme.org) My finger table:
+> [ 630.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 630.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 630.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 630.000000] (5:node@node-4.acme.org)  16509409  | 16728096 
+> [ 630.000000] (5:node@node-4.acme.org)  16509413  | 16728096 
+> [ 630.000000] (5:node@node-4.acme.org)  16509421  | 16728096 
+> [ 630.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 630.000000] (5:node@node-4.acme.org) Predecessor: 10004760
+> [ 653.000000] (7:node@node-6.acme.org) My finger table:
+> [ 653.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 653.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 653.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 653.000000] (7:node@node-6.acme.org)  16728100  |  42 
+> [ 653.000000] (7:node@node-6.acme.org)  16728104  |  42 
+> [ 653.000000] (7:node@node-6.acme.org)  16728112  |  42 
+> [ 653.000000] (7:node@node-6.acme.org)  16728128  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 653.000000] (7:node@node-6.acme.org) Predecessor: 16509405
+> [ 663.000000] (2:node@node-1.acme.org) My finger table:
+> [ 663.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 663.000000] (2:node@node-1.acme.org)  366681  | 533744 
+> [ 663.000000] (2:node@node-1.acme.org)  366682  | 1319738 
+> [ 663.000000] (2:node@node-1.acme.org)  366684  | 1319738 
+> [ 663.000000] (2:node@node-1.acme.org)  366688  | 533744 
+> [ 663.000000] (2:node@node-1.acme.org)  366696  | 533744 
+> [ 663.000000] (2:node@node-1.acme.org)  366712  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 663.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 668.000000] (4:node@node-3.acme.org) My finger table:
+> [ 668.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 668.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 668.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 668.000000] (4:node@node-3.acme.org)  1319742  | 2015253 
+> [ 668.000000] (4:node@node-3.acme.org)  1319746  | 2015253 
+> [ 668.000000] (4:node@node-3.acme.org)  1319754  | 2015253 
+> [ 668.000000] (4:node@node-3.acme.org)  1319770  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 668.000000] (4:node@node-3.acme.org) Predecessor: 533744
+> [ 683.000000] (5:node@node-4.acme.org) My finger table:
+> [ 683.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 683.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 683.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 683.000000] (5:node@node-4.acme.org)  16509409  | 16728096 
+> [ 683.000000] (5:node@node-4.acme.org)  16509413  | 16728096 
+> [ 683.000000] (5:node@node-4.acme.org)  16509421  | 16728096 
+> [ 683.000000] (5:node@node-4.acme.org)  16509437  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 683.000000] (5:node@node-4.acme.org) Predecessor: 10874876
+> [ 688.000000] (9:node@node-8.acme.org) My finger table:
+> [ 688.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 688.000000] (9:node@node-8.acme.org)  6518809  | 10004760 
+> [ 688.000000] (9:node@node-8.acme.org)  6518810  | 16728096 
+> [ 688.000000] (9:node@node-8.acme.org)  6518812  | 10004760 
+> [ 688.000000] (9:node@node-8.acme.org)  6518816  | 10004760 
+> [ 688.000000] (9:node@node-8.acme.org)  6518824  | 10004760 
+> [ 688.000000] (9:node@node-8.acme.org)  6518840  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 688.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 699.000000] (10:node@node-9.acme.org) My finger table:
+> [ 699.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 699.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 699.000000] (10:node@node-9.acme.org)  2015255  | 6518808 
+> [ 699.000000] (10:node@node-9.acme.org)  2015257  | 6518808 
+> [ 699.000000] (10:node@node-9.acme.org)  2015261  | 6518808 
+> [ 699.000000] (10:node@node-9.acme.org)  2015269  | 6518808 
+> [ 699.000000] (10:node@node-9.acme.org)  2015285  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 699.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 733.000000] (6:node@node-5.acme.org) My finger table:
+> [ 733.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 733.000000] (6:node@node-5.acme.org)  10874877  | 16509405 
+> [ 733.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 733.000000] (6:node@node-5.acme.org)  10874880  | 533744 
+> [ 733.000000] (6:node@node-5.acme.org)  10874884  | 533744 
+> [ 733.000000] (6:node@node-5.acme.org)  10874892  | 16728096 
+> [ 733.000000] (6:node@node-5.acme.org)  10874908  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 733.000000] (6:node@node-5.acme.org) Predecessor: 10004760
+> [ 735.000000] (1:node@node-0.acme.org) My finger table:
+> [ 735.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 735.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 735.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 735.000000] (1:node@node-0.acme.org)   46  | 366680 
+> [ 735.000000] (1:node@node-0.acme.org)   50  | 366680 
+> [ 735.000000] (1:node@node-0.acme.org)   58  | 366680 
+> [ 735.000000] (1:node@node-0.acme.org)   74  | 366680 
+> [ 735.000000] (1:node@node-0.acme.org)  106  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 735.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 735.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 743.000000] (3:node@node-2.acme.org) My finger table:
+> [ 743.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 743.000000] (3:node@node-2.acme.org)  533745  | 1319738 
+> [ 743.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 743.000000] (3:node@node-2.acme.org)  533748  | 10004760 
+> [ 743.000000] (3:node@node-2.acme.org)  533752  | 1319738 
+> [ 743.000000] (3:node@node-2.acme.org)  533760  | 1319738 
+> [ 743.000000] (3:node@node-2.acme.org)  533776  | 1319738 
+> [ 743.000000] (3:node@node-2.acme.org)  533808  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 743.000000] (3:node@node-2.acme.org) Predecessor: 366680
+> [ 752.000000] (5:node@node-4.acme.org) My finger table:
+> [ 752.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 752.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 752.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 752.000000] (5:node@node-4.acme.org)  16509409  | 16728096 
+> [ 752.000000] (5:node@node-4.acme.org)  16509413  | 16728096 
+> [ 752.000000] (5:node@node-4.acme.org)  16509421  | 16728096 
+> [ 752.000000] (5:node@node-4.acme.org)  16509437  | 16728096 
+> [ 752.000000] (5:node@node-4.acme.org)  16509469  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 752.000000] (5:node@node-4.acme.org) Predecessor: 10874876
+> [ 753.000000] (6:node@node-5.acme.org) My finger table:
+> [ 753.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 753.000000] (6:node@node-5.acme.org)  10874877  | 16509405 
+> [ 753.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 753.000000] (6:node@node-5.acme.org)  10874880  | 533744 
+> [ 753.000000] (6:node@node-5.acme.org)  10874884  | 533744 
+> [ 753.000000] (6:node@node-5.acme.org)  10874892  | 16728096 
+> [ 753.000000] (6:node@node-5.acme.org)  10874908  | 16509405 
+> [ 753.000000] (6:node@node-5.acme.org)  10874940  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 753.000000] (6:node@node-5.acme.org) Predecessor: 10004760
+> [ 765.000000] (8:node@node-7.acme.org) My finger table:
+> [ 765.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 765.000000] (8:node@node-7.acme.org)  10004761  | 10874876 
+> [ 765.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 765.000000] (8:node@node-7.acme.org)  10004764  | 16509405 
+> [ 765.000000] (8:node@node-7.acme.org)  10004768  | 16509405 
+> [ 765.000000] (8:node@node-7.acme.org)  10004776  | 16509405 
+> [ 765.000000] (8:node@node-7.acme.org)  10004792  | 10874876 
+> [ 765.000000] (8:node@node-7.acme.org)  10004824  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 765.000000] (8:node@node-7.acme.org) Predecessor: 6518808
+> [ 774.000000] (7:node@node-6.acme.org) My finger table:
+> [ 774.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 774.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 774.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 774.000000] (7:node@node-6.acme.org)  16728100  |  42 
+> [ 774.000000] (7:node@node-6.acme.org)  16728104  |  42 
+> [ 774.000000] (7:node@node-6.acme.org)  16728112  |  42 
+> [ 774.000000] (7:node@node-6.acme.org)  16728128  |  42 
+> [ 774.000000] (7:node@node-6.acme.org)  16728160  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 774.000000] (7:node@node-6.acme.org) Predecessor: 16509405
+> [ 796.000000] (2:node@node-1.acme.org) My finger table:
+> [ 796.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 796.000000] (2:node@node-1.acme.org)  366681  | 533744 
+> [ 796.000000] (2:node@node-1.acme.org)  366682  | 1319738 
+> [ 796.000000] (2:node@node-1.acme.org)  366684  | 1319738 
+> [ 796.000000] (2:node@node-1.acme.org)  366688  | 533744 
+> [ 796.000000] (2:node@node-1.acme.org)  366696  | 533744 
+> [ 796.000000] (2:node@node-1.acme.org)  366712  | 533744 
+> [ 796.000000] (2:node@node-1.acme.org)  366744  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 796.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 808.000000] (9:node@node-8.acme.org) My finger table:
+> [ 808.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 808.000000] (9:node@node-8.acme.org)  6518809  | 10004760 
+> [ 808.000000] (9:node@node-8.acme.org)  6518810  | 16728096 
+> [ 808.000000] (9:node@node-8.acme.org)  6518812  | 10004760 
+> [ 808.000000] (9:node@node-8.acme.org)  6518816  | 10004760 
+> [ 808.000000] (9:node@node-8.acme.org)  6518824  | 10004760 
+> [ 808.000000] (9:node@node-8.acme.org)  6518840  | 10004760 
+> [ 808.000000] (9:node@node-8.acme.org)  6518872  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 808.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 810.000000] (4:node@node-3.acme.org) My finger table:
+> [ 810.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 810.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 810.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 810.000000] (4:node@node-3.acme.org)  1319742  | 2015253 
+> [ 810.000000] (4:node@node-3.acme.org)  1319746  | 2015253 
+> [ 810.000000] (4:node@node-3.acme.org)  1319754  | 2015253 
+> [ 810.000000] (4:node@node-3.acme.org)  1319770  | 2015253 
+> [ 810.000000] (4:node@node-3.acme.org)  1319802  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 810.000000] (4:node@node-3.acme.org) Predecessor: 533744
+> [ 831.000000] (10:node@node-9.acme.org) My finger table:
+> [ 831.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 831.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 831.000000] (10:node@node-9.acme.org)  2015255  | 6518808 
+> [ 831.000000] (10:node@node-9.acme.org)  2015257  | 6518808 
+> [ 831.000000] (10:node@node-9.acme.org)  2015261  | 6518808 
+> [ 831.000000] (10:node@node-9.acme.org)  2015269  | 6518808 
+> [ 831.000000] (10:node@node-9.acme.org)  2015285  | 6518808 
+> [ 831.000000] (10:node@node-9.acme.org)  2015317  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 831.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 859.000000] (1:node@node-0.acme.org) My finger table:
+> [ 859.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 859.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)   46  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)   50  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)   58  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)   74  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)  106  | 366680 
+> [ 859.000000] (1:node@node-0.acme.org)  170  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 859.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 859.000000] (1:node@node-0.acme.org) Predecessor: 16728096
+> [ 873.000000] (5:node@node-4.acme.org) My finger table:
+> [ 873.000000] (5:node@node-4.acme.org) Start | Succ 
+> [ 873.000000] (5:node@node-4.acme.org)  16509406  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509407  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509409  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509413  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509421  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509437  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509469  | 16728096 
+> [ 873.000000] (5:node@node-4.acme.org)  16509533  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16509661  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16509917  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16510429  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16511453  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16513501  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16517597  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16525789  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16542173  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16574941  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16640477  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  16771549  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  256477  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  780765  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  1829341  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  3926493  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org)  8120797  | 16509405 
+> [ 873.000000] (5:node@node-4.acme.org) Predecessor: 10874876
+> [ 893.000000] (3:node@node-2.acme.org) My finger table:
+> [ 893.000000] (3:node@node-2.acme.org) Start | Succ 
+> [ 893.000000] (3:node@node-2.acme.org)  533745  | 1319738 
+> [ 893.000000] (3:node@node-2.acme.org)  533746  | 10004760 
+> [ 893.000000] (3:node@node-2.acme.org)  533748  | 10004760 
+> [ 893.000000] (3:node@node-2.acme.org)  533752  | 1319738 
+> [ 893.000000] (3:node@node-2.acme.org)  533760  | 1319738 
+> [ 893.000000] (3:node@node-2.acme.org)  533776  | 1319738 
+> [ 893.000000] (3:node@node-2.acme.org)  533808  | 1319738 
+> [ 893.000000] (3:node@node-2.acme.org)  533872  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  534000  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  534256  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  534768  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  535792  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  537840  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  541936  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  550128  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  566512  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  599280  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  664816  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  795888  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  1058032  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  1582320  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  2630896  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  4728048  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org)  8922352  | 533744 
+> [ 893.000000] (3:node@node-2.acme.org) Predecessor: 366680
+> [ 896.000000] (7:node@node-6.acme.org) My finger table:
+> [ 896.000000] (7:node@node-6.acme.org) Start | Succ 
+> [ 896.000000] (7:node@node-6.acme.org)  16728097  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728098  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728100  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728104  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728112  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728128  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728160  |  42 
+> [ 896.000000] (7:node@node-6.acme.org)  16728224  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16728352  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16728608  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16729120  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16730144  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16732192  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16736288  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16744480  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16760864  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  16416  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  81952  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  213024  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  475168  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  999456  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  2048032  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  4145184  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org)  8339488  | 16728096 
+> [ 896.000000] (7:node@node-6.acme.org) Predecessor: 16509405
+> [ 899.000000] (6:node@node-5.acme.org) My finger table:
+> [ 899.000000] (6:node@node-5.acme.org) Start | Succ 
+> [ 899.000000] (6:node@node-5.acme.org)  10874877  | 16509405 
+> [ 899.000000] (6:node@node-5.acme.org)  10874878  | 533744 
+> [ 899.000000] (6:node@node-5.acme.org)  10874880  | 533744 
+> [ 899.000000] (6:node@node-5.acme.org)  10874884  | 533744 
+> [ 899.000000] (6:node@node-5.acme.org)  10874892  | 16728096 
+> [ 899.000000] (6:node@node-5.acme.org)  10874908  | 16509405 
+> [ 899.000000] (6:node@node-5.acme.org)  10874940  | 16509405 
+> [ 899.000000] (6:node@node-5.acme.org)  10875004  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10875132  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10875388  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10875900  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10876924  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10878972  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10883068  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10891260  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10907644  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  10940412  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  11005948  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  11137020  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  11399164  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  11923452  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  12972028  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  15069180  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org)  2486268  | 10874876 
+> [ 899.000000] (6:node@node-5.acme.org) Predecessor: 10004760
+> [ 899.000000] (8:node@node-7.acme.org) My finger table:
+> [ 899.000000] (8:node@node-7.acme.org) Start | Succ 
+> [ 899.000000] (8:node@node-7.acme.org)  10004761  | 10874876 
+> [ 899.000000] (8:node@node-7.acme.org)  10004762  | 16509405 
+> [ 899.000000] (8:node@node-7.acme.org)  10004764  | 16509405 
+> [ 899.000000] (8:node@node-7.acme.org)  10004768  | 16509405 
+> [ 899.000000] (8:node@node-7.acme.org)  10004776  | 16509405 
+> [ 899.000000] (8:node@node-7.acme.org)  10004792  | 10874876 
+> [ 899.000000] (8:node@node-7.acme.org)  10004824  | 10874876 
+> [ 899.000000] (8:node@node-7.acme.org)  10004888  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10005016  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10005272  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10005784  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10006808  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10008856  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10012952  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10021144  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10037528  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10070296  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10135832  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10266904  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  10529048  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  11053336  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  12101912  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  14199064  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org)  1616152  | 10004760 
+> [ 899.000000] (8:node@node-7.acme.org) Predecessor: 6518808
+> [ 921.000000] (2:node@node-1.acme.org) My finger table:
+> [ 921.000000] (2:node@node-1.acme.org) Start | Succ 
+> [ 921.000000] (2:node@node-1.acme.org)  366681  | 533744 
+> [ 921.000000] (2:node@node-1.acme.org)  366682  | 1319738 
+> [ 921.000000] (2:node@node-1.acme.org)  366684  | 1319738 
+> [ 921.000000] (2:node@node-1.acme.org)  366688  | 533744 
+> [ 921.000000] (2:node@node-1.acme.org)  366696  | 533744 
+> [ 921.000000] (2:node@node-1.acme.org)  366712  | 533744 
+> [ 921.000000] (2:node@node-1.acme.org)  366744  | 533744 
+> [ 921.000000] (2:node@node-1.acme.org)  366808  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  366936  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  367192  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  367704  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  368728  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  370776  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  374872  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  383064  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  399448  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  432216  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  497752  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  628824  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  890968  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  1415256  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  2463832  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  4560984  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org)  8755288  | 366680 
+> [ 921.000000] (2:node@node-1.acme.org) Predecessor: 42
+> [ 928.000000] (9:node@node-8.acme.org) My finger table:
+> [ 928.000000] (9:node@node-8.acme.org) Start | Succ 
+> [ 928.000000] (9:node@node-8.acme.org)  6518809  | 10004760 
+> [ 928.000000] (9:node@node-8.acme.org)  6518810  | 16728096 
+> [ 928.000000] (9:node@node-8.acme.org)  6518812  | 10004760 
+> [ 928.000000] (9:node@node-8.acme.org)  6518816  | 10004760 
+> [ 928.000000] (9:node@node-8.acme.org)  6518824  | 10004760 
+> [ 928.000000] (9:node@node-8.acme.org)  6518840  | 10004760 
+> [ 928.000000] (9:node@node-8.acme.org)  6518872  | 10004760 
+> [ 928.000000] (9:node@node-8.acme.org)  6518936  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6519064  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6519320  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6519832  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6520856  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6522904  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6527000  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6535192  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6551576  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6584344  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6649880  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  6780952  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  7043096  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  7567384  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  8615960  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  10713112  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org)  14907416  | 6518808 
+> [ 928.000000] (9:node@node-8.acme.org) Predecessor: 2015253
+> [ 930.000000] (4:node@node-3.acme.org) My finger table:
+> [ 930.000000] (4:node@node-3.acme.org) Start | Succ 
+> [ 930.000000] (4:node@node-3.acme.org)  1319739  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319740  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319742  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319746  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319754  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319770  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319802  | 2015253 
+> [ 930.000000] (4:node@node-3.acme.org)  1319866  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1319994  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1320250  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1320762  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1321786  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1323834  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1327930  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1336122  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1352506  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1385274  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1450810  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1581882  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  1844026  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  2368314  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  3416890  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  5514042  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org)  9708346  | 1319738 
+> [ 930.000000] (4:node@node-3.acme.org) Predecessor: 533744
+> [ 962.000000] (10:node@node-9.acme.org) My finger table:
+> [ 962.000000] (10:node@node-9.acme.org) Start | Succ 
+> [ 962.000000] (10:node@node-9.acme.org)  2015254  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015255  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015257  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015261  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015269  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015285  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015317  | 6518808 
+> [ 962.000000] (10:node@node-9.acme.org)  2015381  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2015509  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2015765  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2016277  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2017301  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2019349  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2023445  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2031637  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2048021  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2080789  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2146325  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2277397  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  2539541  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  3063829  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  4112405  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  6209557  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org)  10403861  | 2015253 
+> [ 962.000000] (10:node@node-9.acme.org) Predecessor: 1319738
+> [ 982.000000] (1:node@node-0.acme.org) My finger table:
+> [ 982.000000] (1:node@node-0.acme.org) Start | Succ 
+> [ 982.000000] (1:node@node-0.acme.org)   43  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)   44  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)   46  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)   50  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)   58  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)   74  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)  106  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)  170  | 366680 
+> [ 982.000000] (1:node@node-0.acme.org)  298  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  554  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  1066  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  2090  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  4138  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  8234  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  16426  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  32810  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  65578  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  131114  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  262186  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  524330  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  1048618  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  2097194  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  4194346  |  42 
+> [ 982.000000] (1:node@node-0.acme.org)  8388650  |  42 
+> [ 982.000000] (1:node@node-0.acme.org) Predecessor: 16728096
 > [1154.000000] (0:@) Messages created: 2049
 > [1154.000000] (0:@) Simulated time: 1154
index b6d1c07..4ae7dab 100644 (file)
@@ -1,3 +1,3 @@
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
index b6d1c07..4ae7dab 100644 (file)
@@ -1,3 +1,3 @@
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
index 7c988f8..c5d2c79 100644 (file)
@@ -1,36 +1,36 @@
-c-1.me
-c-2.me
-c-3.me
-c-4.me
-c-5.me
-c-6.me
-c-7.me
-c-8.me
-c-9.me
-c-10.me
-c-11.me
-c-12.me
-c-13.me
-c-14.me
-c-15.me
-c-16.me
-c-17.me
-c-18.me
-c-19.me
-c-20.me
-c-21.me
-c-22.me
-c-23.me
-c-24.me
-c-25.me
-c-26.me
-c-27.me
-c-28.me
-c-29.me
-c-30.me
-c-31.me
-c-32.me
-c-33.me
-c-34.me
-c-35.me
-c-36.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
+node-4.acme.org
+node-5.acme.org
+node-6.acme.org
+node-7.acme.org
+node-8.acme.org
+node-9.acme.org
+node-10.acme.org
+node-11.acme.org
+node-12.acme.org
+node-13.acme.org
+node-14.acme.org
+node-15.acme.org
+node-16.acme.org
+node-17.acme.org
+node-18.acme.org
+node-19.acme.org
+node-20.acme.org
+node-21.acme.org
+node-22.acme.org
+node-23.acme.org
+node-24.acme.org
+node-25.acme.org
+node-26.acme.org
+node-27.acme.org
+node-28.acme.org
+node-29.acme.org
+node-30.acme.org
+node-31.acme.org
+node-32.acme.org
+node-33.acme.org
+node-34.acme.org
+node-35.acme.org
+node-36.acme.org
index b6d1c07..4ae7dab 100644 (file)
@@ -1,3 +1,3 @@
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
index b6d1c07..4ae7dab 100644 (file)
@@ -1,3 +1,3 @@
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
index 4a0c7dc..9df64c0 100644 (file)
@@ -32,20 +32,20 @@ int main(int argc, char **argv)
   }
 
   if (rank == 0) {
-    printf("MPI_ISend / MPI_IRecv Test \n");
+    //printf("MPI_ISend / MPI_IRecv Test \n");
 
     for(i=0; i < size - 1; i++){
       MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-      printf("Message received from %d\n", recv_buff);
+      //printf("Message received from %d\n", recv_buff);
       MPI_Send(&recv_buff, 1, MPI_INT, status.MPI_SOURCE, 42, MPI_COMM_WORLD);
       // printf("Sent %d to rank %d\n", status.MPI_SOURCE);
     }
 
   }else{
     MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-    printf("Sent %d to rank 0\n", rank);
+    //printf("Sent %d to rank 0\n", rank);
     MPI_Recv(&recv_buff, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-    printf("Message received from %d\n", recv_buff);
+    //printf("Message received from %d\n", recv_buff);
   }
 
   MPI_Finalize();
diff --git a/examples/smpi/mc/non_deterministic.tesh b/examples/smpi/mc/non_deterministic.tesh
new file mode 100644 (file)
index 0000000..5ea8b13
--- /dev/null
@@ -0,0 +1,48 @@
+#! ./tesh
+
+! timeout 60
+$ ../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/hostfile_non_deterministic  -platform ${srcdir:=.}/../../platforms/cluster.xml --cfg=model-check:1 --cfg=model-check/communications_determinism:1 --cfg=smpi/send_is_detached_thres:0 --cfg=smpi/running_power:1e9 ./non_deterministic
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-3'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/communications_determinism' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/send_is_detached_thres' to '0'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0.000000] [mc_global/INFO] Check communication determinism
+> [0.000000] [mc_global/INFO] Get debug information ...
+> [0.000000] [mc_global/INFO] Get debug information done !
+> [0.000000] [mc_comm_determinism/INFO] The communications pattern of the process 1 is different!
+> [0.000000] [mc_comm_determinism/INFO] ****************************************************
+> [0.000000] [mc_comm_determinism/INFO] ***** Non-deterministic communications pattern *****
+> [0.000000] [mc_comm_determinism/INFO] ****************************************************
+> [0.000000] [mc_comm_determinism/INFO] ** Initial communications pattern (per process): **
+> [0.000000] [mc_comm_determinism/INFO] Communications from the process 1:
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org <- (2) node-2.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org -> (2) node-2.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org <- (3) node-3.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org -> (3) node-3.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] Communications from the process 2:
+> [0.000000] [mc_comm_determinism/INFO] [(2) node-2.acme.org -> (1) node-1.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] [(2) node-2.acme.org <- (1) node-1.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] Communications from the process 3:
+> [0.000000] [mc_comm_determinism/INFO] [(3) node-3.acme.org -> (1) node-1.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] [(3) node-3.acme.org <- (1) node-1.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] ** Communications pattern counter-example (per process): **
+> [0.000000] [mc_comm_determinism/INFO] Communications from the process 1:
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org <- (3) node-3.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org -> (3) node-3.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org <- (2) node-2.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] [(1) node-1.acme.org -> (2) node-2.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] Communications from the process 2:
+> [0.000000] [mc_comm_determinism/INFO] [(2) node-2.acme.org -> (1) node-1.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] [(2) node-2.acme.org <- (1) node-1.acme.org] iRecv 
+> [0.000000] [mc_comm_determinism/INFO] Communications from the process 3:
+> [0.000000] [mc_comm_determinism/INFO] [(3) node-3.acme.org -> (1) node-1.acme.org] iSend 
+> [0.000000] [mc_comm_determinism/INFO] [(3) node-3.acme.org <- (1) node-1.acme.org] iRecv 
+> [0.000000] [mc_global/INFO] Expanded states = 16037
+> [0.000000] [mc_global/INFO] Visited states = 80801
+> [0.000000] [mc_global/INFO] Executed transitions = 76048
+> [0.000000] [mc_global/INFO] Communication-deterministic : No
index 048d75c..6406ce8 100644 (file)
@@ -32,16 +32,16 @@ int main(int argc, char **argv)
   }
 
   if (rank == 0) {
-    printf("MPI_ISend / MPI_IRecv Test \n");
+    //printf("MPI_ISend / MPI_IRecv Test \n");
 
     for(i=0; i < size - 1; i++){
       MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-      printf("Message received from %d\n", recv_buff);
+      //printf("Message received from %d\n", recv_buff);
     }
 
   }else{
     MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-    printf("Sent %d to rank 0\n", rank);
+    //printf("Sent %d to rank 0\n", rank);
   }
 
   MPI_Finalize();
diff --git a/examples/smpi/mc/send_deterministic.tesh b/examples/smpi/mc/send_deterministic.tesh
new file mode 100644 (file)
index 0000000..8831df2
--- /dev/null
@@ -0,0 +1,20 @@
+#! ./tesh
+
+! timeout 60
+$ ../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/hostfile_send_deterministic  -platform ${srcdir:=.}/../../platforms/cluster.xml --cfg=model-check:1 --cfg=model-check/send_determinism:1 --cfg=smpi/send_is_detached_thres:0 --cfg=smpi/running_power:1e9 ./send_deterministic
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-3'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/send_determinism' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/send_is_detached_thres' to '0'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/running_power' to '1e9'
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0.000000] [mc_global/INFO] Check communication determinism
+> [0.000000] [mc_global/INFO] Get debug information ...
+> [0.000000] [mc_global/INFO] Get debug information done !
+> [0.000000] [mc_global/INFO] Expanded states = 520
+> [0.000000] [mc_global/INFO] Visited states = 1476
+> [0.000000] [mc_global/INFO] Executed transitions = 1312
+> [0.000000] [mc_global/INFO] Send-deterministic : Yes
index 3be8fc1..a0620ab 100644 (file)
@@ -235,6 +235,9 @@ SG_BEGIN_DECL()
 /** Cache the size of a memory page for the current system. */
 XBT_PUBLIC_DATA(int) xbt_pagesize;
 
+/** Cache the number of bits of addresses inside a given page, log2(xbt_pagesize). */
+ XBT_PUBLIC_DATA(int) xbt_pagebits;
+
 XBT_PUBLIC(const char *) xbt_procname(void);
 
 #define XBT_BACKTRACE_SIZE 10   /* FIXME: better place? Do document */
index b97779a..13222c6 100644 (file)
@@ -23,6 +23,8 @@
 #include "xbt/dynar.h"
 #include "xbt/dict.h"
 
+SG_BEGIN_DECL()
+
 /* Datatype representing a separate heap. The whole point of the mmalloc module
  * is to allow several such heaps in the process. It thus works by redefining
  * all the classical memory management functions (malloc and friends) with an
@@ -48,6 +50,10 @@ XBT_PUBLIC( void ) mfree(xbt_mheap_t md, void *ptr);
 
 XBT_PUBLIC( xbt_mheap_t ) xbt_mheap_new(int fd, void *baseaddr);
 
+#define XBT_MHEAP_OPTION_MEMSET 1
+
+XBT_PUBLIC( xbt_mheap_t ) xbt_mheap_new_options(int fd, void *baseaddr, int options);
+
 XBT_PUBLIC( void ) xbt_mheap_destroy_no_free(xbt_mheap_t md);
 
 XBT_PUBLIC( void ) *xbt_mheap_destroy(xbt_mheap_t md);
@@ -62,7 +68,7 @@ xbt_mheap_t mmalloc_get_current_heap(void);
 struct s_mc_snapshot;
 struct s_dw_type;
 
-int mmalloc_compare_heap(struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_mheap_t heap1, xbt_mheap_t heap2);
+int mmalloc_compare_heap(struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2);
 int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
 int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2);
 int compare_heap_area(void *area1, void* area2, struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level);
@@ -71,5 +77,7 @@ void reset_heap_information(void);
 size_t mmalloc_get_bytes_used(xbt_mheap_t);
 ssize_t mmalloc_get_busy_size(xbt_mheap_t, void *ptr);
 
+SG_END_DECL()
+
 #endif
 #endif                          /* MMALLOC_H */
index 4537717..fae839c 100644 (file)
@@ -45,12 +45,13 @@ XBT_PUBLIC(void) xbt_abort(void) _XBT_GNUC_NORETURN;
  */
 #define xbt_die(...)                            \
   do {                                          \
-    XBT_LOG_EXTERNAL_CATEGORY(xbt);             \
     XBT_CCRITICAL(xbt, __VA_ARGS__);            \
     xbt_abort();                                \
   } while (0)
 /** @} */
 
+XBT_LOG_EXTERNAL_CATEGORY(xbt);
+
 /* these ones live in str.h, but redeclare them here so that we do
    not need to load the whole str.h and its heavy dependencies */
 #ifndef __USE_GNU               /* do not redeclare existing headers */
index 1af3e60..36aac64 100644 (file)
@@ -12,6 +12,8 @@
 #include <xbt/misc.h>           /* XBT_PUBLIC */
 #include <stddef.h>             /* size_t */
 
+SG_BEGIN_DECL()
+
 /** @brief get time in seconds 
 
   * gives  the  number  of  seconds since the Epoch (00:00:00 UTC, January 1, 1970).
@@ -37,4 +39,7 @@ XBT_PUBLIC(void) xbt_os_cputimer_stop(xbt_os_timer_t timer);
 XBT_PUBLIC(void) xbt_os_threadtimer_start(xbt_os_timer_t timer);
 XBT_PUBLIC(void) xbt_os_threadtimer_resume(xbt_os_timer_t timer);
 XBT_PUBLIC(void) xbt_os_threadtimer_stop(xbt_os_timer_t timer);
+
+SG_END_DECL()
+
 #endif
index e207590..3922d53 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2014. The SimGrid Team.
+  /* Copyright (c) 2008-2014. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -38,6 +38,8 @@ SG_BEGIN_DECL()
 /********************************** Configuration of MC **************************************/        
 extern int _sg_do_model_check;
 extern int _sg_mc_checkpoint;
+extern int _sg_mc_sparse_checkpoint;
+extern int _sg_mc_soft_dirty;
 extern char* _sg_mc_property_file;
 extern int _sg_mc_timeout;
 extern int _sg_mc_hash;
@@ -46,6 +48,8 @@ extern int _sg_mc_visited;
 extern char* _sg_mc_dot_output_file;
 extern int _sg_mc_comms_determinism;
 extern int _sg_mc_send_determinism;
+extern int _sg_mc_safety;
+extern int _sg_mc_liveness;
 
 extern xbt_dynar_t mc_heap_comparison_ignore;
 extern xbt_dynar_t stacks_areas;
@@ -55,6 +59,8 @@ extern void *maestro_stack_end;
 /********************************* Global *************************************/
 void _mc_cfg_cb_reduce(const char *name, int pos);
 void _mc_cfg_cb_checkpoint(const char *name, int pos);
+void _mc_cfg_cb_sparse_checkpoint(const char *name, int pos);
+void _mc_cfg_cb_soft_dirty(const char *name, int pos);
 void _mc_cfg_cb_property(const char *name, int pos);
 void _mc_cfg_cb_timeout(const char *name, int pos);
 void _mc_cfg_cb_hash(const char *name, int pos);
@@ -65,11 +71,8 @@ void _mc_cfg_cb_comms_determinism(const char *name, int pos);
 void _mc_cfg_cb_send_determinism(const char *name, int pos);
 
 XBT_PUBLIC(void) MC_do_the_modelcheck_for_real(void);
-
 XBT_PUBLIC(void) MC_init(void);
 XBT_PUBLIC(void) MC_exit(void);
-XBT_PUBLIC(void) MC_modelcheck_safety(void);
-XBT_PUBLIC(void) MC_modelcheck_liveness(void);
 XBT_PUBLIC(void) MC_process_clock_add(smx_process_t, double);
 XBT_PUBLIC(double) MC_process_clock_get(smx_process_t);
 void MC_automaton_load(const char *file);
index 3e96454..202a2f1 100644 (file)
@@ -13,6 +13,7 @@
 #include "xbt/module.h"
 #include <xbt/mmalloc.h>
 #include "../smpi/private.h"
+#include <alloca.h>
 
 #include "xbt/mmalloc/mmprivate.h"
 
@@ -22,6 +23,9 @@
 #include <libelf.h>
 
 #include "mc_private.h"
+#include <mc/mc.h>
+
+#include "mc_mmu.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
                                 "Logging specific to mc_checkpoint");
@@ -31,45 +35,55 @@ char *libsimgrid_path;
 /************************************  Free functions **************************************/
 /*****************************************************************************************/
 
-static void MC_snapshot_stack_free(mc_snapshot_stack_t s){
-  if(s){
+static void MC_snapshot_stack_free(mc_snapshot_stack_t s)
+{
+  if (s) {
     xbt_dynar_free(&(s->local_variables));
     xbt_dynar_free(&(s->stack_frames));
     xbt_free(s);
   }
 }
 
-static void MC_snapshot_stack_free_voidp(void *s){
+static void MC_snapshot_stack_free_voidp(void *s)
+{
   MC_snapshot_stack_free((mc_snapshot_stack_t) * (void **) s);
 }
 
-static void local_variable_free(local_variable_t v){
+static void local_variable_free(local_variable_t v)
+{
   xbt_free(v->name);
   xbt_free(v);
 }
 
-static void local_variable_free_voidp(void *v){
+static void local_variable_free_voidp(void *v)
+{
   local_variable_free((local_variable_t) * (void **) v);
 }
 
 static void MC_region_destroy(mc_mem_region_t reg)
 {
-  munmap(reg->data, reg->size);
+  //munmap(reg->data, reg->size);
+  xbt_free(reg->data);
+  if (reg->page_numbers) {
+    mc_free_page_snapshot_region(reg->page_numbers, mc_page_count(reg->size));
+  }
   xbt_free(reg);
 }
 
-void MC_free_snapshot(mc_snapshot_t snapshot){
+void MC_free_snapshot(mc_snapshot_t snapshot)
+{
   unsigned int i;
-  for(i=0; i < NB_REGIONS; i++)
+  for (i = 0; i < NB_REGIONS; i++)
     MC_region_destroy(snapshot->regions[i]);
 
   xbt_free(snapshot->stack_sizes);
   xbt_dynar_free(&(snapshot->stacks));
   xbt_dynar_free(&(snapshot->to_ignore));
+  xbt_dynar_free(&snapshot->ignored_data);
 
-  if(snapshot->privatization_regions){
-    size_t n = snapshot->nb_processes;
-    for(i=0; i!=n; ++i) {
+  if (snapshot->privatization_regions) {
+    size_t n = xbt_dynar_length(snapshot->enabled_processes);
+    for (i = 0; i != n; ++i) {
       MC_region_destroy(snapshot->privatization_regions[i]);
     }
     xbt_free(snapshot->privatization_regions);
@@ -78,67 +92,96 @@ void MC_free_snapshot(mc_snapshot_t snapshot){
   xbt_free(snapshot);
 }
 
-
 /*******************************  Snapshot regions ********************************/
 /*********************************************************************************/
 
-static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
+static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size, mc_mem_region_t ref_reg)
 {
+  if (_sg_mc_sparse_checkpoint) {
+    return mc_region_new_sparse(type, start_addr, size, ref_reg);
+  }
+
   mc_mem_region_t new_reg = xbt_new(s_mc_mem_region_t, 1);
   new_reg->start_addr = start_addr;
+  new_reg->data = NULL;
   new_reg->size = size;
-  new_reg->data = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-  if(new_reg->data==MAP_FAILED)
-    xbt_die("Could not mmap new memory for snapshot.");
+  new_reg->page_numbers = NULL;
+  new_reg->data = xbt_malloc(size);
   memcpy(new_reg->data, start_addr, size);
-  madvise(new_reg->data, size, MADV_MERGEABLE);
-
-  XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", type, new_reg->data, start_addr, size);
-  
+  XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu",
+            type, new_reg->data, start_addr, size);
   return new_reg;
+
 }
 
-static void MC_region_restore(mc_mem_region_t reg)
+/** @brief Restore a region from a snapshot
+ *
+ *  If we are using per page snapshots, it is possible to use the reference
+ *  region in order to do an incremental restoration of the region: the
+ *  softclean pages which are shared between the two snapshots do not need
+ *  to be restored.
+ *
+ *  @param reg     Target region
+ *  @param reg_reg Current region (if not NULL), used for lazy per page restoration
+ */
+static void MC_region_restore(mc_mem_region_t reg, mc_mem_region_t ref_reg)
 {
   /*FIXME: check if start_addr is still mapped, if it is not, then map it
     before copying the data */
-  memcpy(reg->start_addr, reg->data, reg->size);
+  if (!reg->page_numbers) {
+    memcpy(reg->start_addr, reg->data, reg->size);
+  } else {
+    mc_region_restore_sparse(reg, ref_reg);
+  }
   return;
 }
 
-static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size)
+static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type,
+                                   void *start_addr, size_t size)
+
 {
-  mc_mem_region_t new_reg = MC_region_new(type, start_addr, size);
+  mc_mem_region_t ref_reg =
+    mc_model_checker->parent_snapshot ? mc_model_checker->parent_snapshot->regions[type] : NULL;
+  mc_mem_region_t new_reg = MC_region_new(type, start_addr, size, ref_reg);
   snapshot->regions[type] = new_reg;
   return;
-} 
+}
 
-static void MC_get_memory_regions(mc_snapshot_t snapshot){
+static void MC_get_memory_regions(mc_snapshot_t snapshot)
+{
   size_t i;
 
-  void* start_heap = ((xbt_mheap_t)std_heap)->base;
-  void* end_heap   = ((xbt_mheap_t)std_heap)->breakval;
-  MC_snapshot_add_region(snapshot, 0, start_heap, (char*) end_heap - (char*) start_heap);
+  void *start_heap = ((xbt_mheap_t) std_heap)->base;
+  void *end_heap = ((xbt_mheap_t) std_heap)->breakval;
+  MC_snapshot_add_region(snapshot, 0, start_heap,
+                         (char *) end_heap - (char *) start_heap);
   snapshot->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
 
-  MC_snapshot_add_region(snapshot, 1,  mc_libsimgrid_info->start_rw, mc_libsimgrid_info->end_rw - mc_libsimgrid_info->start_rw);
-  if(!smpi_privatize_global_variables) {
-    MC_snapshot_add_region(snapshot, 2,  mc_binary_info->start_rw, mc_binary_info->end_rw - mc_binary_info->start_rw);
+  MC_snapshot_add_region(snapshot, 1, mc_libsimgrid_info->start_rw,
+                         mc_libsimgrid_info->end_rw -
+                         mc_libsimgrid_info->start_rw);
+  if (!smpi_privatize_global_variables) {
+    MC_snapshot_add_region(snapshot, 2, mc_binary_info->start_rw,
+                           mc_binary_info->end_rw - mc_binary_info->start_rw);
     snapshot->privatization_regions = NULL;
     snapshot->privatization_index = -1;
   } else {
-    snapshot->privatization_regions = xbt_new(mc_mem_region_t, SIMIX_process_count());
-    for (i=0; i< SIMIX_process_count(); i++){
-      snapshot->privatization_regions[i] = MC_region_new(-1, mappings[i], size_data_exe);
+    snapshot->privatization_regions =
+        xbt_new(mc_mem_region_t, SIMIX_process_count());
+    for (i = 0; i < SIMIX_process_count(); i++) {
+      mc_mem_region_t ref_reg =
+        mc_model_checker->parent_snapshot ? mc_model_checker->parent_snapshot->privatization_regions[i] : NULL;
+      snapshot->privatization_regions[i] =
+        MC_region_new(-1, mappings[i], size_data_exe, ref_reg);
     }
     snapshot->privatization_index = loaded_page;
   }
 }
 
 /** @brief Finds the range of the different memory segments and binary paths */
-void MC_init_memory_map_info(){
+void MC_init_memory_map_info()
+{
+
   unsigned int i = 0;
   s_map_region_t reg;
   memory_map_t maps = MC_get_memory_map();
@@ -151,13 +194,15 @@ void MC_init_memory_map_info(){
     reg = maps->regions[i];
     if (maps->regions[i].pathname == NULL) {
       // Nothing to do
-    }
-    else if ((reg.prot & PROT_WRITE) && !memcmp(maps->regions[i].pathname, "[stack]", 7)){
-          maestro_stack_start = reg.start_addr;
-          maestro_stack_end = reg.end_addr;
-    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC) && !memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
-      if(libsimgrid_path == NULL)
-          libsimgrid_path = strdup(maps->regions[i].pathname);
+    } else if ((reg.prot & PROT_WRITE)
+               && !memcmp(maps->regions[i].pathname, "[stack]", 7)) {
+      maestro_stack_start = reg.start_addr;
+      maestro_stack_end = reg.end_addr;
+    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)
+               && !memcmp(basename(maps->regions[i].pathname), "libsimgrid",
+                          10)) {
+      if (libsimgrid_path == NULL)
+        libsimgrid_path = strdup(maps->regions[i].pathname);
     }
     i++;
   }
@@ -172,41 +217,45 @@ void MC_init_memory_map_info(){
 
 /** \brief Fill/lookup the "subtype" field.
  */
-static void MC_resolve_subtype(mc_object_info_t info, dw_type_t type) {
+static void MC_resolve_subtype(mc_object_info_t info, dw_type_t type)
+{
 
-  if(type->dw_type_id==NULL)
+  if (type->dw_type_id == NULL)
     return;
   type->subtype = xbt_dict_get_or_null(info->types, type->dw_type_id);
-  if(type->subtype==NULL)
+  if (type->subtype == NULL)
     return;
-  if(type->subtype->byte_size != 0)
+  if (type->subtype->byte_size != 0)
     return;
-  if(type->subtype->name==NULL)
+  if (type->subtype->name == NULL)
     return;
   // Try to find a more complete description of the type:
   // We need to fix in order to support C++.
 
-  dw_type_t subtype = xbt_dict_get_or_null(info->full_types_by_name, type->subtype->name);
-  if(subtype!=NULL) {
+  dw_type_t subtype =
+      xbt_dict_get_or_null(info->full_types_by_name, type->subtype->name);
+  if (subtype != NULL) {
     type->subtype = subtype;
   }
 
 }
 
-void MC_post_process_types(mc_object_info_t info) {
+void MC_post_process_types(mc_object_info_t info)
+{
   xbt_dict_cursor_t cursor = NULL;
   char *origin;
   dw_type_t type;
 
   // Lookup "subtype" field:
-  xbt_dict_foreach(info->types, cursor, origin, type){
+  xbt_dict_foreach(info->types, cursor, origin, type) {
     MC_resolve_subtype(info, type);
 
     dw_type_t member;
     unsigned int i = 0;
-    if(type->members!=NULL) xbt_dynar_foreach(type->members, i, member) {
+    if (type->members != NULL)
+      xbt_dynar_foreach(type->members, i, member) {
       MC_resolve_subtype(info, member);
-    }
+      }
   }
 }
 
@@ -214,40 +263,41 @@ void MC_post_process_types(mc_object_info_t info) {
  *
  * TODO, use dl_iterate_phdr to be more robust
  * */
-void MC_find_object_address(memory_map_t maps, mc_object_info_t result) {
+void MC_find_object_address(memory_map_t maps, mc_object_info_t result)
+{
 
   unsigned int i = 0;
   s_map_region_t reg;
-  const charname = basename(result->file_name);
+  const char *name = basename(result->file_name);
   while (i < maps->mapsize) {
     reg = maps->regions[i];
-    if (maps->regions[i].pathname == NULL || strcmp(basename(maps->regions[i].pathname),  name)) {
+    if (maps->regions[i].pathname == NULL
+        || strcmp(basename(maps->regions[i].pathname), name)) {
       // Nothing to do
-    }
-    else if ((reg.prot & PROT_WRITE)){
-          xbt_assert(!result->start_rw,
-            "Multiple read-write segments for %s, not supported",
-            maps->regions[i].pathname);
-          result->start_rw = reg.start_addr;
-          result->end_rw   = reg.end_addr;
-          // .bss is usually after the .data:
-          s_map_region_t* next = &(maps->regions[i+1]);
-          if(next->pathname == NULL && (next->prot & PROT_WRITE) && next->start_addr == reg.end_addr) {
-            result->end_rw = maps->regions[i+1].end_addr;
-          }
-    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)){
-          xbt_assert(!result->start_exec,
-            "Multiple executable segments for %s, not supported",
-            maps->regions[i].pathname);
-          result->start_exec = reg.start_addr;
-          result->end_exec   = reg.end_addr;
-    }
-    else if((reg.prot & PROT_READ) && !(reg.prot & PROT_EXEC)) {
-        xbt_assert(!result->start_ro,
-          "Multiple read only segments for %s, not supported",
-          maps->regions[i].pathname);
-        result->start_ro = reg.start_addr;
-        result->end_ro   = reg.end_addr;
+    } else if ((reg.prot & PROT_WRITE)) {
+      xbt_assert(!result->start_rw,
+                 "Multiple read-write segments for %s, not supported",
+                 maps->regions[i].pathname);
+      result->start_rw = reg.start_addr;
+      result->end_rw = reg.end_addr;
+      // .bss is usually after the .data:
+      s_map_region_t *next = &(maps->regions[i + 1]);
+      if (next->pathname == NULL && (next->prot & PROT_WRITE)
+          && next->start_addr == reg.end_addr) {
+        result->end_rw = maps->regions[i + 1].end_addr;
+      }
+    } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)) {
+      xbt_assert(!result->start_exec,
+                 "Multiple executable segments for %s, not supported",
+                 maps->regions[i].pathname);
+      result->start_exec = reg.start_addr;
+      result->end_exec = reg.end_addr;
+    } else if ((reg.prot & PROT_READ) && !(reg.prot & PROT_EXEC)) {
+      xbt_assert(!result->start_ro,
+                 "Multiple read only segments for %s, not supported",
+                 maps->regions[i].pathname);
+      result->start_ro = reg.start_addr;
+      result->end_ro = reg.end_addr;
     }
     i++;
   }
@@ -269,28 +319,32 @@ void MC_find_object_address(memory_map_t maps, mc_object_info_t result) {
  *  \param ip    Instruction pointer
  *  \return      true if the variable is valid
  * */
-static bool mc_valid_variable(dw_variable_t var, dw_frame_t scope, const void* ip) {
+static bool mc_valid_variable(dw_variable_t var, dw_frame_t scope,
+                              const void *ip)
+{
   // The variable is not yet valid:
-  if((const void*)((const char*) scope->low_pc + var->start_scope) > ip)
+  if ((const void *) ((const char *) scope->low_pc + var->start_scope) > ip)
     return false;
   else
     return true;
 }
 
-static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_frame_t scope, xbt_dynar_t result) {
-  void* ip = (void*) stack_frame->ip;
-  if(ip < scope->low_pc || ip>= scope->high_pc)
+static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame,
+                                           dw_frame_t scope, xbt_dynar_t result)
+{
+  void *ip = (void *) stack_frame->ip;
+  if (ip < scope->low_pc || ip >= scope->high_pc)
     return;
 
   unsigned cursor = 0;
   dw_variable_t current_variable;
-  xbt_dynar_foreach(scope->variables, cursor, current_variable){
+  xbt_dynar_foreach(scope->variables, cursor, current_variable) {
 
-    if(!mc_valid_variable(current_variable, scope, (void*) stack_frame->ip))
+    if (!mc_valid_variable(current_variable, scope, (void *) stack_frame->ip))
       continue;
 
     int region_type;
-    if((long)stack_frame->ip > (long)mc_libsimgrid_info->start_exec)
+    if ((long) stack_frame->ip > (long) mc_libsimgrid_info->start_exec)
       region_type = 1;
     else
       region_type = 2;
@@ -300,15 +354,17 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_fram
     new_var->ip = stack_frame->ip;
     new_var->name = xbt_strdup(current_variable->name);
     new_var->type = current_variable->type;
-    new_var->region= region_type;
+    new_var->region = region_type;
 
-    if(current_variable->address!=NULL) {
+    if (current_variable->address != NULL) {
       new_var->address = current_variable->address;
-    } else
-    if(current_variable->locations.size != 0){
-      new_var->address = (void*) mc_dwarf_resolve_locations(&current_variable->locations,
-        current_variable->object_info,
-        &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, NULL);
+    } else if (current_variable->locations.size != 0) {
+      new_var->address =
+          (void *) mc_dwarf_resolve_locations(&current_variable->locations,
+                                              current_variable->object_info,
+                                              &(stack_frame->unw_cursor),
+                                              (void *) stack_frame->frame_base,
+                                              NULL);
     } else {
       xbt_die("No address");
     }
@@ -323,78 +379,86 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_fram
   }
 }
 
-static xbt_dynar_t MC_get_local_variables_values(xbt_dynar_t stack_frames){
+static xbt_dynar_t MC_get_local_variables_values(xbt_dynar_t stack_frames)
+{
 
   unsigned cursor1 = 0;
   mc_stack_frame_t stack_frame;
-  xbt_dynar_t variables = xbt_dynar_new(sizeof(local_variable_t), local_variable_free_voidp);
+  xbt_dynar_t variables =
+      xbt_dynar_new(sizeof(local_variable_t), local_variable_free_voidp);
 
-  xbt_dynar_foreach(stack_frames,cursor1,stack_frame) {
+  xbt_dynar_foreach(stack_frames, cursor1, stack_frame) {
     mc_fill_local_variables_values(stack_frame, stack_frame->frame, variables);
   }
 
   return variables;
 }
 
-static void MC_stack_frame_free_voipd(void *s){
-  mc_stack_frame_t stack_frame = *(mc_stack_frame_t*)s;
-  if(stack_frame) {
+static void MC_stack_frame_free_voipd(void *s)
+{
+  mc_stack_frame_t stack_frame = *(mc_stack_frame_t *) s;
+  if (stack_frame) {
     xbt_free(stack_frame->frame_name);
     xbt_free(stack_frame);
   }
 }
 
-static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) {
-  xbt_dynar_t result = xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd);
+static xbt_dynar_t MC_unwind_stack_frames(void *stack_context)
+{
+  xbt_dynar_t result =
+      xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd);
 
   unw_cursor_t c;
 
   // TODO, check condition check (unw_init_local==0 means end of frame)
-  if(unw_init_local(&c, (unw_context_t *)stack_context)!=0) {
+  if (unw_init_local(&c, (unw_context_t *) stack_context) != 0) {
 
     xbt_die("Could not initialize stack unwinding");
 
-  } else while(1) {
+  } else
+    while (1) {
 
-    mc_stack_frame_t stack_frame = xbt_new(s_mc_stack_frame_t, 1);
-    xbt_dynar_push(result, &stack_frame);
+      mc_stack_frame_t stack_frame = xbt_new(s_mc_stack_frame_t, 1);
+      xbt_dynar_push(result, &stack_frame);
 
-    stack_frame->unw_cursor = c;
+      stack_frame->unw_cursor = c;
 
-    unw_word_t ip, sp;
+      unw_word_t ip, sp;
 
-    unw_get_reg(&c, UNW_REG_IP, &ip);
-    unw_get_reg(&c, UNW_REG_SP, &sp);
+      unw_get_reg(&c, UNW_REG_IP, &ip);
+      unw_get_reg(&c, UNW_REG_SP, &sp);
 
-    stack_frame->ip = ip;
-    stack_frame->sp = sp;
+      stack_frame->ip = ip;
+      stack_frame->sp = sp;
 
-    // TODO, use real addresses in frame_t instead of fixing it here
+      // TODO, use real addresses in frame_t instead of fixing it here
 
-    dw_frame_t frame = MC_find_function_by_ip((void*) ip);
-    stack_frame->frame = frame;
+      dw_frame_t frame = MC_find_function_by_ip((void *) ip);
+      stack_frame->frame = frame;
 
-    if(frame) {
-      stack_frame->frame_name = xbt_strdup(frame->name);
-      stack_frame->frame_base = (unw_word_t)mc_find_frame_base(frame, frame->object_info, &c);
-    } else {
-      stack_frame->frame_base = 0;
-      stack_frame->frame_name = NULL;
-    }
+      if (frame) {
+        stack_frame->frame_name = xbt_strdup(frame->name);
+        stack_frame->frame_base =
+            (unw_word_t) mc_find_frame_base(frame, frame->object_info, &c);
+      } else {
+        stack_frame->frame_base = 0;
+        stack_frame->frame_name = NULL;
+      }
 
-    /* Stop before context switch with maestro */
-    if(frame!=NULL && frame->name!=NULL && !strcmp(frame->name, "smx_ctx_sysv_wrapper"))
-      break;
+      /* Stop before context switch with maestro */
+      if (frame != NULL && frame->name != NULL
+          && !strcmp(frame->name, "smx_ctx_sysv_wrapper"))
+        break;
 
-    int ret = ret = unw_step(&c);
-    if(ret==0) {
-      xbt_die("Unexpected end of stack.");
-    } else if(ret<0) {
-      xbt_die("Error while unwinding stack.");
+      int ret = ret = unw_step(&c);
+      if (ret == 0) {
+        xbt_die("Unexpected end of stack.");
+      } else if (ret < 0) {
+        xbt_die("Error while unwinding stack.");
+      }
     }
-  }
 
-  if(xbt_dynar_length(result) == 0){
+  if (xbt_dynar_length(result) == 0) {
     XBT_INFO("unw_init_local failed");
     xbt_abort();
   }
@@ -402,42 +466,48 @@ static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) {
   return result;
 };
 
-static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t *snapshot, void *heap){
+static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t * snapshot)
+{
 
-  xbt_dynar_t res = xbt_dynar_new(sizeof(s_mc_snapshot_stack_t), MC_snapshot_stack_free_voidp);
+  xbt_dynar_t res =
+      xbt_dynar_new(sizeof(s_mc_snapshot_stack_t),
+                    MC_snapshot_stack_free_voidp);
 
   unsigned int cursor = 0;
   stack_region_t current_stack;
-  
-  xbt_dynar_foreach(stacks_areas, cursor, current_stack){
+
+  xbt_dynar_foreach(stacks_areas, cursor, current_stack) {
     mc_snapshot_stack_t st = xbt_new(s_mc_snapshot_stack_t, 1);
     st->stack_frames = MC_unwind_stack_frames(current_stack->context);
     st->local_variables = MC_get_local_variables_values(st->stack_frames);
 
     unw_word_t sp = xbt_dynar_get_as(st->stack_frames, 0, mc_stack_frame_t)->sp;
-    st->stack_pointer = ((char *)heap + (size_t)(((char *)((long)sp) - (char*)std_heap)));
 
-    st->real_address = current_stack->address;
     xbt_dynar_push(res, &st);
-    (*snapshot)->stack_sizes = xbt_realloc((*snapshot)->stack_sizes, (cursor + 1) * sizeof(size_t));
-    (*snapshot)->stack_sizes[cursor] = current_stack->size - ((char *)st->stack_pointer - (char *)((char *)heap + ((char *)current_stack->address - (char *)std_heap)));
+    (*snapshot)->stack_sizes =
+        xbt_realloc((*snapshot)->stack_sizes, (cursor + 1) * sizeof(size_t));
+    (*snapshot)->stack_sizes[cursor] =
+      (char*) current_stack->address + current_stack->size - (char*) sp;
   }
 
   return res;
 
 }
 
-static xbt_dynar_t MC_take_snapshot_ignore(){
-  
-  if(mc_heap_comparison_ignore == NULL)
+static xbt_dynar_t MC_take_snapshot_ignore()
+{
+
+  if (mc_heap_comparison_ignore == NULL)
     return NULL;
 
-  xbt_dynar_t cpy = xbt_dynar_new(sizeof(mc_heap_ignore_region_t), heap_ignore_region_free_voidp);
+  xbt_dynar_t cpy =
+      xbt_dynar_new(sizeof(mc_heap_ignore_region_t),
+                    heap_ignore_region_free_voidp);
 
   unsigned int cursor = 0;
   mc_heap_ignore_region_t current_region;
 
-  xbt_dynar_foreach(mc_heap_comparison_ignore, cursor, current_region){
+  xbt_dynar_foreach(mc_heap_comparison_ignore, cursor, current_region) {
     mc_heap_ignore_region_t new_region = NULL;
     new_region = xbt_new0(s_mc_heap_ignore_region_t, 1);
     new_region->address = current_region->address;
@@ -451,127 +521,133 @@ static xbt_dynar_t MC_take_snapshot_ignore(){
 
 }
 
-static void MC_dump_checkpoint_ignore(mc_snapshot_t snapshot){
-  
+static void mc_free_snapshot_ignored_data_pvoid(void* data) {
+  mc_snapshot_ignored_data_t ignored_data = (mc_snapshot_ignored_data_t) data;
+  free(ignored_data->data);
+}
+
+static void MC_snapshot_handle_ignore(mc_snapshot_t snapshot)
+{
+  snapshot->ignored_data = xbt_dynar_new(sizeof(s_mc_snapshot_ignored_data_t), mc_free_snapshot_ignored_data_pvoid);
+
+  // Copy the memory:
   unsigned int cursor = 0;
   mc_checkpoint_ignore_region_t region;
-  size_t offset;
-  
-  xbt_dynar_foreach(mc_checkpoint_ignore, cursor, region){
-    if(region->addr > snapshot->regions[0]->start_addr && (char *)(region->addr) < (char *)snapshot->regions[0]->start_addr + STD_HEAP_SIZE){
-      offset = (char *)region->addr - (char *)snapshot->regions[0]->start_addr;
-      memset((char *)snapshot->regions[0]->data + offset, 0, region->size);
-    }else if(region->addr > snapshot->regions[2]->start_addr && (char *)(region->addr) < (char*)snapshot->regions[2]->start_addr + snapshot->regions[2]->size){
-      offset = (char *)region->addr - (char *)snapshot->regions[2]->start_addr;
-      memset((char *)snapshot->regions[2]->data + offset, 0, region->size);
-    }else if(region->addr > snapshot->regions[1]->start_addr && (char *)(region->addr) < (char*)snapshot->regions[1]->start_addr + snapshot->regions[1]->size){
-      offset = (char *)region->addr - (char *)snapshot->regions[1]->start_addr;
-      memset((char *)snapshot->regions[1]->data + offset, 0, region->size);
-    }
+  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
+    s_mc_snapshot_ignored_data_t ignored_data;
+    ignored_data.start = region->addr;
+    ignored_data.size = region->size;
+    ignored_data.data = malloc(region->size);
+    memcpy(ignored_data.data, region->addr, region->size);
+    xbt_dynar_push(snapshot->ignored_data, &ignored_data);
+  }
+
+  // Zero the memory:
+  xbt_dynar_foreach (mc_checkpoint_ignore, cursor, region) {
+    memset(region->addr, 0, region->size);
   }
 
 }
 
+static void MC_snapshot_ignore_restore(mc_snapshot_t snapshot)
+{
+  unsigned int cursor = 0;
+  s_mc_snapshot_ignored_data_t ignored_data;
+  xbt_dynar_foreach (snapshot->ignored_data, cursor, ignored_data) {
+    memcpy(ignored_data.start, ignored_data.data, ignored_data.size);
+  }
+}
 
-mc_snapshot_t MC_take_snapshot(int num_state){
+/** @brief Can we remove this snapshot?
+ *
+ * Some snapshots cannot be removed (yet) because we need them
+ * at this point.
+ *
+ * @param snapshot
+ */
+int mc_important_snapshot(mc_snapshot_t snapshot)
+{
+  // We need this snapshot in order to know which
+  // pages needs to be stored in the next snapshot:
+  if (_sg_mc_sparse_checkpoint && snapshot == mc_model_checker->parent_snapshot)
+    return true;
+
+  return false;
+}
+
+mc_snapshot_t MC_take_snapshot(int num_state)
+{
 
   mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1);
-  snapshot->nb_processes = xbt_swag_size(simix_global->process_list);
+  snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL);
+  smx_process_t process;
+  xbt_swag_foreach(process, simix_global->process_list) {
+    xbt_dynar_push_as(snapshot->enabled_processes, int, (int)process->pid);
+  }
+
+  MC_snapshot_handle_ignore(snapshot);
 
   /* Save the std heap and the writable mapped pages of libsimgrid and binary */
   MC_get_memory_regions(snapshot);
+  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+    mc_softdirty_reset();
+  }
 
   snapshot->to_ignore = MC_take_snapshot_ignore();
 
-  if(_sg_mc_visited > 0 || strcmp(_sg_mc_property_file,"")){
-    snapshot->stacks = MC_take_snapshot_stacks(&snapshot, snapshot->regions[0]->data);
-    if(_sg_mc_hash && snapshot->stacks!=NULL) {
+  if (_sg_mc_visited > 0 || strcmp(_sg_mc_property_file, "")) {
+    snapshot->stacks =
+        MC_take_snapshot_stacks(&snapshot);
+    if (_sg_mc_hash && snapshot->stacks != NULL) {
       snapshot->hash = mc_hash_processes_state(num_state, snapshot->stacks);
     } else {
       snapshot->hash = 0;
     }
-  }
-  else {
+  } else {
     snapshot->hash = 0;
   }
 
-  if(num_state > 0)
-    MC_dump_checkpoint_ignore(snapshot);
-
-  // mprotect the region after zero-ing ignored parts:
-  size_t i;
-  for(i=0; i!=NB_REGIONS; ++i) {
-    mc_mem_region_t region = snapshot->regions[i];
-    mprotect(region->data, region->size, PROT_READ);
-  }
-
+  MC_snapshot_ignore_restore(snapshot);
+  mc_model_checker->parent_snapshot = snapshot;
   return snapshot;
-
 }
 
-void MC_restore_snapshot(mc_snapshot_t snapshot){
+void MC_restore_snapshot(mc_snapshot_t snapshot)
+{
+  mc_snapshot_t parent_snapshot = mc_model_checker->parent_snapshot;
+
   unsigned int i;
-  for(i=0; i < NB_REGIONS; i++){
+  for (i = 0; i < NB_REGIONS; i++) {
     // For privatized, variables we decided it was not necessary to take the snapshot:
-    if(snapshot->regions[i])
-      MC_region_restore(snapshot->regions[i]);
+    if (snapshot->regions[i])
+      MC_region_restore(snapshot->regions[i],
+        parent_snapshot ? parent_snapshot->regions[i] : NULL);
   }
 
-  if(snapshot->privatization_regions) {
-    for (i=0; i< SIMIX_process_count(); i++){
-      if(snapshot->privatization_regions[i]) {
-        MC_region_restore(snapshot->privatization_regions[i]);
+  if (snapshot->privatization_regions) {
+    for (i = 0; i < SIMIX_process_count(); i++) {
+      if (snapshot->privatization_regions[i]) {
+        MC_region_restore(snapshot->privatization_regions[i],
+          parent_snapshot ? parent_snapshot->privatization_regions[i] : NULL);
       }
     }
     switch_data_segment(snapshot->privatization_index);
   }
-}
-
-void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot) {
 
-  // If not in a process state/clone:
-  if(!snapshot) {
-    return (uintptr_t*) addr;
+  if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {
+    mc_softdirty_reset();
   }
 
-  // If it is in a snapshot:
-  for(size_t i=0; i!=NB_REGIONS; ++i) {
-    mc_mem_region_t region = snapshot->regions[i];
-    uintptr_t start = (uintptr_t) region->start_addr;
-    uintptr_t end = start + region->size;
-
-    // The address is in this region:
-    if(addr >= start && addr < end) {
-      uintptr_t offset = addr - start;
-      return (void*) ((uintptr_t)region->data + offset);
-    }
-
-  }
-
-  // It is not in a snapshot:
-  return (void*) addr;
+  MC_snapshot_ignore_restore(snapshot);
+  mc_model_checker->parent_snapshot = snapshot;
 }
 
-uintptr_t mc_untranslate_address(void* addr, mc_snapshot_t snapshot) {
-  if(!snapshot) {
-    return (uintptr_t) addr;
-  }
-
-  for(size_t i=0; i!=NB_REGIONS; ++i) {
-    mc_mem_region_t region = snapshot->regions[i];
-    if(addr>=region->data && addr<=(void*)(((char*)region->data)+region->size)) {
-      size_t offset = (size_t) ((char*) addr - (char*) region->data);
-      return ((uintptr_t) region->start_addr) + offset;
-    }
-  }
-
-  return (uintptr_t) addr;
-}
-
-mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall){
+mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall)
+{
   return MC_take_snapshot(1);
 }
 
-void *MC_snapshot(void){
+void *MC_snapshot(void)
+{
   return simcall_mc_snapshot();
 }
diff --git a/src/mc/mc_comm_determinism.c b/src/mc/mc_comm_determinism.c
new file mode 100644 (file)
index 0000000..ff04989
--- /dev/null
@@ -0,0 +1,523 @@
+/* Copyright (c) 2008-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "mc_private.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_comm_determinism, mc,
+                                "Logging specific to MC communication determinism detection");
+
+/********** Global variables **********/
+
+xbt_dynar_t initial_communications_pattern;
+xbt_dynar_t incomplete_communications_pattern;
+xbt_dynar_t communications_pattern;
+int nb_comm_pattern;
+
+/********** Static functions ***********/
+
+static void comm_pattern_free(mc_comm_pattern_t p)
+{
+  xbt_free(p->rdv);
+  xbt_free(p->data);
+  xbt_free(p);
+  p = NULL;
+}
+
+static void comm_pattern_free_voidp(void *p)
+{
+  comm_pattern_free((mc_comm_pattern_t) * (void **) p);
+}
+
+static mc_comm_pattern_t get_comm_pattern_from_idx(xbt_dynar_t pattern,
+                                                   unsigned int *idx,
+                                                   e_smx_comm_type_t type,
+                                                   unsigned long proc)
+{
+  mc_comm_pattern_t current_comm;
+  while (*idx < xbt_dynar_length(pattern)) {
+    current_comm =
+        (mc_comm_pattern_t) xbt_dynar_get_as(pattern, *idx, mc_comm_pattern_t);
+    if (current_comm->type == type && type == SIMIX_COMM_SEND) {
+      if (current_comm->src_proc == proc)
+        return current_comm;
+    } else if (current_comm->type == type && type == SIMIX_COMM_RECEIVE) {
+      if (current_comm->dst_proc == proc)
+        return current_comm;
+    }
+    (*idx)++;
+  }
+  return NULL;
+}
+
+static int compare_comm_pattern(mc_comm_pattern_t comm1,
+                                mc_comm_pattern_t comm2)
+{
+  if (strcmp(comm1->rdv, comm2->rdv) != 0)
+    return 1;
+  if (comm1->src_proc != comm2->src_proc)
+    return 1;
+  if (comm1->dst_proc != comm2->dst_proc)
+    return 1;
+  if (comm1->data_size != comm2->data_size)
+    return 1;
+  if (memcmp(comm1->data, comm2->data, comm1->data_size) != 0)
+    return 1;
+  return 0;
+}
+
+static void deterministic_pattern(xbt_dynar_t pattern, int partial)
+{
+
+  unsigned int cursor = 0, send_index = 0, recv_index = 0;
+  mc_comm_pattern_t comm1, comm2;
+  unsigned int current_process = 1; /* Process 0 corresponds to maestro */
+  unsigned int nb_comms1, nb_comms2;
+  xbt_dynar_t process_comms_pattern1, process_comms_pattern2; 
+  
+  while (current_process < simix_process_maxpid) {
+    process_comms_pattern1 = (xbt_dynar_t)xbt_dynar_get_as(initial_communications_pattern, current_process, xbt_dynar_t);
+    process_comms_pattern2 = (xbt_dynar_t)xbt_dynar_get_as(pattern, current_process, xbt_dynar_t);
+    nb_comms1 = xbt_dynar_length(process_comms_pattern1);
+    nb_comms2 = xbt_dynar_length(process_comms_pattern2);
+    if(!xbt_dynar_is_empty((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, current_process, xbt_dynar_t)))
+      xbt_die("Damn ! Some communications from the process %u are incomplete (%lu)! That means one or several simcalls are not handle.", current_process, xbt_dynar_length((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, current_process, xbt_dynar_t)));
+    if (partial && (nb_comms1 != nb_comms2)) {
+      XBT_INFO("The total number of communications is different between the compared patterns for the process %u.\n Communication determinism verification for this process cannot be performed.", current_process);
+      initial_global_state->send_deterministic = -1;
+      initial_global_state->comm_deterministic = -1;
+    } else {
+      while (cursor < nb_comms2) {
+        comm1 = (mc_comm_pattern_t)xbt_dynar_get_as(process_comms_pattern1, cursor, mc_comm_pattern_t);
+        if (comm1->type == SIMIX_COMM_SEND && comm1->src_proc == current_process) {
+          comm2 = get_comm_pattern_from_idx(process_comms_pattern2, &send_index, comm1->type, current_process);
+          if (compare_comm_pattern(comm1, comm2)) {
+            XBT_INFO("The communications pattern of the process %u is different!", current_process);
+            initial_global_state->send_deterministic = 0;
+            initial_global_state->comm_deterministic = 0;
+            return;
+          }
+          send_index++;
+        } else if (comm1->type == SIMIX_COMM_RECEIVE && comm1->dst_proc == current_process) {
+          comm2 = get_comm_pattern_from_idx(process_comms_pattern2, &recv_index, comm1->type, current_process);
+          if (compare_comm_pattern(comm1, comm2)) {
+            initial_global_state->comm_deterministic = 0;
+            if (!_sg_mc_send_determinism){
+              XBT_INFO("The communications pattern of the process %u is different!", current_process);
+              return;
+            }
+          }
+          recv_index++;
+        }
+        cursor++;
+      }
+    }
+    current_process++;
+    cursor = 0;
+    send_index = 0;
+    recv_index = 0;
+  }
+}
+
+static void print_communications_pattern(xbt_dynar_t comms_pattern)
+{
+  unsigned int cursor = 0;
+  mc_comm_pattern_t current_comm;
+  unsigned int current_process = 1;
+  xbt_dynar_t current_pattern;
+  while (current_process < simix_process_maxpid) {
+    current_pattern = (xbt_dynar_t)xbt_dynar_get_as(comms_pattern, current_process, xbt_dynar_t);
+    XBT_INFO("Communications from the process %u:", current_process);
+    xbt_dynar_foreach(current_pattern, cursor, current_comm) {
+      if (current_comm->type == SIMIX_COMM_SEND) {
+        XBT_INFO("[(%lu) %s -> (%lu) %s] %s ", current_comm->src_proc,
+                 current_comm->src_host, current_comm->dst_proc,
+                 current_comm->dst_host, "iSend");
+      } else {
+        XBT_INFO("[(%lu) %s <- (%lu) %s] %s ", current_comm->dst_proc,
+                 current_comm->dst_host, current_comm->src_proc,
+                 current_comm->src_host, "iRecv");
+      }
+    }
+    current_process++;
+    cursor = 0;
+  }
+}
+
+static void update_comm_pattern(mc_comm_pattern_t comm_pattern, smx_action_t comm)
+{
+  void *addr_pointed;
+  comm_pattern->src_proc = comm->comm.src_proc->pid;
+  comm_pattern->dst_proc = comm->comm.dst_proc->pid;
+  comm_pattern->src_host =
+    simcall_host_get_name(comm->comm.src_proc->smx_host);
+  comm_pattern->dst_host =
+    simcall_host_get_name(comm->comm.dst_proc->smx_host);
+  if (comm_pattern->data_size == -1) {
+    comm_pattern->data_size = *(comm->comm.dst_buff_size);
+    comm_pattern->data = xbt_malloc0(comm_pattern->data_size);
+    addr_pointed = *(void **) comm->comm.src_buff;
+    if (addr_pointed > std_heap && addr_pointed < ((xbt_mheap_t) std_heap)->breakval)
+      memcpy(comm_pattern->data, addr_pointed, comm_pattern->data_size);
+    else
+      memcpy(comm_pattern->data, comm->comm.src_buff, comm_pattern->data_size);
+  }
+}
+
+/********** Non Static functions ***********/
+
+void get_comm_pattern(xbt_dynar_t list, smx_simcall_t request, int call)
+{
+  mc_comm_pattern_t pattern = NULL;
+  pattern = xbt_new0(s_mc_comm_pattern_t, 1);
+  pattern->num = ++nb_comm_pattern;
+  pattern->data_size = -1;
+  void *addr_pointed;
+  if (call == 1) {              // ISEND
+    pattern->type = SIMIX_COMM_SEND;
+    pattern->comm = simcall_comm_isend__get__result(request);
+    pattern->src_proc = pattern->comm->comm.src_proc->pid;
+    pattern->src_host = simcall_host_get_name(request->issuer->smx_host);
+    pattern->data_size = pattern->comm->comm.src_buff_size;
+    pattern->data = xbt_malloc0(pattern->data_size);
+    addr_pointed = *(void **) pattern->comm->comm.src_buff;
+    if (addr_pointed > std_heap
+        && addr_pointed < ((xbt_mheap_t) std_heap)->breakval)
+      memcpy(pattern->data, addr_pointed, pattern->data_size);
+    else
+      memcpy(pattern->data, pattern->comm->comm.src_buff, pattern->data_size);
+  } else {                      // IRECV
+    pattern->type = SIMIX_COMM_RECEIVE;
+    pattern->comm = simcall_comm_irecv__get__result(request);
+    pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
+    pattern->dst_host = simcall_host_get_name(request->issuer->smx_host);
+  }
+
+  if (pattern->comm->comm.rdv != NULL)
+    pattern->rdv = strdup(pattern->comm->comm.rdv->name);
+  else
+    pattern->rdv = strdup(pattern->comm->comm.rdv_cpy->name);
+
+  xbt_dynar_push((xbt_dynar_t)xbt_dynar_get_as(list, request->issuer->pid, xbt_dynar_t), &pattern);
+
+  xbt_dynar_push_as((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, request->issuer->pid, xbt_dynar_t), int, xbt_dynar_length((xbt_dynar_t)xbt_dynar_get_as(list, request->issuer->pid, xbt_dynar_t)) - 1);
+
+}
+
+void complete_comm_pattern(xbt_dynar_t list, smx_action_t comm)
+{
+  mc_comm_pattern_t current_comm_pattern;
+  unsigned int cursor = 0;
+  int index;
+  unsigned int src = comm->comm.src_proc->pid;
+  unsigned int dst = comm->comm.dst_proc->pid;
+  int src_completed = 0, dst_completed = 0;
+
+  /* Looking for the corresponding communication in the comm pattern list of the src process */
+  xbt_dynar_foreach((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, src, xbt_dynar_t), cursor, index){
+    current_comm_pattern = (mc_comm_pattern_t) xbt_dynar_get_as((xbt_dynar_t)xbt_dynar_get_as(list, src, xbt_dynar_t), index, mc_comm_pattern_t);
+    if(current_comm_pattern->comm == comm){
+      update_comm_pattern(current_comm_pattern, comm);
+      xbt_dynar_remove_at((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, src, xbt_dynar_t), cursor, NULL);
+      src_completed = 1;
+      break;
+    }
+  }
+
+  if(!src_completed)
+    xbt_die("Corresponding communication for the source process not found!");
+
+  cursor = 0;
+
+  /* Looking for the corresponding communication in the comm pattern list of the dst process */
+  xbt_dynar_foreach((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, dst, xbt_dynar_t), cursor, index){
+    current_comm_pattern = (mc_comm_pattern_t) xbt_dynar_get_as((xbt_dynar_t)xbt_dynar_get_as(list, dst, xbt_dynar_t), index, mc_comm_pattern_t);
+    if(current_comm_pattern->comm == comm){
+      update_comm_pattern(current_comm_pattern, comm);
+      xbt_dynar_remove_at((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, dst, xbt_dynar_t), cursor, NULL);
+      dst_completed = 1;
+      break;
+    }
+  }
+
+  if(!dst_completed)
+    xbt_die("Corresponding communication for the dest process not found!");
+
+
+}
+
+/************************ Main algorithm ************************/
+
+void MC_pre_modelcheck_comm_determinism(void)
+{
+
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  mc_state_t initial_state = NULL;
+  smx_process_t process;
+  int i;
+
+  if (!mc_mem_set)
+    MC_SET_MC_HEAP;
+
+  if (_sg_mc_visited > 0)
+    visited_states = xbt_dynar_new(sizeof(mc_visited_state_t), visited_state_free_voidp);
+  initial_communications_pattern = xbt_dynar_new(sizeof(xbt_dynar_t), xbt_dynar_free_voidp);
+  for (i=0; i<simix_process_maxpid; i++){
+    xbt_dynar_t process_pattern = xbt_dynar_new(sizeof(mc_comm_pattern_t), comm_pattern_free_voidp);
+    xbt_dynar_insert_at(initial_communications_pattern, i, &process_pattern);
+  }
+  communications_pattern = xbt_dynar_new(sizeof(xbt_dynar_t), xbt_dynar_free_voidp);
+  for (i=0; i<simix_process_maxpid; i++){
+    xbt_dynar_t process_pattern = xbt_dynar_new(sizeof(mc_comm_pattern_t), comm_pattern_free_voidp);
+    xbt_dynar_insert_at(communications_pattern, i, &process_pattern);
+  }
+  incomplete_communications_pattern = xbt_dynar_new(sizeof(xbt_dynar_t), xbt_dynar_free_voidp);
+  for (i=0; i<simix_process_maxpid; i++){
+    xbt_dynar_t process_pattern = xbt_dynar_new(sizeof(int), NULL);
+    xbt_dynar_insert_at(incomplete_communications_pattern, i, &process_pattern);
+  }
+
+  nb_comm_pattern = 0;
+
+  initial_state = MC_state_new();
+
+  MC_SET_STD_HEAP;
+
+  XBT_DEBUG("********* Start communication determinism verification *********");
+
+  /* Wait for requests (schedules processes) */
+  MC_wait_for_requests();
+
+  MC_SET_MC_HEAP;
+
+  /* Get an enabled process and insert it in the interleave set of the initial state */
+  xbt_swag_foreach(process, simix_global->process_list) {
+    if (MC_process_is_enabled(process)) {
+      MC_state_interleave_process(initial_state, process);
+    }
+  }
+
+  xbt_fifo_unshift(mc_stack, initial_state);
+
+  MC_SET_STD_HEAP;
+
+}
+
+void MC_modelcheck_comm_determinism(void)
+{
+
+  char *req_str = NULL;
+  int value, call = 0;
+  mc_visited_state_t visited_state = NULL;
+  smx_simcall_t req = NULL;
+  smx_process_t process = NULL;
+  mc_state_t state = NULL, next_state = NULL;
+  smx_action_t current_comm;
+  xbt_dynar_t current_pattern;
+
+  while (xbt_fifo_size(mc_stack) > 0) {
+
+    /* Get current state */
+    state =
+        (mc_state_t)
+        xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack));
+
+    XBT_DEBUG("**************************************************");
+    XBT_DEBUG("Exploration depth = %d (state = %d, interleaved processes = %d)",
+              xbt_fifo_size(mc_stack), state->num,
+              MC_state_interleave_size(state));
+
+    /* Update statistics */
+    mc_stats->visited_states++;
+
+    if ((xbt_fifo_size(mc_stack) <= _sg_mc_max_depth)
+        && (req = MC_state_get_request(state, &value))
+        && (visited_state == NULL)) {
+
+      /* Debug information */
+      if (XBT_LOG_ISENABLED(mc_comm_determinism, xbt_log_priority_debug)) {
+        req_str = MC_request_to_string(req, value);
+        XBT_DEBUG("Execute: %s", req_str);
+        xbt_free(req_str);
+      }
+
+      MC_SET_MC_HEAP;
+      if (dot_output != NULL)
+        req_str = MC_request_get_dot_output(req, value);
+      MC_SET_STD_HEAP;
+
+      MC_state_set_executed_request(state, req, value);
+      mc_stats->executed_transitions++;
+
+      /* TODO : handle test and testany simcalls */
+      if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
+        if (req->call == SIMCALL_COMM_ISEND)
+          call = 1;
+        else if (req->call == SIMCALL_COMM_IRECV)
+          call = 2;
+        else if (req->call == SIMCALL_COMM_WAIT)
+          call = 3;
+        else if (req->call == SIMCALL_COMM_WAITANY)
+          call = 4;
+      }
+
+      /* Answer the request */
+      SIMIX_simcall_pre(req, value);    /* After this call req is no longer usefull */
+
+      MC_SET_MC_HEAP;
+      current_pattern = !initial_global_state->initial_communications_pattern_done ? initial_communications_pattern : communications_pattern; 
+      if (call == 1) { /* Send */
+        get_comm_pattern(current_pattern, req, call);
+      } else if (call == 2) { /* Recv */
+        get_comm_pattern(current_pattern, req, call);
+      } else if (call == 3) { /* Wait */
+        current_comm = simcall_comm_wait__get__comm(req);
+        if (current_comm->comm.refcount == 1)  /* First wait only must be considered */
+          complete_comm_pattern(current_pattern, current_comm);
+      } else if (call == 4) { /* WaitAny */
+        current_comm = xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), value, smx_action_t);
+        if (current_comm->comm.refcount == 1) /* First wait only must be considered */
+          complete_comm_pattern(current_pattern, current_comm);
+      }
+      MC_SET_STD_HEAP;
+
+      call = 0;
+
+      /* Wait for requests (schedules processes) */
+      MC_wait_for_requests();
+
+      /* Create the new expanded state */
+      MC_SET_MC_HEAP;
+
+      next_state = MC_state_new();
+
+      if ((visited_state = is_visited_state()) == NULL) {
+
+        /* Get enabled processes and insert them in the interleave set of the next state */
+        xbt_swag_foreach(process, simix_global->process_list) {
+          if (MC_process_is_enabled(process)) {
+            MC_state_interleave_process(next_state, process);
+          }
+        }
+
+        if (dot_output != NULL)
+          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num,
+                  next_state->num, req_str);
+
+      } else {
+
+        if (dot_output != NULL)
+          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num,
+                  visited_state->other_num == -1 ? visited_state->num : visited_state->other_num, req_str);
+
+      }
+
+      xbt_fifo_unshift(mc_stack, next_state);
+
+      if (dot_output != NULL)
+        xbt_free(req_str);
+
+      MC_SET_STD_HEAP;
+
+    } else {
+
+      if (xbt_fifo_size(mc_stack) > _sg_mc_max_depth) {
+        XBT_WARN("/!\\ Max depth reached ! /!\\ ");
+      } else if (visited_state != NULL) {
+        XBT_DEBUG("State already visited (equal to state %d), exploration stopped on this path.", visited_state->other_num == -1 ? visited_state->num : visited_state->other_num);
+      } else {
+        XBT_DEBUG("There are no more processes to interleave. (depth %d)", xbt_fifo_size(mc_stack));
+      }
+
+      MC_SET_MC_HEAP;
+
+      if (initial_global_state->initial_communications_pattern_done) {
+        if (!visited_state) {
+          deterministic_pattern(communications_pattern, 0);
+        } else {
+          deterministic_pattern(communications_pattern, 1);
+        }
+
+        if (_sg_mc_comms_determinism && !initial_global_state->comm_deterministic) {
+            XBT_INFO("****************************************************");
+            XBT_INFO("***** Non-deterministic communications pattern *****");
+            XBT_INFO("****************************************************");
+            XBT_INFO("** Initial communications pattern (per process): **");
+            print_communications_pattern(initial_communications_pattern);
+            XBT_INFO("** Communications pattern counter-example (per process): **");
+            print_communications_pattern(communications_pattern);
+            MC_print_statistics(mc_stats);
+            MC_SET_STD_HEAP;
+            return;
+          } else if (_sg_mc_send_determinism && !initial_global_state->send_deterministic) {
+            XBT_INFO
+                ("*********************************************************");
+            XBT_INFO
+                ("***** Non-send-deterministic communications pattern *****");
+            XBT_INFO
+                ("*********************************************************");
+            XBT_INFO("** Initial communications pattern: **");
+            print_communications_pattern(initial_communications_pattern);
+            XBT_INFO("** Communications pattern counter-example: **");
+            print_communications_pattern(communications_pattern);
+            MC_print_statistics(mc_stats);
+            MC_SET_STD_HEAP;
+            return;
+        }
+
+      } else {
+        initial_global_state->initial_communications_pattern_done = 1;
+      }
+
+      /* Trash the current state, no longer needed */
+      xbt_fifo_shift(mc_stack);
+      MC_state_delete(state);
+      XBT_DEBUG("Delete state %d at depth %d", state->num,
+                xbt_fifo_size(mc_stack) + 1);
+
+      MC_SET_STD_HEAP;
+
+      visited_state = NULL;
+
+      /* Check for deadlocks */
+      if (MC_deadlock_check()) {
+        MC_show_deadlock(NULL);
+        return;
+      }
+
+      MC_SET_MC_HEAP;
+
+      while ((state = xbt_fifo_shift(mc_stack)) != NULL) {
+        if (MC_state_interleave_size(state)
+            && xbt_fifo_size(mc_stack) < _sg_mc_max_depth) {
+          /* We found a back-tracking point, let's loop */
+          XBT_DEBUG("Back-tracking to state %d at depth %d", state->num,
+                    xbt_fifo_size(mc_stack) + 1);
+          xbt_fifo_unshift(mc_stack, state);
+          MC_SET_STD_HEAP;
+
+          MC_replay(mc_stack, -1);
+
+          XBT_DEBUG("Back-tracking to state %d at depth %d done", state->num,
+                    xbt_fifo_size(mc_stack));
+          break;
+        } else {
+          XBT_DEBUG("Delete state %d at depth %d", state->num,
+                    xbt_fifo_size(mc_stack) + 1);
+          MC_state_delete(state);
+        }
+      }
+
+      MC_SET_STD_HEAP;
+    }
+  }
+
+  MC_print_statistics(mc_stats);
+  MC_SET_STD_HEAP;
+
+  return;
+}
diff --git a/src/mc/mc_compare.c b/src/mc/mc_compare.c
deleted file mode 100644 (file)
index 5bc8380..0000000
+++ /dev/null
@@ -1,635 +0,0 @@
-/* Copyright (c) 2012-2014. The SimGrid Team.
- * All rights reserved.                                                     */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include <inttypes.h>
-
-#include "mc_private.h"
-
-#include "xbt/mmalloc.h"
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, mc,
-                                "Logging specific to mc_compare");
-
-typedef struct s_pointers_pair{
-  void *p1;
-  void *p2;
-}s_pointers_pair_t, *pointers_pair_t;
-
-__thread xbt_dynar_t compared_pointers;
-
-/************************** Free functions ****************************/
-/********************************************************************/
-
-static void stack_region_free(stack_region_t s){
-  if(s){
-    xbt_free(s->process_name);
-    xbt_free(s);
-  }
-}
-
-static void stack_region_free_voidp(void *s){
-  stack_region_free((stack_region_t) * (void **) s);
-}
-
-static void pointers_pair_free(pointers_pair_t p){
-  xbt_free(p);
-}
-
-static void pointers_pair_free_voidp(void *p){
-  pointers_pair_free((pointers_pair_t) * (void **)p);
-}
-
-/************************** Snapshot comparison *******************************/
-/******************************************************************************/
-
-/** \brief Try to add a pair a compared pointers to the set of compared pointers
- *
- *  \result !=0 if the pointers were added (they were not in the set),
- *      0 otherwise (they were already in the set)
- */
-static int add_compared_pointers(void *p1, void *p2){
-
-  pointers_pair_t new_pair = xbt_new0(s_pointers_pair_t, 1);
-  new_pair->p1 = p1;
-  new_pair->p2 = p2;
-  
-  if(xbt_dynar_is_empty(compared_pointers)){
-    xbt_dynar_push(compared_pointers, &new_pair);
-    return 1;
-  }
-
-  unsigned int cursor = 0;
-  int start = 0;
-  int end = xbt_dynar_length(compared_pointers) - 1;
-  pointers_pair_t pair = NULL;
-
-  pointers_pair_t* p = (pointers_pair_t*) xbt_dynar_get_ptr(compared_pointers, 0);
-
-  while(start <= end){
-    cursor = (start + end) / 2;
-    pair = p[cursor];
-    if(pair->p1 < p1){
-      start = cursor + 1;
-    } else if(pair->p1 > p1) {
-      end = cursor - 1 ;
-    } else if(pair->p2 < p2){
-      start = cursor + 1;
-    } else if(pair->p2 > p2) {
-      end = cursor - 1 ;
-    } else {
-      pointers_pair_free(new_pair);
-      return 0;
-    }
-  }
-
-  if(pair->p1 < p1)
-    xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
-  else if(pair->p1 > p1)
-    xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);
-  else if(pair->p2 < p2)
-    xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
-  else if(pair->p2 > p2)
-    xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);
-  else
-    xbt_die("Unrecheable");
-
-  return 1;
-}
-
-static int compare_areas_with_type(void *area1, void *area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, dw_type_t type, int region_size, int region_type, void *start_data, int pointer_level){
-
-  unsigned int cursor = 0;
-  dw_type_t member, subtype, subsubtype;
-  int elm_size, i, res;
-  void *addr_pointed1, *addr_pointed2;
-
-  switch(type->type){
-  case DW_TAG_unspecified_type:
-    return 1;
-
-  case DW_TAG_base_type:
-  case DW_TAG_enumeration_type:
-  case DW_TAG_union_type:
-    return (memcmp(area1, area2, type->byte_size) != 0);
-    break;
-  case DW_TAG_typedef:
-  case DW_TAG_volatile_type:
-  case DW_TAG_const_type:
-    return compare_areas_with_type(area1, area2, snapshot1, snapshot2, type->subtype, region_size, region_type, start_data, pointer_level);
-    break;
-  case DW_TAG_array_type:
-    subtype = type->subtype;
-    switch(subtype->type){
-    case DW_TAG_unspecified_type:
-      return 1;
-
-    case DW_TAG_base_type:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_pointer_type:
-    case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_class_type:
-    case DW_TAG_union_type:
-      if(subtype->full_type)
-        subtype = subtype->full_type;
-      elm_size = subtype->byte_size;
-      break;
-    case DW_TAG_const_type:
-    case DW_TAG_typedef:
-    case DW_TAG_volatile_type:
-      subsubtype = subtype->subtype;
-      if(subsubtype->full_type)
-          subsubtype = subsubtype->full_type;
-      elm_size = subsubtype->byte_size;
-      break;
-    default : 
-      return 0;
-      break;
-    }
-    for(i=0; i<type->element_count; i++){
-      res = compare_areas_with_type((char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), snapshot1, snapshot2, type->subtype, region_size, region_type, start_data, pointer_level);
-      if(res == 1)
-        return res;
-    }
-    break;
-  case DW_TAG_pointer_type:
-  case DW_TAG_reference_type:
-  case DW_TAG_rvalue_reference_type:
-
-    addr_pointed1 = *((void **)(area1));
-    addr_pointed2 = *((void **)(area2));
-
-    if(type->subtype && type->subtype->type == DW_TAG_subroutine_type){
-      return (addr_pointed1 != addr_pointed2);
-    }else{
-      
-      if(addr_pointed1 == NULL && addr_pointed2 == NULL)
-        return 0;
-      if(!add_compared_pointers(addr_pointed1, addr_pointed2))
-        return 0;
-
-      pointer_level++;
-      
-      // Some cases are not handled here:
-      // * the pointers lead to different areas (one to the heap, the other to the RW segment ...);
-      // * a pointer leads to the read-only segment of the current object;
-      // * a pointer lead to a different ELF object.
-
-      // The pointers are both in the heap:
-      if(addr_pointed1 > std_heap && (char *)addr_pointed1 < (char*) std_heap + STD_HEAP_SIZE){
-        if(!(addr_pointed2 > std_heap && (char *)addr_pointed2 < (char*) std_heap + STD_HEAP_SIZE))
-          return 1;
-        return compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, NULL, type->subtype, pointer_level);
-      }
-
-      // The pointers are both in the current object R/W segment:
-      else if(addr_pointed1 > start_data && (char*)addr_pointed1 <= (char *)start_data + region_size){
-        if(!(addr_pointed2 > start_data && (char*)addr_pointed2 <= (char *)start_data + region_size))
-          return 1;
-        if(type->dw_type_id == NULL)
-          return  (addr_pointed1 != addr_pointed2);
-        else {
-          void* translated_addr_pointer1 = mc_translate_address((uintptr_t)addr_pointed1, snapshot1);
-          void* translated_addr_pointer2 = mc_translate_address((uintptr_t)addr_pointed2, snapshot2);
-          return  compare_areas_with_type(
-            translated_addr_pointer1, translated_addr_pointer2, snapshot1, snapshot2, type->subtype, region_size, region_type, start_data, pointer_level);
-        }
-      }
-
-      else{
-        return (addr_pointed1 != addr_pointed2);
-      }
-    }
-    break;
-  case DW_TAG_structure_type:
-  case DW_TAG_class_type:
-    xbt_dynar_foreach(type->members, cursor, member){
-      XBT_DEBUG("Compare member %s", member->name);
-      void* member1 = mc_member_snapshot_resolve(area1, type, member, snapshot1);
-      void* member2 = mc_member_snapshot_resolve(area2, type, member, snapshot2);
-      res = compare_areas_with_type(member1, member2, snapshot1, snapshot2, member->subtype, region_size, region_type, start_data, pointer_level);
-      if(res == 1)
-        return res;
-    }
-    break;
-  case DW_TAG_subroutine_type:
-    return -1;
-    break;
-  default:
-    XBT_VERB("Unknown case : %d", type->type);
-    break;
-  }
-  
-  return 0;
-}
-
-static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_region_t r2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2){
-
-  if(!compared_pointers){
-    compared_pointers = xbt_dynar_new(sizeof(pointers_pair_t), pointers_pair_free_voidp);
-  }else{
-    xbt_dynar_reset(compared_pointers);
-  }
-
-  xbt_dynar_t variables;
-  int res;
-  unsigned int cursor = 0;
-  dw_variable_t current_var;
-  size_t offset;
-  void *start_data;
-  void* start_data_binary = mc_binary_info->start_rw;
-  void* start_data_libsimgrid = mc_libsimgrid_info->start_rw;
-
-  mc_object_info_t object_info = NULL;
-  if(region_type == 2){
-    object_info = mc_binary_info;
-    start_data = start_data_binary;
-  }else{
-    object_info = mc_libsimgrid_info;
-    start_data = start_data_libsimgrid;
-  }
-  variables = object_info->global_variables;
-
-  xbt_dynar_foreach(variables, cursor, current_var){
-
-    // If the variable is not in this object, skip it:
-    // We do not expect to find a pointer to something which is not reachable
-    // by the global variables.
-    if((char*) current_var->address < (char*) object_info->start_rw
-      || (char*) current_var->address > (char*) object_info->end_rw)
-       continue;
-
-    offset = (char *)current_var->address - (char *)object_info->start_rw;
-
-    dw_type_t bvariable_type = current_var->type;
-    res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, snapshot1, snapshot2, bvariable_type, r1->size, region_type, start_data, 0);
-    if(res == 1){
-      XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset);
-      xbt_dynar_free(&compared_pointers);
-      compared_pointers = NULL;
-      return 1;
-    }
-
-  }
-
-  xbt_dynar_free(&compared_pointers);
-  compared_pointers = NULL;
-
-  return 0;
-
-}
-
-static int compare_local_variables(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, mc_snapshot_stack_t stack1, mc_snapshot_stack_t stack2, void *heap1, void *heap2){
-  void* start_data_binary = mc_binary_info->start_rw;
-  void* start_data_libsimgrid = mc_libsimgrid_info->start_rw;
-
-  if(!compared_pointers){
-    compared_pointers = xbt_dynar_new(sizeof(pointers_pair_t), pointers_pair_free_voidp);
-  }else{
-    xbt_dynar_reset(compared_pointers);
-  }
-
-  if(xbt_dynar_length(stack1->local_variables) != xbt_dynar_length(stack2->local_variables)){
-    XBT_VERB("Different number of local variables");
-    xbt_dynar_free(&compared_pointers);
-    compared_pointers = NULL;
-    return 1;
-  }else{
-    unsigned int cursor = 0;
-    local_variable_t current_var1, current_var2;
-    int offset1, offset2, res;
-    while(cursor < xbt_dynar_length(stack1->local_variables)){
-      current_var1 = (local_variable_t)xbt_dynar_get_as(stack1->local_variables, cursor, local_variable_t);
-      current_var2 = (local_variable_t)xbt_dynar_get_as(stack2->local_variables, cursor, local_variable_t);
-      if(strcmp(current_var1->name, current_var2->name) != 0 || current_var1->subprogram != current_var1->subprogram || current_var1->ip != current_var2->ip){
-        xbt_dynar_free(&compared_pointers);
-        // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
-        XBT_VERB("Different name of variable (%s - %s) or frame (%s - %s) or ip (%lu - %lu)", current_var1->name, current_var2->name, current_var1->subprogram->name, current_var2->subprogram->name, current_var1->ip, current_var2->ip);
-        return 1;
-      }
-      offset1 = (char *)current_var1->address - (char *)std_heap;
-      offset2 = (char *)current_var2->address - (char *)std_heap;
-      // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
-      XBT_DEBUG("Compare local variable %s of frame %s", current_var1->subprogram->name, current_var1->subprogram->name);
-
-
-      if(current_var1->region == 1) {
-        dw_type_t subtype = current_var1->type;
-        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, snapshot1, snapshot2, subtype, 0, 1, start_data_libsimgrid, 0);
-      } else {
-        dw_type_t subtype = current_var2->type;
-        res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, snapshot1, snapshot2, subtype, 0, 2, start_data_binary, 0);
-      }
-      if(res == 1){
-        // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
-        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->subprogram->name);
-        xbt_dynar_free(&compared_pointers);
-        compared_pointers = NULL;
-        return res;
-      }
-      cursor++;
-    }
-    xbt_dynar_free(&compared_pointers);
-    compared_pointers = NULL;
-    return 0;
-  }
-}
-
-int snapshot_compare(void *state1, void *state2){
-
-  mc_snapshot_t s1, s2;
-  int num1, num2;
-  
-  if(_sg_mc_property_file && _sg_mc_property_file[0] != '\0'){ /* Liveness MC */
-    s1 = ((mc_visited_pair_t)state1)->graph_state->system_state;
-    s2 = ((mc_visited_pair_t)state2)->graph_state->system_state;
-    num1 = ((mc_visited_pair_t)state1)->num;
-    num2 =  ((mc_visited_pair_t)state2)->num;
-    /* Firstly compare automaton state */
-    /*if(xbt_automaton_state_compare(((mc_pair_t)state1)->automaton_state, ((mc_pair_t)state2)->automaton_state) != 0)
-      return 1;
-    if(xbt_automaton_propositional_symbols_compare_value(((mc_pair_t)state1)->atomic_propositions, ((mc_pair_t)state2)->atomic_propositions) != 0)
-    return 1;*/
-  }else{ /* Safety MC */
-    s1 = ((mc_visited_state_t)state1)->system_state;
-    s2 = ((mc_visited_state_t)state2)->system_state;
-    num1 = ((mc_visited_state_t)state1)->num;
-    num2 = ((mc_visited_state_t)state2)->num;
-  }
-
-  int errors = 0;
-  int res_init;
-
-  xbt_os_timer_t global_timer = xbt_os_timer_new();
-  xbt_os_timer_t timer = xbt_os_timer_new();
-
-  xbt_os_walltimer_start(global_timer);
-
-  #ifdef MC_DEBUG
-    xbt_os_walltimer_start(timer);
-  #endif
-
-  int hash_result = 0;
-  if(_sg_mc_hash) {
-    hash_result = (s1->hash != s2->hash);
-    if(hash_result) {
-      XBT_VERB("(%d - %d) Different hash : 0x%" PRIx64 "--0x%" PRIx64, num1, num2, s1->hash, s2->hash);
-#ifndef MC_DEBUG
-      return 1;
-#endif
-    } else {
-      XBT_VERB("(%d - %d) Same hash : 0x%" PRIx64, num1, num2, s1->hash);
-    }
-  }
-
-  int i = 0;
-  size_t size_used1, size_used2;
-  int is_diff = 0;
-
-
-  /* Compare size of stacks */
-  while(i < xbt_dynar_length(s1->stacks)){
-    size_used1 = s1->stack_sizes[i];
-    size_used2 = s2->stack_sizes[i];
-    if(size_used1 != size_used2){
-    #ifdef MC_DEBUG
-      if(is_diff == 0){
-        xbt_os_walltimer_stop(timer);
-        mc_comp_times->stacks_sizes_comparison_time = xbt_os_timer_elapsed(timer);
-      }
-      XBT_DEBUG("(%d - %d) Different size used in stacks : %zu - %zu", num1, num2, size_used1, size_used2);
-      errors++;
-      is_diff = 1;
-    #else
-      #ifdef MC_VERBOSE
-      XBT_VERB("(%d - %d) Different size used in stacks : %zu - %zu", num1, num2, size_used1, size_used2);
-      #endif
-
-      xbt_os_walltimer_stop(timer);
-      xbt_os_timer_free(timer);
-      xbt_os_walltimer_stop(global_timer);
-      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-      xbt_os_timer_free(global_timer);
-
-      return 1;
-    #endif  
-    }
-    i++;
-  }
-
-  #ifdef MC_DEBUG
-    if(is_diff == 0)
-      xbt_os_walltimer_stop(timer);
-    xbt_os_walltimer_start(timer);
-  #endif
-
-  /* Init heap information used in heap comparison algorithm */
-  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);
-  if(res_init == -1){
-     #ifdef MC_DEBUG
-    XBT_DEBUG("(%d - %d) Different heap information", num1, num2); 
-        errors++; 
-      #else
-        #ifdef MC_VERBOSE
-        XBT_VERB("(%d - %d) Different heap information", num1, num2); 
-        #endif
-
-        xbt_os_walltimer_stop(global_timer);
-        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-        xbt_os_timer_free(global_timer);
-
-        return 1;
-      #endif
-  }
-
-  #ifdef MC_DEBUG
-    xbt_os_walltimer_start(timer);
-  #endif
-
-  /* Stacks comparison */
-  unsigned int  cursor = 0;
-  int diff_local = 0;
-#ifdef MC_DEBUG
-  is_diff = 0;
-#endif
-  mc_snapshot_stack_t stack1, stack2;
-    
-  while(cursor < xbt_dynar_length(s1->stacks)){
-    stack1 = (mc_snapshot_stack_t)xbt_dynar_get_as(s1->stacks, cursor, mc_snapshot_stack_t);
-    stack2 = (mc_snapshot_stack_t)xbt_dynar_get_as(s2->stacks, cursor, mc_snapshot_stack_t);
-    diff_local = compare_local_variables(s1, s2, stack1, stack2, s1->regions[0]->data, s2->regions[0]->data);
-    if(diff_local > 0){
-      #ifdef MC_DEBUG
-        if(is_diff == 0){
-          xbt_os_walltimer_stop(timer);
-          mc_comp_times->stacks_comparison_time = xbt_os_timer_elapsed(timer);
-        }
-        XBT_DEBUG("(%d - %d) Different local variables between stacks %d", num1, num2, cursor + 1);
-        errors++;
-        is_diff = 1;
-      #else
-        
-        #ifdef MC_VERBOSE
-        XBT_VERB("(%d - %d) Different local variables between stacks %d", num1, num2, cursor + 1);
-        #endif
-          
-        reset_heap_information();
-        xbt_os_walltimer_stop(timer);
-        xbt_os_timer_free(timer);
-        xbt_os_walltimer_stop(global_timer);
-        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-        xbt_os_timer_free(global_timer);
-        return 1;
-      #endif
-    }
-    cursor++;
-  }
-
-
-
- const char* names[3] = { "?", "libsimgrid", "binary" };
-#ifdef MC_DEBUG
- double *times[3] = {
-   NULL,
-   &mc_comp_times->libsimgrid_global_variables_comparison_time,
-   &mc_comp_times->binary_global_variables_comparison_time
- };
-#endif
-
- int k=0;
- for(k=2; k!=0; --k) {
-    #ifdef MC_DEBUG
-      if(is_diff == 0)
-        xbt_os_walltimer_stop(timer);
-      xbt_os_walltimer_start(timer);
-    #endif
-
-  /* Compare global variables */
-  is_diff = compare_global_variables(k, s1->regions[k], s2->regions[k], s1, s2);
-  if(is_diff != 0){
-    #ifdef MC_DEBUG
-      xbt_os_walltimer_stop(timer);
-      *times[k] = xbt_os_timer_elapsed(timer);
-      XBT_DEBUG("(%d - %d) Different global variables in %s", num1, num2, names[k]);
-      errors++;
-    #else
-      #ifdef MC_VERBOSE
-      XBT_VERB("(%d - %d) Different global variables in %s", num1, num2, names[k]);
-      #endif
-
-      reset_heap_information();
-      xbt_os_walltimer_stop(timer);
-      xbt_os_timer_free(timer);
-      xbt_os_walltimer_stop(global_timer);
-      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-      xbt_os_timer_free(global_timer);
-
-      return 1;
-    #endif
-  }
- }
-
-  #ifdef MC_DEBUG
-    xbt_os_walltimer_start(timer);
-  #endif
-
-  /* Compare heap */
-    if(mmalloc_compare_heap(s1, s2, (xbt_mheap_t)s1->regions[0]->data,
-                            (xbt_mheap_t)s2->regions[0]->data) > 0){
-
-    #ifdef MC_DEBUG
-      xbt_os_walltimer_stop(timer);
-      mc_comp_times->heap_comparison_time = xbt_os_timer_elapsed(timer); 
-      XBT_DEBUG("(%d - %d) Different heap (mmalloc_compare)", num1, num2);
-      errors++;
-    #else
-      #ifdef MC_VERBOSE
-      XBT_VERB("(%d - %d) Different heap (mmalloc_compare)", num1, num2);
-      #endif
-       
-      reset_heap_information();
-      xbt_os_walltimer_stop(timer);
-      xbt_os_timer_free(timer);
-      xbt_os_walltimer_stop(global_timer);
-      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-      xbt_os_timer_free(global_timer);
-
-      return 1;
-    #endif
-  }else{
-    #ifdef MC_DEBUG
-      xbt_os_walltimer_stop(timer);
-    #endif
-  }
-
-  reset_heap_information();
-  
-  xbt_os_walltimer_stop(timer);
-  xbt_os_timer_free(timer);
-
-  #ifdef MC_VERBOSE
-    xbt_os_walltimer_stop(global_timer);
-    mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-  #endif
-
-  xbt_os_timer_free(global_timer);
-
-  #ifdef MC_DEBUG
-    print_comparison_times();
-  #endif
-
-#ifdef MC_VERBOSE
-   if(errors || hash_result)
-     XBT_VERB("(%d - %d) Difference found", num1, num2);
-   else
-     XBT_VERB("(%d - %d) No difference found", num1, num2);
-#endif
-
-#if defined(MC_DEBUG) && defined(MC_VERBOSE)
-   if(_sg_mc_hash) {
-     // * false positive SHOULD be avoided.
-     // * There MUST not be any false negative.
-
-     XBT_VERB("(%d - %d) State equality hash test is %s %s", num1, num2,
-       (hash_result!=0) == (errors!=0) ? "true" : "false",
-       !hash_result ? "positive" : "negative");
-   }
-#endif
-
-   return errors > 0 || hash_result;
-  
-}
-
-/***************************** Statistics *****************************/
-/*******************************************************************/
-
-void print_comparison_times(){
-  XBT_DEBUG("*** Comparison times ***");
-  XBT_DEBUG("- Nb processes : %f", mc_comp_times->nb_processes_comparison_time);
-  XBT_DEBUG("- Nb bytes used : %f", mc_comp_times->bytes_used_comparison_time);
-  XBT_DEBUG("- Stacks sizes : %f", mc_comp_times->stacks_sizes_comparison_time);
-  XBT_DEBUG("- Binary global variables : %f", mc_comp_times->binary_global_variables_comparison_time);
-  XBT_DEBUG("- Libsimgrid global variables : %f", mc_comp_times->libsimgrid_global_variables_comparison_time);
-  XBT_DEBUG("- Heap : %f", mc_comp_times->heap_comparison_time);
-  XBT_DEBUG("- Stacks : %f", mc_comp_times->stacks_comparison_time);
-}
-
-/**************************** MC snapshot compare simcall **************************/
-/***********************************************************************************/
-
-int SIMIX_pre_mc_compare_snapshots(smx_simcall_t simcall,
-                                   mc_snapshot_t s1, mc_snapshot_t s2){
-  return snapshot_compare(s1, s2);
-}
-
-int MC_compare_snapshots(void *s1, void *s2){
-
-  return simcall_mc_compare_snapshots(s1, s2);
-
-}
diff --git a/src/mc/mc_compare.cpp b/src/mc/mc_compare.cpp
new file mode 100644 (file)
index 0000000..ada39e6
--- /dev/null
@@ -0,0 +1,668 @@
+/* Copyright (c) 2012-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <inttypes.h>
+#include <boost/unordered_set.hpp>
+
+#include "mc_private.h"
+
+#include "xbt/mmalloc.h"
+#include "xbt/mmalloc/mmprivate.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, mc,
+                                "Logging specific to mc_compare");
+
+typedef struct s_pointers_pair {
+  void *p1;
+  void *p2;
+  bool operator==(s_pointers_pair const& x) const {
+    return this->p1 == x.p1 && this->p2 == x.p2;
+  }
+  bool operator<(s_pointers_pair const& x) const {
+    return this->p1 < x.p1 || (this->p1 == x.p1 && this->p2 < x.p2);
+  }
+} s_pointers_pair_t, *pointers_pair_t;
+
+namespace boost {
+  template<>
+  struct hash<s_pointers_pair> {
+    typedef uintptr_t result_type;
+    result_type operator()(s_pointers_pair const& x) const {
+      return (result_type) x.p1 ^
+        ((result_type) x.p2 << 8 | (result_type) x.p2 >> (8*sizeof(uintptr_t) - 8));
+    }
+  };
+}
+
+struct mc_compare_state {
+  boost::unordered_set<s_pointers_pair> compared_pointers;
+};
+
+extern "C" {
+
+/************************** Free functions ****************************/
+/********************************************************************/
+
+static void stack_region_free(stack_region_t s)
+{
+  if (s) {
+    xbt_free(s->process_name);
+    xbt_free(s);
+  }
+}
+
+static void stack_region_free_voidp(void *s)
+{
+  stack_region_free((stack_region_t) * (void **) s);
+}
+
+static void pointers_pair_free(pointers_pair_t p)
+{
+  xbt_free(p);
+}
+
+static void pointers_pair_free_voidp(void *p)
+{
+  pointers_pair_free((pointers_pair_t) * (void **) p);
+}
+
+/************************** Snapshot comparison *******************************/
+/******************************************************************************/
+
+/** \brief Try to add a pair a compared pointers to the set of compared pointers
+ *
+ *  \result !=0 if the pointers were added (they were not in the set),
+ *      0 otherwise (they were already in the set)
+ */
+static int add_compared_pointers(mc_compare_state& state, void *p1, void *p2)
+{
+  s_pointers_pair_t new_pair;
+  new_pair.p1 = p1;
+  new_pair.p2 = p2;
+  return state.compared_pointers.insert(new_pair).second ? 1 : 0;
+}
+
+static int compare_areas_with_type(struct mc_compare_state& state,
+                                   void* real_area1, mc_snapshot_t snapshot1, mc_mem_region_t region1,
+                                   void* real_area2, mc_snapshot_t snapshot2, mc_mem_region_t region2,
+                                   dw_type_t type, int pointer_level)
+{
+  unsigned int cursor = 0;
+  dw_type_t member, subtype, subsubtype;
+  int elm_size, i, res;
+
+  top:
+  switch (type->type) {
+  case DW_TAG_unspecified_type:
+    return 1;
+
+  case DW_TAG_base_type:
+  case DW_TAG_enumeration_type:
+  case DW_TAG_union_type:
+  {
+    void* data1 =
+      mc_snapshot_read_region(real_area1, region1, alloca(type->byte_size), type->byte_size);
+    void* data2 =
+      mc_snapshot_read_region(real_area2, region1, alloca(type->byte_size), type->byte_size);
+    return (memcmp(data1, data2, type->byte_size) != 0);
+    break;
+  }
+  case DW_TAG_typedef:
+  case DW_TAG_volatile_type:
+  case DW_TAG_const_type:
+    // Poor man's TCO:
+    type = type->subtype;
+    goto top;
+  case DW_TAG_array_type:
+    subtype = type->subtype;
+    switch (subtype->type) {
+    case DW_TAG_unspecified_type:
+      return 1;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_reference_type:
+    case DW_TAG_rvalue_reference_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+      if (subtype->full_type)
+        subtype = subtype->full_type;
+      elm_size = subtype->byte_size;
+      break;
+    case DW_TAG_const_type:
+    case DW_TAG_typedef:
+    case DW_TAG_volatile_type:
+      subsubtype = subtype->subtype;
+      if (subsubtype->full_type)
+        subsubtype = subsubtype->full_type;
+      elm_size = subsubtype->byte_size;
+      break;
+    default:
+      return 0;
+      break;
+    }
+    for (i = 0; i < type->element_count; i++) {
+      size_t off = i * elm_size;
+      res = compare_areas_with_type(state,
+            (char*) real_area1 + off, snapshot1, region1,
+            (char*) real_area2 + off, snapshot2, region2,
+            type->subtype, pointer_level);
+      if (res == 1)
+        return res;
+    }
+    break;
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_rvalue_reference_type:
+  {
+    void* temp;
+    void* addr_pointed1 = *(void**) mc_snapshot_read_region(real_area1, region1, &temp, sizeof(void**));
+    void* addr_pointed2 = *(void**) mc_snapshot_read_region(real_area2, region2, &temp, sizeof(void**));
+
+    if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
+      return (addr_pointed1 != addr_pointed2);
+    } else {
+
+      if (addr_pointed1 == NULL && addr_pointed2 == NULL)
+        return 0;
+      if (!add_compared_pointers(state, addr_pointed1, addr_pointed2))
+        return 0;
+
+      pointer_level++;
+
+      // Some cases are not handled here:
+      // * the pointers lead to different areas (one to the heap, the other to the RW segment ...);
+      // * a pointer leads to the read-only segment of the current object;
+      // * a pointer lead to a different ELF object.
+
+      if (addr_pointed1 > std_heap
+          && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)) {
+        if (!
+            (addr_pointed2 > std_heap
+             && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2)))
+          return 1;
+        // The pointers are both in the heap:
+        return compare_heap_area(addr_pointed1, addr_pointed2, snapshot1,
+                                 snapshot2, NULL, type->subtype, pointer_level);
+      }
+      // The pointers are both in the current object R/W segment:
+      else if (addr_pointed1 > region1->start_addr
+               && (char *) addr_pointed1 <= (char *) region1->start_addr + region1->size) {
+        if (!
+            (addr_pointed2 > region2->start_addr
+             && (char *) addr_pointed2 <= (char *) region2->start_addr + region2->size))
+          return 1;
+        if (type->dw_type_id == NULL)
+          return (addr_pointed1 != addr_pointed2);
+        else {
+          return compare_areas_with_type(state,
+                                         addr_pointed1, snapshot1, region1,
+                                         addr_pointed2, snapshot2, region2,
+                                         type->subtype, pointer_level);
+        }
+      }
+
+      else {
+        return (addr_pointed1 != addr_pointed2);
+      }
+    }
+    break;
+  }
+  case DW_TAG_structure_type:
+  case DW_TAG_class_type:
+    xbt_dynar_foreach(type->members, cursor, member) {
+      void *member1 =
+        mc_member_resolve(real_area1, type, member, snapshot1);
+      void *member2 =
+        mc_member_resolve(real_area2, type, member, snapshot2);
+      mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, region1);
+      mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, region2);
+      res =
+          compare_areas_with_type(state,
+                                  member1, snapshot1, subregion1,
+                                  member2, snapshot2, subregion2,
+                                  member->subtype, pointer_level);
+      if (res == 1)
+        return res;
+    }
+    break;
+  case DW_TAG_subroutine_type:
+    return -1;
+    break;
+  default:
+    XBT_VERB("Unknown case : %d", type->type);
+    break;
+  }
+
+  return 0;
+}
+
+static int compare_global_variables(int region_type, mc_mem_region_t r1,
+                                    mc_mem_region_t r2, mc_snapshot_t snapshot1,
+                                    mc_snapshot_t snapshot2)
+{
+  xbt_assert(r1 && r2,
+    "Missing region. Did you enable SMPI privatisation? It is not compatible with state comparison.");
+  struct mc_compare_state state;
+
+  xbt_dynar_t variables;
+  int res;
+  unsigned int cursor = 0;
+  dw_variable_t current_var;
+
+  mc_object_info_t object_info = NULL;
+  if (region_type == 2) {
+    object_info = mc_binary_info;
+  } else {
+    object_info = mc_libsimgrid_info;
+  }
+  variables = object_info->global_variables;
+
+  xbt_dynar_foreach(variables, cursor, current_var) {
+
+    // If the variable is not in this object, skip it:
+    // We do not expect to find a pointer to something which is not reachable
+    // by the global variables.
+    if ((char *) current_var->address < (char *) object_info->start_rw
+        || (char *) current_var->address > (char *) object_info->end_rw)
+      continue;
+
+    dw_type_t bvariable_type = current_var->type;
+    res =
+        compare_areas_with_type(state,
+                                (char *) current_var->address, snapshot1, r1,
+                                (char *) current_var->address, snapshot2, r2,
+                                bvariable_type, 0);
+    if (res == 1) {
+      XBT_VERB("Global variable %s (%p) is different between snapshots",
+               current_var->name, (char *) current_var->address);
+      return 1;
+    }
+
+  }
+
+  return 0;
+
+}
+
+static int compare_local_variables(mc_snapshot_t snapshot1,
+                                   mc_snapshot_t snapshot2,
+                                   mc_snapshot_stack_t stack1,
+                                   mc_snapshot_stack_t stack2)
+{
+  struct mc_compare_state state;
+
+  if (xbt_dynar_length(stack1->local_variables) !=
+      xbt_dynar_length(stack2->local_variables)) {
+    XBT_VERB("Different number of local variables");
+    return 1;
+  } else {
+    unsigned int cursor = 0;
+    local_variable_t current_var1, current_var2;
+    int res;
+    while (cursor < xbt_dynar_length(stack1->local_variables)) {
+      current_var1 =
+          (local_variable_t) xbt_dynar_get_as(stack1->local_variables, cursor,
+                                              local_variable_t);
+      current_var2 =
+          (local_variable_t) xbt_dynar_get_as(stack2->local_variables, cursor,
+                                              local_variable_t);
+      if (strcmp(current_var1->name, current_var2->name) != 0
+          || current_var1->subprogram != current_var1->subprogram
+          || current_var1->ip != current_var2->ip) {
+        // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
+        XBT_VERB
+            ("Different name of variable (%s - %s) or frame (%s - %s) or ip (%lu - %lu)",
+             current_var1->name, current_var2->name,
+             current_var1->subprogram->name, current_var2->subprogram->name,
+             current_var1->ip, current_var2->ip);
+        return 1;
+      }
+      // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
+
+        dw_type_t subtype = current_var1->type;
+        res =
+            compare_areas_with_type(state,
+                                    current_var1->address, snapshot1, mc_get_snapshot_region(current_var1->address, snapshot1),
+                                    current_var2->address, snapshot2, mc_get_snapshot_region(current_var2->address, snapshot2),
+                                    subtype, 0);
+
+      if (res == 1) {
+        // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
+        XBT_VERB
+            ("Local variable %s (%p - %p) in frame %s  is different between snapshots",
+             current_var1->name, current_var1->address, current_var2->address,
+             current_var1->subprogram->name);
+        return res;
+      }
+      cursor++;
+    }
+    return 0;
+  }
+}
+
+int snapshot_compare(void *state1, void *state2)
+{
+
+  mc_snapshot_t s1, s2;
+  int num1, num2;
+
+  if (_sg_mc_liveness) {        /* Liveness MC */
+    s1 = ((mc_visited_pair_t) state1)->graph_state->system_state;
+    s2 = ((mc_visited_pair_t) state2)->graph_state->system_state;
+    num1 = ((mc_visited_pair_t) state1)->num;
+    num2 = ((mc_visited_pair_t) state2)->num;
+  } else {                      /* Safety or comm determinism MC */
+    s1 = ((mc_visited_state_t) state1)->system_state;
+    s2 = ((mc_visited_state_t) state2)->system_state;
+    num1 = ((mc_visited_state_t) state1)->num;
+    num2 = ((mc_visited_state_t) state2)->num;
+  }
+
+  int errors = 0;
+  int res_init;
+
+  xbt_os_timer_t global_timer = xbt_os_timer_new();
+  xbt_os_timer_t timer = xbt_os_timer_new();
+
+  xbt_os_walltimer_start(global_timer);
+
+#ifdef MC_DEBUG
+  xbt_os_walltimer_start(timer);
+#endif
+
+  int hash_result = 0;
+  if (_sg_mc_hash) {
+    hash_result = (s1->hash != s2->hash);
+    if (hash_result) {
+      XBT_VERB("(%d - %d) Different hash : 0x%" PRIx64 "--0x%" PRIx64, num1,
+               num2, s1->hash, s2->hash);
+#ifndef MC_DEBUG
+      return 1;
+#endif
+    } else {
+      XBT_VERB("(%d - %d) Same hash : 0x%" PRIx64, num1, num2, s1->hash);
+    }
+  }
+
+  /* Compare enabled processes */
+  unsigned int cursor;
+  int pid;
+  xbt_dynar_foreach(s1->enabled_processes, cursor, pid){
+    if(!xbt_dynar_member(s2->enabled_processes, &pid))
+      XBT_VERB("(%d - %d) Different enabled processes", num1, num2);
+  }
+
+  unsigned long i = 0;
+  size_t size_used1, size_used2;
+  int is_diff = 0;
+
+  /* Compare size of stacks */
+  while (i < xbt_dynar_length(s1->stacks)) {
+    size_used1 = s1->stack_sizes[i];
+    size_used2 = s2->stack_sizes[i];
+    if (size_used1 != size_used2) {
+#ifdef MC_DEBUG
+      if (is_diff == 0) {
+        xbt_os_walltimer_stop(timer);
+        mc_comp_times->stacks_sizes_comparison_time =
+            xbt_os_timer_elapsed(timer);
+      }
+      XBT_DEBUG("(%d - %d) Different size used in stacks : %zu - %zu", num1,
+                num2, size_used1, size_used2);
+      errors++;
+      is_diff = 1;
+#else
+#ifdef MC_VERBOSE
+      XBT_VERB("(%d - %d) Different size used in stacks : %zu - %zu", num1,
+               num2, size_used1, size_used2);
+#endif
+
+      xbt_os_walltimer_stop(timer);
+      xbt_os_timer_free(timer);
+      xbt_os_walltimer_stop(global_timer);
+      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+      xbt_os_timer_free(global_timer);
+
+      return 1;
+#endif
+    }
+    i++;
+  }
+
+#ifdef MC_DEBUG
+  if (is_diff == 0)
+    xbt_os_walltimer_stop(timer);
+  xbt_os_walltimer_start(timer);
+#endif
+
+  /* Init heap information used in heap comparison algorithm */
+  xbt_mheap_t heap1 = (xbt_mheap_t) mc_snapshot_read(std_heap, s1,
+    alloca(sizeof(struct mdesc)), sizeof(struct mdesc));
+  xbt_mheap_t heap2 = (xbt_mheap_t) mc_snapshot_read(std_heap, s2,
+    alloca(sizeof(struct mdesc)), sizeof(struct mdesc));
+  res_init = init_heap_information(heap1, heap2, s1->to_ignore, s2->to_ignore);
+  if (res_init == -1) {
+#ifdef MC_DEBUG
+    XBT_DEBUG("(%d - %d) Different heap information", num1, num2);
+    errors++;
+#else
+#ifdef MC_VERBOSE
+    XBT_VERB("(%d - %d) Different heap information", num1, num2);
+#endif
+
+    xbt_os_walltimer_stop(global_timer);
+    mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+    xbt_os_timer_free(global_timer);
+
+    return 1;
+#endif
+  }
+#ifdef MC_DEBUG
+  xbt_os_walltimer_start(timer);
+#endif
+
+  /* Stacks comparison */
+  cursor = 0;
+  int diff_local = 0;
+#ifdef MC_DEBUG
+  is_diff = 0;
+#endif
+  mc_snapshot_stack_t stack1, stack2;
+
+  while (cursor < xbt_dynar_length(s1->stacks)) {
+    stack1 =
+        (mc_snapshot_stack_t) xbt_dynar_get_as(s1->stacks, cursor,
+                                               mc_snapshot_stack_t);
+    stack2 =
+        (mc_snapshot_stack_t) xbt_dynar_get_as(s2->stacks, cursor,
+                                               mc_snapshot_stack_t);
+    diff_local =
+        compare_local_variables(s1, s2, stack1, stack2);
+    if (diff_local > 0) {
+#ifdef MC_DEBUG
+      if (is_diff == 0) {
+        xbt_os_walltimer_stop(timer);
+        mc_comp_times->stacks_comparison_time = xbt_os_timer_elapsed(timer);
+      }
+      XBT_DEBUG("(%d - %d) Different local variables between stacks %d", num1,
+                num2, cursor + 1);
+      errors++;
+      is_diff = 1;
+#else
+
+#ifdef MC_VERBOSE
+      XBT_VERB("(%d - %d) Different local variables between stacks %d", num1,
+               num2, cursor + 1);
+#endif
+
+      reset_heap_information();
+      xbt_os_walltimer_stop(timer);
+      xbt_os_timer_free(timer);
+      xbt_os_walltimer_stop(global_timer);
+      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+      xbt_os_timer_free(global_timer);
+
+      return 1;
+#endif
+    }
+    cursor++;
+  }
+
+
+
+  const char *names[3] = { "?", "libsimgrid", "binary" };
+#ifdef MC_DEBUG
+  double *times[3] = {
+    NULL,
+    &mc_comp_times->libsimgrid_global_variables_comparison_time,
+    &mc_comp_times->binary_global_variables_comparison_time
+  };
+#endif
+
+  int k = 0;
+  for (k = 2; k != 0; --k) {
+#ifdef MC_DEBUG
+    if (is_diff == 0)
+      xbt_os_walltimer_stop(timer);
+    xbt_os_walltimer_start(timer);
+#endif
+
+    /* Compare global variables */
+    is_diff =
+        compare_global_variables(k, s1->regions[k], s2->regions[k], s1, s2);
+    if (is_diff != 0) {
+#ifdef MC_DEBUG
+      xbt_os_walltimer_stop(timer);
+      *times[k] = xbt_os_timer_elapsed(timer);
+      XBT_DEBUG("(%d - %d) Different global variables in %s", num1, num2,
+                names[k]);
+      errors++;
+#else
+#ifdef MC_VERBOSE
+      XBT_VERB("(%d - %d) Different global variables in %s", num1, num2,
+               names[k]);
+#endif
+
+      reset_heap_information();
+      xbt_os_walltimer_stop(timer);
+      xbt_os_timer_free(timer);
+      xbt_os_walltimer_stop(global_timer);
+      mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+      xbt_os_timer_free(global_timer);
+
+      return 1;
+#endif
+    }
+  }
+
+#ifdef MC_DEBUG
+  xbt_os_walltimer_start(timer);
+#endif
+
+  /* Compare heap */
+  if (mmalloc_compare_heap(s1, s2) > 0) {
+
+#ifdef MC_DEBUG
+    xbt_os_walltimer_stop(timer);
+    mc_comp_times->heap_comparison_time = xbt_os_timer_elapsed(timer);
+    XBT_DEBUG("(%d - %d) Different heap (mmalloc_compare)", num1, num2);
+    errors++;
+#else
+
+#ifdef MC_VERBOSE
+    XBT_VERB("(%d - %d) Different heap (mmalloc_compare)", num1, num2);
+#endif
+
+    reset_heap_information();
+    xbt_os_walltimer_stop(timer);
+    xbt_os_timer_free(timer);
+    xbt_os_walltimer_stop(global_timer);
+    mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+    xbt_os_timer_free(global_timer);
+
+    return 1;
+#endif
+  } else {
+#ifdef MC_DEBUG
+    xbt_os_walltimer_stop(timer);
+#endif
+  }
+
+  reset_heap_information();
+
+  xbt_os_walltimer_stop(timer);
+  xbt_os_timer_free(timer);
+
+#ifdef MC_VERBOSE
+  xbt_os_walltimer_stop(global_timer);
+  mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+#endif
+
+  xbt_os_timer_free(global_timer);
+
+#ifdef MC_DEBUG
+  print_comparison_times();
+#endif
+
+#ifdef MC_VERBOSE
+  if (errors || hash_result)
+    XBT_VERB("(%d - %d) Difference found", num1, num2);
+  else
+    XBT_VERB("(%d - %d) No difference found", num1, num2);
+#endif
+
+#if defined(MC_DEBUG) && defined(MC_VERBOSE)
+  if (_sg_mc_hash) {
+    // * false positive SHOULD be avoided.
+    // * There MUST not be any false negative.
+
+    XBT_VERB("(%d - %d) State equality hash test is %s %s", num1, num2,
+             (hash_result != 0) == (errors != 0) ? "true" : "false",
+             !hash_result ? "positive" : "negative");
+  }
+#endif
+
+  return errors > 0 || hash_result;
+
+}
+
+/***************************** Statistics *****************************/
+/*******************************************************************/
+
+void print_comparison_times()
+{
+  XBT_DEBUG("*** Comparison times ***");
+  XBT_DEBUG("- Nb processes : %f", mc_comp_times->nb_processes_comparison_time);
+  XBT_DEBUG("- Nb bytes used : %f", mc_comp_times->bytes_used_comparison_time);
+  XBT_DEBUG("- Stacks sizes : %f", mc_comp_times->stacks_sizes_comparison_time);
+  XBT_DEBUG("- Binary global variables : %f",
+            mc_comp_times->binary_global_variables_comparison_time);
+  XBT_DEBUG("- Libsimgrid global variables : %f",
+            mc_comp_times->libsimgrid_global_variables_comparison_time);
+  XBT_DEBUG("- Heap : %f", mc_comp_times->heap_comparison_time);
+  XBT_DEBUG("- Stacks : %f", mc_comp_times->stacks_comparison_time);
+}
+
+/**************************** MC snapshot compare simcall **************************/
+/***********************************************************************************/
+
+int SIMIX_pre_mc_compare_snapshots(smx_simcall_t simcall,
+                                   mc_snapshot_t s1, mc_snapshot_t s2)
+{
+  return snapshot_compare(s1, s2);
+}
+
+int MC_compare_snapshots(void *s1, void *s2)
+{
+
+  return simcall_mc_compare_snapshots(s1, s2);
+
+}
+
+}
diff --git a/src/mc/mc_diff.c b/src/mc/mc_diff.c
new file mode 100644 (file)
index 0000000..336897d
--- /dev/null
@@ -0,0 +1,1713 @@
+/* mc_diff - Memory snapshooting and comparison                             */
+
+/* Copyright (c) 2008-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "xbt/ex_interface.h"   /* internals of backtrace setup */
+#include "xbt/str.h"
+#include "mc/mc.h"
+#include "xbt/mmalloc.h"
+#include "mc/datatypes.h"
+#include "mc/mc_private.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_diff, xbt,
+                                "Logging specific to mc_diff in mc");
+
+xbt_dynar_t mc_heap_comparison_ignore;
+xbt_dynar_t stacks_areas;
+void *maestro_stack_start, *maestro_stack_end;
+
+
+/********************************* Backtrace ***********************************/
+/******************************************************************************/
+
+static void mmalloc_backtrace_block_display(void *heapinfo, int block)
+{
+
+  /* xbt_ex_t e; */
+
+  /* if (((malloc_info *)heapinfo)[block].busy_block.bt_size == 0) { */
+  /*   fprintf(stderr, "No backtrace available for that block, sorry.\n"); */
+  /*   return; */
+  /* } */
+
+  /* memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_block.bt),sizeof(void*)*XBT_BACKTRACE_SIZE); */
+  /* e.used = ((malloc_info *)heapinfo)[block].busy_block.bt_size; */
+
+  /* xbt_ex_setup_backtrace(&e); */
+  /* if (e.used == 0) { */
+  /*   fprintf(stderr, "(backtrace not set)\n"); */
+  /* } else if (e.bt_strings == NULL) { */
+  /*   fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet"); */
+  /* } else { */
+  /*   int i; */
+
+  /*   fprintf(stderr, "Backtrace of where the block %d was malloced (%d frames):\n", block ,e.used); */
+  /*   for (i = 0; i < e.used; i++)       /\* no need to display "xbt_backtrace_display" *\/{ */
+  /*     fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4); */
+  /*   } */
+  /* } */
+}
+
+static void mmalloc_backtrace_fragment_display(void *heapinfo, int block,
+                                               int frag)
+{
+
+  /* xbt_ex_t e; */
+
+  /* memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_frag.bt[frag]),sizeof(void*)*XBT_BACKTRACE_SIZE); */
+  /* e.used = XBT_BACKTRACE_SIZE; */
+
+  /* xbt_ex_setup_backtrace(&e); */
+  /* if (e.used == 0) { */
+  /*   fprintf(stderr, "(backtrace not set)\n"); */
+  /* } else if (e.bt_strings == NULL) { */
+  /*   fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet"); */
+  /* } else { */
+  /*   int i; */
+
+  /*   fprintf(stderr, "Backtrace of where the fragment %d in block %d was malloced (%d frames):\n", frag, block ,e.used); */
+  /*   for (i = 0; i < e.used; i++)       /\* no need to display "xbt_backtrace_display" *\/{ */
+  /*     fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4); */
+  /*   } */
+  /* } */
+
+}
+
+static void mmalloc_backtrace_display(void *addr)
+{
+
+  /* size_t block, frag_nb; */
+  /* int type; */
+
+  /* xbt_mheap_t heap = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit(); */
+
+  /* block = (((char*) (addr) - (char*) heap -> heapbase) / BLOCKSIZE + 1); */
+
+  /* type = heap->heapinfo[block].type; */
+
+  /* switch(type){ */
+  /* case -1 : /\* Free block *\/ */
+  /*   fprintf(stderr, "Asked to display the backtrace of a block that is free. I'm puzzled\n"); */
+  /*   xbt_abort(); */
+  /*   break;  */
+  /* case 0: /\* Large block *\/ */
+  /*   mmalloc_backtrace_block_display(heap->heapinfo, block); */
+  /*   break; */
+  /* default: /\* Fragmented block *\/ */
+  /*   frag_nb = RESIDUAL(addr, BLOCKSIZE) >> type; */
+  /*   if(heap->heapinfo[block].busy_frag.frag_size[frag_nb] == -1){ */
+  /*     fprintf(stderr , "Asked to display the backtrace of a fragment that is free. I'm puzzled\n"); */
+  /*     xbt_abort(); */
+  /*   } */
+  /*   mmalloc_backtrace_fragment_display(heap->heapinfo, block, frag_nb); */
+  /*   break; */
+  /* } */
+}
+
+
+static int compare_backtrace(int b1, int f1, int b2, int f2)
+{
+  /*int i = 0;
+     if(f1 != -1){
+     for(i=0; i< XBT_BACKTRACE_SIZE; i++){
+     if(heapinfo1[b1].busy_frag.bt[f1][i] != heapinfo2[b2].busy_frag.bt[f2][i]){
+     //mmalloc_backtrace_fragment_display((void*)heapinfo1, b1, f1);
+     //mmalloc_backtrace_fragment_display((void*)heapinfo2, b2, f2);
+     return 1;
+     }
+     }
+     }else{
+     for(i=0; i< heapinfo1[b1].busy_block.bt_size; i++){
+     if(heapinfo1[b1].busy_block.bt[i] != heapinfo2[b2].busy_block.bt[i]){
+     //mmalloc_backtrace_block_display((void*)heapinfo1, b1);
+     //mmalloc_backtrace_block_display((void*)heapinfo2, b2);
+     return 1;
+     }
+     }
+     } */
+  return 0;
+}
+
+
+/*********************************** Heap comparison ***********************************/
+/***************************************************************************************/
+
+typedef char *type_name;
+
+struct s_mc_diff {
+  /** \brief Base address of the real heap */
+  void *s_heap;
+  size_t heaplimit;
+  // Number of blocks in the heaps:
+  size_t heapsize1, heapsize2;
+  xbt_dynar_t to_ignore1, to_ignore2;
+  s_heap_area_t *equals_to1, *equals_to2;
+  dw_type_t *types1, *types2;
+  size_t available;
+};
+
+#define equals_to1_(i,j) equals_to1[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
+#define equals_to2_(i,j) equals_to2[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
+#define types1_(i,j) types1[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
+#define types2_(i,j) types2[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
+
+__thread struct s_mc_diff *mc_diff_info = NULL;
+
+/*********************************** Free functions ************************************/
+
+static void heap_area_pair_free(heap_area_pair_t pair)
+{
+  xbt_free(pair);
+  pair = NULL;
+}
+
+static void heap_area_pair_free_voidp(void *d)
+{
+  heap_area_pair_free((heap_area_pair_t) * (void **) d);
+}
+
+static void heap_area_free(heap_area_t area)
+{
+  xbt_free(area);
+  area = NULL;
+}
+
+/************************************************************************************/
+
+static s_heap_area_t make_heap_area(int block, int fragment)
+{
+  s_heap_area_t area;
+  area.valid = 1;
+  area.block = block;
+  area.fragment = fragment;
+  return area;
+}
+
+
+static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1,
+                                 int block2, int fragment2)
+{
+
+  unsigned int cursor = 0;
+  heap_area_pair_t current_pair;
+
+  xbt_dynar_foreach(list, cursor, current_pair) {
+    if (current_pair->block1 == block1 && current_pair->block2 == block2
+        && current_pair->fragment1 == fragment1
+        && current_pair->fragment2 == fragment2)
+      return 0;
+  }
+
+  return 1;
+}
+
+static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1,
+                              int block2, int fragment2)
+{
+
+  if (is_new_heap_area_pair(list, block1, fragment1, block2, fragment2)) {
+    heap_area_pair_t pair = NULL;
+    pair = xbt_new0(s_heap_area_pair_t, 1);
+    pair->block1 = block1;
+    pair->fragment1 = fragment1;
+    pair->block2 = block2;
+    pair->fragment2 = fragment2;
+
+    xbt_dynar_push(list, &pair);
+
+    return 1;
+  }
+
+  return 0;
+}
+
+static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list,
+                                           void *address)
+{
+
+  unsigned int cursor = 0;
+  int start = 0;
+  int end = xbt_dynar_length(ignore_list) - 1;
+  mc_heap_ignore_region_t region;
+
+  while (start <= end) {
+    cursor = (start + end) / 2;
+    region =
+        (mc_heap_ignore_region_t) xbt_dynar_get_as(ignore_list, cursor,
+                                                   mc_heap_ignore_region_t);
+    if (region->address == address)
+      return region->size;
+    if (region->address < address)
+      start = cursor + 1;
+    if (region->address > address)
+      end = cursor - 1;
+  }
+
+  return -1;
+}
+
+static int is_stack(void *address)
+{
+  unsigned int cursor = 0;
+  stack_region_t stack;
+
+  xbt_dynar_foreach(stacks_areas, cursor, stack) {
+    if (address == stack->address)
+      return 1;
+  }
+
+  return 0;
+}
+
+// TODO, this should depend on the snapshot?
+static int is_block_stack(int block)
+{
+  unsigned int cursor = 0;
+  stack_region_t stack;
+
+  xbt_dynar_foreach(stacks_areas, cursor, stack) {
+    if (block == stack->block)
+      return 1;
+  }
+
+  return 0;
+}
+
+static void match_equals(struct s_mc_diff *state, xbt_dynar_t list)
+{
+
+  unsigned int cursor = 0;
+  heap_area_pair_t current_pair;
+
+  xbt_dynar_foreach(list, cursor, current_pair) {
+
+    if (current_pair->fragment1 != -1) {
+
+      state->equals_to1_(current_pair->block1, current_pair->fragment1) =
+          make_heap_area(current_pair->block2, current_pair->fragment2);
+      state->equals_to2_(current_pair->block2, current_pair->fragment2) =
+          make_heap_area(current_pair->block1, current_pair->fragment1);
+
+    } else {
+
+      state->equals_to1_(current_pair->block1, 0) =
+          make_heap_area(current_pair->block2, current_pair->fragment2);
+      state->equals_to2_(current_pair->block2, 0) =
+          make_heap_area(current_pair->block1, current_pair->fragment1);
+
+    }
+
+  }
+}
+
+/** Check whether two blocks are known to be matching
+ *
+ *  @param state  State used
+ *  @param b1     Block of state 1
+ *  @param b2     Block of state 2
+ *  @return       if the blocks are known to be matching
+ */
+static int equal_blocks(struct s_mc_diff *state, int b1, int b2)
+{
+
+  if (state->equals_to1_(b1, 0).block == b2
+      && state->equals_to2_(b2, 0).block == b1)
+    return 1;
+
+  return 0;
+}
+
+/** Check whether two fragments are known to be matching
+ *
+ *  @param state  State used
+ *  @param b1     Block of state 1
+ *  @param f1     Fragment of state 1
+ *  @param b2     Block of state 2
+ *  @param f2     Fragment of state 2
+ *  @return       if the fragments are known to be matching
+ */
+static int equal_fragments(struct s_mc_diff *state, int b1, int f1, int b2,
+                           int f2)
+{
+
+  if (state->equals_to1_(b1, f1).block == b2
+      && state->equals_to1_(b1, f1).fragment == f2
+      && state->equals_to2_(b2, f2).block == b1
+      && state->equals_to2_(b2, f2).fragment == f1)
+    return 1;
+
+  return 0;
+}
+
+int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1,
+                          xbt_dynar_t i2)
+{
+  if (mc_diff_info == NULL) {
+    mc_diff_info = xbt_new0(struct s_mc_diff, 1);
+    mc_diff_info->equals_to1 = NULL;
+    mc_diff_info->equals_to2 = NULL;
+    mc_diff_info->types1 = NULL;
+    mc_diff_info->types2 = NULL;
+  }
+  struct s_mc_diff *state = mc_diff_info;
+
+  if ((((struct mdesc *) heap1)->heaplimit !=
+       ((struct mdesc *) heap2)->heaplimit)
+      ||
+      ((((struct mdesc *) heap1)->heapsize !=
+        ((struct mdesc *) heap2)->heapsize)))
+    return -1;
+
+  state->heaplimit = ((struct mdesc *) heap1)->heaplimit;
+
+  // Mamailloute in order to find the base address of the main heap:
+  state->s_heap =
+      (char *) mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
+
+  state->heapsize1 = heap1->heapsize;
+  state->heapsize2 = heap2->heapsize;
+
+  state->to_ignore1 = i1;
+  state->to_ignore2 = i2;
+
+  if (state->heaplimit > state->available) {
+    state->equals_to1 =
+        realloc(state->equals_to1,
+                state->heaplimit * MAX_FRAGMENT_PER_BLOCK *
+                sizeof(s_heap_area_t));
+    state->types1 =
+        realloc(state->types1,
+                state->heaplimit * MAX_FRAGMENT_PER_BLOCK *
+                sizeof(type_name *));
+    state->equals_to2 =
+        realloc(state->equals_to2,
+                state->heaplimit * MAX_FRAGMENT_PER_BLOCK *
+                sizeof(s_heap_area_t));
+    state->types2 =
+        realloc(state->types2,
+                state->heaplimit * MAX_FRAGMENT_PER_BLOCK *
+                sizeof(type_name *));
+    state->available = state->heaplimit;
+  }
+
+  memset(state->equals_to1, 0,
+         state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(s_heap_area_t));
+  memset(state->equals_to2, 0,
+         state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(s_heap_area_t));
+  memset(state->types1, 0,
+         state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(type_name *));
+  memset(state->types2, 0,
+         state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(type_name *));
+
+  return 0;
+
+}
+
+void reset_heap_information()
+{
+
+}
+
+int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2)
+{
+
+  struct s_mc_diff *state = mc_diff_info;
+
+  /* Start comparison */
+  size_t i1, i2, j1, j2, k;
+  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
+  int nb_diff1 = 0, nb_diff2 = 0;
+
+  xbt_dynar_t previous =
+      xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
+
+  int equal, res_compare = 0;
+
+  /* Check busy blocks */
+
+  i1 = 1;
+
+  malloc_info heapinfo_temp1, heapinfo_temp2;
+  malloc_info heapinfo_temp2b;
+
+  mc_mem_region_t heap_region1 = snapshot1->regions[0];
+  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+
+  // This is in snapshot do not use them directly:
+  malloc_info* heapinfos1 = mc_snapshot_read_pointer(&((xbt_mheap_t)std_heap)->heapinfo, snapshot1);
+  malloc_info* heapinfos2 = mc_snapshot_read_pointer(&((xbt_mheap_t)std_heap)->heapinfo, snapshot2);
+
+  while (i1 <= state->heaplimit) {
+
+    // TODO, lookup in the correct region in order to speed it up:
+    malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i1], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
+    malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i1], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
+
+    if (heapinfo1->type == -1) {      /* Free block */
+      i1++;
+      continue;
+    }
+
+    addr_block1 =
+        ((void *) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE +
+                   (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+
+    if (heapinfo1->type == 0) {       /* Large block */
+
+      if (is_stack(addr_block1)) {
+        for (k = 0; k < heapinfo1->busy_block.size; k++)
+          state->equals_to1_(i1 + k, 0) = make_heap_area(i1, -1);
+        for (k = 0; k < heapinfo2->busy_block.size; k++)
+          state->equals_to2_(i1 + k, 0) = make_heap_area(i1, -1);
+        i1 += heapinfo1->busy_block.size;
+        continue;
+      }
+
+      if (state->equals_to1_(i1, 0).valid) {
+        i1++;
+        continue;
+      }
+
+      i2 = 1;
+      equal = 0;
+      res_compare = 0;
+
+      /* Try first to associate to same block in the other heap */
+      if (heapinfo2->type == heapinfo1->type) {
+
+        if (state->equals_to2_(i1, 0).valid == 0) {
+
+          addr_block2 =
+              ((void *) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE +
+                         (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+
+          res_compare =
+              compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2,
+                                NULL, NULL, 0);
+
+          if (res_compare != 1) {
+            for (k = 1; k < heapinfo2->busy_block.size; k++)
+              state->equals_to2_(i1 + k, 0) = make_heap_area(i1, -1);
+            for (k = 1; k < heapinfo1->busy_block.size; k++)
+              state->equals_to1_(i1 + k, 0) = make_heap_area(i1, -1);
+            equal = 1;
+            i1 += heapinfo1->busy_block.size;
+          }
+
+          xbt_dynar_reset(previous);
+
+        }
+
+      }
+
+      while (i2 <= state->heaplimit && !equal) {
+
+        addr_block2 =
+            ((void *) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE +
+                       (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+
+        if (i2 == i1) {
+          i2++;
+          continue;
+        }
+
+        malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info));
+
+        if (heapinfo2b->type != 0) {
+          i2++;
+          continue;
+        }
+
+        if (state->equals_to2_(i2, 0).valid) {
+          i2++;
+          continue;
+        }
+
+        res_compare =
+            compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2,
+                              NULL, NULL, 0);
+
+        if (res_compare != 1) {
+          for (k = 1; k < heapinfo2b->busy_block.size; k++)
+            state->equals_to2_(i2 + k, 0) = make_heap_area(i1, -1);
+          for (k = 1; k < heapinfo1->busy_block.size; k++)
+            state->equals_to1_(i1 + k, 0) = make_heap_area(i2, -1);
+          equal = 1;
+          i1 += heapinfo1->busy_block.size;
+        }
+
+        xbt_dynar_reset(previous);
+
+        i2++;
+
+      }
+
+      if (!equal) {
+        XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1,
+                  heapinfo1->busy_block.busy_size, addr_block1);
+        i1 = state->heaplimit + 1;
+        nb_diff1++;
+        //i1++;
+      }
+
+    } else {                    /* Fragmented block */
+
+      for (j1 = 0; j1 < (size_t) (BLOCKSIZE >> heapinfo1->type); j1++) {
+
+        if (heapinfo1->busy_frag.frag_size[j1] == -1) /* Free fragment */
+          continue;
+
+        if (state->equals_to1_(i1, j1).valid)
+          continue;
+
+        addr_frag1 =
+            (void *) ((char *) addr_block1 + (j1 << heapinfo1->type));
+
+        i2 = 1;
+        equal = 0;
+
+        /* Try first to associate to same fragment in the other heap */
+        if (heapinfo2->type == heapinfo1->type) {
+
+          if (state->equals_to2_(i1, j1).valid == 0) {
+
+            addr_block2 =
+                ((void *) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE +
+                           (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+            addr_frag2 =
+                (void *) ((char *) addr_block2 +
+                          (j1 << ((xbt_mheap_t) state->s_heap)->heapinfo[i1].
+                           type));
+
+            res_compare =
+                compare_heap_area(addr_frag1, addr_frag2, snapshot1, snapshot2,
+                                  NULL, NULL, 0);
+
+            if (res_compare != 1)
+              equal = 1;
+
+            xbt_dynar_reset(previous);
+
+          }
+
+        }
+
+        while (i2 <= state->heaplimit && !equal) {
+
+          malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info));
+          if (heapinfo2b->type <= 0) {
+            i2++;
+            continue;
+          }
+
+          for (j2 = 0; j2 < (size_t) (BLOCKSIZE >> heapinfo2b->type);
+               j2++) {
+
+            if (i2 == i1 && j2 == j1)
+              continue;
+
+            if (state->equals_to2_(i2, j2).valid)
+              continue;
+
+            addr_block2 =
+                ((void *) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE +
+                           (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+            addr_frag2 =
+                (void *) ((char *) addr_block2 +
+                          (j2 << ((xbt_mheap_t) state->s_heap)->heapinfo[i2].
+                           type));
+
+            res_compare =
+                compare_heap_area(addr_frag1, addr_frag2, snapshot2, snapshot2,
+                                  NULL, NULL, 0);
+
+            if (res_compare != 1) {
+              equal = 1;
+              xbt_dynar_reset(previous);
+              break;
+            }
+
+            xbt_dynar_reset(previous);
+
+          }
+
+          i2++;
+
+        }
+
+        if (!equal) {
+          XBT_DEBUG
+              ("Block %zu, fragment %zu not found (size_used = %zd, address = %p)\n",
+               i1, j1, heapinfo1->busy_frag.frag_size[j1],
+               addr_frag1);
+          i2 = state->heaplimit + 1;
+          i1 = state->heaplimit + 1;
+          nb_diff1++;
+          break;
+        }
+
+      }
+
+      i1++;
+
+    }
+
+  }
+
+  /* All blocks/fragments are equal to another block/fragment ? */
+  size_t i = 1, j = 0;
+
+  for(i = 1; i <= state->heaplimit; i++) {
+    malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
+    if (heapinfo1->type == 0) {
+      if (i1 == state->heaplimit) {
+        if (heapinfo1->busy_block.busy_size > 0) {
+          if (state->equals_to1_(i, 0).valid == 0) {
+            if (XBT_LOG_ISENABLED(mc_diff, xbt_log_priority_debug)) {
+              // TODO, add address
+              XBT_DEBUG("Block %zu not found (size used = %zu)", i,
+                        heapinfo1->busy_block.busy_size);
+              //mmalloc_backtrace_block_display((void*)heapinfo1, i);
+            }
+            nb_diff1++;
+          }
+        }
+      }
+    }
+    if (heapinfo1->type > 0) {
+      for (j = 0; j < (size_t) (BLOCKSIZE >> heapinfo1->type); j++) {
+        if (i1 == state->heaplimit) {
+          if (heapinfo1->busy_frag.frag_size[j] > 0) {
+            if (state->equals_to1_(i, j).valid == 0) {
+              if (XBT_LOG_ISENABLED(mc_diff, xbt_log_priority_debug)) {
+                // TODO, print fragment address
+                XBT_DEBUG
+                    ("Block %zu, Fragment %zu not found (size used = %zd)",
+                     i, j,
+                     heapinfo1->busy_frag.frag_size[j]);
+                //mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
+              }
+              nb_diff1++;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (i1 == state->heaplimit)
+    XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1);
+
+  for (i=1; i <= state->heaplimit; i++) {
+    malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
+    if (heapinfo2->type == 0) {
+      if (i1 == state->heaplimit) {
+        if (heapinfo2->busy_block.busy_size > 0) {
+          if (state->equals_to2_(i, 0).valid == 0) {
+            if (XBT_LOG_ISENABLED(mc_diff, xbt_log_priority_debug)) {
+              // TODO, print address of the block
+              XBT_DEBUG("Block %zu not found (size used = %zu)", i,
+                        heapinfo2->busy_block.busy_size);
+              //mmalloc_backtrace_block_display((void*)heapinfo2, i);
+            }
+            nb_diff2++;
+          }
+        }
+      }
+    }
+    if (heapinfo2->type > 0) {
+      for (j = 0; j < (size_t) (BLOCKSIZE >> heapinfo2->type); j++) {
+        if (i1 == state->heaplimit) {
+          if (heapinfo2->busy_frag.frag_size[j] > 0) {
+            if (state->equals_to2_(i, j).valid == 0) {
+              if (XBT_LOG_ISENABLED(mc_diff, xbt_log_priority_debug)) {
+                // TODO, print address of the block
+                XBT_DEBUG
+                    ("Block %zu, Fragment %zu not found (size used = %zd)",
+                     i, j,
+                     heapinfo2->busy_frag.frag_size[j]);
+                //mmalloc_backtrace_fragment_display((void*)heapinfo2, i, j);
+              }
+              nb_diff2++;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (i1 == state->heaplimit)
+    XBT_DEBUG("Number of blocks/fragments not found in heap2 : %d", nb_diff2);
+
+  xbt_dynar_free(&previous);
+  return ((nb_diff1 > 0) || (nb_diff2 > 0));
+}
+
+/**
+ *
+ * @param state
+ * @param real_area1     Process address for state 1
+ * @param real_area2     Process address for state 2
+ * @param snapshot1      Snapshot of state 1
+ * @param snapshot2      Snapshot of state 2
+ * @param previous
+ * @param size
+ * @param check_ignore
+ */
+static int compare_heap_area_without_type(struct s_mc_diff *state,
+                                          void *real_area1, void *real_area2,
+                                          mc_snapshot_t snapshot1,
+                                          mc_snapshot_t snapshot2,
+                                          xbt_dynar_t previous, int size,
+                                          int check_ignore)
+{
+
+  int i = 0;
+  void *addr_pointed1, *addr_pointed2;
+  int pointer_align, res_compare;
+  ssize_t ignore1, ignore2;
+
+  mc_mem_region_t heap_region1 = snapshot1->regions[0];
+  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+
+  while (i < size) {
+
+    if (check_ignore > 0) {
+      if ((ignore1 =
+           heap_comparison_ignore_size(state->to_ignore1,
+                                       (char *) real_area1 + i)) != -1) {
+        if ((ignore2 =
+             heap_comparison_ignore_size(state->to_ignore2,
+                                         (char *) real_area2 + i)) == ignore1) {
+          if (ignore1 == 0) {
+            check_ignore--;
+            return 0;
+          } else {
+            i = i + ignore2;
+            check_ignore--;
+            continue;
+          }
+        }
+      }
+    }
+
+    if (mc_snapshot_region_memcp(((char *) real_area1) + i, heap_region1, ((char *) real_area2) + i, heap_region2, 1) != 0) {
+
+      pointer_align = (i / sizeof(void *)) * sizeof(void *);
+      addr_pointed1 = mc_snapshot_read_pointer((char *) real_area1 + pointer_align, snapshot1);
+      addr_pointed2 = mc_snapshot_read_pointer((char *) real_area2 + pointer_align, snapshot2);
+
+      if (addr_pointed1 > maestro_stack_start
+          && addr_pointed1 < maestro_stack_end
+          && addr_pointed2 > maestro_stack_start
+          && addr_pointed2 < maestro_stack_end) {
+        i = pointer_align + sizeof(void *);
+        continue;
+      } else if (addr_pointed1 > state->s_heap
+                 && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)
+                 && addr_pointed2 > state->s_heap
+                 && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2)) {
+        // Both addreses are in the heap:
+        res_compare =
+            compare_heap_area(addr_pointed1, addr_pointed2, snapshot1,
+                              snapshot2, previous, NULL, 0);
+        if (res_compare == 1) {
+          return res_compare;
+        }
+        i = pointer_align + sizeof(void *);
+        continue;
+      } else {
+        return 1;
+      }
+
+    }
+
+    i++;
+
+  }
+
+  return 0;
+
+}
+
+/**
+ *
+ * @param state
+ * @param real_area1     Process address for state 1
+ * @param real_area2     Process address for state 2
+ * @param snapshot1      Snapshot of state 1
+ * @param snapshot2      Snapshot of state 2
+ * @param previous
+ * @param type_id
+ * @param area_size      either a byte_size or an elements_count (?)
+ * @param check_ignore
+ * @param pointer_level
+ * @return               0 (same), 1 (different), -1 (unknown)
+ */
+static int compare_heap_area_with_type(struct s_mc_diff *state,
+                                       void *real_area1, void *real_area2,
+                                       mc_snapshot_t snapshot1,
+                                       mc_snapshot_t snapshot2,
+                                       xbt_dynar_t previous, dw_type_t type,
+                                       int area_size, int check_ignore,
+                                       int pointer_level)
+{
+top:
+  if (is_stack(real_area1) && is_stack(real_area2))
+    return 0;
+
+  ssize_t ignore1, ignore2;
+
+  if ((check_ignore > 0)
+      && ((ignore1 = heap_comparison_ignore_size(state->to_ignore1, real_area1))
+          > 0)
+      && ((ignore2 = heap_comparison_ignore_size(state->to_ignore2, real_area2))
+          == ignore1)) {
+    return 0;
+  }
+
+  dw_type_t subtype, subsubtype;
+  int res, elm_size, i;
+  unsigned int cursor = 0;
+  dw_type_t member;
+  void *addr_pointed1, *addr_pointed2;;
+
+  mc_mem_region_t heap_region1 = snapshot1->regions[0];
+  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+
+  switch (type->type) {
+  case DW_TAG_unspecified_type:
+    return 1;
+
+  case DW_TAG_base_type:
+    if (type->name != NULL && strcmp(type->name, "char") == 0) {        /* String, hence random (arbitrary ?) size */
+      if (real_area1 == real_area2)
+        return -1;
+      else
+        return (mc_snapshot_region_memcp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0);
+    } else {
+      if (area_size != -1 && type->byte_size != area_size)
+        return -1;
+      else {
+        return (mc_snapshot_region_memcp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0);
+      }
+    }
+    break;
+  case DW_TAG_enumeration_type:
+    if (area_size != -1 && type->byte_size != area_size)
+      return -1;
+    else
+      return (mc_snapshot_region_memcp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0);
+    break;
+  case DW_TAG_typedef:
+  case DW_TAG_const_type:
+  case DW_TAG_volatile_type:
+    // Poor man's TCO:
+    type = type->subtype;
+    goto top;
+    break;
+  case DW_TAG_array_type:
+    subtype = type->subtype;
+    switch (subtype->type) {
+    case DW_TAG_unspecified_type:
+      return 1;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_reference_type:
+    case DW_TAG_rvalue_reference_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+      if (subtype->full_type)
+        subtype = subtype->full_type;
+      elm_size = subtype->byte_size;
+      break;
+      // TODO, just remove the type indirection?
+    case DW_TAG_const_type:
+    case DW_TAG_typedef:
+    case DW_TAG_volatile_type:
+      subsubtype = subtype->subtype;
+      if (subsubtype->full_type)
+        subsubtype = subsubtype->full_type;
+      elm_size = subsubtype->byte_size;
+      break;
+    default:
+      return 0;
+      break;
+    }
+    for (i = 0; i < type->element_count; i++) {
+      // TODO, add support for variable stride (DW_AT_byte_stride)
+      res =
+          compare_heap_area_with_type(state,
+                                      (char *) real_area1 + (i * elm_size),
+                                      (char *) real_area2 + (i * elm_size),
+                                      snapshot1, snapshot2, previous,
+                                      type->subtype, subtype->byte_size,
+                                      check_ignore, pointer_level);
+      if (res == 1)
+        return res;
+    }
+    break;
+  case DW_TAG_reference_type:
+  case DW_TAG_rvalue_reference_type:
+  case DW_TAG_pointer_type:
+    if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
+      addr_pointed1 = mc_snapshot_read_pointer(real_area1, snapshot1);
+      addr_pointed2 = mc_snapshot_read_pointer(real_area2, snapshot2);
+      return (addr_pointed1 != addr_pointed2);;
+    } else {
+      pointer_level++;
+      if (pointer_level > 1) {  /* Array of pointers */
+        for (i = 0; i < (area_size / sizeof(void *)); i++) {
+          addr_pointed1 = mc_snapshot_read_pointer((char*) real_area1 + i * sizeof(void *), snapshot1);
+          addr_pointed2 = mc_snapshot_read_pointer((char*) real_area2 + i * sizeof(void *), snapshot2);
+          if (addr_pointed1 > state->s_heap
+              && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)
+              && addr_pointed2 > state->s_heap
+              && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2))
+            res =
+                compare_heap_area(addr_pointed1, addr_pointed2, snapshot1,
+                                  snapshot2, previous, type->subtype,
+                                  pointer_level);
+          else
+            res = (addr_pointed1 != addr_pointed2);
+          if (res == 1)
+            return res;
+        }
+      } else {
+        addr_pointed1 = mc_snapshot_read_pointer(real_area1, snapshot1);
+        addr_pointed2 = mc_snapshot_read_pointer(real_area2, snapshot2);
+        if (addr_pointed1 > state->s_heap
+            && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)
+            && addr_pointed2 > state->s_heap
+            && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2))
+          return compare_heap_area(addr_pointed1, addr_pointed2, snapshot1,
+                                   snapshot2, previous, type->subtype,
+                                   pointer_level);
+        else
+          return (addr_pointed1 != addr_pointed2);
+      }
+    }
+    break;
+  case DW_TAG_structure_type:
+  case DW_TAG_class_type:
+    if (type->full_type)
+      type = type->full_type;
+    if (area_size != -1 && type->byte_size != area_size) {
+      if (area_size > type->byte_size && area_size % type->byte_size == 0) {
+        for (i = 0; i < (area_size / type->byte_size); i++) {
+          res =
+              compare_heap_area_with_type(state,
+                                          (char *) real_area1 + i * type->byte_size,
+                                          (char *) real_area2 + i * type->byte_size,
+                                          snapshot1, snapshot2, previous, type, -1,
+                                          check_ignore, 0);
+          if (res == 1)
+            return res;
+        }
+      } else {
+        return -1;
+      }
+    } else {
+      cursor = 0;
+      xbt_dynar_foreach(type->members, cursor, member) {
+        // TODO, optimize this? (for the offset case)
+        char *real_member1 =
+            mc_member_resolve(real_area1, type, member, snapshot1);
+        char *real_member2 =
+            mc_member_resolve(real_area2, type, member, snapshot2);
+        res =
+            compare_heap_area_with_type(state, real_member1, real_member2,
+                                        snapshot1, snapshot2,
+                                        previous, member->subtype, -1,
+                                        check_ignore, 0);
+        if (res == 1) {
+          return res;
+        }
+      }
+    }
+    break;
+  case DW_TAG_union_type:
+    return compare_heap_area_without_type(state, real_area1, real_area2,
+                                          snapshot1, snapshot2, previous,
+                                          type->byte_size, check_ignore);
+    break;
+  default:
+    break;
+  }
+
+  return 0;
+
+}
+
+/** Infer the type of a part of the block from the type of the block
+ *
+ * TODO, handle DW_TAG_array_type as well as arrays of the object ((*p)[5], p[5])
+ *
+ * TODO, handle subfields ((*p).bar.foo, (*p)[5].bar…)
+ *
+ * @param  type_id            DWARF type ID of the root address
+ * @param  area_size
+ * @return                    DWARF type ID for given offset
+ */
+static dw_type_t get_offset_type(void *real_base_address, dw_type_t type,
+                                 int offset, int area_size,
+                                 mc_snapshot_t snapshot)
+{
+
+  // Beginning of the block, the infered variable type if the type of the block:
+  if (offset == 0)
+    return type;
+
+  switch (type->type) {
+  case DW_TAG_structure_type:
+  case DW_TAG_class_type:
+    if (type->full_type)
+      type = type->full_type;
+
+    if (area_size != -1 && type->byte_size != area_size) {
+      if (area_size > type->byte_size && area_size % type->byte_size == 0)
+        return type;
+      else
+        return NULL;
+    } else {
+      unsigned int cursor = 0;
+      dw_type_t member;
+      xbt_dynar_foreach(type->members, cursor, member) {
+
+        if (!member->location.size) {
+          // We have the offset, use it directly (shortcut):
+          if (member->offset == offset)
+            return member->subtype;
+        } else {
+          char *real_member =
+              mc_member_resolve(real_base_address, type, member, snapshot);
+          if (real_member - (char *) real_base_address == offset)
+            return member->subtype;
+        }
+
+      }
+      return NULL;
+    }
+    break;
+  default:
+    /* FIXME : other cases ? */
+    return NULL;
+    break;
+  }
+}
+
+/**
+ *
+ * @param area1          Process address for state 1
+ * @param area2          Process address for state 2
+ * @param snapshot1      Snapshot of state 1
+ * @param snapshot2      Snapshot of state 2
+ * @param previous       Pairs of blocks already compared on the current path (or NULL)
+ * @param type_id        Type of variable
+ * @param pointer_level
+ * @return 0 (same), 1 (different), -1
+ */
+int compare_heap_area(void *area1, void *area2, mc_snapshot_t snapshot1,
+                      mc_snapshot_t snapshot2, xbt_dynar_t previous,
+                      dw_type_t type, int pointer_level)
+{
+
+  struct s_mc_diff *state = mc_diff_info;
+
+  int res_compare;
+  ssize_t block1, frag1, block2, frag2;
+  ssize_t size;
+  int check_ignore = 0;
+
+  void *real_addr_block1, *real_addr_block2, *real_addr_frag1, *real_addr_frag2;
+
+  int type_size = -1;
+  int offset1 = 0, offset2 = 0;
+  int new_size1 = -1, new_size2 = -1;
+  dw_type_t new_type1 = NULL, new_type2 = NULL;
+
+  int match_pairs = 0;
+
+  malloc_info* heapinfos1 = mc_snapshot_read_pointer(&((xbt_mheap_t)std_heap)->heapinfo, snapshot1);
+  malloc_info* heapinfos2 = mc_snapshot_read_pointer(&((xbt_mheap_t)std_heap)->heapinfo, snapshot2);
+
+  malloc_info heapinfo_temp1, heapinfo_temp2;
+
+  if (previous == NULL) {
+    previous =
+        xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
+    match_pairs = 1;
+  }
+  // Get block number:
+  block1 =
+      ((char *) area1 -
+       (char *) ((xbt_mheap_t) state->s_heap)->heapbase) / BLOCKSIZE + 1;
+  block2 =
+      ((char *) area2 -
+       (char *) ((xbt_mheap_t) state->s_heap)->heapbase) / BLOCKSIZE + 1;
+
+  // If either block is a stack block:
+  if (is_block_stack((int) block1) && is_block_stack((int) block2)) {
+    add_heap_area_pair(previous, block1, -1, block2, -1);
+    if (match_pairs) {
+      match_equals(state, previous);
+      xbt_dynar_free(&previous);
+    }
+    return 0;
+  }
+  // If either block is not in the expected area of memory:
+  if (((char *) area1 < (char *) ((xbt_mheap_t) state->s_heap)->heapbase)
+      || (block1 > state->heapsize1) || (block1 < 1)
+      || ((char *) area2 < (char *) ((xbt_mheap_t) state->s_heap)->heapbase)
+      || (block2 > state->heapsize2) || (block2 < 1)) {
+    if (match_pairs) {
+      xbt_dynar_free(&previous);
+    }
+    return 1;
+  }
+
+  // Process address of the block:
+  real_addr_block1 =
+      ((void *) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE +
+                 (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+  real_addr_block2 =
+      ((void *) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE +
+                 (char *) ((xbt_mheap_t) state->s_heap)->heapbase));
+
+  if (type) {
+
+    if (type->full_type)
+      type = type->full_type;
+
+    // This assume that for "boring" types (volatile ...) byte_size is absent:
+    while (type->byte_size == 0 && type->subtype != NULL)
+      type = type->subtype;
+
+    // Find type_size:
+    if ((type->type == DW_TAG_pointer_type)
+        || ((type->type == DW_TAG_base_type) && type->name != NULL
+            && (!strcmp(type->name, "char"))))
+      type_size = -1;
+    else
+      type_size = type->byte_size;
+
+  }
+
+  mc_mem_region_t heap_region1 = snapshot1->regions[0];
+  mc_mem_region_t heap_region2 = snapshot2->regions[0];
+
+  malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[block1], heap_region1, &heapinfo_temp1, sizeof(malloc_info));
+  malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[block2], heap_region2, &heapinfo_temp2, sizeof(malloc_info));
+
+  if ((heapinfo1->type == -1) && (heapinfo2->type == -1)) { /* Free block */
+
+    if (match_pairs) {
+      match_equals(state, previous);
+      xbt_dynar_free(&previous);
+    }
+    return 0;
+
+  } else if ((heapinfo1->type == 0) && (heapinfo2->type == 0)) {    /* Complete block */
+
+    // TODO, lookup variable type from block type as done for fragmented blocks
+
+    if (state->equals_to1_(block1, 0).valid
+        && state->equals_to2_(block2, 0).valid) {
+      if (equal_blocks(state, block1, block2)) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return 0;
+      }
+    }
+
+    if (type_size != -1) {
+      if (type_size != heapinfo1->busy_block.busy_size
+          && type_size != heapinfo2->busy_block.busy_size
+          && type->name != NULL && !strcmp(type->name, "s_smx_context")) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return -1;
+      }
+    }
+
+    if (heapinfo1->busy_block.size !=
+        heapinfo2->busy_block.size) {
+      if (match_pairs) {
+        xbt_dynar_free(&previous);
+      }
+      return 1;
+    }
+
+    if (heapinfo1->busy_block.busy_size !=
+        heapinfo2->busy_block.busy_size) {
+      if (match_pairs) {
+        xbt_dynar_free(&previous);
+      }
+      return 1;
+    }
+
+    if (!add_heap_area_pair(previous, block1, -1, block2, -1)) {
+      if (match_pairs) {
+        match_equals(state, previous);
+        xbt_dynar_free(&previous);
+      }
+      return 0;
+    }
+
+    size = heapinfo1->busy_block.busy_size;
+
+    // Remember (basic) type inference.
+    // The current data structure only allows us to do this for the whole block.
+    if (type != NULL && area1 == real_addr_block1) {
+      state->types1_(block1, 0) = type;
+    }
+    if (type != NULL && area2 == real_addr_block2) {
+      state->types2_(block2, 0) = type;
+    }
+
+    if (size <= 0) {
+      if (match_pairs) {
+        match_equals(state, previous);
+        xbt_dynar_free(&previous);
+      }
+      return 0;
+    }
+
+    frag1 = -1;
+    frag2 = -1;
+
+    if ((heapinfo1->busy_block.ignore > 0)
+        && (heapinfo2->busy_block.ignore ==
+            heapinfo1->busy_block.ignore))
+      check_ignore = heapinfo1->busy_block.ignore;
+
+  } else if ((heapinfo1->type > 0) && (heapinfo2->type > 0)) {      /* Fragmented block */
+
+    // Fragment number:
+    frag1 =
+        ((uintptr_t) (ADDR2UINT(area1) % (BLOCKSIZE))) >> heapinfo1->type;
+    frag2 =
+        ((uintptr_t) (ADDR2UINT(area2) % (BLOCKSIZE))) >> heapinfo2->type;
+
+    // Process address of the fragment:
+    real_addr_frag1 =
+        (void *) ((char *) real_addr_block1 +
+                  (frag1 << ((xbt_mheap_t) state->s_heap)->heapinfo[block1].
+                   type));
+    real_addr_frag2 =
+        (void *) ((char *) real_addr_block2 +
+                  (frag2 << ((xbt_mheap_t) state->s_heap)->heapinfo[block2].
+                   type));
+
+    // Check the size of the fragments against the size of the type:
+    if (type_size != -1) {
+      if (heapinfo1->busy_frag.frag_size[frag1] == -1
+          || heapinfo2->busy_frag.frag_size[frag2] == -1) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return -1;
+      }
+      if (type_size != heapinfo1->busy_frag.frag_size[frag1]
+          || type_size != heapinfo2->busy_frag.frag_size[frag2]) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return -1;
+      }
+    }
+    // Check if the blocks are already matched together:
+    if (state->equals_to1_(block1, frag1).valid
+        && state->equals_to2_(block2, frag2).valid) {
+      if (equal_fragments(state, block1, frag1, block2, frag2)) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return 0;
+      }
+    }
+    // Compare the size of both fragments:
+    if (heapinfo1->busy_frag.frag_size[frag1] !=
+        heapinfo2->busy_frag.frag_size[frag2]) {
+      if (type_size == -1) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return -1;
+      } else {
+        if (match_pairs) {
+          xbt_dynar_free(&previous);
+        }
+        return 1;
+      }
+    }
+    // Size of the fragment:
+    size = heapinfo1->busy_frag.frag_size[frag1];
+
+    // Remember (basic) type inference.
+    // The current data structure only allows us to do this for the whole block.
+    if (type != NULL && area1 == real_addr_frag1) {
+      state->types1_(block1, frag1) = type;
+    }
+    if (type != NULL && area2 == real_addr_frag2) {
+      state->types2_(block2, frag2) = type;
+    }
+    // The type of the variable is already known:
+    if (type) {
+      new_type1 = type;
+      new_type2 = type;
+    }
+    // Type inference from the block type.
+    else if (state->types1_(block1, frag1) != NULL
+             || state->types2_(block2, frag2) != NULL) {
+
+      offset1 = (char *) area1 - (char *) real_addr_frag1;
+      offset2 = (char *) area2 - (char *) real_addr_frag2;
+
+      if (state->types1_(block1, frag1) != NULL
+          && state->types2_(block2, frag2) != NULL) {
+        new_type1 =
+            get_offset_type(real_addr_frag1, state->types1_(block1, frag1),
+                            offset1, size, snapshot1);
+        new_type2 =
+            get_offset_type(real_addr_frag2, state->types2_(block2, frag2),
+                            offset1, size, snapshot2);
+      } else if (state->types1_(block1, frag1) != NULL) {
+        new_type1 =
+            get_offset_type(real_addr_frag1, state->types1_(block1, frag1),
+                            offset1, size, snapshot1);
+        new_type2 =
+            get_offset_type(real_addr_frag2, state->types1_(block1, frag1),
+                            offset2, size, snapshot2);
+      } else if (state->types2_(block2, frag2) != NULL) {
+        new_type1 =
+            get_offset_type(real_addr_frag1, state->types2_(block2, frag2),
+                            offset1, size, snapshot1);
+        new_type2 =
+            get_offset_type(real_addr_frag2, state->types2_(block2, frag2),
+                            offset2, size, snapshot2);
+      } else {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return -1;
+      }
+
+      if (new_type1 != NULL && new_type2 != NULL && new_type1 != new_type2) {
+
+        type = new_type1;
+        while (type->byte_size == 0 && type->subtype != NULL)
+          type = type->subtype;
+        new_size1 = type->byte_size;
+
+        type = new_type2;
+        while (type->byte_size == 0 && type->subtype != NULL)
+          type = type->subtype;
+        new_size2 = type->byte_size;
+
+      } else {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return -1;
+      }
+    }
+
+    if (new_size1 > 0 && new_size1 == new_size2) {
+      type = new_type1;
+      size = new_size1;
+    }
+
+    if (offset1 == 0 && offset2 == 0) {
+      if (!add_heap_area_pair(previous, block1, frag1, block2, frag2)) {
+        if (match_pairs) {
+          match_equals(state, previous);
+          xbt_dynar_free(&previous);
+        }
+        return 0;
+      }
+    }
+
+    if (size <= 0) {
+      if (match_pairs) {
+        match_equals(state, previous);
+        xbt_dynar_free(&previous);
+      }
+      return 0;
+    }
+
+    if ((heapinfo1->busy_frag.ignore[frag1] > 0)
+        && (heapinfo2->busy_frag.ignore[frag2] ==
+            heapinfo1->busy_frag.ignore[frag1]))
+      check_ignore = heapinfo1->busy_frag.ignore[frag1];
+
+  } else {
+
+    if (match_pairs) {
+      xbt_dynar_free(&previous);
+    }
+    return 1;
+
+  }
+
+
+  /* Start comparison */
+  if (type) {
+    res_compare =
+        compare_heap_area_with_type(state, area1, area2, snapshot1, snapshot2,
+                                    previous, type, size, check_ignore,
+                                    pointer_level);
+  } else {
+    res_compare =
+        compare_heap_area_without_type(state, area1, area2, snapshot1, snapshot2,
+                                       previous, size, check_ignore);
+  }
+  if (res_compare == 1) {
+    if (match_pairs)
+      xbt_dynar_free(&previous);
+    return res_compare;
+  }
+
+  if (match_pairs) {
+    match_equals(state, previous);
+    xbt_dynar_free(&previous);
+  }
+
+  return 0;
+}
+
+/*********************************************** Miscellaneous ***************************************************/
+/****************************************************************************************************************/
+
+// Not used and broken code:
+# if 0
+
+// Not used:
+static int get_pointed_area_size(void *area, int heap)
+{
+
+  struct s_mc_diff *state = mc_diff_info;
+
+  int block, frag;
+  malloc_info *heapinfo;
+
+  if (heap == 1)
+    heapinfo = state->heapinfo1;
+  else
+    heapinfo = state->heapinfo2;
+
+  block =
+      ((char *) area -
+       (char *) ((xbt_mheap_t) state->s_heap)->heapbase) / BLOCKSIZE + 1;
+
+  if (((char *) area < (char *) ((xbt_mheap_t) state->s_heap)->heapbase)
+      || (block > state->heapsize1) || (block < 1))
+    return -1;
+
+  if (heapinfo[block].type == -1) {     /* Free block */
+    return -1;
+  } else if (heapinfo[block].type == 0) {       /* Complete block */
+    return (int) heapinfo[block].busy_block.busy_size;
+  } else {
+    frag =
+        ((uintptr_t) (ADDR2UINT(area) % (BLOCKSIZE))) >> heapinfo[block].type;
+    return (int) heapinfo[block].busy_frag.frag_size[frag];
+  }
+}
+
+// Not used:
+char *get_type_description(mc_object_info_t info, char *type_name)
+{
+
+  xbt_dict_cursor_t dict_cursor;
+  char *type_origin;
+  dw_type_t type;
+
+  xbt_dict_foreach(info->types, dict_cursor, type_origin, type) {
+    if (type->name && (strcmp(type->name, type_name) == 0)
+        && type->byte_size > 0) {
+      xbt_dict_cursor_free(&dict_cursor);
+      return type_origin;
+    }
+  }
+
+  xbt_dict_cursor_free(&dict_cursor);
+  return NULL;
+}
+
+
+#ifndef max
+#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
+#endif
+
+// Not used:
+int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2)
+{
+
+  struct s_mc_diff *state = mc_diff_info;
+
+  if (heap1 == NULL && heap1 == NULL) {
+    XBT_DEBUG("Malloc descriptors null");
+    return 0;
+  }
+
+  if (heap1->heaplimit != heap2->heaplimit) {
+    XBT_DEBUG("Different limit of valid info table indices");
+    return 1;
+  }
+
+  /* Heap information */
+  state->heaplimit = ((struct mdesc *) heap1)->heaplimit;
+
+
+  // Mamailloute in order to find the base address of the main heap:
+  state->s_heap =
+      (char *) mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
+
+  state->heapbase1 = (char *) heap1 + BLOCKSIZE;
+  state->heapbase2 = (char *) heap2 + BLOCKSIZE;
+
+  state->heapinfo1 =
+      (malloc_info *) ((char *) heap1 +
+                       ((uintptr_t)
+                        ((char *) heap1->heapinfo - (char *) state->s_heap)));
+  state->heapinfo2 =
+      (malloc_info *) ((char *) heap2 +
+                       ((uintptr_t)
+                        ((char *) heap2->heapinfo - (char *) state->s_heap)));
+
+  state->heapsize1 = heap1->heapsize;
+  state->heapsize2 = heap2->heapsize;
+
+  /* Start comparison */
+  size_t i, j, k;
+  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
+
+  int distance = 0;
+
+  /* Check busy blocks */
+
+  i = 1;
+
+  while (i <= state->heaplimit) {
+
+    addr_block1 =
+        ((void *) (((ADDR2UINT(i)) - 1) * BLOCKSIZE +
+                   (char *) state->heapbase1));
+    addr_block2 =
+        ((void *) (((ADDR2UINT(i)) - 1) * BLOCKSIZE +
+                   (char *) state->heapbase2));
+
+    if (state->heapinfo1[i].type != state->heapinfo2[i].type) {
+
+      distance += BLOCKSIZE;
+      XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i,
+                state->heapinfo1[i].type, state->heapinfo2[i].type, distance);
+      i++;
+
+    } else {
+
+      if (state->heapinfo1[i].type == -1) {     /* Free block */
+        i++;
+        continue;
+      }
+
+      if (state->heapinfo1[i].type == 0) {      /* Large block */
+
+        if (state->heapinfo1[i].busy_block.size !=
+            state->heapinfo2[i].busy_block.size) {
+          distance +=
+              BLOCKSIZE * max(state->heapinfo1[i].busy_block.size,
+                              state->heapinfo2[i].busy_block.size);
+          i += max(state->heapinfo1[i].busy_block.size,
+                   state->heapinfo2[i].busy_block.size);
+          XBT_DEBUG
+              ("Different larger of cluster at block %zu : %zu - %zu -> distance = %d",
+               i, state->heapinfo1[i].busy_block.size,
+               state->heapinfo2[i].busy_block.size, distance);
+          continue;
+        }
+
+        /*if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
+           distance += max(heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size);
+           i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+           XBT_DEBUG("Different size used oin large cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size, distance);
+           continue;
+           } */
+
+        k = 0;
+
+        //while(k < (heapinfo1[i].busy_block.busy_size)){
+        while (k < state->heapinfo1[i].busy_block.size * BLOCKSIZE) {
+          if (memcmp((char *) addr_block1 + k, (char *) addr_block2 + k, 1) !=
+              0) {
+            distance++;
+          }
+          k++;
+        }
+
+        i++;
+
+      } else {                  /* Fragmented block */
+
+        for (j = 0; j < (size_t) (BLOCKSIZE >> state->heapinfo1[i].type); j++) {
+
+          addr_frag1 =
+              (void *) ((char *) addr_block1 + (j << state->heapinfo1[i].type));
+          addr_frag2 =
+              (void *) ((char *) addr_block2 + (j << state->heapinfo2[i].type));
+
+          if (state->heapinfo1[i].busy_frag.frag_size[j] == 0
+              && state->heapinfo2[i].busy_frag.frag_size[j] == 0) {
+            continue;
+          }
+
+
+          /*if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
+             distance += max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]);
+             XBT_DEBUG("Different size used in fragment %zu in block %zu : %d - %d -> distance = %d", j, i, heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j], distance); 
+             continue;
+             } */
+
+          k = 0;
+
+          //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
+          while (k < (BLOCKSIZE / (BLOCKSIZE >> state->heapinfo1[i].type))) {
+            if (memcmp((char *) addr_frag1 + k, (char *) addr_frag2 + k, 1) !=
+                0) {
+              distance++;
+            }
+            k++;
+          }
+
+        }
+
+        i++;
+
+      }
+
+    }
+
+  }
+
+  return distance;
+
+}
+#endif
diff --git a/src/mc/mc_dpor.c b/src/mc/mc_dpor.c
deleted file mode 100644 (file)
index 6c22b82..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-/* Copyright (c) 2008-2014. The SimGrid Team.
- * All rights reserved.                                                     */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include "mc_private.h"
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dpor, mc,
-                                "Logging specific to MC DPOR exploration");
-
-/********** Global variables **********/
-
-xbt_dynar_t visited_states;
-xbt_dict_t first_enabled_state;
-xbt_dynar_t initial_communications_pattern;
-xbt_dynar_t incomplete_communications_pattern;
-xbt_dynar_t communications_pattern;
-int nb_comm_pattern;
-
-/********** Static functions ***********/
-
-static void comm_pattern_free(mc_comm_pattern_t p){
-  xbt_free(p->rdv);
-  xbt_free(p->data);
-  xbt_free(p);
-  p = NULL;
-}
-
-static void comm_pattern_free_voidp( void *p){
-  comm_pattern_free((mc_comm_pattern_t) * (void **)p);
-}
-
-static mc_comm_pattern_t get_comm_pattern_from_idx(xbt_dynar_t pattern, unsigned int *idx, e_smx_comm_type_t type, unsigned long proc){
-  mc_comm_pattern_t current_comm;
-  while(*idx < xbt_dynar_length(pattern)){
-    current_comm = (mc_comm_pattern_t)xbt_dynar_get_as(pattern, *idx, mc_comm_pattern_t);
-    if(current_comm->type == type && type == SIMIX_COMM_SEND){
-      if(current_comm->src_proc == proc)
-        return current_comm;
-    }else if(current_comm->type == type && type == SIMIX_COMM_RECEIVE){
-      if(current_comm->dst_proc == proc)
-        return current_comm;
-    }
-    (*idx)++;
-  }
-  return NULL;
-}
-
-static int compare_comm_pattern(mc_comm_pattern_t comm1, mc_comm_pattern_t comm2){
-  if(strcmp(comm1->rdv, comm2->rdv) != 0)
-    return 1;
-  if(comm1->src_proc != comm2->src_proc)
-    return 1;
-  if(comm1->dst_proc != comm2->dst_proc)
-    return 1;
-  if(comm1->data_size != comm2->data_size)
-    return 1;
-  if(memcmp(comm1->data, comm2->data, comm1->data_size) != 0)
-    return 1;
-  return 0;
-}
-
-static void deterministic_pattern(xbt_dynar_t initial_pattern, xbt_dynar_t pattern){
-  unsigned int cursor = 0, send_index = 0, recv_index = 0;
-  mc_comm_pattern_t comm1, comm2;
-  int comm_comparison = 0;
-  int current_process = 0;
-  while(current_process < simix_process_maxpid){
-    while(cursor < xbt_dynar_length(initial_pattern)){
-      comm1 = (mc_comm_pattern_t)xbt_dynar_get_as(initial_pattern, cursor, mc_comm_pattern_t);
-      if(comm1->type == SIMIX_COMM_SEND && comm1->src_proc == current_process){
-        comm2 = get_comm_pattern_from_idx(pattern, &send_index, comm1->type, current_process);
-        comm_comparison = compare_comm_pattern(comm1, comm2);
-        if(comm_comparison == 1){
-          initial_state_safety->send_deterministic = 0;
-          initial_state_safety->comm_deterministic = 0;
-          return;
-        }
-        send_index++;
-      }else if(comm1->type == SIMIX_COMM_RECEIVE && comm1->dst_proc == current_process){
-        comm2 = get_comm_pattern_from_idx(pattern, &recv_index, comm1->type, current_process);
-        comm_comparison = compare_comm_pattern(comm1, comm2);
-        if(comm_comparison == 1){
-          initial_state_safety->comm_deterministic = 0;
-          if(!_sg_mc_send_determinism)
-            return;
-        }
-        recv_index++;
-      }
-      cursor++;
-    }
-    cursor = 0;
-    send_index = 0;
-    recv_index = 0;
-    current_process++;
-  }
-}
-
-static int complete_comm_pattern(xbt_dynar_t list, mc_comm_pattern_t pattern){
-  mc_comm_pattern_t current_pattern;
-  unsigned int cursor = 0;
-  int index;
-  xbt_dynar_foreach(incomplete_communications_pattern, cursor, index){
-    current_pattern = (mc_comm_pattern_t)xbt_dynar_get_as(list, index, mc_comm_pattern_t);
-    if(current_pattern->comm == pattern->comm){
-      current_pattern->src_proc = pattern->comm->comm.src_proc->pid;
-      current_pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
-      current_pattern->src_host = simcall_host_get_name(pattern->comm->comm.src_proc->smx_host);
-      current_pattern->dst_host = simcall_host_get_name(pattern->comm->comm.dst_proc->smx_host);
-      if(current_pattern->data_size == -1){
-        current_pattern->data_size = pattern->comm->comm.src_buff_size;
-        current_pattern->data = xbt_malloc0(current_pattern->data_size);
-        memcpy(current_pattern->data, current_pattern->comm->comm.src_buff, current_pattern->data_size);
-      }
-      current_pattern->matched_comm = pattern->num;
-      current_pattern->completed = 1;
-      xbt_dynar_remove_at(incomplete_communications_pattern, cursor, NULL);
-      return current_pattern->num;
-    }
-  }
-  return -1;
-}
-
-void get_comm_pattern(xbt_dynar_t list, smx_simcall_t request, int call){
-  mc_comm_pattern_t pattern = NULL;
-  pattern = xbt_new0(s_mc_comm_pattern_t, 1);
-  pattern->num = ++nb_comm_pattern;
-  pattern->completed = 0;
-  pattern->data_size = -1;
-  if(call == 1){ // ISEND
-    pattern->comm = simcall_comm_isend__get__result(request);
-    pattern->type = SIMIX_COMM_SEND;
-    if(pattern->comm->comm.dst_proc != NULL){ 
-      pattern->matched_comm = complete_comm_pattern(list, pattern);
-      pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
-      pattern->dst_host = simcall_host_get_name(pattern->comm->comm.dst_proc->smx_host);
-      pattern->completed = 1;
-    }
-    pattern->src_proc = pattern->comm->comm.src_proc->pid;
-    pattern->src_host = simcall_host_get_name(request->issuer->smx_host);
-    pattern->data_size = pattern->comm->comm.src_buff_size;
-    pattern->data=xbt_malloc0(pattern->data_size);
-    memcpy(pattern->data, pattern->comm->comm.src_buff, pattern->data_size);
-  }else{ // IRECV
-    pattern->comm = simcall_comm_irecv__get__result(request);
-    pattern->type = SIMIX_COMM_RECEIVE;
-    if(pattern->comm->comm.src_proc != NULL){
-      pattern->matched_comm = complete_comm_pattern(list, pattern);
-      pattern->src_proc = pattern->comm->comm.src_proc->pid;
-      pattern->src_host = simcall_host_get_name(request->issuer->smx_host);
-      pattern->completed = 1;
-      pattern->data_size = pattern->comm->comm.src_buff_size;
-      pattern->data=xbt_malloc0(pattern->data_size);
-      memcpy(pattern->data, pattern->comm->comm.src_buff, pattern->data_size);
-    }
-    pattern->dst_proc = pattern->comm->comm.dst_proc->pid;
-    pattern->dst_host = simcall_host_get_name(pattern->comm->comm.dst_proc->smx_host);
-  }
-  
-  if(pattern->comm->comm.rdv != NULL)
-    pattern->rdv = strdup(pattern->comm->comm.rdv->name);
-  else
-    pattern->rdv = strdup(pattern->comm->comm.rdv_cpy->name);
-  
-  xbt_dynar_push(list, &pattern);
-
-  if(!pattern->completed)
-    xbt_dynar_push_as(incomplete_communications_pattern, int, xbt_dynar_length(list) - 1);
-
-}
-
-static void print_communications_pattern(xbt_dynar_t comms_pattern){
-  unsigned int cursor = 0;
-  mc_comm_pattern_t current_comm;
-  xbt_dynar_foreach(comms_pattern, cursor, current_comm){
-    if(current_comm->type == SIMIX_COMM_SEND)
-      XBT_INFO("[(%lu) %s -> %s] %s ", current_comm->src_proc, current_comm->src_host, current_comm->dst_host, "iSend");
-    else
-      XBT_INFO("[(%lu) %s <- %s] %s ", current_comm->dst_proc, current_comm->dst_host, current_comm->src_host, "iRecv");
-  }
-}
-
-static void visited_state_free(mc_visited_state_t state){
-  if(state){
-    MC_free_snapshot(state->system_state);
-    xbt_free(state);
-  }
-}
-
-static void visited_state_free_voidp(void *s){
-  visited_state_free((mc_visited_state_t) * (void **) s);
-}
-
-/** \brief Save the current state
- *
- *  \return Snapshot of the current state.
- */
-static mc_visited_state_t visited_state_new(){
-
-  mc_visited_state_t new_state = NULL;
-  new_state = xbt_new0(s_mc_visited_state_t, 1);
-  new_state->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
-  new_state->nb_processes = xbt_swag_size(simix_global->process_list);
-  new_state->system_state = MC_take_snapshot(mc_stats->expanded_states);
-  new_state->num = mc_stats->expanded_states;
-  new_state->other_num = -1;
-
-  return new_state;
-  
-}
-
-/** \brief Find a suitable subrange of candidate duplicates for a given state
- *
- *  \param all_ pairs dynamic array of states with candidate duplicates of the current state;
- *  \param pair current state;
- *  \param min (output) index of the beginning of the the subrange
- *  \param max (output) index of the enf of the subrange
- *
- *  Given a suitably ordered array of state, this function extracts a subrange
- *  (with index *min <= i <= *max) with candidate duplicates of the given state.
- *  This function uses only fast discriminating criterions and does not use the
- *  full state comparison algorithms.
- *
- *  The states in all_pairs MUST be ordered using a (given) weak order
- *  (based on nb_processes and heap_bytes_used).
- *  The subrange is the subrange of "equivalence" of the given state.
- */
-static int get_search_interval(xbt_dynar_t all_states, mc_visited_state_t state, int *min, int *max){
-  XBT_VERB("Searching interval for state %i: nd_processes=%zu heap_bytes_used=%zu",
-    state->num, (size_t)state->nb_processes, (size_t)state->heap_bytes_used);
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  int cursor = 0, previous_cursor, next_cursor;
-  mc_visited_state_t state_test;
-  int start = 0;
-  int end = xbt_dynar_length(all_states) - 1;
-  
-  while(start <= end){
-    cursor = (start + end) / 2;
-    state_test = (mc_visited_state_t)xbt_dynar_get_as(all_states, cursor, mc_visited_state_t);
-    if(state_test->nb_processes < state->nb_processes){
-      start = cursor + 1;
-    }else if(state_test->nb_processes > state->nb_processes){
-      end = cursor - 1;
-    }else{
-      if(state_test->heap_bytes_used < state->heap_bytes_used){
-        start = cursor +1;
-      }else if(state_test->heap_bytes_used > state->heap_bytes_used){
-        end = cursor - 1;
-      }else{
-        *min = *max = cursor;
-        previous_cursor = cursor - 1;
-        while(previous_cursor >= 0){
-          state_test = (mc_visited_state_t)xbt_dynar_get_as(all_states, previous_cursor, mc_visited_state_t);
-          if(state_test->nb_processes != state->nb_processes || state_test->heap_bytes_used != state->heap_bytes_used)
-            break;
-          *min = previous_cursor;
-          previous_cursor--;
-        }
-        next_cursor = cursor + 1;
-        while(next_cursor < xbt_dynar_length(all_states)){
-          state_test = (mc_visited_state_t)xbt_dynar_get_as(all_states, next_cursor, mc_visited_state_t);
-          if(state_test->nb_processes != state->nb_processes || state_test->heap_bytes_used != state->heap_bytes_used)
-            break;
-          *max = next_cursor;
-          next_cursor++;
-        }
-        if(!raw_mem_set)
-          MC_UNSET_RAW_MEM;
-        return -1;
-      }
-     }
-  }
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-
-  return cursor;
-}
-
-/** \brief Take a snapshot the current state and process it.
- *
- *  \return number of the duplicate state or -1 (not visited)
- */
-static int is_visited_state(){
-
-  if(_sg_mc_visited == 0)
-    return -1;
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  mc_visited_state_t new_state = visited_state_new();
-  
-  if(xbt_dynar_is_empty(visited_states)){
-
-    xbt_dynar_push(visited_states, &new_state); 
-
-    if(!raw_mem_set)
-      MC_UNSET_RAW_MEM;
-
-    return -1;
-
-  }else{
-
-    int min = -1, max = -1, index;
-    //int res;
-    mc_visited_state_t state_test;
-    int cursor;
-
-    index = get_search_interval(visited_states, new_state, &min, &max);
-
-    if(min != -1 && max != -1){
-
-      // Parallell implementation
-      /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_states, min), (max-min)+1, new_state);
-      if(res != -1){
-        state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, (min+res)-1, mc_visited_state_t);
-        if(state_test->other_num == -1)
-          new_state->other_num = state_test->num;
-        else
-          new_state->other_num = state_test->other_num;
-        if(dot_output == NULL)
-          XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num);
-        else
-          XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num);
-        xbt_dynar_remove_at(visited_states, (min + res) - 1, NULL);
-        xbt_dynar_insert_at(visited_states, (min+res) - 1, &new_state);
-        if(!raw_mem_set)
-          MC_UNSET_RAW_MEM;
-        return new_state->other_num;
-        }*/
-
-      cursor = min;
-      while(cursor <= max){
-        state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t);
-        if(snapshot_compare(state_test, new_state) == 0){
-          // The state has been visited:
-
-          if(state_test->other_num == -1)
-            new_state->other_num = state_test->num;
-          else
-            new_state->other_num = state_test->other_num;
-          if(dot_output == NULL)
-            XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num);
-          else
-            XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num);
-
-          // Replace the old state with the new one (why?):
-          xbt_dynar_remove_at(visited_states, cursor, NULL);
-          xbt_dynar_insert_at(visited_states, cursor, &new_state);
-
-          if(!raw_mem_set)
-            MC_UNSET_RAW_MEM;
-          return new_state->other_num;
-        }
-        cursor++;
-      }
-
-      // The state has not been visited, add it to the list:
-      xbt_dynar_insert_at(visited_states, min, &new_state);
-
-    }else{
-
-      // The state has not been visited: insert the state in the dynamic array.
-      state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, index, mc_visited_state_t);
-      if(state_test->nb_processes < new_state->nb_processes){
-        xbt_dynar_insert_at(visited_states, index+1, &new_state);
-      }else{
-        if(state_test->heap_bytes_used < new_state->heap_bytes_used)
-          xbt_dynar_insert_at(visited_states, index + 1, &new_state);
-        else
-          xbt_dynar_insert_at(visited_states, index, &new_state);
-      }
-
-    }
-
-    // We have reached the maximum number of stored states;
-    if(xbt_dynar_length(visited_states) > _sg_mc_visited){
-
-      // Find the (index of the) older state:
-      int min2 = mc_stats->expanded_states;
-      unsigned int cursor2 = 0;
-      unsigned int index2 = 0;
-      xbt_dynar_foreach(visited_states, cursor2, state_test){
-        if(state_test->num < min2){
-          index2 = cursor2;
-          min2 = state_test->num;
-        }
-      }
-
-      // and drop it:
-      xbt_dynar_remove_at(visited_states, index2, NULL);
-    }
-
-    if(!raw_mem_set)
-      MC_UNSET_RAW_MEM;
-    
-    return -1;
-    
-  }
-}
-
-/**
- *  \brief Initialize the DPOR exploration algorithm
- */
-void MC_dpor_init()
-{
-  
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  mc_state_t initial_state = NULL;
-  smx_process_t process;
-  
-  /* Create the initial state and push it into the exploration stack */
-  MC_SET_RAW_MEM;
-
-  if(_sg_mc_visited > 0)
-    visited_states = xbt_dynar_new(sizeof(mc_visited_state_t), visited_state_free_voidp);
-
-  if(mc_reduce_kind == e_mc_reduce_dpor)
-    first_enabled_state = xbt_dict_new_homogeneous(&xbt_free_f);
-
-  if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-    initial_communications_pattern = xbt_dynar_new(sizeof(mc_comm_pattern_t), comm_pattern_free_voidp);
-    communications_pattern = xbt_dynar_new(sizeof(mc_comm_pattern_t), comm_pattern_free_voidp);
-    incomplete_communications_pattern = xbt_dynar_new(sizeof(int), NULL);
-    nb_comm_pattern = 0;
-  }
-
-  initial_state = MC_state_new();
-
-  MC_UNSET_RAW_MEM;
-
-  XBT_DEBUG("**************************************************");
-  XBT_DEBUG("Initial state");
-
-  /* Wait for requests (schedules processes) */
-  MC_wait_for_requests();
-
-  MC_ignore_heap(simix_global->process_to_run->data, 0);
-  MC_ignore_heap(simix_global->process_that_ran->data, 0);
-
-  MC_SET_RAW_MEM;
-  /* Get an enabled process and insert it in the interleave set of the initial state */
-  xbt_swag_foreach(process, simix_global->process_list){
-    if(MC_process_is_enabled(process)){
-      MC_state_interleave_process(initial_state, process);
-      if(mc_reduce_kind != e_mc_reduce_none)
-        break;
-    }
-  }
-
-  xbt_fifo_unshift(mc_stack_safety, initial_state);
-
-  if(mc_reduce_kind == e_mc_reduce_dpor){
-    /* To ensure the soundness of DPOR, we have to keep a list of 
-       processes which are still enabled at each step of the exploration. 
-       If max depth is reached, we interleave them in the state in which they have 
-       been enabled for the first time. */
-    xbt_swag_foreach(process, simix_global->process_list){
-      if(MC_process_is_enabled(process)){
-        char *key = bprintf("%lu", process->pid);
-        char *data = bprintf("%d", xbt_fifo_size(mc_stack_safety));
-        xbt_dict_set(first_enabled_state, key, data, NULL);
-        xbt_free(key);
-      }
-    }
-  }
-
-  MC_UNSET_RAW_MEM;
-
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
-  else
-    MC_UNSET_RAW_MEM;
-  
-}
-
-
-/** \brief Model-check the application using a DFS exploration
- *         with DPOR (Dynamic Partial Order Reductions)
- */
-void MC_dpor(void)
-{
-
-  char *req_str = NULL;
-  int value;
-  smx_simcall_t req = NULL, prev_req = NULL;
-  mc_state_t state = NULL, prev_state = NULL, next_state = NULL, restored_state=NULL;
-  smx_process_t process = NULL;
-  xbt_fifo_item_t item = NULL;
-  mc_state_t state_test = NULL;
-  int pos;
-  int visited_state = -1;
-  int enabled = 0;
-  int interleave_size = 0;
-  int comm_pattern = 0;
-
-  while (xbt_fifo_size(mc_stack_safety) > 0) {
-
-    /* Get current state */
-    state = (mc_state_t) 
-      xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_safety));
-
-    XBT_DEBUG("**************************************************");
-    XBT_DEBUG("Exploration depth=%d (state=%p, num %d)(%u interleave, user_max_depth %d, first_enabled_state size : %d)",
-              xbt_fifo_size(mc_stack_safety), state, state->num,
-              MC_state_interleave_size(state), user_max_depth_reached, xbt_dict_size(first_enabled_state));
-      
-    interleave_size = MC_state_interleave_size(state);
-
-    /* Update statistics */
-    mc_stats->visited_states++;
-
-    /* If there are processes to interleave and the maximum depth has not been reached
-       then perform one step of the exploration algorithm */
-    if (xbt_fifo_size(mc_stack_safety) <= _sg_mc_max_depth && !user_max_depth_reached &&
-        (req = MC_state_get_request(state, &value)) && visited_state == -1) {
-
-      /* Debug information */
-      if(XBT_LOG_ISENABLED(mc_dpor, xbt_log_priority_debug)){
-        req_str = MC_request_to_string(req, value);
-        XBT_DEBUG("Execute: %s", req_str);
-        xbt_free(req_str);
-      }
-      
-      MC_SET_RAW_MEM;
-      if(dot_output != NULL)
-        req_str = MC_request_get_dot_output(req, value);
-      MC_UNSET_RAW_MEM;
-
-      MC_state_set_executed_request(state, req, value);
-      mc_stats->executed_transitions++;
-
-      if(mc_reduce_kind ==  e_mc_reduce_dpor){
-        MC_SET_RAW_MEM;
-        char *key = bprintf("%lu", req->issuer->pid);
-        xbt_dict_remove(first_enabled_state, key); 
-        xbt_free(key);
-        MC_UNSET_RAW_MEM;
-      }
-
-      if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-        if(req->call == SIMCALL_COMM_ISEND)
-          comm_pattern = 1;
-        else if(req->call == SIMCALL_COMM_IRECV)
-          comm_pattern = 2;
-      }
-
-      /* Answer the request */
-      SIMIX_simcall_pre(req, value); /* After this call req is no longer usefull */
-
-      if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-        MC_SET_RAW_MEM;
-        if(comm_pattern != 0){
-          if(!initial_state_safety->initial_communications_pattern_done)
-            get_comm_pattern(initial_communications_pattern, req, comm_pattern);
-          else
-            get_comm_pattern(communications_pattern, req, comm_pattern);
-        }
-        MC_UNSET_RAW_MEM; 
-        comm_pattern = 0;
-      }
-
-      /* Wait for requests (schedules processes) */
-      MC_wait_for_requests();
-
-      /* Create the new expanded state */
-      MC_SET_RAW_MEM;
-
-      next_state = MC_state_new();
-
-      if((visited_state = is_visited_state()) == -1){
-     
-        /* Get an enabled process and insert it in the interleave set of the next state */
-        xbt_swag_foreach(process, simix_global->process_list){
-          if(MC_process_is_enabled(process)){
-            MC_state_interleave_process(next_state, process);
-            if(mc_reduce_kind != e_mc_reduce_none)
-              break;
-          }
-        }
-
-        if(_sg_mc_checkpoint && ((xbt_fifo_size(mc_stack_safety) + 1) % _sg_mc_checkpoint == 0)){
-          next_state->system_state = MC_take_snapshot(next_state->num);
-        }
-
-        if(dot_output != NULL)
-          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num, next_state->num, req_str);
-
-      }else{
-
-        if(dot_output != NULL)
-          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num, visited_state, req_str);
-
-      }
-
-      xbt_fifo_unshift(mc_stack_safety, next_state);
-
-      if(mc_reduce_kind ==  e_mc_reduce_dpor){
-        /* Insert in dict all enabled processes, if not included yet */
-        xbt_swag_foreach(process, simix_global->process_list){
-          if(MC_process_is_enabled(process)){
-            char *key = bprintf("%lu", process->pid);
-            if(xbt_dict_get_or_null(first_enabled_state, key) == NULL){
-              char *data = bprintf("%d", xbt_fifo_size(mc_stack_safety));
-              xbt_dict_set(first_enabled_state, key, data, NULL); 
-            }
-            xbt_free(key);
-          }
-        }
-      }
-      
-      if(dot_output != NULL)
-        xbt_free(req_str);
-
-      MC_UNSET_RAW_MEM;
-
-      /* Let's loop again */
-
-      /* The interleave set is empty or the maximum depth is reached, let's back-track */
-    } else {
-
-      if((xbt_fifo_size(mc_stack_safety) > _sg_mc_max_depth) || user_max_depth_reached || visited_state != -1){  
-
-        if(user_max_depth_reached && visited_state == -1)
-          XBT_DEBUG("User max depth reached !");
-        else if(visited_state == -1)
-          XBT_WARN("/!\\ Max depth reached ! /!\\ ");
-
-        visited_state = -1;
-
-        if(mc_reduce_kind ==  e_mc_reduce_dpor){
-          /* Interleave enabled processes in the state in which they have been enabled for the first time */
-          xbt_swag_foreach(process, simix_global->process_list){
-            if(MC_process_is_enabled(process)){
-              char *key = bprintf("%lu", process->pid);
-              enabled = (int)strtoul(xbt_dict_get_or_null(first_enabled_state, key), 0, 10);
-              xbt_free(key);
-              int cursor = xbt_fifo_size(mc_stack_safety);
-              xbt_fifo_foreach(mc_stack_safety, item, state_test, mc_state_t){
-                if(cursor-- == enabled){ 
-                  if(!MC_state_process_is_done(state_test, process) && state_test->num != state->num){ 
-                    XBT_DEBUG("Interleave process %lu in state %d", process->pid, state_test->num);
-                    MC_state_interleave_process(state_test, process);
-                    break;
-                  }
-                }
-              }
-            }
-          }
-        }
-
-      }else{
-
-        XBT_DEBUG("There are no more processes to interleave. (depth %d)", xbt_fifo_size(mc_stack_safety) + 1);
-
-      }
-
-      MC_SET_RAW_MEM;
-
-      if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-        if(initial_state_safety->initial_communications_pattern_done){
-          if(interleave_size == 0){ /* if (interleave_size > 0), process interleaved but not enabled => "incorrect" path, determinism not evaluated */
-            //print_communications_pattern(communications_pattern);
-            deterministic_pattern(initial_communications_pattern, communications_pattern);
-            if(initial_state_safety->comm_deterministic == 0 && _sg_mc_comms_determinism){
-              XBT_INFO("****************************************************");
-              XBT_INFO("***** Non-deterministic communications pattern *****");
-              XBT_INFO("****************************************************");
-              XBT_INFO("Initial communications pattern:");
-              print_communications_pattern(initial_communications_pattern);
-              XBT_INFO("Communications pattern counter-example:");
-              print_communications_pattern(communications_pattern);
-              MC_print_statistics(mc_stats);
-              return;
-            }else if(initial_state_safety->send_deterministic == 0 && _sg_mc_send_determinism){
-              XBT_INFO("****************************************************");
-              XBT_INFO("***** Non-send-deterministic communications pattern *****");
-              XBT_INFO("****************************************************");
-              XBT_INFO("Initial communications pattern:");
-              print_communications_pattern(initial_communications_pattern);
-              XBT_INFO("Communications pattern counter-example:");
-              print_communications_pattern(communications_pattern);
-              MC_print_statistics(mc_stats);
-              return;
-            }
-          }
-        }else{
-          initial_state_safety->initial_communications_pattern_done = 1;
-        }
-      }
-
-      /* Trash the current state, no longer needed */
-      xbt_fifo_shift(mc_stack_safety);
-      MC_state_delete(state);
-      XBT_DEBUG("Delete state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1);
-
-      MC_UNSET_RAW_MEM;        
-      
-      /* Check for deadlocks */
-      if(MC_deadlock_check()){
-        MC_show_deadlock(NULL);
-        return;
-      }
-
-      MC_SET_RAW_MEM;
-      /* Traverse the stack backwards until a state with a non empty interleave
-         set is found, deleting all the states that have it empty in the way.
-         For each deleted state, check if the request that has generated it 
-         (from it's predecesor state), depends on any other previous request 
-         executed before it. If it does then add it to the interleave set of the
-         state that executed that previous request. */
-      
-      while ((state = xbt_fifo_shift(mc_stack_safety)) != NULL) {
-        if(mc_reduce_kind != e_mc_reduce_none){
-          req = MC_state_get_internal_request(state);
-          xbt_fifo_foreach(mc_stack_safety, item, prev_state, mc_state_t) {
-            if(MC_request_depend(req, MC_state_get_internal_request(prev_state))){
-              if(XBT_LOG_ISENABLED(mc_dpor, xbt_log_priority_debug)){
-                XBT_DEBUG("Dependent Transitions:");
-                prev_req = MC_state_get_executed_request(prev_state, &value);
-                req_str = MC_request_to_string(prev_req, value);
-                XBT_DEBUG("%s (state=%d)", req_str, prev_state->num);
-                xbt_free(req_str);
-                prev_req = MC_state_get_executed_request(state, &value);
-                req_str = MC_request_to_string(prev_req, value);
-                XBT_DEBUG("%s (state=%d)", req_str, state->num);
-                xbt_free(req_str);              
-              }
-
-              if(!MC_state_process_is_done(prev_state, req->issuer))
-                MC_state_interleave_process(prev_state, req->issuer);
-              else
-                XBT_DEBUG("Process %p is in done set", req->issuer);
-
-              break;
-
-            }else if(req->issuer == MC_state_get_internal_request(prev_state)->issuer){
-
-              XBT_DEBUG("Simcall %d and %d with same issuer", req->call, MC_state_get_internal_request(prev_state)->call);
-              break;
-
-            }else{
-
-              XBT_DEBUG("Simcall %d, process %lu (state %d) and simcall %d, process %lu (state %d) are independant", req->call, req->issuer->pid, state->num, MC_state_get_internal_request(prev_state)->call, MC_state_get_internal_request(prev_state)->issuer->pid, prev_state->num);
-
-            }
-          }
-        }
-             
-        if (MC_state_interleave_size(state) && xbt_fifo_size(mc_stack_safety) < _sg_mc_max_depth) {
-          /* We found a back-tracking point, let's loop */
-          XBT_DEBUG("Back-tracking to state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1);
-          if(_sg_mc_checkpoint){
-            if(state->system_state != NULL){
-              MC_restore_snapshot(state->system_state);
-              xbt_fifo_unshift(mc_stack_safety, state);
-              MC_UNSET_RAW_MEM;
-            }else{
-              pos = xbt_fifo_size(mc_stack_safety);
-              item = xbt_fifo_get_first_item(mc_stack_safety);
-              while(pos>0){
-                restored_state = (mc_state_t) xbt_fifo_get_item_content(item);
-                if(restored_state->system_state != NULL){
-                  break;
-                }else{
-                  item = xbt_fifo_get_next_item(item);
-                  pos--;
-                }
-              }
-              MC_restore_snapshot(restored_state->system_state);
-              xbt_fifo_unshift(mc_stack_safety, state);
-              MC_UNSET_RAW_MEM;
-              MC_replay(mc_stack_safety, pos);
-            }
-          }else{
-            xbt_fifo_unshift(mc_stack_safety, state);
-            MC_UNSET_RAW_MEM;
-            MC_replay(mc_stack_safety, -1);
-          }
-          XBT_DEBUG("Back-tracking to state %d at depth %d done", state->num, xbt_fifo_size(mc_stack_safety));
-          break;
-        } else {
-          /*req = MC_state_get_internal_request(state);
-          if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-            if(req->call == SIMCALL_COMM_ISEND || req->call == SIMCALL_COMM_IRECV){
-              if(!xbt_dynar_is_empty(communications_pattern))
-                xbt_dynar_remove_at(communications_pattern, xbt_dynar_length(communications_pattern) - 1, NULL);
-            }
-            }*/
-          XBT_DEBUG("Delete state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1); 
-          MC_state_delete(state);
-        }
-      }
-      MC_UNSET_RAW_MEM;
-    }
-  }
-  MC_print_statistics(mc_stats);
-  MC_UNSET_RAW_MEM;  
-
-  return;
-}
-
-
-
-
index cc9a8eb..c1fd447 100644 (file)
@@ -5,7 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include <stdlib.h>
-#define DW_LANG_Objc DW_LANG_ObjC /* fix spelling error in older dwarf.h */
+#define DW_LANG_Objc DW_LANG_ObjC       /* fix spelling error in older dwarf.h */
 #include <dwarf.h>
 #include <elfutils/libdw.h>
 #include <inttypes.h>
@@ -37,13 +37,14 @@ static uint64_t MC_dwarf_default_lower_bound(int lang);
  * \param die  DIE for the DW_TAG_enumeration_type or DW_TAG_subrange_type
  * \param unit DIE of the DW_TAG_compile_unit
  */
-static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die* die, Dwarf_Die* unit);
+static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die * die,
+                                                Dwarf_Die * unit);
 
 /** \brief Computes the number of elements of a given DW_TAG_array_type.
  *
  * \param die DIE for the DW_TAG_array_type
  */
-static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit);
+static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit);
 
 /** \brief Process a DIE
  *
@@ -52,11 +53,15 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit);
  *  \param unit the DIE of the compile unit of the current DIE
  *  \param frame containg frame if any
  */
-static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace);
+static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die * die,
+                                Dwarf_Die * unit, dw_frame_t frame,
+                                const char *namespace);
 
 /** \brief Process a type DIE
  */
-static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace);
+static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die * die,
+                                     Dwarf_Die * unit, dw_frame_t frame,
+                                     const char *namespace);
 
 /** \brief Calls MC_dwarf_handle_die on all childrend of the given die
  *
@@ -65,7 +70,9 @@ static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die* die, Dwar
  *  \param unit the DIE of the compile unit of the current DIE
  *  \param frame containg frame if any
  */
-static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace);
+static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die,
+                                     Dwarf_Die * unit, dw_frame_t frame,
+                                     const char *namespace);
 
 /** \brief Handle a variable (DW_TAG_variable or other)
  *
@@ -74,21 +81,24 @@ static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die* die, Dwar
  *  \param unit the DIE of the compile unit of the current DIE
  *  \param frame containg frame if any
  */
-static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace);
+static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die * die,
+                                         Dwarf_Die * unit, dw_frame_t frame,
+                                         const char *namespace);
 
 /** \brief Get the DW_TAG_type of the DIE
  *
  *  \param die DIE
  *  \return DW_TAG_type attribute as a new string (NULL if none)
  */
-static char* MC_dwarf_at_type(Dwarf_Die* die);
+static char *MC_dwarf_at_type(Dwarf_Die * die);
 
 /** \brief Get the name of an attribute (DW_AT_*) from its code
  *
  *  \param attr attribute code (see the DWARF specification)
  *  \return name of the attribute
  */
-const char* MC_dwarf_attrname(int attr) {
+const char *MC_dwarf_attrname(int attr)
+{
   switch (attr) {
 #include "mc_dwarf_attrnames.h"
   default:
@@ -101,7 +111,8 @@ const char* MC_dwarf_attrname(int attr) {
  *  \param tag tag code (see the DWARF specification)
  *  \return name of the tag
  */
-const char* MC_dwarf_tagname(int tag) {
+const char *MC_dwarf_tagname(int tag)
+{
   switch (tag) {
 #include "mc_dwarf_tagnames.h"
   case DW_TAG_invalid:
@@ -122,54 +133,55 @@ typedef enum mc_tag_class {
   mc_tag_namespace
 } mc_tag_class;
 
-static mc_tag_class MC_dwarf_tag_classify(int tag) {
+static mc_tag_class MC_dwarf_tag_classify(int tag)
+{
   switch (tag) {
 
-    case DW_TAG_array_type:
-    case DW_TAG_class_type:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_typedef:
-    case DW_TAG_pointer_type:
-    case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
-    case DW_TAG_string_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_subroutine_type:
-    case DW_TAG_union_type:
-    case DW_TAG_ptr_to_member_type:
-    case DW_TAG_set_type:
-    case DW_TAG_subrange_type:
-    case DW_TAG_base_type:
-    case DW_TAG_const_type:
-    case DW_TAG_file_type:
-    case DW_TAG_packed_type:
-    case DW_TAG_volatile_type:
-    case DW_TAG_restrict_type:
-    case DW_TAG_interface_type:
-    case DW_TAG_unspecified_type:
-    case DW_TAG_mutable_type:
-    case DW_TAG_shared_type:
-      return mc_tag_type;
-
-    case DW_TAG_subprogram:
-      return mc_tag_subprogram;
-
-    case DW_TAG_variable:
-    case DW_TAG_formal_parameter:
-      return mc_tag_variable;
-
-    case DW_TAG_lexical_block:
-    case DW_TAG_try_block:
-    case DW_TAG_catch_block:
-    case DW_TAG_inlined_subroutine:
-    case DW_TAG_with_stmt:
-      return mc_tag_scope;
-
-    case DW_TAG_namespace:
-      return mc_tag_namespace;
+  case DW_TAG_array_type:
+  case DW_TAG_class_type:
+  case DW_TAG_enumeration_type:
+  case DW_TAG_typedef:
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_rvalue_reference_type:
+  case DW_TAG_string_type:
+  case DW_TAG_structure_type:
+  case DW_TAG_subroutine_type:
+  case DW_TAG_union_type:
+  case DW_TAG_ptr_to_member_type:
+  case DW_TAG_set_type:
+  case DW_TAG_subrange_type:
+  case DW_TAG_base_type:
+  case DW_TAG_const_type:
+  case DW_TAG_file_type:
+  case DW_TAG_packed_type:
+  case DW_TAG_volatile_type:
+  case DW_TAG_restrict_type:
+  case DW_TAG_interface_type:
+  case DW_TAG_unspecified_type:
+  case DW_TAG_mutable_type:
+  case DW_TAG_shared_type:
+    return mc_tag_type;
+
+  case DW_TAG_subprogram:
+    return mc_tag_subprogram;
+
+  case DW_TAG_variable:
+  case DW_TAG_formal_parameter:
+    return mc_tag_variable;
+
+  case DW_TAG_lexical_block:
+  case DW_TAG_try_block:
+  case DW_TAG_catch_block:
+  case DW_TAG_inlined_subroutine:
+  case DW_TAG_with_stmt:
+    return mc_tag_scope;
+
+  case DW_TAG_namespace:
+    return mc_tag_namespace;
 
-    default:
-      return mc_tag_unknown;
+  default:
+    return mc_tag_unknown;
 
   }
 }
@@ -194,8 +206,9 @@ static mc_tag_class MC_dwarf_tag_classify(int tag) {
  *  \param form The form (values taken from the DWARF spec)
  *  \return An internal representation for the corresponding class
  * */
-static int MC_dwarf_form_get_class(int form) {
-  switch(form) {
+static int MC_dwarf_form_get_class(int form)
+{
+  switch (form) {
   case DW_FORM_addr:
     return MC_DW_CLASS_ADDRESS;
   case DW_FORM_block2:
@@ -225,8 +238,8 @@ static int MC_dwarf_form_get_class(int form) {
     return MC_DW_CLASS_FLAG;
   case DW_FORM_exprloc:
     return MC_DW_CLASS_EXPRLOC;
-  // TODO sec offset
-  // TODO indirect
+    // TODO sec offset
+    // TODO indirect
   default:
     return MC_DW_CLASS_UNKNOWN;
   }
@@ -237,7 +250,8 @@ static int MC_dwarf_form_get_class(int form) {
  *  \param die DIE
  *  \return name of the tag of this DIE
  */
-static inline const char* MC_dwarf_die_tagname(Dwarf_Die* die) {
+static inline const char *MC_dwarf_die_tagname(Dwarf_Die * die)
+{
   return MC_dwarf_tagname(dwarf_tag(die));
 }
 
@@ -249,12 +263,14 @@ static inline const char* MC_dwarf_die_tagname(Dwarf_Die* die) {
  *  \param attribute attribute
  *  \return value of the given attribute of the given DIE
  */
-static const char* MC_dwarf_attr_integrate_string(Dwarf_Die* die, int attribute) {
+static const char *MC_dwarf_attr_integrate_string(Dwarf_Die * die,
+                                                  int attribute)
+{
   Dwarf_Attribute attr;
   if (!dwarf_attr_integrate(die, attribute, &attr)) {
-       return NULL;
+    return NULL;
   } else {
-       return dwarf_formstring(&attr);
+    return dwarf_formstring(&attr);
   }
 }
 
@@ -268,37 +284,41 @@ static const char* MC_dwarf_attr_integrate_string(Dwarf_Die* die, int attribute)
  *  \param  the DIE
  *  \return linkage name of the given DIE (or NULL)
  * */
-static const char* MC_dwarf_at_linkage_name(Dwarf_Die* die) {
-  const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_linkage_name);
+static const char *MC_dwarf_at_linkage_name(Dwarf_Die * die)
+{
+  const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_linkage_name);
   if (!name)
     name = MC_dwarf_attr_integrate_string(die, DW_AT_MIPS_linkage_name);
   return name;
 }
 
-static Dwarf_Off MC_dwarf_attr_dieoffset(Dwarf_Die* die, int attribute) {
+static Dwarf_Off MC_dwarf_attr_dieoffset(Dwarf_Die * die, int attribute)
+{
   Dwarf_Attribute attr;
   if (dwarf_hasattr_integrate(die, attribute)) {
     dwarf_attr_integrate(die, attribute, &attr);
     Dwarf_Die subtype_die;
-    if (dwarf_formref_die(&attr, &subtype_die)==NULL) {
+    if (dwarf_formref_die(&attr, &subtype_die) == NULL) {
       xbt_die("Could not find DIE");
     }
     return dwarf_dieoffset(&subtype_die);
-  }
-  else return 0;
+  } else
+    return 0;
 }
 
-static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die* die, int attribute) {
+static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die * die,
+                                                   int attribute)
+{
   Dwarf_Attribute attr;
   if (dwarf_hasattr_integrate(die, attribute)) {
     dwarf_attr_integrate(die, DW_AT_type, &attr);
     Dwarf_Die subtype_die;
-    if (dwarf_formref_die(&attr, &subtype_die)==NULL) {
+    if (dwarf_formref_die(&attr, &subtype_die) == NULL) {
       xbt_die("Could not find DIE");
     }
     return dwarf_dieoffset(&subtype_die);
-  }
-  else return 0;
+  } else
+    return 0;
 }
 
 /** \brief Find the type/subtype (DW_AT_type) for a DIE
@@ -306,14 +326,16 @@ static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die* die, int attribute
  *  \param dit the DIE
  *  \return DW_AT_type reference as a global offset in hexadecimal (or NULL)
  */
-static char* MC_dwarf_at_type(Dwarf_Die* die) {
+static char *MC_dwarf_at_type(Dwarf_Die * die)
+{
   Dwarf_Off offset = MC_dwarf_attr_integrate_dieoffset(die, DW_AT_type);
-  return offset == 0 ? NULL : bprintf("%" PRIx64 , offset);
+  return offset == 0 ? NULL : bprintf("%" PRIx64, offset);
 }
 
-static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die* die, int attribute) {
+static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die * die, int attribute)
+{
   Dwarf_Attribute attr;
-  if(dwarf_attr_integrate(die, attribute, &attr)==NULL)
+  if (dwarf_attr_integrate(die, attribute, &attr) == NULL)
     return 0;
   Dwarf_Addr value;
   if (dwarf_formaddr(&attr, &value) == 0)
@@ -322,24 +344,27 @@ static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die* die, int attribute) {
     return 0;
 }
 
-static uint64_t MC_dwarf_attr_integrate_uint(Dwarf_Die* die, int attribute, uint64_t default_value) {
+static uint64_t MC_dwarf_attr_integrate_uint(Dwarf_Die * die, int attribute,
+                                             uint64_t default_value)
+{
   Dwarf_Attribute attr;
-  if (dwarf_attr_integrate(die, attribute, &attr)==NULL)
+  if (dwarf_attr_integrate(die, attribute, &attr) == NULL)
     return default_value;
   Dwarf_Word value;
-  return dwarf_formudata(dwarf_attr_integrate(die, attribute, &attr), &value) == 0 ? (uint64_t) value : default_value;
+  return dwarf_formudata(dwarf_attr_integrate(die, attribute, &attr),
+                         &value) == 0 ? (uint64_t) value : default_value;
 }
 
-static bool MC_dwarf_attr_flag(Dwarf_Die* die, int attribute, bool integrate) {
+static bool MC_dwarf_attr_flag(Dwarf_Die * die, int attribute, bool integrate)
+{
   Dwarf_Attribute attr;
   if ((integrate ? dwarf_attr_integrate(die, attribute, &attr)
-                    : dwarf_attr(die, attribute, &attr))==0)
+       : dwarf_attr(die, attribute, &attr)) == 0)
     return false;
 
   bool result;
   if (dwarf_formflag(&attr, &result))
-    xbt_die("Unexpected form for attribute %s",
-      MC_dwarf_attrname(attribute));
+    xbt_die("Unexpected form for attribute %s", MC_dwarf_attrname(attribute));
   return result;
 }
 
@@ -351,8 +376,9 @@ static bool MC_dwarf_attr_flag(Dwarf_Die* die, int attribute, bool integrate) {
  *  \param lang Language of the compilation unit (values defined in the DWARF spec)
  *  \return     Default lower bound of an array in this compilation unit
  * */
-static uint64_t MC_dwarf_default_lower_bound(int lang) {
-  switch(lang) {
+static uint64_t MC_dwarf_default_lower_bound(int lang)
+{
+  switch (lang) {
   case DW_LANG_C:
   case DW_LANG_C89:
   case DW_LANG_C99:
@@ -376,7 +402,8 @@ static uint64_t MC_dwarf_default_lower_bound(int lang) {
   case DW_LANG_Cobol85:
     return 1;
   default:
-    xbt_die("No default DW_TAG_lower_bound for language %i and none given", lang);
+    xbt_die("No default DW_TAG_lower_bound for language %i and none given",
+            lang);
     return 0;
   }
 }
@@ -387,28 +414,32 @@ static uint64_t MC_dwarf_default_lower_bound(int lang) {
  *  \param unit DIE of the compilation unit
  *  \return     number of elements in the range
  * */
-static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die* die, Dwarf_Die* unit) {
-  xbt_assert(dwarf_tag(die)==DW_TAG_enumeration_type ||dwarf_tag(die)==DW_TAG_subrange_type,
-      "MC_dwarf_subrange_element_count called with DIE of type %s", MC_dwarf_die_tagname(die));
+static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die * die,
+                                                Dwarf_Die * unit)
+{
+  xbt_assert(dwarf_tag(die) == DW_TAG_enumeration_type
+             || dwarf_tag(die) == DW_TAG_subrange_type,
+             "MC_dwarf_subrange_element_count called with DIE of type %s",
+             MC_dwarf_die_tagname(die));
 
   // Use DW_TAG_count if present:
   if (dwarf_hasattr_integrate(die, DW_AT_count)) {
     return MC_dwarf_attr_integrate_uint(die, DW_AT_count, 0);
   }
-
   // Otherwise compute DW_TAG_upper_bound-DW_TAG_lower_bound + 1:
 
   if (!dwarf_hasattr_integrate(die, DW_AT_upper_bound)) {
-       // This is not really 0, but the code expects this (we do not know):
+    // This is not really 0, but the code expects this (we do not know):
     return 0;
   }
-  uint64_t upper_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_upper_bound, -1);
+  uint64_t upper_bound =
+      MC_dwarf_attr_integrate_uint(die, DW_AT_upper_bound, -1);
 
   uint64_t lower_bound = 0;
   if (dwarf_hasattr_integrate(die, DW_AT_lower_bound)) {
     lower_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_lower_bound, -1);
   } else {
-       lower_bound = MC_dwarf_default_lower_bound(dwarf_srclang(unit));
+    lower_bound = MC_dwarf_default_lower_bound(dwarf_srclang(unit));
   }
   return upper_bound - lower_bound + 1;
 }
@@ -422,16 +453,20 @@ static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die* die, Dwarf_Die* unit)
  *  \param unit the DIE of the compilation unit
  *  \return number of elements in this array type
  * */
-static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit) {
-  xbt_assert(dwarf_tag(die)==DW_TAG_array_type,
-    "MC_dwarf_array_element_count called with DIE of type %s", MC_dwarf_die_tagname(die));
+static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit)
+{
+  xbt_assert(dwarf_tag(die) == DW_TAG_array_type,
+             "MC_dwarf_array_element_count called with DIE of type %s",
+             MC_dwarf_die_tagname(die));
 
   int result = 1;
   Dwarf_Die child;
   int res;
-  for (res=dwarf_child(die, &child); res==0; res=dwarf_siblingof(&child,&child)) {
-       int child_tag = dwarf_tag(&child);
-    if (child_tag==DW_TAG_subrange_type ||child_tag==DW_TAG_enumeration_type) {
+  for (res = dwarf_child(die, &child); res == 0;
+       res = dwarf_siblingof(&child, &child)) {
+    int child_tag = dwarf_tag(&child);
+    if (child_tag == DW_TAG_subrange_type
+        || child_tag == DW_TAG_enumeration_type) {
       result *= MC_dwarf_subrange_element_count(&child, unit);
     }
   }
@@ -447,16 +482,18 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit) {
  *  \param  member the member of the type
  *  \param  child  DIE of the member (DW_TAG_member)
  */
-static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, Dwarf_Die* child) {
+static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member,
+                                          Dwarf_Die * child)
+{
   if (dwarf_hasattr(child, DW_AT_data_bit_offset)) {
     xbt_die("Can't groke DW_AT_data_bit_offset.");
   }
 
   if (!dwarf_hasattr_integrate(child, DW_AT_data_member_location)) {
     if (type->type != DW_TAG_union_type) {
-        xbt_die(
-          "Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%"PRIx64">%s",
-          member->name, (uint64_t) type->id, type->name);
+      xbt_die
+          ("Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%"
+           PRIx64 ">%s", member->name, (uint64_t) type->id, type->name);
     } else {
       return;
     }
@@ -471,16 +508,16 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, Dwar
   case MC_DW_CLASS_BLOCK:
     // Location expression:
     {
-      Dwarf_Opexpr;
+      Dwarf_Op *expr;
       size_t len;
       if (dwarf_getlocation(&attr, &expr, &len)) {
-        xbt_die(
-          "Could not read location expression DW_AT_data_member_location in DW_TAG_member %s of type <%"PRIx64">%s",
-          MC_dwarf_attr_integrate_string(child, DW_AT_name),
-          (uint64_t) type->id, type->name);
+        xbt_die
+            ("Could not read location expression DW_AT_data_member_location in DW_TAG_member %s of type <%"
+             PRIx64 ">%s", MC_dwarf_attr_integrate_string(child, DW_AT_name),
+             (uint64_t) type->id, type->name);
       }
-      if (len==1 && expr[0].atom == DW_OP_plus_uconst) {
-        member->offset =  expr[0].number;
+      if (len == 1 && expr[0].atom == DW_OP_plus_uconst) {
+        member->offset = expr[0].number;
       } else {
         mc_dwarf_expression_init(&member->location, len, expr);
       }
@@ -493,9 +530,9 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, Dwar
       if (!dwarf_formudata(&attr, &offset))
         member->offset = offset;
       else
-        xbt_die("Cannot get %s location <%"PRIx64">%s",
-          MC_dwarf_attr_integrate_string(child, DW_AT_name),
-          (uint64_t) type->id, type->name);
+        xbt_die("Cannot get %s location <%" PRIx64 ">%s",
+                MC_dwarf_attr_integrate_string(child, DW_AT_name),
+                (uint64_t) type->id, type->name);
       break;
     }
   case MC_DW_CLASS_LOCLISTPTR:
@@ -505,14 +542,14 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, Dwar
     // It's supposed to be possible in DWARF2 but I couldn't find its semantic
     // in the spec.
   default:
-    xbt_die(
-      "Can't handle form class (%i) / form 0x%x as DW_AT_member_location",
-      klass, form);
+    xbt_die("Can't handle form class (%i) / form 0x%x as DW_AT_member_location",
+            klass, form);
   }
 
 }
 
-static void dw_type_free_voidp(void *t){
+static void dw_type_free_voidp(void *t)
+{
   dw_type_free((dw_type_t) * (void **) t);
 }
 
@@ -523,21 +560,25 @@ static void dw_type_free_voidp(void *t){
  *  \param unit DIE of the compilation unit containing the type DIE
  *  \param type the type
  */
-static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_type_t type) {
+static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die * die,
+                                 Dwarf_Die * unit, dw_type_t type)
+{
   int res;
   Dwarf_Die child;
   xbt_assert(!type->members);
-  type->members = xbt_dynar_new(sizeof(dw_type_t), (void(*)(void*))dw_type_free_voidp);
-  for (res=dwarf_child(die, &child); res==0; res=dwarf_siblingof(&child,&child)) {
+  type->members =
+      xbt_dynar_new(sizeof(dw_type_t), (void (*)(void *)) dw_type_free_voidp);
+  for (res = dwarf_child(die, &child); res == 0;
+       res = dwarf_siblingof(&child, &child)) {
     int tag = dwarf_tag(&child);
-    if (tag==DW_TAG_member || tag==DW_TAG_inheritance) {
+    if (tag == DW_TAG_member || tag == DW_TAG_inheritance) {
 
       // Skip declarations:
       if (MC_dwarf_attr_flag(&child, DW_AT_declaration, false))
         continue;
 
       // Skip compile time constants:
-      if(dwarf_hasattr(&child, DW_AT_const_value))
+      if (dwarf_hasattr(&child, DW_AT_const_value))
         continue;
 
       // TODO, we should use another type (because is is not a type but a member)
@@ -547,27 +588,29 @@ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die* die, Dwarf_Di
       // Global Offset:
       member->id = dwarf_dieoffset(&child);
 
-      const charname = MC_dwarf_attr_integrate_string(&child, DW_AT_name);
-      if(name)
+      const char *name = MC_dwarf_attr_integrate_string(&child, DW_AT_name);
+      if (name)
         member->name = xbt_strdup(name);
       else
         member->name = NULL;
 
-      member->byte_size = MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0);
+      member->byte_size =
+          MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0);
       member->element_count = -1;
       member->dw_type_id = MC_dwarf_at_type(&child);
       member->members = NULL;
       member->is_pointer_type = 0;
       member->offset = 0;
 
-      if(dwarf_hasattr(&child, DW_AT_data_bit_offset)) {
+      if (dwarf_hasattr(&child, DW_AT_data_bit_offset)) {
         xbt_die("Can't groke DW_AT_data_bit_offset.");
       }
 
       MC_dwarf_fill_member_location(type, member, &child);
 
       if (!member->dw_type_id) {
-        xbt_die("Missing type for member %s of <%"PRIx64">%s", member->name, (uint64_t) type->id, type->name);
+        xbt_die("Missing type for member %s of <%" PRIx64 ">%s", member->name,
+                (uint64_t) type->id, type->name);
       }
 
       xbt_dynar_push(type->members, &member);
@@ -582,7 +625,10 @@ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die* die, Dwarf_Di
  *  \param unit compilation unit of the current DIE
  *  \return MC representation of the type
  */
-static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
+static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die * die,
+                                      Dwarf_Die * unit, dw_frame_t frame,
+                                      const char *namespace)
+{
 
   dw_type_t type = xbt_new0(s_dw_type_t, 1);
   type->type = -1;
@@ -600,7 +646,7 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwa
   // Global Offset
   type->id = dwarf_dieoffset(die);
 
-  const charprefix = "";
+  const char *prefix = "";
   switch (type->type) {
   case DW_TAG_structure_type:
     prefix = "struct ";
@@ -615,9 +661,11 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwa
     prefix = "";
   }
 
-  const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-  if (name!=NULL) {
-    type->name = namespace ? bprintf("%s%s::%s", prefix, namespace, name) : bprintf("%s%s", prefix, name);
+  const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
+  if (name != NULL) {
+    type->name =
+        namespace ? bprintf("%s%s::%s", prefix, namespace,
+                            name) : bprintf("%s%s", prefix, name);
   }
 
   type->dw_type_id = MC_dwarf_at_type(die);
@@ -625,18 +673,20 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwa
   // Computation of the byte_size;
   if (dwarf_hasattr_integrate(die, DW_AT_byte_size))
     type->byte_size = MC_dwarf_attr_integrate_uint(die, DW_AT_byte_size, 0);
-  else if (type->type == DW_TAG_array_type || type->type==DW_TAG_structure_type || type->type==DW_TAG_class_type) {
+  else if (type->type == DW_TAG_array_type
+           || type->type == DW_TAG_structure_type
+           || type->type == DW_TAG_class_type) {
     Dwarf_Word size;
-    if (dwarf_aggregate_size(die, &size)==0) {
+    if (dwarf_aggregate_size(die, &size) == 0) {
       type->byte_size = size;
     }
   }
 
   switch (type->type) {
   case DW_TAG_array_type:
-       type->element_count = MC_dwarf_array_element_count(die, unit);
-       // TODO, handle DW_byte_stride and (not) DW_bit_stride
-       break;
+    type->element_count = MC_dwarf_array_element_count(die, unit);
+    // TODO, handle DW_byte_stride and (not) DW_bit_stride
+    break;
 
   case DW_TAG_pointer_type:
   case DW_TAG_reference_type:
@@ -647,78 +697,87 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwa
   case DW_TAG_structure_type:
   case DW_TAG_union_type:
   case DW_TAG_class_type:
-         MC_dwarf_add_members(info, die, unit, type);
-         char* new_namespace = namespace == NULL ? xbt_strdup(type->name)
-           : bprintf("%s::%s", namespace, name);
-         MC_dwarf_handle_children(info, die, unit, frame, new_namespace);
-         free(new_namespace);
-         break;
+    MC_dwarf_add_members(info, die, unit, type);
+    char *new_namespace = namespace == NULL ? xbt_strdup(type->name)
+        : bprintf("%s::%s", namespace, name);
+    MC_dwarf_handle_children(info, die, unit, frame, new_namespace);
+    free(new_namespace);
+    break;
   }
 
   return type;
 }
 
-static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
+static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die * die,
+                                     Dwarf_Die * unit, dw_frame_t frame,
+                                     const char *namespace)
+{
   dw_type_t type = MC_dwarf_die_to_type(info, die, unit, frame, namespace);
 
-  charkey = bprintf("%" PRIx64, (uint64_t) type->id);
+  char *key = bprintf("%" PRIx64, (uint64_t) type->id);
   xbt_dict_set(info->types, key, type, NULL);
   xbt_free(key);
 
-  if(type->name && type->byte_size!=0) {
+  if (type->name && type->byte_size != 0) {
     xbt_dict_set(info->full_types_by_name, type->name, type, NULL);
   }
 }
 
 static int mc_anonymous_variable_index = 0;
 
-static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
+static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die * die,
+                                        Dwarf_Die * unit, dw_frame_t frame,
+                                        const char *namespace)
+{
   // Skip declarations:
   if (MC_dwarf_attr_flag(die, DW_AT_declaration, false))
     return NULL;
 
   // Skip compile time constants:
-  if(dwarf_hasattr(die, DW_AT_const_value))
+  if (dwarf_hasattr(die, DW_AT_const_value))
     return NULL;
 
   Dwarf_Attribute attr_location;
-  if (dwarf_attr(die, DW_AT_location, &attr_location)==NULL) {
+  if (dwarf_attr(die, DW_AT_location, &attr_location) == NULL) {
     // No location: do not add it ?
     return NULL;
   }
 
   dw_variable_t variable = xbt_new0(s_dw_variable_t, 1);
   variable->dwarf_offset = dwarf_dieoffset(die);
-  variable->global = frame == NULL; // Can be override base on DW_AT_location
+  variable->global = frame == NULL;     // Can be override base on DW_AT_location
   variable->object_info = info;
 
-  const charname = MC_dwarf_attr_integrate_string(die, DW_AT_name);
+  const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
   variable->name = xbt_strdup(name);
 
   variable->type_origin = MC_dwarf_at_type(die);
 
   int form = dwarf_whatform(&attr_location);
-  int klass = form == DW_FORM_sec_offset ? MC_DW_CLASS_CONSTANT : MC_dwarf_form_get_class(form);
+  int klass =
+      form ==
+      DW_FORM_sec_offset ? MC_DW_CLASS_CONSTANT : MC_dwarf_form_get_class(form);
   switch (klass) {
   case MC_DW_CLASS_EXPRLOC:
   case MC_DW_CLASS_BLOCK:
     // Location expression:
     {
-      Dwarf_Opexpr;
+      Dwarf_Op *expr;
       size_t len;
       if (dwarf_getlocation(&attr_location, &expr, &len)) {
-        xbt_die(
-          "Could not read location expression in DW_AT_location of variable <%"PRIx64">%s",
-          (uint64_t) variable->dwarf_offset, variable->name);
+        xbt_die
+            ("Could not read location expression in DW_AT_location of variable <%"
+             PRIx64 ">%s", (uint64_t) variable->dwarf_offset, variable->name);
       }
 
-      if (len==1 && expr[0].atom == DW_OP_addr) {
+      if (len == 1 && expr[0].atom == DW_OP_addr) {
         variable->global = 1;
         uintptr_t offset = (uintptr_t) expr[0].number;
-        uintptr_t base   = (uintptr_t) MC_object_base_address(info);
-        variable->address = (void*) (base + offset);
+        uintptr_t base = (uintptr_t) MC_object_base_address(info);
+        variable->address = (void *) (base + offset);
       } else {
-        mc_dwarf_location_list_init_from_expression(&variable->locations, len, expr);
+        mc_dwarf_location_list_init_from_expression(&variable->locations, len,
+                                                    expr);
       }
 
       break;
@@ -726,121 +785,136 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, D
   case MC_DW_CLASS_LOCLISTPTR:
   case MC_DW_CLASS_CONSTANT:
     // Reference to location list:
-    mc_dwarf_location_list_init(&variable->locations, info, die, &attr_location);
+    mc_dwarf_location_list_init(&variable->locations, info, die,
+                                &attr_location);
     break;
   default:
-    xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%"PRIx64">%s",
-      form, form, klass, klass, (uint64_t) variable->dwarf_offset, variable->name);
+    xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%"
+            PRIx64 ">%s", form, form, klass, klass,
+            (uint64_t) variable->dwarf_offset, variable->name);
   }
 
   // Handle start_scope:
   if (dwarf_hasattr(die, DW_AT_start_scope)) {
     Dwarf_Attribute attr;
     dwarf_attr(die, DW_AT_start_scope, &attr);
-    int form  = dwarf_whatform(&attr);
+    int form = dwarf_whatform(&attr);
     int klass = MC_dwarf_form_get_class(form);
-    switch(klass) {
+    switch (klass) {
     case MC_DW_CLASS_CONSTANT:
-    {
-      Dwarf_Word value;
-      variable->start_scope = dwarf_formudata(&attr, &value) == 0 ? (size_t) value : 0;
-      break;
-    }
-    case MC_DW_CLASS_RANGELISTPTR: // TODO
+      {
+        Dwarf_Word value;
+        variable->start_scope =
+            dwarf_formudata(&attr, &value) == 0 ? (size_t) value : 0;
+        break;
+      }
+    case MC_DW_CLASS_RANGELISTPTR:     // TODO
     default:
-      xbt_die("Unhandled form 0x%x, class 0x%X for DW_AT_start_scope of variable %s",
-        form, klass, name==NULL ? "?" : name);
+      xbt_die
+          ("Unhandled form 0x%x, class 0x%X for DW_AT_start_scope of variable %s",
+           form, klass, name == NULL ? "?" : name);
     }
   }
 
-  if(namespace && variable->global) {
-    charold_name = variable->name;
+  if (namespace && variable->global) {
+    char *old_name = variable->name;
     variable->name = bprintf("%s::%s", namespace, old_name);
     free(old_name);
   }
-
   // The current code needs a variable name,
   // generate a fake one:
-  if(!variable->name) {
+  if (!variable->name) {
     variable->name = bprintf("@anonymous#%i", mc_anonymous_variable_index++);
   }
 
   return variable;
 }
 
-static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
-  dw_variable_t variable = MC_die_to_variable(info, die, unit, frame, namespace);
-  if(variable==NULL)
-      return;
+static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die * die,
+                                         Dwarf_Die * unit, dw_frame_t frame,
+                                         const char *namespace)
+{
+  dw_variable_t variable =
+      MC_die_to_variable(info, die, unit, frame, namespace);
+  if (variable == NULL)
+    return;
   MC_dwarf_register_variable(info, frame, variable);
 }
 
-static void mc_frame_free_voipd(dw_frame_t* p) {
+static void mc_frame_free_voipd(dw_frame_t * p)
+{
   mc_frame_free(*p);
   *p = NULL;
 }
 
-static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t parent_frame, const char* namespace) {
+static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die,
+                                      Dwarf_Die * unit, dw_frame_t parent_frame,
+                                      const char *namespace)
+{
   // TODO, handle DW_TAG_type/DW_TAG_location for DW_TAG_with_stmt
   int tag = dwarf_tag(die);
   mc_tag_class klass = MC_dwarf_tag_classify(tag);
 
   // (Template) Subprogram declaration:
-  if(klass==mc_tag_subprogram && MC_dwarf_attr_flag(die, DW_AT_declaration, false))
+  if (klass == mc_tag_subprogram
+      && MC_dwarf_attr_flag(die, DW_AT_declaration, false))
     return;
 
-  if(klass==mc_tag_scope)
+  if (klass == mc_tag_scope)
     xbt_assert(parent_frame, "No parent scope for this scope");
 
   dw_frame_t frame = xbt_new0(s_dw_frame_t, 1);
 
-  frame->tag   = tag;
+  frame->tag = tag;
   frame->id = dwarf_dieoffset(die);
   frame->object_info = info;
 
-  if(klass==mc_tag_subprogram) {
-    const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-    frame->name = namespace ? bprintf("%s::%s", namespace, name) : xbt_strdup(name);
+  if (klass == mc_tag_subprogram) {
+    const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
+    frame->name =
+        namespace ? bprintf("%s::%s", namespace, name) : xbt_strdup(name);
   }
 
-  frame->abstract_origin_id = MC_dwarf_attr_dieoffset(die, DW_AT_abstract_origin);
+  frame->abstract_origin_id =
+      MC_dwarf_attr_dieoffset(die, DW_AT_abstract_origin);
 
   // This is the base address for DWARF addresses.
   // Relocated addresses are offset from this base address.
   // See DWARF4 spec 7.5
-  voidbase = MC_object_base_address(info);
+  void *base = MC_object_base_address(info);
 
   // Variables are filled in the (recursive) call of MC_dwarf_handle_children:
-  frame->variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
+  frame->variables =
+      xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
 
   // TODO, support DW_AT_ranges
   uint64_t low_pc = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc);
-  frame->low_pc = low_pc ? ((char*) base) + low_pc : 0;
-  if(low_pc) {
+  frame->low_pc = low_pc ? ((char *) base) + low_pc : 0;
+  if (low_pc) {
     // DW_AT_high_pc:
     Dwarf_Attribute attr;
-    if(!dwarf_attr_integrate(die, DW_AT_high_pc, &attr)) {
+    if (!dwarf_attr_integrate(die, DW_AT_high_pc, &attr)) {
       xbt_die("Missing DW_AT_high_pc matching with DW_AT_low_pc");
     }
 
     Dwarf_Sword offset;
     Dwarf_Addr high_pc;
 
-    switch(MC_dwarf_form_get_class(dwarf_whatform(&attr))) {
+    switch (MC_dwarf_form_get_class(dwarf_whatform(&attr))) {
 
-    // DW_AT_high_pc if an offset from the low_pc:
+      // DW_AT_high_pc if an offset from the low_pc:
     case MC_DW_CLASS_CONSTANT:
 
-      if (dwarf_formsdata(&attr, &offset) !=0)
+      if (dwarf_formsdata(&attr, &offset) != 0)
         xbt_die("Could not read constant");
-      frame->high_pc = (void*) ((char*)frame->low_pc + offset);
+      frame->high_pc = (void *) ((char *) frame->low_pc + offset);
       break;
 
-    // DW_AT_high_pc is a relocatable address:
+      // DW_AT_high_pc is a relocatable address:
     case MC_DW_CLASS_ADDRESS:
       if (dwarf_formaddr(&attr, &high_pc) != 0)
         xbt_die("Could not read address");
-      frame->high_pc = ((char*) base) + high_pc;
+      frame->high_pc = ((char *) base) + high_pc;
       break;
 
     default:
@@ -849,74 +923,85 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die* die, Dwa
     }
   }
 
-  if(klass==mc_tag_subprogram) {
+  if (klass == mc_tag_subprogram) {
     Dwarf_Attribute attr_frame_base;
     if (dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base))
-      mc_dwarf_location_list_init(&frame->frame_base, info, die, &attr_frame_base);
+      mc_dwarf_location_list_init(&frame->frame_base, info, die,
+                                  &attr_frame_base);
   }
 
-  frame->scopes = xbt_dynar_new(sizeof(dw_frame_t), (void_f_pvoid_t) mc_frame_free_voipd);
+  frame->scopes =
+      xbt_dynar_new(sizeof(dw_frame_t), (void_f_pvoid_t) mc_frame_free_voipd);
 
   // Register it:
-  if(klass==mc_tag_subprogram) {
-    charkey = bprintf("%" PRIx64, (uint64_t) frame->id);
-    xbt_dict_set(info->subprograms,  key, frame, NULL);
+  if (klass == mc_tag_subprogram) {
+    char *key = bprintf("%" PRIx64, (uint64_t) frame->id);
+    xbt_dict_set(info->subprograms, key, frame, NULL);
     xbt_free(key);
-  } else if(klass==mc_tag_scope) {
+  } else if (klass == mc_tag_scope) {
     xbt_dynar_push(parent_frame->scopes, &frame);
   }
-
   // Handle children:
   MC_dwarf_handle_children(info, die, unit, frame, namespace);
 }
 
-static void mc_dwarf_handle_namespace_die(
-    mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
-  const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-  if(frame)
+static void mc_dwarf_handle_namespace_die(mc_object_info_t info,
+                                          Dwarf_Die * die, Dwarf_Die * unit,
+                                          dw_frame_t frame,
+                                          const char *namespace)
+{
+  const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
+  if (frame)
     xbt_die("Unexpected namespace in a subprogram");
-  charnew_namespace = namespace == NULL ? xbt_strdup(name)
-    : bprintf("%s::%s", namespace, name);
+  char *new_namespace = namespace == NULL ? xbt_strdup(name)
+      : bprintf("%s::%s", namespace, name);
   MC_dwarf_handle_children(info, die, unit, frame, new_namespace);
   xbt_free(new_namespace);
 }
 
-static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
+static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die,
+                                     Dwarf_Die * unit, dw_frame_t frame,
+                                     const char *namespace)
+{
   // For each child DIE:
   Dwarf_Die child;
   int res;
-  for (res=dwarf_child(die, &child); res==0; res=dwarf_siblingof(&child,&child)) {
+  for (res = dwarf_child(die, &child); res == 0;
+       res = dwarf_siblingof(&child, &child)) {
     MC_dwarf_handle_die(info, &child, unit, frame, namespace);
   }
 }
 
-static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) {
+static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die * die,
+                                Dwarf_Die * unit, dw_frame_t frame,
+                                const char *namespace)
+{
   int tag = dwarf_tag(die);
   mc_tag_class klass = MC_dwarf_tag_classify(tag);
   switch (klass) {
 
     // Type:
-    case mc_tag_type:
-      MC_dwarf_handle_type_die(info, die, unit, frame, namespace);
-      break;
+  case mc_tag_type:
+    MC_dwarf_handle_type_die(info, die, unit, frame, namespace);
+    break;
 
     // Subprogram or scope:
-    case mc_tag_subprogram:
-    case mc_tag_scope:
-      MC_dwarf_handle_scope_die(info, die, unit, frame, namespace);
-      return;
+  case mc_tag_subprogram:
+  case mc_tag_scope:
+    MC_dwarf_handle_scope_die(info, die, unit, frame, namespace);
+    return;
 
     // Variable:
-    case mc_tag_variable:
-      MC_dwarf_handle_variable_die(info, die, unit, frame, namespace);
-      break;
+  case mc_tag_variable:
+    MC_dwarf_handle_variable_die(info, die, unit, frame, namespace);
+    break;
 
-    case mc_tag_namespace:
-      mc_dwarf_handle_namespace_die(info, die, unit, frame, namespace);
-      break;
+  case mc_tag_namespace:
+    mc_dwarf_handle_namespace_die(info, die, unit, frame, namespace);
+    break;
 
-    default:
-      break;
+  default:
+    break;
 
   }
 }
@@ -926,28 +1011,30 @@ static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die
  *  Read the DWARf information of the EFFL object and populate the
  *  lists of types, variables, functions.
  */
-void MC_dwarf_get_variables(mc_object_info_t info) {
+void MC_dwarf_get_variables(mc_object_info_t info)
+{
   int fd = open(info->file_name, O_RDONLY);
-  if (fd<0) {
+  if (fd < 0) {
     xbt_die("Could not open file %s", info->file_name);
   }
   Dwarf *dwarf = dwarf_begin(fd, DWARF_C_READ);
-  if (dwarf==NULL) {
+  if (dwarf == NULL) {
     xbt_die("Your program must be compiled with -g");
   }
-
   // For each compilation unit:
   Dwarf_Off offset = 0;
   Dwarf_Off next_offset = 0;
   size_t length;
-  while (dwarf_nextcu (dwarf, offset, &next_offset, &length, NULL, NULL, NULL) == 0) {
+  while (dwarf_nextcu(dwarf, offset, &next_offset, &length, NULL, NULL, NULL) ==
+         0) {
     Dwarf_Die unit_die;
-    if(dwarf_offdie(dwarf, offset+length, &unit_die)!=NULL) {
+    if (dwarf_offdie(dwarf, offset + length, &unit_die) != NULL) {
 
       // For each child DIE:
       Dwarf_Die child;
       int res;
-      for (res=dwarf_child(&unit_die, &child); res==0; res=dwarf_siblingof(&child,&child)) {
+      for (res = dwarf_child(&unit_die, &child); res == 0;
+           res = dwarf_siblingof(&child, &child)) {
         MC_dwarf_handle_die(info, &child, &unit_die, NULL, NULL);
       }
 
@@ -958,3 +1045,338 @@ void MC_dwarf_get_variables(mc_object_info_t info) {
   dwarf_end(dwarf);
   close(fd);
 }
+
+/************************** Free functions *************************/
+
+void mc_frame_free(dw_frame_t frame)
+{
+  xbt_free(frame->name);
+  mc_dwarf_location_list_clear(&(frame->frame_base));
+  xbt_dynar_free(&(frame->variables));
+  xbt_dynar_free(&(frame->scopes));
+  xbt_free(frame);
+}
+
+void dw_type_free(dw_type_t t)
+{
+  xbt_free(t->name);
+  xbt_free(t->dw_type_id);
+  xbt_dynar_free(&(t->members));
+  mc_dwarf_expression_clear(&t->location);
+  xbt_free(t);
+}
+
+void dw_variable_free(dw_variable_t v)
+{
+  if (v) {
+    xbt_free(v->name);
+    xbt_free(v->type_origin);
+
+    if (v->locations.locations)
+      mc_dwarf_location_list_clear(&v->locations);
+    xbt_free(v);
+  }
+}
+
+void dw_variable_free_voidp(void *t)
+{
+  dw_variable_free((dw_variable_t) * (void **) t);
+}
+
+// ***** object_info
+
+
+
+mc_object_info_t MC_new_object_info(void)
+{
+  mc_object_info_t res = xbt_new0(s_mc_object_info_t, 1);
+  res->subprograms = xbt_dict_new_homogeneous((void (*)(void *)) mc_frame_free);
+  res->global_variables =
+      xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
+  res->types = xbt_dict_new_homogeneous((void (*)(void *)) dw_type_free);
+  res->full_types_by_name = xbt_dict_new_homogeneous(NULL);
+  return res;
+}
+
+void MC_free_object_info(mc_object_info_t * info)
+{
+  xbt_free(&(*info)->file_name);
+  xbt_dict_free(&(*info)->subprograms);
+  xbt_dynar_free(&(*info)->global_variables);
+  xbt_dict_free(&(*info)->types);
+  xbt_dict_free(&(*info)->full_types_by_name);
+  xbt_free(info);
+  xbt_dynar_free(&(*info)->functions_index);
+  *info = NULL;
+}
+
+// ***** Helpers
+
+void *MC_object_base_address(mc_object_info_t info)
+{
+  if (info->flags & MC_OBJECT_INFO_EXECUTABLE)
+    return 0;
+  void *result = info->start_exec;
+  if (info->start_rw != NULL && result > (void *) info->start_rw)
+    result = info->start_rw;
+  if (info->start_ro != NULL && result > (void *) info->start_ro)
+    result = info->start_ro;
+  return result;
+}
+
+// ***** Functions index
+
+static int MC_compare_frame_index_items(mc_function_index_item_t a,
+                                        mc_function_index_item_t b)
+{
+  if (a->low_pc < b->low_pc)
+    return -1;
+  else if (a->low_pc == b->low_pc)
+    return 0;
+  else
+    return 1;
+}
+
+static void MC_make_functions_index(mc_object_info_t info)
+{
+  xbt_dynar_t index = xbt_dynar_new(sizeof(s_mc_function_index_item_t), NULL);
+
+  // Populate the array:
+  dw_frame_t frame = NULL;
+  xbt_dict_cursor_t cursor;
+  char *key;
+  xbt_dict_foreach(info->subprograms, cursor, key, frame) {
+    if (frame->low_pc == NULL)
+      continue;
+    s_mc_function_index_item_t entry;
+    entry.low_pc = frame->low_pc;
+    entry.high_pc = frame->high_pc;
+    entry.function = frame;
+    xbt_dynar_push(index, &entry);
+  }
+
+  mc_function_index_item_t base =
+      (mc_function_index_item_t) xbt_dynar_get_ptr(index, 0);
+
+  // Sort the array by low_pc:
+  qsort(base,
+        xbt_dynar_length(index),
+        sizeof(s_mc_function_index_item_t),
+        (int (*)(const void *, const void *)) MC_compare_frame_index_items);
+
+  info->functions_index = index;
+}
+
+mc_object_info_t MC_ip_find_object_info(void *ip)
+{
+  size_t i;
+  for (i = 0; i != mc_object_infos_size; ++i) {
+    if (ip >= (void *) mc_object_infos[i]->start_exec
+        && ip <= (void *) mc_object_infos[i]->end_exec) {
+      return mc_object_infos[i];
+    }
+  }
+  return NULL;
+}
+
+static dw_frame_t MC_find_function_by_ip_and_object(void *ip,
+                                                    mc_object_info_t info)
+{
+  xbt_dynar_t dynar = info->functions_index;
+  mc_function_index_item_t base =
+      (mc_function_index_item_t) xbt_dynar_get_ptr(dynar, 0);
+  int i = 0;
+  int j = xbt_dynar_length(dynar) - 1;
+  while (j >= i) {
+    int k = i + ((j - i) / 2);
+    if (ip < base[k].low_pc) {
+      j = k - 1;
+    } else if (ip >= base[k].high_pc) {
+      i = k + 1;
+    } else {
+      return base[k].function;
+    }
+  }
+  return NULL;
+}
+
+dw_frame_t MC_find_function_by_ip(void *ip)
+{
+  mc_object_info_t info = MC_ip_find_object_info(ip);
+  if (info == NULL)
+    return NULL;
+  else
+    return MC_find_function_by_ip_and_object(ip, info);
+}
+
+static void MC_post_process_variables(mc_object_info_t info)
+{
+  unsigned cursor = 0;
+  dw_variable_t variable = NULL;
+  xbt_dynar_foreach(info->global_variables, cursor, variable) {
+    if (variable->type_origin) {
+      variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
+    }
+  }
+}
+
+static void mc_post_process_scope(mc_object_info_t info, dw_frame_t scope)
+{
+
+  if (scope->tag == DW_TAG_inlined_subroutine) {
+
+    // Attach correct namespaced name in inlined subroutine:
+    char *key = bprintf("%" PRIx64, (uint64_t) scope->abstract_origin_id);
+    dw_frame_t abstract_origin = xbt_dict_get_or_null(info->subprograms, key);
+    xbt_assert(abstract_origin, "Could not lookup abstract origin %s", key);
+    xbt_free(key);
+    scope->name = xbt_strdup(abstract_origin->name);
+
+  }
+  // Direct:
+  unsigned cursor = 0;
+  dw_variable_t variable = NULL;
+  xbt_dynar_foreach(scope->variables, cursor, variable) {
+    if (variable->type_origin) {
+      variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
+    }
+  }
+
+  // Recursive post-processing of nested-scopes:
+  dw_frame_t nested_scope = NULL;
+  xbt_dynar_foreach(scope->scopes, cursor, nested_scope)
+      mc_post_process_scope(info, nested_scope);
+
+}
+
+static void MC_post_process_functions(mc_object_info_t info)
+{
+  xbt_dict_cursor_t cursor;
+  char *key;
+  dw_frame_t subprogram = NULL;
+  xbt_dict_foreach(info->subprograms, cursor, key, subprogram) {
+    mc_post_process_scope(info, subprogram);
+  }
+}
+
+/** \brief Finds informations about a given shared object/executable */
+mc_object_info_t MC_find_object_info(memory_map_t maps, char *name,
+                                     int executable)
+{
+  mc_object_info_t result = MC_new_object_info();
+  if (executable)
+    result->flags |= MC_OBJECT_INFO_EXECUTABLE;
+  result->file_name = xbt_strdup(name);
+  MC_find_object_address(maps, result);
+  MC_dwarf_get_variables(result);
+  MC_post_process_types(result);
+  MC_post_process_variables(result);
+  MC_post_process_functions(result);
+  MC_make_functions_index(result);
+  return result;
+}
+
+/*************************************************************************/
+
+static int MC_dwarf_get_variable_index(xbt_dynar_t variables, char *var,
+                                       void *address)
+{
+
+  if (xbt_dynar_is_empty(variables))
+    return 0;
+
+  unsigned int cursor = 0;
+  int start = 0;
+  int end = xbt_dynar_length(variables) - 1;
+  dw_variable_t var_test = NULL;
+
+  while (start <= end) {
+    cursor = (start + end) / 2;
+    var_test =
+        (dw_variable_t) xbt_dynar_get_as(variables, cursor, dw_variable_t);
+    if (strcmp(var_test->name, var) < 0) {
+      start = cursor + 1;
+    } else if (strcmp(var_test->name, var) > 0) {
+      end = cursor - 1;
+    } else {
+      if (address) {            /* global variable */
+        if (var_test->address == address)
+          return -1;
+        if (var_test->address > address)
+          end = cursor - 1;
+        else
+          start = cursor + 1;
+      } else {                  /* local variable */
+        return -1;
+      }
+    }
+  }
+
+  if (strcmp(var_test->name, var) == 0) {
+    if (address && var_test->address < address)
+      return cursor + 1;
+    else
+      return cursor;
+  } else if (strcmp(var_test->name, var) < 0)
+    return cursor + 1;
+  else
+    return cursor;
+
+}
+
+void MC_dwarf_register_global_variable(mc_object_info_t info,
+                                       dw_variable_t variable)
+{
+  int index =
+      MC_dwarf_get_variable_index(info->global_variables, variable->name,
+                                  variable->address);
+  if (index != -1)
+    xbt_dynar_insert_at(info->global_variables, index, &variable);
+  // TODO, else ?
+}
+
+void MC_dwarf_register_non_global_variable(mc_object_info_t info,
+                                           dw_frame_t frame,
+                                           dw_variable_t variable)
+{
+  xbt_assert(frame, "Frame is NULL");
+  int index =
+      MC_dwarf_get_variable_index(frame->variables, variable->name, NULL);
+  if (index != -1)
+    xbt_dynar_insert_at(frame->variables, index, &variable);
+  // TODO, else ?
+}
+
+void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame,
+                                dw_variable_t variable)
+{
+  if (variable->global)
+    MC_dwarf_register_global_variable(info, variable);
+  else if (frame == NULL)
+    xbt_die("No frame for this local variable");
+  else
+    MC_dwarf_register_non_global_variable(info, frame, variable);
+}
+
+void MC_post_process_object_info(mc_object_info_t info)
+{
+  xbt_dict_cursor_t cursor = NULL;
+  char *key = NULL;
+  dw_type_t type = NULL;
+  xbt_dict_foreach(info->types, cursor, key, type) {
+
+    // Resolve full_type:
+    if (type->name && type->byte_size == 0) {
+      for (size_t i = 0; i != mc_object_infos_size; ++i) {
+        dw_type_t same_type =
+            xbt_dict_get_or_null(mc_object_infos[i]->full_types_by_name,
+                                 type->name);
+        if (same_type && same_type->name && same_type->byte_size) {
+          type->full_type = same_type;
+          break;
+        }
+      }
+    }
+
+  }
+}
index e92da2a..b1f0ac5 100644 (file)
 
 #include "mc_private.h"
 
-static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value) {
-  if(state->stack_size>=MC_EXPRESSION_STACK_SIZE)
+static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value)
+{
+  if (state->stack_size >= MC_EXPRESSION_STACK_SIZE)
     return MC_EXPRESSION_E_STACK_OVERFLOW;
 
   state->stack[state->stack_size++] = value;
   return 0;
 }
 
-static int mc_dwarf_register_to_libunwind(int dwarf_register) {
-  #if defined(UNW_TARGET_X86_64)
+static int mc_dwarf_register_to_libunwind(int dwarf_register)
+{
+#if defined(UNW_TARGET_X86_64)
   // It seems for this arch, DWARF and libunwind agree in the numbering:
   return dwarf_register;
-  #elif defined(UNW_TARGET_X86)
+#elif defined(UNW_TARGET_X86)
   // Could't find the authoritative source of information for this.
   // This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517.
-  switch(dwarf_register) {
-  case 0:  return UNW_X86_EAX;
-  case 1:  return UNW_X86_ECX;
-  case 2:  return UNW_X86_EDX;
-  case 3:  return UNW_X86_EBX;
-  case 4:  return UNW_X86_ESP;
-  case 5:  return UNW_X86_EBP;
-  case 6:  return UNW_X86_ESI;
-  case 7:  return UNW_X86_EDI;
-  case 8:  return UNW_X86_EIP;
-  case 9:  return UNW_X86_EFLAGS;
-  case 10: return UNW_X86_CS;
-  case 11: return UNW_X86_SS;
-  case 12: return UNW_X86_DS;
-  case 13: return UNW_X86_ES;
-  case 14: return UNW_X86_FS;
-  case 15: return UNW_X86_GS;
-  case 16: return UNW_X86_ST0;
-  case 17: return UNW_X86_ST1;
-  case 18: return UNW_X86_ST2;
-  case 19: return UNW_X86_ST3;
-  case 20: return UNW_X86_ST4;
-  case 21: return UNW_X86_ST5;
-  case 22: return UNW_X86_ST6;
-  case 23: return UNW_X86_ST7;
-  default: xbt_die("Bad/unknown register number.");
+  switch (dwarf_register) {
+  case 0:
+    return UNW_X86_EAX;
+  case 1:
+    return UNW_X86_ECX;
+  case 2:
+    return UNW_X86_EDX;
+  case 3:
+    return UNW_X86_EBX;
+  case 4:
+    return UNW_X86_ESP;
+  case 5:
+    return UNW_X86_EBP;
+  case 6:
+    return UNW_X86_ESI;
+  case 7:
+    return UNW_X86_EDI;
+  case 8:
+    return UNW_X86_EIP;
+  case 9:
+    return UNW_X86_EFLAGS;
+  case 10:
+    return UNW_X86_CS;
+  case 11:
+    return UNW_X86_SS;
+  case 12:
+    return UNW_X86_DS;
+  case 13:
+    return UNW_X86_ES;
+  case 14:
+    return UNW_X86_FS;
+  case 15:
+    return UNW_X86_GS;
+  case 16:
+    return UNW_X86_ST0;
+  case 17:
+    return UNW_X86_ST1;
+  case 18:
+    return UNW_X86_ST2;
+  case 19:
+    return UNW_X86_ST3;
+  case 20:
+    return UNW_X86_ST4;
+  case 21:
+    return UNW_X86_ST5;
+  case 22:
+    return UNW_X86_ST6;
+  case 23:
+    return UNW_X86_ST7;
+  default:
+    xbt_die("Bad/unknown register number.");
   }
-  #else
-  #error This architecture is not supported yet.
-  #endif
+#else
+#error This architecture is not supported yet.
+#endif
 }
 
-int mc_dwarf_execute_expression(
-  size_t n, const Dwarf_Op* ops, mc_expression_state_t state) {
-  for(int i=0; i!=n; ++i) {
+int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops,
+                                mc_expression_state_t state)
+{
+  for (int i = 0; i != n; ++i) {
     int error = 0;
-    const Dwarf_Opop = ops + i;
+    const Dwarf_Op *op = ops + i;
     uint8_t atom = op->atom;
 
     switch (atom) {
 
-    // Registers:
-
-    case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3:
-    case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7:
-    case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11:
-    case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15:
-    case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19:
-    case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
-    case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27:
-    case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31:{
-        int register_id = mc_dwarf_register_to_libunwind(op->atom - DW_OP_breg0);
+      // Registers:
+
+    case DW_OP_breg0:
+    case DW_OP_breg1:
+    case DW_OP_breg2:
+    case DW_OP_breg3:
+    case DW_OP_breg4:
+    case DW_OP_breg5:
+    case DW_OP_breg6:
+    case DW_OP_breg7:
+    case DW_OP_breg8:
+    case DW_OP_breg9:
+    case DW_OP_breg10:
+    case DW_OP_breg11:
+    case DW_OP_breg12:
+    case DW_OP_breg13:
+    case DW_OP_breg14:
+    case DW_OP_breg15:
+    case DW_OP_breg16:
+    case DW_OP_breg17:
+    case DW_OP_breg18:
+    case DW_OP_breg19:
+    case DW_OP_breg20:
+    case DW_OP_breg21:
+    case DW_OP_breg22:
+    case DW_OP_breg23:
+    case DW_OP_breg24:
+    case DW_OP_breg25:
+    case DW_OP_breg26:
+    case DW_OP_breg27:
+    case DW_OP_breg28:
+    case DW_OP_breg29:
+    case DW_OP_breg30:
+    case DW_OP_breg31:{
+        int register_id =
+            mc_dwarf_register_to_libunwind(op->atom - DW_OP_breg0);
         unw_word_t res;
-        if(!state->cursor)
+        if (!state->cursor)
           return MC_EXPRESSION_E_MISSING_STACK_CONTEXT;
         unw_get_reg(state->cursor, register_id, &res);
         error = mc_dwarf_push_value(state, res + op->number);
         break;
       }
 
-    // Push the CFA (Canonical Frame Addresse):
+      // Push the CFA (Canonical Frame Addresse):
     case DW_OP_call_frame_cfa:
-    {
-      // UNW_X86_64_CFA does not return the CFA DWARF expects
-      // (it is a synonym for UNW_X86_64_RSP) so copy the cursor,
-      // unwind it once in order to find the parent SP:
+      {
+        // UNW_X86_64_CFA does not return the CFA DWARF expects
+        // (it is a synonym for UNW_X86_64_RSP) so copy the cursor,
+        // unwind it once in order to find the parent SP:
 
-      if(!state->cursor)
-        return MC_EXPRESSION_E_MISSING_STACK_CONTEXT;
+        if (!state->cursor)
+          return MC_EXPRESSION_E_MISSING_STACK_CONTEXT;
 
-      // Get frame:
-      unw_cursor_t cursor = *(state->cursor);
-      unw_step(&cursor);
+        // Get frame:
+        unw_cursor_t cursor = *(state->cursor);
+        unw_step(&cursor);
 
-      unw_word_t res;
-      unw_get_reg(&cursor, UNW_TDEP_SP, &res);
-      error = mc_dwarf_push_value(state, res);
-      break;
-    }
+        unw_word_t res;
+        unw_get_reg(&cursor, UNW_TDEP_SP, &res);
+        error = mc_dwarf_push_value(state, res);
+        break;
+      }
 
-    // Frame base:
+      // Frame base:
 
     case DW_OP_fbreg:
       {
-        if(!state->frame_base)
+        if (!state->frame_base)
           return MC_EXPRESSION_E_MISSING_FRAME_BASE;
-        error = mc_dwarf_push_value(state, ((uintptr_t)state->frame_base) + op->number);
+        error =
+            mc_dwarf_push_value(state,
+                                ((uintptr_t) state->frame_base) + op->number);
         break;
       }
 
 
-    // Constants:
-
-    case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3:
-    case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7:
-    case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11:
-    case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15:
-    case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19:
-    case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23:
-    case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27:
-    case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31:
+      // Constants:
+
+    case DW_OP_lit0:
+    case DW_OP_lit1:
+    case DW_OP_lit2:
+    case DW_OP_lit3:
+    case DW_OP_lit4:
+    case DW_OP_lit5:
+    case DW_OP_lit6:
+    case DW_OP_lit7:
+    case DW_OP_lit8:
+    case DW_OP_lit9:
+    case DW_OP_lit10:
+    case DW_OP_lit11:
+    case DW_OP_lit12:
+    case DW_OP_lit13:
+    case DW_OP_lit14:
+    case DW_OP_lit15:
+    case DW_OP_lit16:
+    case DW_OP_lit17:
+    case DW_OP_lit18:
+    case DW_OP_lit19:
+    case DW_OP_lit20:
+    case DW_OP_lit21:
+    case DW_OP_lit22:
+    case DW_OP_lit23:
+    case DW_OP_lit24:
+    case DW_OP_lit25:
+    case DW_OP_lit26:
+    case DW_OP_lit27:
+    case DW_OP_lit28:
+    case DW_OP_lit29:
+    case DW_OP_lit30:
+    case DW_OP_lit31:
       error = mc_dwarf_push_value(state, atom - DW_OP_lit0);
       break;
 
     case DW_OP_addr:
-      if(!state->object_info)
+      if (!state->object_info)
         return MC_EXPRESSION_E_NO_BASE_ADDRESS;
-      if(state->stack_size==MC_EXPRESSION_STACK_SIZE)
+      if (state->stack_size == MC_EXPRESSION_STACK_SIZE)
         return MC_EXPRESSION_E_STACK_OVERFLOW;
       error = mc_dwarf_push_value(state,
-        (Dwarf_Off)(uintptr_t)MC_object_base_address(state->object_info) + op->number);
+                                  (Dwarf_Off) (uintptr_t)
+                                  MC_object_base_address(state->object_info) +
+                                  op->number);
       break;
 
     case DW_OP_const1u:
@@ -150,124 +231,139 @@ int mc_dwarf_execute_expression(
     case DW_OP_const8s:
     case DW_OP_constu:
     case DW_OP_consts:
-      if(state->stack_size==MC_EXPRESSION_STACK_SIZE)
+      if (state->stack_size == MC_EXPRESSION_STACK_SIZE)
         return MC_EXPRESSION_E_STACK_OVERFLOW;
       error = mc_dwarf_push_value(state, op->number);
       break;
 
-    // Stack manipulation:
+      // Stack manipulation:
 
-    // Push the value at the top of the stack:
+      // Push the value at the top of the stack:
     case DW_OP_dup:
-      if(state->stack_size==0)
+      if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       else
-        error = mc_dwarf_push_value(state, state->stack[state->stack_size-1]);
+        error = mc_dwarf_push_value(state, state->stack[state->stack_size - 1]);
       break;
 
     case DW_OP_drop:
-      if(state->stack_size==0)
+      if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       else
         state->stack_size--;
       break;
 
     case DW_OP_swap:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t temp = state->stack[state->stack_size-2];
-        state->stack[state->stack_size-2] = state->stack[state->stack_size-1];
-        state->stack[state->stack_size-1] = temp;
+        uintptr_t temp = state->stack[state->stack_size - 2];
+        state->stack[state->stack_size - 2] =
+            state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 1] = temp;
       }
       break;
 
     case DW_OP_over:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
-      error = mc_dwarf_push_value(state, state->stack[state->stack_size-2]);
+      error = mc_dwarf_push_value(state, state->stack[state->stack_size - 2]);
       break;
 
-    // Operations:
+      // Operations:
 
     case DW_OP_plus:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t result = state->stack[state->stack_size-2] + state->stack[state->stack_size-1];
-        state->stack[state->stack_size-2] = result;
+        uintptr_t result =
+            state->stack[state->stack_size - 2] +
+            state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 2] = result;
         state->stack_size--;
       }
       break;
 
     case DW_OP_mul:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t result = state->stack[state->stack_size-2] - state->stack[state->stack_size-1];
-        state->stack[state->stack_size-2] = result;
+        uintptr_t result =
+            state->stack[state->stack_size - 2] -
+            state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 2] = result;
         state->stack_size--;
       }
       break;
 
     case DW_OP_plus_uconst:
-      if(state->stack_size==0)
+      if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
-      state->stack[state->stack_size-1] += op->number;
+      state->stack[state->stack_size - 1] += op->number;
       break;
 
     case DW_OP_not:
-      if(state->stack_size==0)
+      if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
-      state->stack[state->stack_size-1] = ~state->stack[state->stack_size-1];
+      state->stack[state->stack_size - 1] =
+          ~state->stack[state->stack_size - 1];
       break;
 
     case DW_OP_neg:
-      if(state->stack_size==0)
+      if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        intptr_t value = state->stack[state->stack_size-1];
-        if(value<0) value = -value;
-        state->stack[state->stack_size-1] = value;
+        intptr_t value = state->stack[state->stack_size - 1];
+        if (value < 0)
+          value = -value;
+        state->stack[state->stack_size - 1] = value;
       }
       break;
 
     case DW_OP_minus:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t result = state->stack[state->stack_size-2] - state->stack[state->stack_size-1];
-        state->stack[state->stack_size-2] = result;
+        uintptr_t result =
+            state->stack[state->stack_size - 2] -
+            state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 2] = result;
         state->stack_size--;
       }
       break;
 
     case DW_OP_and:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t result = state->stack[state->stack_size-2] & state->stack[state->stack_size-1];
-        state->stack[state->stack_size-2] = result;
+        uintptr_t result =
+            state->stack[state->stack_size -
+                         2] & state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 2] = result;
         state->stack_size--;
       }
       break;
 
     case DW_OP_or:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t result = state->stack[state->stack_size-2] | state->stack[state->stack_size-1];
-        state->stack[state->stack_size-2] = result;
+        uintptr_t result =
+            state->stack[state->stack_size -
+                         2] | state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 2] = result;
         state->stack_size--;
       }
       break;
 
     case DW_OP_xor:
-      if(state->stack_size<2)
+      if (state->stack_size < 2)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
-        uintptr_t result = state->stack[state->stack_size-2] ^ state->stack[state->stack_size-1];
-        state->stack[state->stack_size-2] = result;
+        uintptr_t result =
+            state->stack[state->stack_size -
+                         2] ^ state->stack[state->stack_size - 1];
+        state->stack[state->stack_size - 2] = result;
         state->stack_size--;
       }
       break;
@@ -275,27 +371,29 @@ int mc_dwarf_execute_expression(
     case DW_OP_nop:
       break;
 
-    // Dereference:
+      // Dereference:
     case DW_OP_deref_size:
       return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
 
     case DW_OP_deref:
-      if(state->stack_size==0)
+      if (state->stack_size == 0)
         return MC_EXPRESSION_E_STACK_UNDERFLOW;
       {
         // Computed address:
-        uintptr_t address = (uintptr_t) state->stack[state->stack_size-1];
-        uintptr_t* p = (uintptr_t*)mc_translate_address(address, state->snapshot);
-        state->stack[state->stack_size-1] = *p;
+        uintptr_t address = (uintptr_t) state->stack[state->stack_size - 1];
+        uintptr_t temp;
+        uintptr_t* res = (uintptr_t*) mc_snapshot_read((void*) address, state->snapshot, &temp, sizeof(uintptr_t));
+        state->stack[state->stack_size - 1] = *res;
       }
       break;
 
-    // Not handled:
+      // Not handled:
     default:
-     return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
+      return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
     }
 
-    if(error) return error;
+    if (error)
+      return error;
   }
   return 0;
 }
@@ -305,7 +403,12 @@ int mc_dwarf_execute_expression(
 /** \brief Resolve a location expression
  *  \deprecated Use mc_dwarf_resolve_expression
  */
-uintptr_t mc_dwarf_resolve_location(mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot) {
+uintptr_t mc_dwarf_resolve_location(mc_expression_t expression,
+                                    mc_object_info_t object_info,
+                                    unw_cursor_t * c,
+                                    void *frame_pointer_address,
+                                    mc_snapshot_t snapshot)
+{
   s_mc_expression_state_t state;
   memset(&state, 0, sizeof(s_mc_expression_state_t));
   state.frame_base = frame_pointer_address;
@@ -313,27 +416,34 @@ uintptr_t mc_dwarf_resolve_location(mc_expression_t expression, mc_object_info_t
   state.snapshot = snapshot;
   state.object_info = object_info;
 
-  if(mc_dwarf_execute_expression(expression->size, expression->ops, &state))
+  if (mc_dwarf_execute_expression(expression->size, expression->ops, &state))
     xbt_die("Error evaluating DWARF expression");
-  if(state.stack_size==0)
+  if (state.stack_size == 0)
     xbt_die("No value on the stack");
   else
-    return state.stack[state.stack_size-1];
+    return state.stack[state.stack_size - 1];
 }
 
-uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot) {
+uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations,
+                                     mc_object_info_t object_info,
+                                     unw_cursor_t * c,
+                                     void *frame_pointer_address,
+                                     mc_snapshot_t snapshot)
+{
 
   unw_word_t ip;
-  if(c) {
-    if(unw_get_reg(c, UNW_REG_IP, &ip))
+  if (c) {
+    if (unw_get_reg(c, UNW_REG_IP, &ip))
       xbt_die("Could not resolve IP");
   }
 
-  for(size_t i=0; i!=locations->size; ++i) {
+  for (size_t i = 0; i != locations->size; ++i) {
     mc_expression_t expression = locations->locations + i;
-    if( (expression->lowpc==NULL && expression->highpc==NULL)
-      || (c && ip >= (unw_word_t) expression->lowpc && ip < (unw_word_t) expression->highpc)) {
-      return mc_dwarf_resolve_location(expression, object_info, c, frame_pointer_address, snapshot);
+    if ((expression->lowpc == NULL && expression->highpc == NULL)
+        || (c && ip >= (unw_word_t) expression->lowpc
+            && ip < (unw_word_t) expression->highpc)) {
+      return mc_dwarf_resolve_location(expression, object_info, c,
+                                       frame_pointer_address, snapshot);
     }
   }
   xbt_die("Could not resolve location");
@@ -344,11 +454,15 @@ uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations, mc_object_inf
  *  \param frame
  *  \param unw_cursor
  */
-void* mc_find_frame_base(dw_frame_t frame, mc_object_info_t object_info, unw_cursor_t* unw_cursor) {
-  return (void*) mc_dwarf_resolve_locations(&frame->frame_base, object_info, unw_cursor, NULL, NULL);
+void *mc_find_frame_base(dw_frame_t frame, mc_object_info_t object_info,
+                         unw_cursor_t * unw_cursor)
+{
+  return (void *) mc_dwarf_resolve_locations(&frame->frame_base, object_info,
+                                             unw_cursor, NULL, NULL);
 }
 
-void mc_dwarf_expression_clear(mc_expression_t expression) {
+void mc_dwarf_expression_clear(mc_expression_t expression)
+{
   free(expression->ops);
   expression->ops = NULL;
   expression->size = 0;
@@ -356,8 +470,9 @@ void mc_dwarf_expression_clear(mc_expression_t expression) {
   expression->highpc = NULL;
 }
 
-void mc_dwarf_location_list_clear(mc_location_list_t list) {
-  for(size_t i=0; i!=list->size; ++i) {
+void mc_dwarf_location_list_clear(mc_location_list_t list)
+{
+  for (size_t i = 0; i != list->size; ++i) {
     mc_dwarf_expression_clear(list->locations + i);
   }
   free(list->locations);
@@ -365,28 +480,28 @@ void mc_dwarf_location_list_clear(mc_location_list_t list) {
   list->size = 0;
 }
 
-void mc_dwarf_expression_init(mc_expression_t expression, size_t len, Dwarf_Op* ops) {
-  if(expression->ops) {
-    free(expression->ops);
-  }
+void mc_dwarf_expression_init(mc_expression_t expression, size_t len,
+                              Dwarf_Op * ops)
+{
   expression->lowpc = NULL;
   expression->highpc = NULL;
   expression->size = len;
-  expression->ops = xbt_malloc(len*sizeof(Dwarf_Op));
-  memcpy(expression->ops, ops, len*sizeof(Dwarf_Op));
+  expression->ops = xbt_malloc(len * sizeof(Dwarf_Op));
+  memcpy(expression->ops, ops, len * sizeof(Dwarf_Op));
 }
 
-void mc_dwarf_location_list_init_from_expression(mc_location_list_t target, size_t len, Dwarf_Op* ops) {
-  if(target->locations) {
-    mc_dwarf_location_list_clear(target);
-  }
+void mc_dwarf_location_list_init_from_expression(mc_location_list_t target,
+                                                 size_t len, Dwarf_Op * ops)
+{
   target->size = 1;
   target->locations = (mc_expression_t) xbt_malloc(sizeof(s_mc_expression_t));
   mc_dwarf_expression_init(target->locations, len, ops);
 }
 
-void mc_dwarf_location_list_init(mc_location_list_t list, mc_object_info_t info, Dwarf_Die* die, Dwarf_Attribute* attr) {
-  if(list->locations) {
+void mc_dwarf_location_list_init(mc_location_list_t list, mc_object_info_t info,
+                                 Dwarf_Die * die, Dwarf_Attribute * attr)
+{
+  if (list->locations) {
     mc_dwarf_location_list_clear(list);
   }
   list->size = 0;
@@ -399,22 +514,26 @@ void mc_dwarf_location_list_init(mc_location_list_t list, mc_object_info_t info,
   while (1) {
 
     offset = dwarf_getlocations(attr, offset, &base, &start, &end, &ops, &len);
-    if (offset==0)
+    if (offset == 0)
       return;
-    else if (offset==-1)
+    else if (offset == -1)
       xbt_die("Error while loading location list");
 
     int i = list->size;
     list->size++;
-    list->locations = (mc_expression_t) realloc(list->locations, list->size*sizeof(s_mc_expression_t));
+    list->locations =
+        (mc_expression_t) realloc(list->locations,
+                                  list->size * sizeof(s_mc_expression_t));
     mc_expression_t expression = list->locations + i;
     expression->ops = NULL;
     mc_dwarf_expression_init(expression, len, ops);
 
-    void* base = info->flags & MC_OBJECT_INFO_EXECUTABLE ? 0 : MC_object_base_address(info);
+    void *base =
+        info->
+        flags & MC_OBJECT_INFO_EXECUTABLE ? 0 : MC_object_base_address(info);
     // If start == 0, this is not a location list:
-    expression->lowpc = start == 0 ? NULL : (char*) base + start;
-    expression->highpc = start == 0 ? NULL : (char*) base + end;
+    expression->lowpc = start == 0 ? NULL : (char *) base + start;
+    expression->highpc = start == 0 ? NULL : (char *) base + end;
   }
 
 }
index 5ca58db..1ae1229 100644 (file)
@@ -25,95 +25,137 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_global, mc,
                                 "Logging specific to MC (global)");
 
 /* Configuration support */
-e_mc_reduce_t mc_reduce_kind=e_mc_reduce_unset;
+e_mc_reduce_t mc_reduce_kind = e_mc_reduce_unset;
 
 int _sg_do_model_check = 0;
-int _sg_mc_checkpoint=0;
-char* _sg_mc_property_file=NULL;
-int _sg_mc_timeout=0;
-int _sg_mc_hash=0;
-int _sg_mc_max_depth=1000;
-int _sg_mc_visited=0;
+int _sg_mc_checkpoint = 0;
+int _sg_mc_sparse_checkpoint = 0;
+int _sg_mc_soft_dirty = 1;
+char *_sg_mc_property_file = NULL;
+int _sg_mc_timeout = 0;
+int _sg_mc_hash = 0;
+int _sg_mc_max_depth = 1000;
+int _sg_mc_visited = 0;
 char *_sg_mc_dot_output_file = NULL;
-int _sg_mc_comms_determinism=0;
-int _sg_mc_send_determinism=0;
+int _sg_mc_comms_determinism = 0;
+int _sg_mc_send_determinism = 0;
+int _sg_mc_safety = 0;
+int _sg_mc_liveness = 0;
 
 int user_max_depth_reached = 0;
 
-void _mc_cfg_cb_reduce(const char *name, int pos) {
+void _mc_cfg_cb_reduce(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a reduction strategy after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a reduction strategy after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  char *val= xbt_cfg_get_string(_sg_cfg_set, name);
-  if (!strcasecmp(val,"none")) {
+  char *val = xbt_cfg_get_string(_sg_cfg_set, name);
+  if (!strcasecmp(val, "none")) {
     mc_reduce_kind = e_mc_reduce_none;
-  } else if (!strcasecmp(val,"dpor")) {
+  } else if (!strcasecmp(val, "dpor")) {
     mc_reduce_kind = e_mc_reduce_dpor;
   } else {
-    xbt_die("configuration option %s can only take 'none' or 'dpor' as a value",name);
+    xbt_die("configuration option %s can only take 'none' or 'dpor' as a value",
+            name);
   }
 }
 
-void _mc_cfg_cb_checkpoint(const char *name, int pos) {
+void _mc_cfg_cb_checkpoint(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a checkpointing value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a checkpointing value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
   _sg_mc_checkpoint = xbt_cfg_get_int(_sg_cfg_set, name);
 }
-void _mc_cfg_cb_property(const char *name, int pos) {
+
+void _mc_cfg_cb_sparse_checkpoint(const char *name, int pos) {
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a property after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die("You are specifying a checkpointing value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_property_file= xbt_cfg_get_string(_sg_cfg_set, name);
+  _sg_mc_sparse_checkpoint = xbt_cfg_get_boolean(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_timeout(const char *name, int pos) {
+void _mc_cfg_cb_soft_dirty(const char *name, int pos) {
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a value to enable/disable timeout for wait requests after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die("You are specifying a soft dirty value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_timeout= xbt_cfg_get_boolean(_sg_cfg_set, name);
+  _sg_mc_soft_dirty = xbt_cfg_get_boolean(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_hash(const char *name, int pos) {
+void _mc_cfg_cb_property(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a value to enable/disable the use of global hash to speedup state comparaison, but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a property after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_hash= xbt_cfg_get_boolean(_sg_cfg_set, name);
+  _sg_mc_property_file = xbt_cfg_get_string(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_max_depth(const char *name, int pos) {
+void _mc_cfg_cb_timeout(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a max depth value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a value to enable/disable timeout for wait requests after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_max_depth= xbt_cfg_get_int(_sg_cfg_set, name);
+  _sg_mc_timeout = xbt_cfg_get_boolean(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_visited(const char *name, int pos) {
+void _mc_cfg_cb_hash(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a number of stored visited states after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a value to enable/disable the use of global hash to speedup state comparaison, but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_visited= xbt_cfg_get_int(_sg_cfg_set, name);
+  _sg_mc_hash = xbt_cfg_get_boolean(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_dot_output(const char *name, int pos) {
+void _mc_cfg_cb_max_depth(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a file name for a dot output of graph state after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a max depth value after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_dot_output_file= xbt_cfg_get_string(_sg_cfg_set, name);
+  _sg_mc_max_depth = xbt_cfg_get_int(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_comms_determinism(const char *name, int pos) {
+void _mc_cfg_cb_visited(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a value to enable/disable the detection of determinism in the communications schemes after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a number of stored visited states after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_comms_determinism= xbt_cfg_get_boolean(_sg_cfg_set, name);
+  _sg_mc_visited = xbt_cfg_get_int(_sg_cfg_set, name);
 }
 
-void _mc_cfg_cb_send_determinism(const char *name, int pos) {
+void _mc_cfg_cb_dot_output(const char *name, int pos)
+{
+  if (_sg_cfg_init_status && !_sg_do_model_check) {
+    xbt_die
+        ("You are specifying a file name for a dot output of graph state after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+  }
+  _sg_mc_dot_output_file = xbt_cfg_get_string(_sg_cfg_set, name);
+}
+
+void _mc_cfg_cb_comms_determinism(const char *name, int pos)
+{
+  if (_sg_cfg_init_status && !_sg_do_model_check) {
+    xbt_die
+        ("You are specifying a value to enable/disable the detection of determinism in the communications schemes after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+  }
+  _sg_mc_comms_determinism = xbt_cfg_get_boolean(_sg_cfg_set, name);
+  mc_reduce_kind = e_mc_reduce_none;
+}
+
+void _mc_cfg_cb_send_determinism(const char *name, int pos)
+{
   if (_sg_cfg_init_status && !_sg_do_model_check) {
-    xbt_die("You are specifying a value to enable/disable the detection of send-determinism in the communications schemes after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+    xbt_die
+        ("You are specifying a value to enable/disable the detection of send-determinism in the communications schemes after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
   }
-  _sg_mc_send_determinism= xbt_cfg_get_boolean(_sg_cfg_set, name);
+  _sg_mc_send_determinism = xbt_cfg_get_boolean(_sg_cfg_set, name);
+  mc_reduce_kind = e_mc_reduce_none;
 }
 
 /* MC global data structures */
@@ -123,16 +165,10 @@ double *mc_time = NULL;
 __thread mc_comparison_times_t mc_comp_times = NULL;
 __thread double mc_snapshot_comparison_time;
 mc_stats_t mc_stats = NULL;
-
-/* Safety */
-xbt_fifo_t mc_stack_safety = NULL;
-mc_global_t initial_state_safety = NULL;
+mc_global_t initial_global_state = NULL;
+xbt_fifo_t mc_stack = NULL;
 
 /* Liveness */
-xbt_fifo_t mc_stack_liveness = NULL;
-mc_global_t initial_state_liveness = NULL;
-int compare;
-
 xbt_automaton_t _mc_property_automaton = NULL;
 
 /* Variables */
@@ -140,655 +176,48 @@ mc_object_info_t mc_libsimgrid_info = NULL;
 mc_object_info_t mc_binary_info = NULL;
 
 mc_object_info_t mc_object_infos[2] = { NULL, NULL };
-size_t mc_object_infos_size = 2;
 
-/* Ignore mechanism */
-extern xbt_dynar_t mc_heap_comparison_ignore;
-extern xbt_dynar_t stacks_areas;
+size_t mc_object_infos_size = 2;
 
 /* Dot output */
 FILE *dot_output = NULL;
-const char* colors[13];
-
-
-/*******************************  DWARF Information *******************************/
-/**********************************************************************************/
-
-/************************** Free functions *************************/
-
-void mc_frame_free(dw_frame_t frame){
-  xbt_free(frame->name);
-  mc_dwarf_location_list_clear(&(frame->frame_base));
-  xbt_dynar_free(&(frame->variables));
-  xbt_dynar_free(&(frame->scopes));
-  xbt_free(frame);
-}
-
-void dw_type_free(dw_type_t t){
-  xbt_free(t->name);
-  xbt_free(t->dw_type_id);
-  xbt_dynar_free(&(t->members));
-  mc_dwarf_expression_clear(&t->location);
-  xbt_free(t);
-}
-
-void dw_variable_free(dw_variable_t v){
-  if(v){
-    xbt_free(v->name);
-    xbt_free(v->type_origin);
-
-    if(v->locations.locations)
-      mc_dwarf_location_list_clear(&v->locations);
-    xbt_free(v);
-  }
-}
-
-void dw_variable_free_voidp(void *t){
-  dw_variable_free((dw_variable_t) * (void **) t);
-}
-
-// ***** object_info
-
-
-
-mc_object_info_t MC_new_object_info(void) {
-  mc_object_info_t res = xbt_new0(s_mc_object_info_t, 1);
-  res->subprograms = xbt_dict_new_homogeneous((void (*)(void*))mc_frame_free);
-  res->global_variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp);
-  res->types = xbt_dict_new_homogeneous((void (*)(void*))dw_type_free);
-  res->full_types_by_name = xbt_dict_new_homogeneous(NULL);
-  return res;
-}
-
-void MC_free_object_info(mc_object_info_t* info) {
-  xbt_free(&(*info)->file_name);
-  xbt_dict_free(&(*info)->subprograms);
-  xbt_dynar_free(&(*info)->global_variables);
-  xbt_dict_free(&(*info)->types);
-  xbt_dict_free(&(*info)->full_types_by_name);
-  xbt_free(info);
-  xbt_dynar_free(&(*info)->functions_index);
-  *info = NULL;
-}
-
-// ***** Helpers
-
-void* MC_object_base_address(mc_object_info_t info) {
-  if(info->flags & MC_OBJECT_INFO_EXECUTABLE)
-    return 0;
-  void* result = info->start_exec;
-  if(info->start_rw!=NULL && result > (void*) info->start_rw) result = info->start_rw;
-  if(info->start_ro!=NULL && result > (void*) info->start_ro) result = info->start_ro;
-  return result;
-}
-
-// ***** Functions index
-
-static int MC_compare_frame_index_items(mc_function_index_item_t a, mc_function_index_item_t b) {
-  if(a->low_pc < b->low_pc)
-    return -1;
-  else if(a->low_pc == b->low_pc)
-    return 0;
-  else
-    return 1;
-}
-
-static void MC_make_functions_index(mc_object_info_t info) {
-  xbt_dynar_t index = xbt_dynar_new(sizeof(s_mc_function_index_item_t), NULL);
-
-  // Populate the array:
-  dw_frame_t frame = NULL;
-  xbt_dict_cursor_t cursor;
-  char* key;
-  xbt_dict_foreach(info->subprograms, cursor, key, frame) {
-    if(frame->low_pc==NULL)
-      continue;
-    s_mc_function_index_item_t entry;
-    entry.low_pc = frame->low_pc;
-    entry.high_pc = frame->high_pc;
-    entry.function = frame;
-    xbt_dynar_push(index, &entry);
-  }
-
-  mc_function_index_item_t base = (mc_function_index_item_t) xbt_dynar_get_ptr(index, 0);
-
-  // Sort the array by low_pc:
-  qsort(base,
-    xbt_dynar_length(index),
-    sizeof(s_mc_function_index_item_t),
-    (int (*)(const void *, const void *))MC_compare_frame_index_items);
-
-  info->functions_index = index;
-}
-
-mc_object_info_t MC_ip_find_object_info(void* ip) {
-  size_t i;
-  for(i=0; i!=mc_object_infos_size; ++i) {
-    if(ip >= (void*)mc_object_infos[i]->start_exec && ip <= (void*)mc_object_infos[i]->end_exec) {
-      return mc_object_infos[i];
-    }
-  }
-  return NULL;
-}
-
-static dw_frame_t MC_find_function_by_ip_and_object(void* ip, mc_object_info_t info) {
-  xbt_dynar_t dynar = info->functions_index;
-  mc_function_index_item_t base = (mc_function_index_item_t) xbt_dynar_get_ptr(dynar, 0);
-  int i = 0;
-  int j = xbt_dynar_length(dynar) - 1;
-  while(j>=i) {
-    int k = i + ((j-i)/2);
-    if(ip < base[k].low_pc) {
-      j = k-1;
-    } else if(ip >= base[k].high_pc) {
-      i = k+1;
-    } else {
-      return base[k].function;
-    }
-  }
-  return NULL;
-}
-
-dw_frame_t MC_find_function_by_ip(void* ip) {
-  mc_object_info_t info = MC_ip_find_object_info(ip);
-  if(info==NULL)
-    return NULL;
-  else
-    return MC_find_function_by_ip_and_object(ip, info);
-}
-
-static void MC_post_process_variables(mc_object_info_t info) {
-  unsigned cursor = 0;
-  dw_variable_t variable = NULL;
-  xbt_dynar_foreach(info->global_variables, cursor, variable) {
-    if(variable->type_origin) {
-      variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
-    }
-  }
-}
-
-static void mc_post_process_scope(mc_object_info_t info, dw_frame_t scope) {
-
-  if(scope->tag == DW_TAG_inlined_subroutine) {
-
-    // Attach correct namespaced name in inlined subroutine:
-    char* key = bprintf("%" PRIx64, (uint64_t) scope->abstract_origin_id);
-    dw_frame_t abstract_origin = xbt_dict_get_or_null(info->subprograms, key);
-    xbt_assert(abstract_origin, "Could not lookup abstract origin %s", key);
-    xbt_free(key);
-    scope->name = xbt_strdup(abstract_origin->name);
-
-  }
-
-  // Direct:
-  unsigned cursor = 0;
-  dw_variable_t variable = NULL;
-  xbt_dynar_foreach(scope->variables, cursor, variable) {
-    if(variable->type_origin) {
-      variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
-    }
-  }
-
-  // Recursive post-processing of nested-scopes:
-  dw_frame_t nested_scope = NULL;
-  xbt_dynar_foreach(scope->scopes, cursor, nested_scope)
-    mc_post_process_scope(info, nested_scope);
+const char *colors[13];
 
-}
-
-static void MC_post_process_functions(mc_object_info_t info) {
-  xbt_dict_cursor_t cursor;
-  char* key;
-  dw_frame_t subprogram = NULL;
-  xbt_dict_foreach(info->subprograms, cursor, key, subprogram) {
-    mc_post_process_scope(info, subprogram);
-  }
-}
-
-/** \brief Finds informations about a given shared object/executable */
-mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable) {
-  mc_object_info_t result = MC_new_object_info();
-  if(executable)
-    result->flags |= MC_OBJECT_INFO_EXECUTABLE;
-  result->file_name = xbt_strdup(name);
-  MC_find_object_address(maps, result);
-  MC_dwarf_get_variables(result);
-  MC_post_process_types(result);
-  MC_post_process_variables(result);
-  MC_post_process_functions(result);
-  MC_make_functions_index(result);
-  return result;
-}
-
-/*************************************************************************/
-
-static int MC_dwarf_get_variable_index(xbt_dynar_t variables, char* var, void *address){
-
-  if(xbt_dynar_is_empty(variables))
-    return 0;
-
-  unsigned int cursor = 0;
-  int start = 0;
-  int end = xbt_dynar_length(variables) - 1;
-  dw_variable_t var_test = NULL;
-
-  while(start <= end){
-    cursor = (start + end) / 2;
-    var_test = (dw_variable_t)xbt_dynar_get_as(variables, cursor, dw_variable_t);
-    if(strcmp(var_test->name, var) < 0){
-      start = cursor + 1;
-    }else if(strcmp(var_test->name, var) > 0){
-      end = cursor - 1;
-    }else{
-      if(address){ /* global variable */
-        if(var_test->address == address)
-          return -1;
-        if(var_test->address > address)
-          end = cursor - 1;
-        else
-          start = cursor + 1;
-      }else{ /* local variable */
-        return -1;
-      }
-    }
-  }
-
-  if(strcmp(var_test->name, var) == 0){
-    if(address && var_test->address < address)
-      return cursor+1;
-    else
-      return cursor;
-  }else if(strcmp(var_test->name, var) < 0)
-    return cursor+1;
-  else
-    return cursor;
-
-}
-
-void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t variable) {
-  int index = MC_dwarf_get_variable_index(info->global_variables, variable->name, variable->address);
-  if (index != -1)
-    xbt_dynar_insert_at(info->global_variables, index, &variable);
-  // TODO, else ?
-}
 
-void MC_dwarf_register_non_global_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable) {
-  xbt_assert(frame, "Frame is NULL");
-  int index = MC_dwarf_get_variable_index(frame->variables, variable->name, NULL);
-  if (index != -1)
-    xbt_dynar_insert_at(frame->variables, index, &variable);
-  // TODO, else ?
-}
-
-void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable) {
-  if(variable->global)
-    MC_dwarf_register_global_variable(info, variable);
-  else if(frame==NULL)
-    xbt_die("No frame for this local variable");
-  else
-    MC_dwarf_register_non_global_variable(info, frame, variable);
-}
-
-
-/*******************************  Ignore mechanism *******************************/
+/*******************************  Initialisation of MC *******************************/
 /*********************************************************************************/
 
-xbt_dynar_t mc_checkpoint_ignore;
-
-typedef struct s_mc_stack_ignore_variable{
-  char *var_name;
-  char *frame;
-}s_mc_stack_ignore_variable_t, *mc_stack_ignore_variable_t;
-
-/**************************** Free functions ******************************/
-
-static void stack_ignore_variable_free(mc_stack_ignore_variable_t v){
-  xbt_free(v->var_name);
-  xbt_free(v->frame);
-  xbt_free(v);
-}
-
-static void stack_ignore_variable_free_voidp(void *v){
-  stack_ignore_variable_free((mc_stack_ignore_variable_t) * (void **) v);
-}
-
-void heap_ignore_region_free(mc_heap_ignore_region_t r){
-  xbt_free(r);
-}
-
-void heap_ignore_region_free_voidp(void *r){
-  heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
-}
-
-static void checkpoint_ignore_region_free(mc_checkpoint_ignore_region_t r){
-  xbt_free(r);
-}
-
-static void checkpoint_ignore_region_free_voidp(void *r){
-  checkpoint_ignore_region_free((mc_checkpoint_ignore_region_t) * (void **) r);
-}
-
-/***********************************************************************/
-
-void MC_ignore_heap(void *address, size_t size){
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  mc_heap_ignore_region_t region = NULL;
-  region = xbt_new0(s_mc_heap_ignore_region_t, 1);
-  region->address = address;
-  region->size = size;
-  
-  region->block = ((char*)address - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
-  
-  if(((xbt_mheap_t)std_heap)->heapinfo[region->block].type == 0){
-    region->fragment = -1;
-    ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_block.ignore++;
-  }else{
-    region->fragment = ((uintptr_t) (ADDR2UINT (address) % (BLOCKSIZE))) >> ((xbt_mheap_t)std_heap)->heapinfo[region->block].type;
-    ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_frag.ignore[region->fragment]++;
-  }
-  
-  if(mc_heap_comparison_ignore == NULL){
-    mc_heap_comparison_ignore = xbt_dynar_new(sizeof(mc_heap_ignore_region_t), heap_ignore_region_free_voidp);
-    xbt_dynar_push(mc_heap_comparison_ignore, &region);
-    if(!raw_mem_set)
-      MC_UNSET_RAW_MEM;
-    return;
-  }
-
-  unsigned int cursor = 0;
-  mc_heap_ignore_region_t current_region = NULL;
-  int start = 0;
-  int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
-  
-  while(start <= end){
-    cursor = (start + end) / 2;
-    current_region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
-    if(current_region->address == address){
-      heap_ignore_region_free(region);
-      if(!raw_mem_set)
-        MC_UNSET_RAW_MEM;
-      return;
-    }else if(current_region->address < address){
-      start = cursor + 1;
-    }else{
-      end = cursor - 1;
-    }   
-  }
-
-  if(current_region->address < address)
-    xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, &region);
-  else
-    xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, &region);
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-}
-
-void MC_remove_ignore_heap(void *address, size_t size){
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  unsigned int cursor = 0;
-  int start = 0;
-  int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
-  mc_heap_ignore_region_t region;
-  int ignore_found = 0;
-
-  while(start <= end){
-    cursor = (start + end) / 2;
-    region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
-    if(region->address == address){
-      ignore_found = 1;
-      break;
-    }else if(region->address < address){
-      start = cursor + 1;
-    }else{
-      if((char * )region->address <= ((char *)address + size)){
-        ignore_found = 1;
-        break;
-      }else{
-        end = cursor - 1;   
-      }
-    }
-  }
-  
-  if(ignore_found == 1){
-    xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
-    MC_remove_ignore_heap(address, size);
-  }
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-
-}
-
-void MC_ignore_global_variable(const char *name){
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  xbt_assert(mc_libsimgrid_info, "MC subsystem not initialized");
-
-    unsigned int cursor = 0;
-    dw_variable_t current_var;
-    int start = 0;
-    int end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
-
-    while(start <= end){
-      cursor = (start + end) /2;
-      current_var = (dw_variable_t)xbt_dynar_get_as(mc_libsimgrid_info->global_variables, cursor, dw_variable_t);
-      if(strcmp(current_var->name, name) == 0){
-        xbt_dynar_remove_at(mc_libsimgrid_info->global_variables, cursor, NULL);
-        start = 0;
-        end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
-      }else if(strcmp(current_var->name, name) < 0){
-        start = cursor + 1;
-      }else{
-        end = cursor - 1;
-      } 
-    }
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-}
-
-/** \brief Ignore a local variable in a scope
- *
- *  Ignore all instances of variables with a given name in
- *  any (possibly inlined) subprogram with a given namespaced
- *  name.
- *
- *  \param var_name        Name of the local variable (or parameter to ignore)
- *  \param subprogram_name Name of the subprogram fo ignore (NULL for any)
- *  \param subprogram      (possibly inlined) Subprogram of the scope
- *  \param scope           Current scope
- */
-static void mc_ignore_local_variable_in_scope(
-  const char *var_name, const char *subprogram_name,
-  dw_frame_t subprogram, dw_frame_t scope) {
-  // Processing of direct variables:
-
-  // If the current subprogram matche the given name:
-  if(subprogram_name==NULL || strcmp(subprogram_name, subprogram->name)==0) {
-
-    // Try to find the variable and remove it:
-    int start = 0;
-    int end = xbt_dynar_length(scope->variables) - 1;
-
-    // Dichotomic search:
-    while(start <= end){
-      int cursor = (start + end) / 2;
-      dw_variable_t current_var = (dw_variable_t)xbt_dynar_get_as(scope->variables, cursor, dw_variable_t);
-
-      int compare = strcmp(current_var->name, var_name);
-      if(compare == 0){
-        // Variable found, remove it:
-        xbt_dynar_remove_at(scope->variables, cursor, NULL);
-
-        // and start again:
-        start = 0;
-        end = xbt_dynar_length(scope->variables) - 1;
-      }else if(compare < 0){
-        start = cursor + 1;
-      }else{
-        end = cursor - 1;
-      }
-    }
-
-  }
-
-  // And recursive processing in nested scopes:
-  unsigned cursor = 0;
-  dw_frame_t nested_scope = NULL;
-  xbt_dynar_foreach(scope->scopes, cursor, nested_scope) {
-    // The new scope may be an inlined subroutine, in this case we want to use its
-    // namespaced name in recursive calls:
-    dw_frame_t nested_subprogram = nested_scope->tag == DW_TAG_inlined_subroutine ? nested_scope : subprogram;
-
-    mc_ignore_local_variable_in_scope(var_name, subprogram_name, nested_subprogram, nested_scope);
-  }
-}
-
-static void MC_ignore_local_variable_in_object(const char *var_name, const char *subprogram_name, mc_object_info_t info) {
-  xbt_dict_cursor_t cursor2;
-  dw_frame_t frame;
-  char* key;
-  xbt_dict_foreach(info->subprograms, cursor2, key, frame) {
-    mc_ignore_local_variable_in_scope(var_name, subprogram_name, frame, frame);
-  }
-}
-
-void MC_ignore_local_variable(const char *var_name, const char *frame_name){
-  
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  if(strcmp(frame_name, "*") == 0)
-    frame_name = NULL;
-
-  MC_SET_RAW_MEM;
-
-  MC_ignore_local_variable_in_object(var_name, frame_name, mc_libsimgrid_info);
-  if(frame_name!=NULL)
-    MC_ignore_local_variable_in_object(var_name, frame_name, mc_binary_info);
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-
-}
-
-void MC_new_stack_area(void *stack, char *name, void* context, size_t size){
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+static void MC_init_dot_output()
+{                               /* FIXME : more colors */
 
-  MC_SET_RAW_MEM;
-
-  if(stacks_areas == NULL)
-    stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
-  
-  stack_region_t region = NULL;
-  region = xbt_new0(s_stack_region_t, 1);
-  region->address = stack;
-  region->process_name = strdup(name);
-  region->context = context;
-  region->size = size;
-  region->block = ((char*)stack - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
-  xbt_dynar_push(stacks_areas, &region);
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-}
+  colors[0] = "blue";
+  colors[1] = "red";
+  colors[2] = "green3";
+  colors[3] = "goldenrod";
+  colors[4] = "brown";
+  colors[5] = "purple";
+  colors[6] = "magenta";
+  colors[7] = "turquoise4";
+  colors[8] = "gray25";
+  colors[9] = "forestgreen";
+  colors[10] = "hotpink";
+  colors[11] = "lightblue";
+  colors[12] = "tan";
 
-void MC_ignore(void *addr, size_t size){
-
-  int raw_mem_set= (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  if(mc_checkpoint_ignore == NULL)
-    mc_checkpoint_ignore = xbt_dynar_new(sizeof(mc_checkpoint_ignore_region_t), checkpoint_ignore_region_free_voidp);
-
-  mc_checkpoint_ignore_region_t region = xbt_new0(s_mc_checkpoint_ignore_region_t, 1);
-  region->addr = addr;
-  region->size = size;
-
-  if(xbt_dynar_is_empty(mc_checkpoint_ignore)){
-    xbt_dynar_push(mc_checkpoint_ignore, &region);
-  }else{
-     
-    unsigned int cursor = 0;
-    int start = 0;
-    int end = xbt_dynar_length(mc_checkpoint_ignore) -1;
-    mc_checkpoint_ignore_region_t current_region = NULL;
-
-    while(start <= end){
-      cursor = (start + end) / 2;
-      current_region = (mc_checkpoint_ignore_region_t)xbt_dynar_get_as(mc_checkpoint_ignore, cursor, mc_checkpoint_ignore_region_t);
-      if(current_region->addr == addr){
-        if(current_region->size == size){
-          checkpoint_ignore_region_free(region);
-          if(!raw_mem_set)
-            MC_UNSET_RAW_MEM;
-          return;
-        }else if(current_region->size < size){
-          start = cursor + 1;
-        }else{
-          end = cursor - 1;
-        }
-      }else if(current_region->addr < addr){
-          start = cursor + 1;
-      }else{
-        end = cursor - 1;
-      }
-    }
+  dot_output = fopen(_sg_mc_dot_output_file, "w");
 
-     if(current_region->addr == addr){
-       if(current_region->size < size){
-        xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, &region);
-      }else{
-        xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, &region);
-      }
-    }else if(current_region->addr < addr){
-       xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, &region);
-    }else{
-       xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, &region);
-    }
+  if (dot_output == NULL) {
+    perror("Error open dot output file");
+    xbt_abort();
   }
 
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-}
-
-/*******************************  Initialisation of MC *******************************/
-/*********************************************************************************/
-
-static void MC_post_process_object_info(mc_object_info_t info) {
-  xbt_dict_cursor_t cursor = NULL;
-  char* key = NULL;
-  dw_type_t type = NULL;
-  xbt_dict_foreach(info->types, cursor, key, type){
-
-    // Resolve full_type:
-    if(type->name && type->byte_size == 0) {
-      for(size_t i=0; i!=mc_object_infos_size; ++i) {
-        dw_type_t same_type =  xbt_dict_get_or_null(mc_object_infos[i]->full_types_by_name, type->name);
-        if(same_type && same_type->name && same_type->byte_size) {
-          type->full_type = same_type;
-          break;
-        }
-      }
-    }
+  fprintf(dot_output,
+          "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.25; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n");
 
-  }
 }
 
-static void MC_init_debug_info(void) {
+static void MC_init_debug_info(void)
+{
   XBT_INFO("Get debug information ...");
 
   memory_map_t maps = MC_get_memory_map();
@@ -808,218 +237,214 @@ static void MC_init_debug_info(void) {
   XBT_INFO("Get debug information done !");
 }
 
-void MC_init(){
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+mc_model_checker_t mc_model_checker = NULL;
 
-  compare = 0;
+void MC_init()
+{
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  mc_time = xbt_new0(double, simix_process_maxpid);
 
   /* Initialize the data structures that must be persistent across every
      iteration of the model-checker (in RAW memory) */
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
-  MC_init_memory_map_info();
-  MC_init_debug_info();
-
-   /* Init parmap */
-  parmap = xbt_parmap_mc_new(xbt_os_get_numcores(), XBT_PARMAP_DEFAULT);
-
-  MC_UNSET_RAW_MEM;
-
-   /* Ignore some variables from xbt/ex.h used by exception e for stacks comparison */
-  MC_ignore_local_variable("e", "*");
-  MC_ignore_local_variable("__ex_cleanup", "*");
-  MC_ignore_local_variable("__ex_mctx_en", "*");
-  MC_ignore_local_variable("__ex_mctx_me", "*");
-  MC_ignore_local_variable("__xbt_ex_ctx_ptr", "*");
-  MC_ignore_local_variable("_log_ev", "*");
-  MC_ignore_local_variable("_throw_ctx", "*");
-  MC_ignore_local_variable("ctx", "*");
-
-  MC_ignore_local_variable("self", "simcall_BODY_mc_snapshot");
-  MC_ignore_local_variable("next_context", "smx_ctx_sysv_suspend_serial");
-  MC_ignore_local_variable("i", "smx_ctx_sysv_suspend_serial");
-
-  /* Ignore local variable about time used for tracing */
-  MC_ignore_local_variable("start_time", "*"); 
-
-  MC_ignore_global_variable("compared_pointers");
-  MC_ignore_global_variable("mc_comp_times");
-  MC_ignore_global_variable("mc_snapshot_comparison_time"); 
-  MC_ignore_global_variable("mc_time");
-  MC_ignore_global_variable("counter"); /* Static variable used for tracing */
-  MC_ignore_global_variable("maestro_stack_start");
-  MC_ignore_global_variable("maestro_stack_end");
-  MC_ignore_global_variable("smx_total_comms");
-
-  MC_ignore_heap(&(simix_global->process_to_run), sizeof(simix_global->process_to_run));
-  MC_ignore_heap(&(simix_global->process_that_ran), sizeof(simix_global->process_that_ran));
-  MC_ignore_heap(simix_global->process_to_run, sizeof(*(simix_global->process_to_run)));
-  MC_ignore_heap(simix_global->process_that_ran, sizeof(*(simix_global->process_that_ran)));
-  
-  smx_process_t process;
-  xbt_swag_foreach(process, simix_global->process_list){
-    MC_ignore_heap(&(process->process_hookup), sizeof(process->process_hookup));
-  }
+  mc_model_checker = xbt_new0(s_mc_model_checker_t, 1);
+  mc_model_checker->pages = mc_pages_store_new();
+  mc_model_checker->fd_clear_refs = -1;
+  mc_model_checker->fd_pagemap = -1;
 
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
+  mc_comp_times = xbt_new0(s_mc_comparison_times_t, 1);
 
-}
+  /* Initialize statistics */
+  mc_stats = xbt_new0(s_mc_stats_t, 1);
+  mc_stats->state_size = 1;
 
-static void MC_init_dot_output(){ /* FIXME : more colors */
+  MC_init_memory_map_info();
+  MC_init_debug_info();         /* FIXME : get debug information only if liveness verification or visited state reduction */
 
-  colors[0] = "blue";
-  colors[1] = "red";
-  colors[2] = "green3";
-  colors[3] = "goldenrod";
-  colors[4] = "brown";
-  colors[5] = "purple";
-  colors[6] = "magenta";
-  colors[7] = "turquoise4";
-  colors[8] = "gray25";
-  colors[9] = "forestgreen";
-  colors[10] = "hotpink";
-  colors[11] = "lightblue";
-  colors[12] = "tan";
+  if ((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0] != '\0'))
+    MC_init_dot_output();
 
-  dot_output = fopen(_sg_mc_dot_output_file, "w");
-  
-  if(dot_output == NULL){
-    perror("Error open dot output file");
-    xbt_abort();
+  /* Init parmap */
+  //parmap = xbt_parmap_mc_new(xbt_os_get_numcores(), XBT_PARMAP_DEFAULT);
+
+  MC_SET_STD_HEAP;
+
+  if (_sg_mc_visited > 0 || _sg_mc_liveness) {
+    /* Ignore some variables from xbt/ex.h used by exception e for stacks comparison */
+    MC_ignore_local_variable("e", "*");
+    MC_ignore_local_variable("__ex_cleanup", "*");
+    MC_ignore_local_variable("__ex_mctx_en", "*");
+    MC_ignore_local_variable("__ex_mctx_me", "*");
+    MC_ignore_local_variable("__xbt_ex_ctx_ptr", "*");
+    MC_ignore_local_variable("_log_ev", "*");
+    MC_ignore_local_variable("_throw_ctx", "*");
+    MC_ignore_local_variable("ctx", "*");
+
+    MC_ignore_local_variable("self", "simcall_BODY_mc_snapshot");
+    MC_ignore_local_variable("next_cont"
+      "ext", "smx_ctx_sysv_suspend_serial");
+    MC_ignore_local_variable("i", "smx_ctx_sysv_suspend_serial");
+
+    /* Ignore local variable about time used for tracing */
+    MC_ignore_local_variable("start_time", "*");
+
+    MC_ignore_global_variable("mc_model_checker");
+
+    // Mot of those things could be moved into mc_model_checker:
+    MC_ignore_global_variable("compared_pointers");
+    MC_ignore_global_variable("mc_comp_times");
+    MC_ignore_global_variable("mc_snapshot_comparison_time");
+    MC_ignore_global_variable("mc_time");
+    MC_ignore_global_variable("smpi_current_rank");
+    MC_ignore_global_variable("counter");       /* Static variable used for tracing */
+    MC_ignore_global_variable("maestro_stack_start");
+    MC_ignore_global_variable("maestro_stack_end");
+    MC_ignore_global_variable("smx_total_comms");
+    MC_ignore_global_variable("communications_pattern");
+    MC_ignore_global_variable("initial_communications_pattern");
+    MC_ignore_global_variable("incomplete_communications_pattern");
+
+    if (MC_is_active()) {
+      MC_ignore_global_variable("mc_diff_info");
+    }
+
+    MC_ignore_heap(mc_time, simix_process_maxpid * sizeof(double));
+
+    smx_process_t process;
+    xbt_swag_foreach(process, simix_global->process_list) {
+      MC_ignore_heap(&(process->process_hookup),
+                     sizeof(process->process_hookup));
+                     }
   }
 
-  fprintf(dot_output, "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.25; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n");
+  if (raw_mem_set)
+    MC_SET_MC_HEAP;
 
 }
 
 /*******************************  Core of MC *******************************/
 /**************************************************************************/
 
-void MC_do_the_modelcheck_for_real() {
+static void MC_modelcheck_comm_determinism_init(void)
+{
 
-  MC_SET_RAW_MEM;
-  mc_comp_times = xbt_new0(s_mc_comparison_times_t, 1);
-  MC_UNSET_RAW_MEM;
-  
-  if (!_sg_mc_property_file || _sg_mc_property_file[0]=='\0') {
-    if (mc_reduce_kind==e_mc_reduce_unset)
-      mc_reduce_kind=e_mc_reduce_dpor;
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-    XBT_INFO("Check a safety property");
-    MC_modelcheck_safety();
+  MC_init();
 
-  } else  {
+  if (!mc_mem_set)
+    MC_SET_MC_HEAP;
 
-    if (mc_reduce_kind==e_mc_reduce_unset)
-      mc_reduce_kind=e_mc_reduce_none;
+  /* Create exploration stack */
+  mc_stack = xbt_fifo_new();
 
-    XBT_INFO("Check the liveness property %s",_sg_mc_property_file);
-    MC_automaton_load(_sg_mc_property_file);
-    MC_modelcheck_liveness();
-  }
-}
+  MC_SET_STD_HEAP;
 
-void MC_modelcheck_safety(void)
-{
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  MC_pre_modelcheck_comm_determinism();
 
-  /* Check if MC is already initialized */
-  if (initial_state_safety)
-    return;
+  MC_SET_MC_HEAP;
+  initial_global_state = xbt_new0(s_mc_global_t, 1);
+  initial_global_state->snapshot = MC_take_snapshot(0);
+  initial_global_state->initial_communications_pattern_done = 0;
+  initial_global_state->comm_deterministic = 1;
+  initial_global_state->send_deterministic = 1;
+  MC_SET_STD_HEAP;
 
-  mc_time = xbt_new0(double, simix_process_maxpid);
+  MC_modelcheck_comm_determinism();
 
-  /* mc_time refers to clock for each process -> ignore it for heap comparison */  
-  MC_ignore_heap(mc_time, simix_process_maxpid * sizeof(double));
+  if(mc_mem_set)
+    MC_SET_MC_HEAP;
 
-  /* Initialize the data structures that must be persistent across every
-     iteration of the model-checker (in RAW memory) */
-  
-  MC_SET_RAW_MEM;
+}
 
-  /* Initialize statistics */
-  mc_stats = xbt_new0(s_mc_stats_t, 1);
-  mc_stats->state_size = 1;
+static void MC_modelcheck_safety_init(void)
+{
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  /* Create exploration stack */
-  mc_stack_safety = xbt_fifo_new();
+  _sg_mc_safety = 1;
 
-  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0'))
-    MC_init_dot_output();
+  MC_init();
 
-  MC_UNSET_RAW_MEM;
+  if (!mc_mem_set)
+    MC_SET_MC_HEAP;
 
-  if(_sg_mc_visited > 0){
-    MC_init();
-  }else{
-    MC_SET_RAW_MEM;
-    MC_init_memory_map_info();
-    MC_init_debug_info();
-    MC_UNSET_RAW_MEM;
-  }
+  /* Create exploration stack */
+  mc_stack = xbt_fifo_new();
+
+  MC_SET_STD_HEAP;
 
-  MC_dpor_init();
+  MC_pre_modelcheck_safety();
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
   /* Save the initial state */
-  initial_state_safety = xbt_new0(s_mc_global_t, 1);
-  initial_state_safety->snapshot = MC_take_snapshot(0);
-  initial_state_safety->initial_communications_pattern_done = 0;
-  initial_state_safety->comm_deterministic = 1;
-  initial_state_safety->send_deterministic = 1;
-  MC_UNSET_RAW_MEM;
+  initial_global_state = xbt_new0(s_mc_global_t, 1);
+  initial_global_state->snapshot = MC_take_snapshot(0);
+  MC_SET_STD_HEAP;
 
-  MC_dpor();
+  MC_modelcheck_safety();
 
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (mc_mem_set)
+    MC_SET_MC_HEAP;
 
   xbt_abort();
   //MC_exit();
 }
 
-void MC_modelcheck_liveness(){
+static void MC_modelcheck_liveness_init()
+{
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  MC_init();
+  _sg_mc_liveness = 1;
 
-  mc_time = xbt_new0(double, simix_process_maxpid);
+  MC_init();
 
-  /* mc_time refers to clock for each process -> ignore it for heap comparison */  
-  MC_ignore_heap(mc_time, simix_process_maxpid * sizeof(double));
-  MC_SET_RAW_MEM;
-  /* Initialize statistics */
-  mc_stats = xbt_new0(s_mc_stats_t, 1);
-  mc_stats->state_size = 1;
+  if (!mc_mem_set)
+    MC_SET_MC_HEAP;
 
   /* Create exploration stack */
-  mc_stack_liveness = xbt_fifo_new();
+  mc_stack = xbt_fifo_new();
 
   /* Create the initial state */
-  initial_state_liveness = xbt_new0(s_mc_global_t, 1);
+  initial_global_state = xbt_new0(s_mc_global_t, 1);
 
-  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0'))
-    MC_init_dot_output();
-  
-  MC_UNSET_RAW_MEM;
+  MC_SET_STD_HEAP;
 
-  MC_ddfs_init();
+  MC_pre_modelcheck_liveness();
 
   /* We're done */
   MC_print_statistics(mc_stats);
   xbt_free(mc_time);
 
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (mc_mem_set)
+    MC_SET_MC_HEAP;
 
 }
 
+void MC_do_the_modelcheck_for_real()
+{
+
+  if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
+    XBT_INFO("Check communication determinism");
+    MC_modelcheck_comm_determinism_init();
+  } else if (!_sg_mc_property_file || _sg_mc_property_file[0] == '\0') {
+    if (mc_reduce_kind == e_mc_reduce_unset)
+      mc_reduce_kind = e_mc_reduce_dpor;
+    XBT_INFO("Check a safety property");
+    MC_modelcheck_safety_init();
+  } else {
+    if (mc_reduce_kind == e_mc_reduce_unset)
+      mc_reduce_kind = e_mc_reduce_none;
+    XBT_INFO("Check the liveness property %s", _sg_mc_property_file);
+    MC_automaton_load(_sg_mc_property_file);
+    MC_modelcheck_liveness_init();
+  }
+}
+
 
 void MC_exit(void)
 {
@@ -1029,7 +454,8 @@ void MC_exit(void)
   //xbt_abort();
 }
 
-int SIMIX_pre_mc_random(smx_simcall_t simcall, int min, int max){
+int SIMIX_pre_mc_random(smx_simcall_t simcall, int min, int max)
+{
 
   return simcall->mc_value;
 }
@@ -1037,7 +463,7 @@ int SIMIX_pre_mc_random(smx_simcall_t simcall, int min, int max){
 
 int MC_random(int min, int max)
 {
-  /*FIXME: return mc_current_state->executed_transition->random.value;*/
+  /*FIXME: return mc_current_state->executed_transition->random.value; */
   return simcall_mc_random(min, max);
 }
 
@@ -1064,11 +490,11 @@ int MC_deadlock_check()
 {
   int deadlock = FALSE;
   smx_process_t process;
-  if(xbt_swag_size(simix_global->process_list)){
+  if (xbt_swag_size(simix_global->process_list)) {
     deadlock = TRUE;
-    xbt_swag_foreach(process, simix_global->process_list){
-      if(process->simcall.call != SIMCALL_NONE
-         && MC_request_is_enabled(&process->simcall)){
+    xbt_swag_foreach(process, simix_global->process_list) {
+      if (process->simcall.call != SIMCALL_NONE
+          && MC_request_is_enabled(&process->simcall)) {
         deadlock = FALSE;
         break;
       }
@@ -1085,55 +511,59 @@ int MC_deadlock_check()
  */
 void MC_replay(xbt_fifo_t stack, int start)
 {
-  int raw_mem = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem = (mmalloc_get_current_heap() == mc_heap);
 
-  int value, i = 1, count = 1;
+  int value, i = 1, count = 1, call = 0, j;
   char *req_str;
   smx_simcall_t req = NULL, saved_req = NULL;
   xbt_fifo_item_t item, start_item;
   mc_state_t state;
   smx_process_t process = NULL;
-  int comm_pattern = 0;
+  smx_action_t current_comm;
 
   XBT_DEBUG("**** Begin Replay ****");
 
-  if(start == -1){
+  if (start == -1) {
     /* Restore the initial state */
-    MC_restore_snapshot(initial_state_safety->snapshot);
+    MC_restore_snapshot(initial_global_state->snapshot);
     /* At the moment of taking the snapshot the raw heap was set, so restoring
      * it will set it back again, we have to unset it to continue  */
-    MC_UNSET_RAW_MEM;
+    MC_SET_STD_HEAP;
   }
 
   start_item = xbt_fifo_get_last_item(stack);
-  if(start != -1){
-    while (i != start){
+  if (start != -1) {
+    while (i != start) {
       start_item = xbt_fifo_get_prev_item(start_item);
       i++;
     }
   }
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
-  if(mc_reduce_kind ==  e_mc_reduce_dpor){
+  if (mc_reduce_kind == e_mc_reduce_dpor) {
     xbt_dict_reset(first_enabled_state);
-    xbt_swag_foreach(process, simix_global->process_list){
-      if(MC_process_is_enabled(process)){
-      char *key = bprintf("%lu", process->pid);
-      char *data = bprintf("%d", count);
-      xbt_dict_set(first_enabled_state, key, data, NULL);
-      xbt_free(key);
+    xbt_swag_foreach(process, simix_global->process_list) {
+      if (MC_process_is_enabled(process)) {
+        char *key = bprintf("%lu", process->pid);
+        char *data = bprintf("%d", count);
+        xbt_dict_set(first_enabled_state, key, data, NULL);
+        xbt_free(key);
       }
     }
   }
 
-  if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-    xbt_dynar_reset(communications_pattern);
-    xbt_dynar_reset(incomplete_communications_pattern);
+  if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
+    for (j=0; j<simix_process_maxpid; j++) {
+      xbt_dynar_reset((xbt_dynar_t)xbt_dynar_get_as(communications_pattern, j, xbt_dynar_t));
+    }
+    for (j=0; j<simix_process_maxpid; j++) {
+      xbt_dynar_reset((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, j, xbt_dynar_t));
+    }
   }
 
-  MC_UNSET_RAW_MEM;
-  
+  MC_SET_STD_HEAP;
+
 
   /* Traverse the stack from the state at position start and re-execute the transitions */
   for (item = start_item;
@@ -1142,66 +572,82 @@ void MC_replay(xbt_fifo_t stack, int start)
 
     state = (mc_state_t) xbt_fifo_get_item_content(item);
     saved_req = MC_state_get_executed_request(state, &value);
-   
-    if(mc_reduce_kind ==  e_mc_reduce_dpor){
-      MC_SET_RAW_MEM;
+
+    if (mc_reduce_kind == e_mc_reduce_dpor) {
+      MC_SET_MC_HEAP;
       char *key = bprintf("%lu", saved_req->issuer->pid);
-      xbt_dict_remove(first_enabled_state, key); 
+      xbt_dict_remove(first_enabled_state, key);
       xbt_free(key);
-      MC_UNSET_RAW_MEM;
+      MC_SET_STD_HEAP;
     }
-   
-    if(saved_req){
+
+    if (saved_req) {
       /* because we got a copy of the executed request, we have to fetch the  
          real one, pointed by the request field of the issuer process */
       req = &saved_req->issuer->simcall;
 
       /* Debug information */
-      if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
+      if (XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)) {
         req_str = MC_request_to_string(req, value);
         XBT_DEBUG("Replay: %s (%p)", req_str, state);
         xbt_free(req_str);
       }
-    }
-
-    if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-      if(req->call == SIMCALL_COMM_ISEND)
-        comm_pattern = 1;
-      else if(req->call == SIMCALL_COMM_IRECV)
-        comm_pattern = 2;
-    }
 
-    SIMIX_simcall_pre(req, value);
+      /* TODO : handle test and testany simcalls */
+      if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
+        if (req->call == SIMCALL_COMM_ISEND)
+          call = 1;
+        else if (req->call == SIMCALL_COMM_IRECV)
+          call = 2;
+        else if (req->call == SIMCALL_COMM_WAIT)
+          call = 3;
+        else if (req->call == SIMCALL_COMM_WAITANY)
+          call = 4;
+      }
 
-    if(_sg_mc_comms_determinism || _sg_mc_send_determinism){
-      MC_SET_RAW_MEM;
-      if(comm_pattern != 0){
-        get_comm_pattern(communications_pattern, req, comm_pattern);
+      SIMIX_simcall_pre(req, value);
+
+      if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
+        MC_SET_MC_HEAP;
+        if (call == 1) { /* Send */
+          get_comm_pattern(communications_pattern, req, call);
+        } else if (call == 2) { /* Recv */
+          get_comm_pattern(communications_pattern, req, call);
+        } else if (call == 3) { /* Wait */
+          current_comm = simcall_comm_wait__get__comm(req);
+          if (current_comm->comm.refcount == 1)  /* First wait only must be considered */
+            complete_comm_pattern(communications_pattern, current_comm);
+        } else if (call == 4) { /* WaitAny */
+          current_comm = xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), value, smx_action_t);
+          if (current_comm->comm.refcount == 1) /* First wait only must be considered */
+            complete_comm_pattern(communications_pattern, current_comm);
+        }
+        MC_SET_STD_HEAP;
+        call = 0;
       }
-      MC_UNSET_RAW_MEM;
-      comm_pattern = 0;
-    }
-    
-    MC_wait_for_requests();
-
-    count++;
-
-    if(mc_reduce_kind ==  e_mc_reduce_dpor){
-      MC_SET_RAW_MEM;
-      /* Insert in dict all enabled processes */
-      xbt_swag_foreach(process, simix_global->process_list){
-        if(MC_process_is_enabled(process) /*&& !MC_state_process_is_done(state, process)*/){
-          char *key = bprintf("%lu", process->pid);
-          if(xbt_dict_get_or_null(first_enabled_state, key) == NULL){
-            char *data = bprintf("%d", count);
-            xbt_dict_set(first_enabled_state, key, data, NULL);
+
+
+      MC_wait_for_requests();
+
+      count++;
+
+      if (mc_reduce_kind == e_mc_reduce_dpor) {
+        MC_SET_MC_HEAP;
+        /* Insert in dict all enabled processes */
+        xbt_swag_foreach(process, simix_global->process_list) {
+          if (MC_process_is_enabled(process) ) {
+            char *key = bprintf("%lu", process->pid);
+            if (xbt_dict_get_or_null(first_enabled_state, key) == NULL) {
+              char *data = bprintf("%d", count);
+              xbt_dict_set(first_enabled_state, key, data, NULL);
+            }
+            xbt_free(key);
           }
-          xbt_free(key);
         }
+        MC_SET_STD_HEAP;
       }
-      MC_UNSET_RAW_MEM;
     }
-         
+
     /* Update statistics */
     mc_stats->visited_states++;
     mc_stats->executed_transitions++;
@@ -1210,18 +656,18 @@ void MC_replay(xbt_fifo_t stack, int start)
 
   XBT_DEBUG("**** End Replay ****");
 
-  if(raw_mem)
-    MC_SET_RAW_MEM;
+  if (raw_mem)
+    MC_SET_MC_HEAP;
   else
-    MC_UNSET_RAW_MEM;
-  
+    MC_SET_STD_HEAP;
+
 
 }
 
 void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
 {
 
-  initial_state_liveness->raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  initial_global_state->raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
   int value;
   char *req_str;
@@ -1234,48 +680,48 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
   XBT_DEBUG("**** Begin Replay ****");
 
   /* Restore the initial state */
-  MC_restore_snapshot(initial_state_liveness->snapshot);
+  MC_restore_snapshot(initial_global_state->snapshot);
 
   /* At the moment of taking the snapshot the raw heap was set, so restoring
    * it will set it back again, we have to unset it to continue  */
-  if(!initial_state_liveness->raw_mem_set)
-    MC_UNSET_RAW_MEM;
+  if (!initial_global_state->raw_mem_set)
+    MC_SET_STD_HEAP;
 
-  if(all_stack){
+  if (all_stack) {
 
     item = xbt_fifo_get_last_item(stack);
 
-    while(depth <= xbt_fifo_size(stack)){
+    while (depth <= xbt_fifo_size(stack)) {
 
       pair = (mc_pair_t) xbt_fifo_get_item_content(item);
       state = (mc_state_t) pair->graph_state;
 
-      if(pair->requests > 0){
-   
+      if (pair->requests > 0) {
+
         saved_req = MC_state_get_executed_request(state, &value);
         //XBT_DEBUG("SavedReq->call %u", saved_req->call);
-      
-        if(saved_req != NULL){
+
+        if (saved_req != NULL) {
           /* because we got a copy of the executed request, we have to fetch the  
              real one, pointed by the request field of the issuer process */
           req = &saved_req->issuer->simcall;
           //XBT_DEBUG("Req->call %u", req->call);
-  
+
           /* Debug information */
-          if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
+          if (XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)) {
             req_str = MC_request_to_string(req, value);
             XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, req_str, state);
             xbt_free(req_str);
           }
-  
+
         }
+
         SIMIX_simcall_pre(req, value);
         MC_wait_for_requests();
       }
 
       depth++;
-    
+
       /* Update statistics */
       mc_stats->visited_pairs++;
       mc_stats->executed_transitions++;
@@ -1283,7 +729,7 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
       item = xbt_fifo_get_prev_item(item);
     }
 
-  }else{
+  } else {
 
     /* Traverse the stack from the initial state and re-execute the transitions */
     for (item = xbt_fifo_get_last_item(stack);
@@ -1293,45 +739,45 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
       pair = (mc_pair_t) xbt_fifo_get_item_content(item);
       state = (mc_state_t) pair->graph_state;
 
-      if(pair->requests > 0){
-   
+      if (pair->requests > 0) {
+
         saved_req = MC_state_get_executed_request(state, &value);
         //XBT_DEBUG("SavedReq->call %u", saved_req->call);
-      
-        if(saved_req != NULL){
+
+        if (saved_req != NULL) {
           /* because we got a copy of the executed request, we have to fetch the  
              real one, pointed by the request field of the issuer process */
           req = &saved_req->issuer->simcall;
           //XBT_DEBUG("Req->call %u", req->call);
-  
+
           /* Debug information */
-          if(XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)){
+          if (XBT_LOG_ISENABLED(mc_global, xbt_log_priority_debug)) {
             req_str = MC_request_to_string(req, value);
             XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, req_str, state);
             xbt_free(req_str);
           }
-  
+
         }
+
         SIMIX_simcall_pre(req, value);
         MC_wait_for_requests();
       }
 
       depth++;
-    
+
       /* Update statistics */
       mc_stats->visited_pairs++;
       mc_stats->executed_transitions++;
     }
-  }  
+  }
 
   XBT_DEBUG("**** End Replay ****");
 
-  if(initial_state_liveness->raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (initial_global_state->raw_mem_set)
+    MC_SET_MC_HEAP;
   else
-    MC_UNSET_RAW_MEM;
-  
+    MC_SET_STD_HEAP;
+
 }
 
 /**
@@ -1341,110 +787,112 @@ void MC_replay_liveness(xbt_fifo_t stack, int all_stack)
  */
 void MC_dump_stack_safety(xbt_fifo_t stack)
 {
-  
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
   MC_show_stack_safety(stack);
 
-  if(!_sg_mc_checkpoint){
+  if (!_sg_mc_checkpoint) {
 
     mc_state_t state;
 
-    MC_SET_RAW_MEM;
+    MC_SET_MC_HEAP;
     while ((state = (mc_state_t) xbt_fifo_pop(stack)) != NULL)
       MC_state_delete(state);
-    MC_UNSET_RAW_MEM;
+    MC_SET_STD_HEAP;
 
   }
 
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (raw_mem_set)
+    MC_SET_MC_HEAP;
   else
-    MC_UNSET_RAW_MEM;
-  
+    MC_SET_STD_HEAP;
+
 }
 
 
 void MC_show_stack_safety(xbt_fifo_t stack)
 {
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
   int value;
   mc_state_t state;
   xbt_fifo_item_t item;
   smx_simcall_t req;
   char *req_str = NULL;
-  
+
   for (item = xbt_fifo_get_last_item(stack);
        (item ? (state = (mc_state_t) (xbt_fifo_get_item_content(item)))
         : (NULL)); item = xbt_fifo_get_prev_item(item)) {
     req = MC_state_get_executed_request(state, &value);
-    if(req){
+    if (req) {
       req_str = MC_request_to_string(req, value);
       XBT_INFO("%s", req_str);
       xbt_free(req_str);
     }
   }
 
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
 }
 
 void MC_show_deadlock(smx_simcall_t req)
 {
-  /*char *req_str = NULL;*/
+  /*char *req_str = NULL; */
   XBT_INFO("**************************");
   XBT_INFO("*** DEAD-LOCK DETECTED ***");
   XBT_INFO("**************************");
   XBT_INFO("Locked request:");
   /*req_str = MC_request_to_string(req);
-    XBT_INFO("%s", req_str);
-    xbt_free(req_str);*/
+     XBT_INFO("%s", req_str);
+     xbt_free(req_str); */
   XBT_INFO("Counter-example execution trace:");
-  MC_dump_stack_safety(mc_stack_safety);
+  MC_dump_stack_safety(mc_stack);
   MC_print_statistics(mc_stats);
 }
 
 
-void MC_show_stack_liveness(xbt_fifo_t stack){
+void MC_show_stack_liveness(xbt_fifo_t stack)
+{
   int value;
   mc_pair_t pair;
   xbt_fifo_item_t item;
   smx_simcall_t req;
   char *req_str = NULL;
-  
+
   for (item = xbt_fifo_get_last_item(stack);
        (item ? (pair = (mc_pair_t) (xbt_fifo_get_item_content(item)))
         : (NULL)); item = xbt_fifo_get_prev_item(item)) {
     req = MC_state_get_executed_request(pair->graph_state, &value);
-    if(req){
-      if(pair->requests>0){
+    if (req) {
+      if (pair->requests > 0) {
         req_str = MC_request_to_string(req, value);
         XBT_INFO("%s", req_str);
         xbt_free(req_str);
-      }else{
+      } else {
         XBT_INFO("End of system requests but evolution in Büchi automaton");
       }
     }
   }
 }
 
-void MC_dump_stack_liveness(xbt_fifo_t stack){
+void MC_dump_stack_liveness(xbt_fifo_t stack)
+{
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
   mc_pair_t pair;
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
   while ((pair = (mc_pair_t) xbt_fifo_pop(stack)) != NULL)
     MC_pair_delete(pair);
-  MC_UNSET_RAW_MEM;
+  MC_SET_STD_HEAP;
 
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (raw_mem_set)
+    MC_SET_MC_HEAP;
 
 }
 
@@ -1453,43 +901,45 @@ void MC_print_statistics(mc_stats_t stats)
 {
   xbt_mheap_t previous_heap = mmalloc_get_current_heap();
 
-  if(stats->expanded_pairs == 0){
+  if (stats->expanded_pairs == 0) {
     XBT_INFO("Expanded states = %lu", stats->expanded_states);
     XBT_INFO("Visited states = %lu", stats->visited_states);
-  }else{
+  } else {
     XBT_INFO("Expanded pairs = %lu", stats->expanded_pairs);
     XBT_INFO("Visited pairs = %lu", stats->visited_pairs);
   }
   XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
-
-  MC_SET_RAW_MEM;
-  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0')){
+  MC_SET_MC_HEAP;
+  if ((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0] != '\0')) {
     fprintf(dot_output, "}\n");
     fclose(dot_output);
   }
-  if(initial_state_safety != NULL){
-    if(_sg_mc_comms_determinism)
-      XBT_INFO("Communication-deterministic : %s", !initial_state_safety->comm_deterministic ? "No" : "Yes");
+  if (initial_global_state != NULL) {
+    if (_sg_mc_comms_determinism)
+      XBT_INFO("Communication-deterministic : %s",
+               !initial_global_state->comm_deterministic ? "No" : "Yes");
     if (_sg_mc_send_determinism)
-      XBT_INFO("Send-deterministic : %s", !initial_state_safety->send_deterministic ? "No" : "Yes");
+      XBT_INFO("Send-deterministic : %s",
+               !initial_global_state->send_deterministic ? "No" : "Yes");
   }
   mmalloc_set_current_heap(previous_heap);
 }
 
 void MC_assert(int prop)
 {
-  if (MC_is_active() && !prop){
+  if (MC_is_active() && !prop) {
     XBT_INFO("**************************");
     XBT_INFO("*** PROPERTY NOT VALID ***");
     XBT_INFO("**************************");
     XBT_INFO("Counter-example execution trace:");
-    MC_dump_stack_safety(mc_stack_safety);
+    MC_dump_stack_safety(mc_stack);
     MC_print_statistics(mc_stats);
     xbt_abort();
   }
 }
 
-void MC_cut(void){
+void MC_cut(void)
+{
   user_max_depth_reached = 1;
 }
 
@@ -1500,51 +950,50 @@ void MC_process_clock_add(smx_process_t process, double amount)
 
 double MC_process_clock_get(smx_process_t process)
 {
-  if(mc_time){
-    if(process != NULL)
+  if (mc_time) {
+    if (process != NULL)
       return mc_time[process->pid];
-    else 
+    else
       return -1;
-  }else{
+  } else {
     return 0;
   }
 }
 
-void MC_automaton_load(const char *file){
+void MC_automaton_load(const char *file)
+{
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
   if (_mc_property_automaton == NULL)
     _mc_property_automaton = xbt_automaton_new();
-  
-  xbt_automaton_load(_mc_property_automaton,file);
 
-  MC_UNSET_RAW_MEM;
+  xbt_automaton_load(_mc_property_automaton, file);
+
+  MC_SET_STD_HEAP;
 
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (raw_mem_set)
+    MC_SET_MC_HEAP;
 
 }
 
-void MC_automaton_new_propositional_symbol(const char* id, void* fct) {
+void MC_automaton_new_propositional_symbol(const char *id, void *fct)
+{
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
   if (_mc_property_automaton == NULL)
     _mc_property_automaton = xbt_automaton_new();
 
-  xbt_automaton_propositional_symbol_new(_mc_property_automaton,id,fct);
-
-  MC_UNSET_RAW_MEM;
-
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
-  
-}
+  xbt_automaton_propositional_symbol_new(_mc_property_automaton, id, fct);
 
+  MC_SET_STD_HEAP;
 
+  if (raw_mem_set)
+    MC_SET_MC_HEAP;
 
+}
index c4ba6c6..3a96df8 100644 (file)
@@ -11,8 +11,7 @@
 #include "mc/datatypes.h"
 #include <mc/mc.h>
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_hash, mc,
-                                "Logging specific to mc_hash");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_hash, mc, "Logging specific to mc_hash");
 
 // This is djb2:
 typedef uint64_t mc_hash_t;
@@ -30,38 +29,42 @@ typedef struct s_mc_hashing_state {
   mc_address_set_t handled_addresses;
 } mc_hashing_state;
 
-void mc_hash_state_init(mc_hashing_state* state);
-void mc_hash_state_destroy(mc_hashing_state* state);
+void mc_hash_state_init(mc_hashing_state * state);
+void mc_hash_state_destroy(mc_hashing_state * state);
 
-void mc_hash_state_init(mc_hashing_state* state) {
+void mc_hash_state_init(mc_hashing_state * state)
+{
   state->handled_addresses = mc_address_set_new();
 }
 
-void mc_hash_state_destroy(mc_hashing_state* state) {
-   mc_address_set_free(&state->handled_addresses);
+void mc_hash_state_destroy(mc_hashing_state * state)
+{
+  mc_address_set_free(&state->handled_addresses);
 }
 
 // TODO, detect and avoid loops
 
-static bool mc_ignored(const void* address, size_t size) {
+static bool mc_ignored(const void *address, size_t size)
+{
   mc_heap_ignore_region_t region;
   unsigned int cursor = 0;
-  const void* end = (char*) address + size;
+  const void *end = (char *) address + size;
   xbt_dynar_foreach(mc_heap_comparison_ignore, cursor, region) {
-   void* istart = region->address;
-   void* iend   = (char*) region->address + region->size;
+    void *istart = region->address;
+    void *iend = (char *) region->address + region->size;
 
-   if(address>=istart && address<iend && end>=istart && end<iend)
-     return true;
+    if (address >= istart && address < iend && end >= istart && end < iend)
+      return true;
   }
 
   return false;
 }
 
-static void mc_hash_binary(mc_hash_t *hash, const void* s, size_t len) {
-  const char* p = (const void*) s;
+static void mc_hash_binary(mc_hash_t * hash, const void *s, size_t len)
+{
+  const char *p = (const void *) s;
   int i;
-  for(i=0; i!=len; ++i) {
+  for (i = 0; i != len; ++i) {
     MC_HASH(*hash, p[i]);
   }
 }
@@ -73,117 +76,122 @@ static void mc_hash_binary(mc_hash_t *hash, const void* s, size_t len) {
  *  \param address address of the variable
  *  \param type type of the variable
  * */
-static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_info_t info, const void* address, dw_type_t type) {
-  top:
+static void mc_hash_value(mc_hash_t * hash, mc_hashing_state * state,
+                          mc_object_info_t info, const void *address,
+                          dw_type_t type)
+{
+top:
 
-  switch(type->type){
+  switch (type->type) {
 
-  // Not relevant, do nothing:
+    // Not relevant, do nothing:
   case DW_TAG_unspecified_type:
     return;
 
-  // Simple case, hash this has binary:
+    // Simple case, hash this has binary:
   case DW_TAG_base_type:
   case DW_TAG_enumeration_type:
-  {
-    if(mc_ignored(address, 1))
+    {
+      if (mc_ignored(address, 1))
+        return;
+      mc_hash_binary(hash, address, type->byte_size);
       return;
-    mc_hash_binary(hash, address, type->byte_size);
-    return;
-  }
+    }
 
   case DW_TAG_array_type:
-  {
-    if(mc_ignored(address, type->byte_size))
-      return;
+    {
+      if (mc_ignored(address, type->byte_size))
+        return;
 
-    long element_count = type->element_count;
-    dw_type_t subtype = type->subtype;
-    if(subtype==NULL) {
-      XBT_DEBUG("Hash array without subtype");
+      long element_count = type->element_count;
+      dw_type_t subtype = type->subtype;
+      if (subtype == NULL) {
+        XBT_DEBUG("Hash array without subtype");
+        return;
+      }
+      int i;
+      for (i = 0; i != element_count; ++i) {
+        XBT_DEBUG("Hash array element %i", i);
+        void *subaddress = ((char *) address) + i * subtype->byte_size;
+        mc_hash_value(hash, state, info, subaddress, subtype);
+      }
       return;
     }
-    int i;
-    for(i=0; i!=element_count; ++i) {
-      XBT_DEBUG("Hash array element %i", i);
-      void* subaddress = ((char*)address)+i*subtype->byte_size;
-      mc_hash_value(hash, state, info, subaddress, subtype);
-    }
-    return;
-  }
 
-  // Get the raw type:
+    // Get the raw type:
   case DW_TAG_typedef:
   case DW_TAG_volatile_type:
   case DW_TAG_const_type:
   case DW_TAG_restrict_type:
-  {
-    type = type->subtype;
-    if(type==NULL)
-      return;
-    else
-      goto top;
-  }
+    {
+      type = type->subtype;
+      if (type == NULL)
+        return;
+      else
+        goto top;
+    }
 
   case DW_TAG_structure_type:
   case DW_TAG_class_type:
-  {
-    if(mc_ignored(address, type->byte_size))
-      return;
-
-    unsigned int cursor = 0;
-    dw_type_t member;
-    xbt_dynar_foreach(type->members, cursor, member){
-      XBT_DEBUG("Hash struct member %s", member->name);
-      if(type->subtype==NULL)
+    {
+      if (mc_ignored(address, type->byte_size))
         return;
-      void* member_variable = mc_member_resolve(address, type, member, NULL);
-      mc_hash_value(hash, state, info, member_variable, type->subtype);
+
+      unsigned int cursor = 0;
+      dw_type_t member;
+      xbt_dynar_foreach(type->members, cursor, member) {
+        XBT_DEBUG("Hash struct member %s", member->name);
+        if (type->subtype == NULL)
+          return;
+        void *member_variable = mc_member_resolve(address, type, member, NULL);
+        mc_hash_value(hash, state, info, member_variable, type->subtype);
+      }
+      return;
     }
-    return;
-  }
 
-  // Pointer, we hash a single value but it might be an array.
+    // Pointer, we hash a single value but it might be an array.
   case DW_TAG_pointer_type:
   case DW_TAG_reference_type:
   case DW_TAG_rvalue_reference_type:
-  {
-    if(mc_ignored(address, 1))
-      return;
+    {
+      if (mc_ignored(address, 1))
+        return;
 
-    void* pointed = *(void**)address;
-    if(pointed==NULL) {
-      XBT_DEBUG("Hashed pinter is NULL");
-      return;
-    }
+      void *pointed = *(void **) address;
+      if (pointed == NULL) {
+        XBT_DEBUG("Hashed pinter is NULL");
+        return;
+      }
+      // Avoid loops:
+      if (mc_address_test(state->handled_addresses, pointed)) {
+        XBT_DEBUG("Hashed pointed data %p already hashed", pointed);
+        return;
+      }
+      mc_address_add(state->handled_addresses, pointed);
+
+      // Anything outside the R/W segments and the heap is not hashed:
+      bool valid_pointer = (pointed >= (void *) mc_binary_info->start_rw
+                            && pointed <= (void *) mc_binary_info->end_rw)
+          || (pointed >= (void *) mc_libsimgrid_info->start_rw
+              && pointed <= (void *) mc_libsimgrid_info->end_rw)
+          || (pointed >= std_heap
+              && pointed < (void *) ((const char *) std_heap + STD_HEAP_SIZE));
+      if (!valid_pointer) {
+        XBT_DEBUG("Hashed pointed data %p is in an ignored range", pointed);
+        return;
+      }
 
-    // Avoid loops:
-    if(mc_address_test(state->handled_addresses, pointed)) {
-      XBT_DEBUG("Hashed pointed data %p already hashed", pointed);
-      return;
-    }
-    mc_address_add(state->handled_addresses, pointed);
-
-    // Anything outside the R/W segments and the heap is not hashed:
-    bool valid_pointer = (pointed >= (void*) mc_binary_info->start_rw && pointed <= (void*) mc_binary_info->end_rw)
-        || (pointed >= (void*) mc_libsimgrid_info->start_rw && pointed <= (void*) mc_libsimgrid_info->end_rw)
-        || (pointed >= std_heap && pointed < (void*) ((const char*)std_heap + STD_HEAP_SIZE));
-    if(!valid_pointer) {
-      XBT_DEBUG("Hashed pointed data %p is in an ignored range", pointed);
-      return;
-    }
+      if (type->subtype == NULL) {
+        XBT_DEBUG("Missing type for %p (type=%s)", pointed, type->dw_type_id);
+        return;
+      }
 
-    if(type->subtype==NULL) {
-      XBT_DEBUG("Missing type for %p (type=%s)", pointed, type->dw_type_id);
-      return;
+      address = pointed;
+      type = type->subtype;
+      goto top;
     }
 
-    address = pointed;
-    type = type->subtype;
-    goto top;
-  }
-
-  // Skip this:
+    // Skip this:
   case DW_TAG_union_type:
   case DW_TAG_subroutine_type:
   default:
@@ -192,60 +200,69 @@ static void mc_hash_value(mc_hash_t* hash, mc_hashing_state* state, mc_object_in
 }
 
 
-static void mc_hash_object_globals(mc_hash_t *hash, mc_hashing_state* state, mc_object_info_t info) {
+static void mc_hash_object_globals(mc_hash_t * hash, mc_hashing_state * state,
+                                   mc_object_info_t info)
+{
   unsigned int cursor = 0;
   dw_variable_t variable;
   xbt_dynar_foreach(info->global_variables, cursor, variable) {
     XBT_DEBUG("Hash global variable %s", variable->name);
 
-    if(variable->type_origin == NULL) {
+    if (variable->type_origin == NULL) {
       // Nothing
       continue;
     }
 
     dw_type_t type = variable->type;
-    if(type==NULL) {
+    if (type == NULL) {
       // Nothing
       continue;
     }
 
-    const char* address = variable->address;
-    bool valid_pointer = (address >= mc_binary_info->start_rw && address <= mc_binary_info->end_rw)
-        || (address >= mc_libsimgrid_info->start_rw && address <= mc_libsimgrid_info->end_rw)
-        || (address >= (const char*) std_heap && address < (const char *)std_heap + STD_HEAP_SIZE);
-    if(!valid_pointer) continue;
+    const char *address = variable->address;
+    bool valid_pointer = (address >= mc_binary_info->start_rw
+                          && address <= mc_binary_info->end_rw)
+        || (address >= mc_libsimgrid_info->start_rw
+            && address <= mc_libsimgrid_info->end_rw)
+        || (address >= (const char *) std_heap
+            && address < (const char *) std_heap + STD_HEAP_SIZE);
+    if (!valid_pointer)
+      continue;
 
     mc_hash_value(hash, state, info, variable->address, type);
   }
 }
 
-static void mc_hash_stack_frame(
-  mc_hash_t *hash,
-    mc_object_info_t info, unw_cursor_t* unw_cursor, dw_frame_t frame, char* frame_pointer, mc_hashing_state* state
-    ) {
+static void mc_hash_stack_frame(mc_hash_t * hash,
+                                mc_object_info_t info,
+                                unw_cursor_t * unw_cursor, dw_frame_t frame,
+                                char *frame_pointer, mc_hashing_state * state)
+{
 
   // return; // TEMP
 
   unsigned int cursor = 0;
   dw_variable_t variable;
-  xbt_dynar_foreach(frame->variables, cursor, variable){
+  xbt_dynar_foreach(frame->variables, cursor, variable) {
 
-    if(variable->type_origin==NULL) {
+    if (variable->type_origin == NULL) {
       XBT_DEBUG("Hash local variable %s without type", variable->name);
       continue;
     }
-    if(variable->locations.size == 0) {
+    if (variable->locations.size == 0) {
       XBT_DEBUG("Hash local variable %s without location", variable->name);
       continue;
     }
 
     XBT_DEBUG("Hash local variable %s", variable->name);
 
-    void* variable_address = (void*) mc_dwarf_resolve_locations(
-      &variable->locations, variable->object_info, unw_cursor, frame_pointer, NULL);
+    void *variable_address =
+        (void *) mc_dwarf_resolve_locations(&variable->locations,
+                                            variable->object_info, unw_cursor,
+                                            frame_pointer, NULL);
 
     dw_type_t type = variable->type;
-    if(type==NULL) {
+    if (type == NULL) {
       XBT_DEBUG("Hash local variable %s without loctypeation", variable->name);
       continue;
     }
@@ -256,7 +273,9 @@ static void mc_hash_stack_frame(
   // TODO, handle nested scopes
 }
 
-static void mc_hash_stack(mc_hash_t *hash, mc_snapshot_stack_t stack, mc_hashing_state* state) {
+static void mc_hash_stack(mc_hash_t * hash, mc_snapshot_stack_t stack,
+                          mc_hashing_state * state)
+{
 
   unsigned cursor = 0;
   mc_stack_frame_t stack_frame;
@@ -266,33 +285,40 @@ static void mc_hash_stack(mc_hash_t *hash, mc_snapshot_stack_t stack, mc_hashing
     MC_HASH(*hash, stack_frame->ip);
 
     mc_object_info_t info;
-    if(stack_frame->ip >= (unw_word_t) mc_libsimgrid_info->start_exec && stack_frame->ip < (unw_word_t) mc_libsimgrid_info->end_exec)
+    if (stack_frame->ip >= (unw_word_t) mc_libsimgrid_info->start_exec
+        && stack_frame->ip < (unw_word_t) mc_libsimgrid_info->end_exec)
       info = mc_libsimgrid_info;
-    else if(stack_frame->ip >= (unw_word_t) mc_binary_info->start_exec && stack_frame->ip < (unw_word_t) mc_binary_info->end_exec)
+    else if (stack_frame->ip >= (unw_word_t) mc_binary_info->start_exec
+             && stack_frame->ip < (unw_word_t) mc_binary_info->end_exec)
       info = mc_binary_info;
     else
       continue;
 
-    mc_hash_stack_frame(hash, info, &(stack_frame->unw_cursor), stack_frame->frame, (void*)stack_frame->frame_base, state);
+    mc_hash_stack_frame(hash, info, &(stack_frame->unw_cursor),
+                        stack_frame->frame, (void *) stack_frame->frame_base,
+                        state);
 
   }
 }
 
-static void mc_hash_stacks(mc_hash_t *hash, mc_hashing_state* state, xbt_dynar_t stacks) {
+static void mc_hash_stacks(mc_hash_t * hash, mc_hashing_state * state,
+                           xbt_dynar_t stacks)
+{
   unsigned int cursor = 0;
   mc_snapshot_stack_t current_stack;
 
   MC_HASH(*hash, xbt_dynar_length(stacks_areas));
 
-  int i=0;
-  xbt_dynar_foreach(stacks, cursor, current_stack){
+  int i = 0;
+  xbt_dynar_foreach(stacks, cursor, current_stack) {
     XBT_DEBUG("Stack %i", i);
     mc_hash_stack(hash, current_stack, state);
     ++i;
   }
 }
 
-uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks) {
+uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks)
+{
   XBT_DEBUG("START hash %i", num_state);
 
   mc_hashing_state state;
@@ -300,7 +326,7 @@ uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks) {
 
   mc_hash_t hash = MC_HASH_INIT;
 
-  MC_HASH(hash, xbt_swag_size(simix_global->process_list)); // process count
+  MC_HASH(hash, xbt_swag_size(simix_global->process_list));     // process count
   mc_hash_object_globals(&hash, &state, mc_binary_info);
   // mc_hash_object_globals(&hash, &state, mc_libsimgrid_info);
   mc_hash_stacks(&hash, &state, stacks);
diff --git a/src/mc/mc_ignore.c b/src/mc/mc_ignore.c
new file mode 100644 (file)
index 0000000..8fab43c
--- /dev/null
@@ -0,0 +1,392 @@
+/* Copyright (c) 2008-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "mc_private.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_ignore, mc,
+                                "Logging specific to MC ignore mechanism");
+
+
+/**************************** Global variables ******************************/
+xbt_dynar_t mc_checkpoint_ignore;
+extern xbt_dynar_t mc_heap_comparison_ignore;
+extern xbt_dynar_t stacks_areas;
+
+/**************************** Structures ******************************/
+typedef struct s_mc_stack_ignore_variable {
+  char *var_name;
+  char *frame;
+} s_mc_stack_ignore_variable_t, *mc_stack_ignore_variable_t;
+
+/**************************** Free functions ******************************/
+
+static void stack_ignore_variable_free(mc_stack_ignore_variable_t v)
+{
+  xbt_free(v->var_name);
+  xbt_free(v->frame);
+  xbt_free(v);
+}
+
+static void stack_ignore_variable_free_voidp(void *v)
+{
+  stack_ignore_variable_free((mc_stack_ignore_variable_t) * (void **) v);
+}
+
+void heap_ignore_region_free(mc_heap_ignore_region_t r)
+{
+  xbt_free(r);
+}
+
+void heap_ignore_region_free_voidp(void *r)
+{
+  heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
+}
+
+static void checkpoint_ignore_region_free(mc_checkpoint_ignore_region_t r)
+{
+  xbt_free(r);
+}
+
+static void checkpoint_ignore_region_free_voidp(void *r)
+{
+  checkpoint_ignore_region_free((mc_checkpoint_ignore_region_t) * (void **) r);
+}
+
+/***********************************************************************/
+
+void MC_ignore_heap(void *address, size_t size)
+{
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  mc_heap_ignore_region_t region = NULL;
+  region = xbt_new0(s_mc_heap_ignore_region_t, 1);
+  region->address = address;
+  region->size = size;
+
+  region->block =
+      ((char *) address -
+       (char *) ((xbt_mheap_t) std_heap)->heapbase) / BLOCKSIZE + 1;
+
+  if (((xbt_mheap_t) std_heap)->heapinfo[region->block].type == 0) {
+    region->fragment = -1;
+    ((xbt_mheap_t) std_heap)->heapinfo[region->block].busy_block.ignore++;
+  } else {
+    region->fragment =
+        ((uintptr_t) (ADDR2UINT(address) % (BLOCKSIZE))) >> ((xbt_mheap_t)
+                                                             std_heap)->
+        heapinfo[region->block].type;
+    ((xbt_mheap_t) std_heap)->heapinfo[region->block].busy_frag.ignore[region->
+                                                                       fragment]++;
+  }
+
+  if (mc_heap_comparison_ignore == NULL) {
+    mc_heap_comparison_ignore =
+        xbt_dynar_new(sizeof(mc_heap_ignore_region_t),
+                      heap_ignore_region_free_voidp);
+    xbt_dynar_push(mc_heap_comparison_ignore, &region);
+    if (!raw_mem_set)
+      MC_SET_STD_HEAP;
+    return;
+  }
+
+  unsigned int cursor = 0;
+  mc_heap_ignore_region_t current_region = NULL;
+  int start = 0;
+  int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
+
+  while (start <= end) {
+    cursor = (start + end) / 2;
+    current_region =
+        (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
+                                                   cursor,
+                                                   mc_heap_ignore_region_t);
+    if (current_region->address == address) {
+      heap_ignore_region_free(region);
+      if (!raw_mem_set)
+        MC_SET_STD_HEAP;
+      return;
+    } else if (current_region->address < address) {
+      start = cursor + 1;
+    } else {
+      end = cursor - 1;
+    }
+  }
+
+  if (current_region->address < address)
+    xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor + 1, &region);
+  else
+    xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, &region);
+
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
+}
+
+void MC_remove_ignore_heap(void *address, size_t size)
+{
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  unsigned int cursor = 0;
+  int start = 0;
+  int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
+  mc_heap_ignore_region_t region;
+  int ignore_found = 0;
+
+  while (start <= end) {
+    cursor = (start + end) / 2;
+    region =
+        (mc_heap_ignore_region_t) xbt_dynar_get_as(mc_heap_comparison_ignore,
+                                                   cursor,
+                                                   mc_heap_ignore_region_t);
+    if (region->address == address) {
+      ignore_found = 1;
+      break;
+    } else if (region->address < address) {
+      start = cursor + 1;
+    } else {
+      if ((char *) region->address <= ((char *) address + size)) {
+        ignore_found = 1;
+        break;
+      } else {
+        end = cursor - 1;
+      }
+    }
+  }
+
+  if (ignore_found == 1) {
+    xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
+    MC_remove_ignore_heap(address, size);
+  }
+
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
+
+}
+
+void MC_ignore_global_variable(const char *name)
+{
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  xbt_assert(mc_libsimgrid_info, "MC subsystem not initialized");
+
+  unsigned int cursor = 0;
+  dw_variable_t current_var;
+  int start = 0;
+  int end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
+
+  while (start <= end) {
+    cursor = (start + end) / 2;
+    current_var =
+        (dw_variable_t) xbt_dynar_get_as(mc_libsimgrid_info->global_variables,
+                                         cursor, dw_variable_t);
+    if (strcmp(current_var->name, name) == 0) {
+      xbt_dynar_remove_at(mc_libsimgrid_info->global_variables, cursor, NULL);
+      start = 0;
+      end = xbt_dynar_length(mc_libsimgrid_info->global_variables) - 1;
+    } else if (strcmp(current_var->name, name) < 0) {
+      start = cursor + 1;
+    } else {
+      end = cursor - 1;
+    }
+  }
+
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
+}
+
+/** \brief Ignore a local variable in a scope
+ *
+ *  Ignore all instances of variables with a given name in
+ *  any (possibly inlined) subprogram with a given namespaced
+ *  name.
+ *
+ *  \param var_name        Name of the local variable (or parameter to ignore)
+ *  \param subprogram_name Name of the subprogram fo ignore (NULL for any)
+ *  \param subprogram      (possibly inlined) Subprogram of the scope
+ *  \param scope           Current scope
+ */
+static void mc_ignore_local_variable_in_scope(const char *var_name,
+                                              const char *subprogram_name,
+                                              dw_frame_t subprogram,
+                                              dw_frame_t scope)
+{
+  // Processing of direct variables:
+
+  // If the current subprogram matche the given name:
+  if (subprogram_name == NULL || strcmp(subprogram_name, subprogram->name) == 0) {
+
+    // Try to find the variable and remove it:
+    int start = 0;
+    int end = xbt_dynar_length(scope->variables) - 1;
+
+    // Dichotomic search:
+    while (start <= end) {
+      int cursor = (start + end) / 2;
+      dw_variable_t current_var =
+          (dw_variable_t) xbt_dynar_get_as(scope->variables, cursor,
+                                           dw_variable_t);
+
+      int compare = strcmp(current_var->name, var_name);
+      if (compare == 0) {
+        // Variable found, remove it:
+        xbt_dynar_remove_at(scope->variables, cursor, NULL);
+
+        // and start again:
+        start = 0;
+        end = xbt_dynar_length(scope->variables) - 1;
+      } else if (compare < 0) {
+        start = cursor + 1;
+      } else {
+        end = cursor - 1;
+      }
+    }
+
+  }
+  // And recursive processing in nested scopes:
+  unsigned cursor = 0;
+  dw_frame_t nested_scope = NULL;
+  xbt_dynar_foreach(scope->scopes, cursor, nested_scope) {
+    // The new scope may be an inlined subroutine, in this case we want to use its
+    // namespaced name in recursive calls:
+    dw_frame_t nested_subprogram =
+        nested_scope->tag ==
+        DW_TAG_inlined_subroutine ? nested_scope : subprogram;
+
+    mc_ignore_local_variable_in_scope(var_name, subprogram_name,
+                                      nested_subprogram, nested_scope);
+  }
+}
+
+static void MC_ignore_local_variable_in_object(const char *var_name,
+                                               const char *subprogram_name,
+                                               mc_object_info_t info)
+{
+  xbt_dict_cursor_t cursor2;
+  dw_frame_t frame;
+  char *key;
+  xbt_dict_foreach(info->subprograms, cursor2, key, frame) {
+    mc_ignore_local_variable_in_scope(var_name, subprogram_name, frame, frame);
+  }
+}
+
+void MC_ignore_local_variable(const char *var_name, const char *frame_name)
+{
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  if (strcmp(frame_name, "*") == 0)
+    frame_name = NULL;
+
+  MC_SET_MC_HEAP;
+
+  MC_ignore_local_variable_in_object(var_name, frame_name, mc_libsimgrid_info);
+  if (frame_name != NULL)
+    MC_ignore_local_variable_in_object(var_name, frame_name, mc_binary_info);
+
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
+
+}
+
+void MC_new_stack_area(void *stack, char *name, void *context, size_t size)
+{
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  if (stacks_areas == NULL)
+    stacks_areas = xbt_dynar_new(sizeof(stack_region_t), NULL);
+
+  stack_region_t region = NULL;
+  region = xbt_new0(s_stack_region_t, 1);
+  region->address = stack;
+  region->process_name = strdup(name);
+  region->context = context;
+  region->size = size;
+  region->block =
+      ((char *) stack -
+       (char *) ((xbt_mheap_t) std_heap)->heapbase) / BLOCKSIZE + 1;
+  xbt_dynar_push(stacks_areas, &region);
+
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
+}
+
+void MC_ignore(void *addr, size_t size)
+{
+
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  if (mc_checkpoint_ignore == NULL)
+    mc_checkpoint_ignore =
+        xbt_dynar_new(sizeof(mc_checkpoint_ignore_region_t),
+                      checkpoint_ignore_region_free_voidp);
+
+  mc_checkpoint_ignore_region_t region =
+      xbt_new0(s_mc_checkpoint_ignore_region_t, 1);
+  region->addr = addr;
+  region->size = size;
+
+  if (xbt_dynar_is_empty(mc_checkpoint_ignore)) {
+    xbt_dynar_push(mc_checkpoint_ignore, &region);
+  } else {
+
+    unsigned int cursor = 0;
+    int start = 0;
+    int end = xbt_dynar_length(mc_checkpoint_ignore) - 1;
+    mc_checkpoint_ignore_region_t current_region = NULL;
+
+    while (start <= end) {
+      cursor = (start + end) / 2;
+      current_region =
+          (mc_checkpoint_ignore_region_t) xbt_dynar_get_as(mc_checkpoint_ignore,
+                                                           cursor,
+                                                           mc_checkpoint_ignore_region_t);
+      if (current_region->addr == addr) {
+        if (current_region->size == size) {
+          checkpoint_ignore_region_free(region);
+          if (!raw_mem_set)
+            MC_SET_STD_HEAP;
+          return;
+        } else if (current_region->size < size) {
+          start = cursor + 1;
+        } else {
+          end = cursor - 1;
+        }
+      } else if (current_region->addr < addr) {
+        start = cursor + 1;
+      } else {
+        end = cursor - 1;
+      }
+    }
+
+    if (current_region->addr == addr) {
+      if (current_region->size < size) {
+        xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, &region);
+      } else {
+        xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, &region);
+      }
+    } else if (current_region->addr < addr) {
+      xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, &region);
+    } else {
+      xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, &region);
+    }
+  }
+
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
+}
index 96e6513..4717fcd 100644 (file)
@@ -14,21 +14,21 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc,
 /********* Global variables *********/
 
 xbt_dynar_t acceptance_pairs;
-xbt_dynar_t visited_pairs;
 xbt_dynar_t successors;
 xbt_parmap_t parmap;
 
 /********* Static functions *********/
 
-static xbt_dynar_t get_atomic_propositions_values(){
+static xbt_dynar_t get_atomic_propositions_values()
+{
   int res;
   int_f_void_t f;
   unsigned int cursor = 0;
   xbt_automaton_propositional_symbol_t ps = NULL;
   xbt_dynar_t values = xbt_dynar_new(sizeof(int), NULL);
 
-  xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-    f = (int_f_void_t)ps->function;
+  xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps) {
+    f = (int_f_void_t) ps->function;
     res = f();
     xbt_dynar_push_as(values, int, res);
   }
@@ -36,79 +36,27 @@ static xbt_dynar_t get_atomic_propositions_values(){
   return values;
 }
 
-/** \brief Find a suitable subrange of candidate duplicates for a given state
- *
- *  See mc_dpor.c with a similar (same?) function.
- */
-static int get_search_interval(xbt_dynar_t all_pairs, mc_visited_pair_t pair, int *min, int *max){
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  int cursor = 0, previous_cursor, next_cursor;
-  mc_visited_pair_t pair_test;
-  int start = 0;
-  int end = xbt_dynar_length(all_pairs) - 1;
-  
-  while(start <= end){
-    cursor = (start + end) / 2;
-    pair_test = (mc_visited_pair_t)xbt_dynar_get_as(all_pairs, cursor, mc_visited_pair_t);
-    if(pair_test->nb_processes < pair->nb_processes){
-      start = cursor + 1;
-    }else if(pair_test->nb_processes > pair->nb_processes){
-      end = cursor - 1;
-    }else{
-      if(pair_test->heap_bytes_used < pair->heap_bytes_used){
-        start = cursor +1;
-      }else if(pair_test->heap_bytes_used > pair->heap_bytes_used){
-        end = cursor - 1;
-      }else{
-        *min = *max = cursor;
-        previous_cursor = cursor - 1;
-        while(previous_cursor >= 0){
-          pair_test = (mc_visited_pair_t)xbt_dynar_get_as(all_pairs, previous_cursor, mc_visited_pair_t);
-          if(pair_test->nb_processes != pair->nb_processes || pair_test->heap_bytes_used != pair->heap_bytes_used)
-            break;
-          *min = previous_cursor;
-          previous_cursor--;
-        }
-        next_cursor = cursor + 1;
-        while(next_cursor < xbt_dynar_length(all_pairs)){
-          pair_test = (mc_visited_pair_t)xbt_dynar_get_as(all_pairs, next_cursor, mc_visited_pair_t);
-          if(pair_test->nb_processes != pair->nb_processes || pair_test->heap_bytes_used != pair->heap_bytes_used)
-            break;
-          *max = next_cursor;
-          next_cursor++;
-        }
-        if(!raw_mem_set)
-          MC_UNSET_RAW_MEM;
-        return -1;
-      }
-     }
-  }
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
 
-  return cursor;
-}
+static mc_visited_pair_t is_reached_acceptance_pair(int pair_num,
+                                                    xbt_automaton_state_t
+                                                    automaton_state,
+                                                    xbt_dynar_t
+                                                    atomic_propositions)
+{
 
-static mc_visited_pair_t is_reached_acceptance_pair(int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions){
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  MC_SET_MC_HEAP;
 
-  MC_SET_RAW_MEM;
-  
   mc_visited_pair_t pair = NULL;
   pair = MC_visited_pair_new(pair_num, automaton_state, atomic_propositions);
   pair->acceptance_pair = 1;
-  
-  if(xbt_dynar_is_empty(acceptance_pairs)){
 
-    xbt_dynar_push(acceptance_pairs, &pair); 
+  if (xbt_dynar_is_empty(acceptance_pairs)) {
 
-  }else{
+    xbt_dynar_push(acceptance_pairs, &pair);
+
+  } else {
 
     int min = -1, max = -1, index;
     //int res;
@@ -117,30 +65,38 @@ static mc_visited_pair_t is_reached_acceptance_pair(int pair_num, xbt_automaton_
 
     index = get_search_interval(acceptance_pairs, pair, &min, &max);
 
-    if(min != -1 && max != -1){ // Acceptance pair with same number of processes and same heap bytes used exists
+    if (min != -1 && max != -1) {       // Acceptance pair with same number of processes and same heap bytes used exists
 
       // Parallell implementation
       /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(acceptance_pairs, min), (max-min)+1, pair);
-      if(res != -1){
-        if(!raw_mem_set)
-          MC_UNSET_RAW_MEM;
-        return ((mc_pair_t)xbt_dynar_get_as(acceptance_pairs, (min+res)-1, mc_pair_t))->num;
-        }*/
+         if(res != -1){
+         if(!raw_mem_set)
+         MC_SET_STD_HEAP;
+         return ((mc_pair_t)xbt_dynar_get_as(acceptance_pairs, (min+res)-1, mc_pair_t))->num;
+         } */
 
       cursor = min;
-      while(cursor <= max){
-        pair_test = (mc_visited_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_visited_pair_t);
-        if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
-          if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
-            if(snapshot_compare(pair_test, pair) == 0){
-              XBT_INFO("Pair %d already reached (equal to pair %d) !", pair->num, pair_test->num);
-              
-              xbt_fifo_shift(mc_stack_liveness);
-              if(dot_output != NULL)
-                fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_state_liveness->prev_pair, pair_test->num, initial_state_liveness->prev_req);
-
-              if(!raw_mem_set)
-                MC_UNSET_RAW_MEM;
+      while (cursor <= max) {
+        pair_test =
+            (mc_visited_pair_t) xbt_dynar_get_as(acceptance_pairs, cursor,
+                                                 mc_visited_pair_t);
+        if (xbt_automaton_state_compare
+            (pair_test->automaton_state, pair->automaton_state) == 0) {
+          if (xbt_automaton_propositional_symbols_compare_value
+              (pair_test->atomic_propositions,
+               pair->atomic_propositions) == 0) {
+            if (snapshot_compare(pair_test, pair) == 0) {
+              XBT_INFO("Pair %d already reached (equal to pair %d) !",
+                       pair->num, pair_test->num);
+
+              xbt_fifo_shift(mc_stack);
+              if (dot_output != NULL)
+                fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n",
+                        initial_global_state->prev_pair, pair_test->num,
+                        initial_global_state->prev_req);
+
+              if (!raw_mem_set)
+                MC_SET_STD_HEAP;
 
               return NULL;
             }
@@ -149,317 +105,195 @@ static mc_visited_pair_t is_reached_acceptance_pair(int pair_num, xbt_automaton_
         cursor++;
       }
       xbt_dynar_insert_at(acceptance_pairs, min, &pair);
-    }else{
-      pair_test = (mc_visited_pair_t)xbt_dynar_get_as(acceptance_pairs, index, mc_visited_pair_t);
-      if(pair_test->nb_processes < pair->nb_processes){
-        xbt_dynar_insert_at(acceptance_pairs, index+1, &pair);
-      }else{
-        if(pair_test->heap_bytes_used < pair->heap_bytes_used)
+    } else {
+      pair_test =
+          (mc_visited_pair_t) xbt_dynar_get_as(acceptance_pairs, index,
+                                               mc_visited_pair_t);
+      if (pair_test->nb_processes < pair->nb_processes) {
+        xbt_dynar_insert_at(acceptance_pairs, index + 1, &pair);
+      } else {
+        if (pair_test->heap_bytes_used < pair->heap_bytes_used)
           xbt_dynar_insert_at(acceptance_pairs, index + 1, &pair);
         else
           xbt_dynar_insert_at(acceptance_pairs, index, &pair);
       }
     }
-    
+
   }
 
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
 
   return pair;
+
 }
 
-static void remove_acceptance_pair(int pair_num){
+static void remove_acceptance_pair(int pair_num)
+{
 
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+  int raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
   unsigned int cursor = 0;
   mc_visited_pair_t pair_test = NULL;
 
-  xbt_dynar_foreach(acceptance_pairs, cursor, pair_test){
-    if(pair_test->num == pair_num){
+  xbt_dynar_foreach(acceptance_pairs, cursor, pair_test) {
+    if (pair_test->num == pair_num) {
       break;
     }
   }
 
   xbt_dynar_remove_at(acceptance_pairs, cursor, &pair_test);
-  
+
   pair_test->acceptance_removed = 1;
 
-  if(_sg_mc_visited == 0){
+  if (_sg_mc_visited == 0) {
     MC_visited_pair_delete(pair_test);
-  }else if(pair_test->visited_removed == 1){
+  } else if (pair_test->visited_removed == 1) {
     MC_visited_pair_delete(pair_test);
   }
 
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
+  if (!raw_mem_set)
+    MC_SET_STD_HEAP;
 }
 
-/** \brief Checks whether a given state has already been visited by the algorithm.
- *
- */
-static int is_visited_pair(mc_visited_pair_t pair, int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions){
-
-  if(_sg_mc_visited == 0)
-    return -1;
-
-  int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  MC_SET_RAW_MEM;
-
-  mc_visited_pair_t new_pair = NULL;
-
-  if(pair == NULL){
-    new_pair = MC_visited_pair_new(pair_num, automaton_state, atomic_propositions);
-  }else{
-    new_pair = pair;
-  }
-
-  if(xbt_dynar_is_empty(visited_pairs)){
-
-    xbt_dynar_push(visited_pairs, &new_pair); 
-
-  }else{
-
-    int min = -1, max = -1, index;
-    //int res;
-    mc_visited_pair_t pair_test;
-    int cursor;
 
-    index = get_search_interval(visited_pairs, new_pair, &min, &max);
+static int MC_automaton_evaluate_label(xbt_automaton_exp_label_t l,
+                                       xbt_dynar_t atomic_propositions_values)
+{
 
-    if(min != -1 && max != -1){ // Visited pair with same number of processes and same heap bytes used exists
-      /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_pairs, min), (max-min)+1, pair);
-      if(res != -1){
-        pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, (min+res)-1, mc_pair_t);
-        if(pair_test->other_num == -1)
-          pair->other_num = pair_test->num;
-        else
-          pair->other_num = pair_test->other_num;
-        if(dot_output == NULL)
-          XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
-        else
-          XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
-        xbt_dynar_remove_at(visited_pairs, (min + res) - 1, NULL);
-        xbt_dynar_insert_at(visited_pairs, (min+res) - 1, &pair);
-        pair_test->visited_removed = 1;
-        if(pair_test->stack_removed && pair_test->visited_removed){
-          if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
-            if(pair_test->acceptance_removed){
-              MC_pair_delete(pair_test);
-            }
-          }else{
-            MC_pair_delete(pair_test);
-          }
-        }
-        if(!raw_mem_set)
-          MC_UNSET_RAW_MEM;
-        return pair->other_num;
-        }*/
-      cursor = min;
-      while(cursor <= max){
-        pair_test = (mc_visited_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_visited_pair_t);
-        //if(pair_test->acceptance_pair == 0){ /* Acceptance pair have been already checked before */
-          if(xbt_automaton_state_compare(pair_test->automaton_state, new_pair->automaton_state) == 0){
-            if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, new_pair->atomic_propositions) == 0){
-              if(snapshot_compare(pair_test, new_pair) == 0){
-                if(pair_test->other_num == -1)
-                  new_pair->other_num = pair_test->num;
-                else
-                  new_pair->other_num = pair_test->other_num;
-                if(dot_output == NULL)
-                  XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", new_pair->num, pair_test->num);
-                else
-                  XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", new_pair->num, pair_test->num, new_pair->other_num);
-                xbt_dynar_remove_at(visited_pairs, cursor, NULL);
-                xbt_dynar_insert_at(visited_pairs, cursor, &new_pair);
-                pair_test->visited_removed = 1;
-                if(pair_test->acceptance_pair){
-                  if(pair_test->acceptance_removed == 1)
-                    MC_visited_pair_delete(pair_test);
-                }else{
-                  MC_visited_pair_delete(pair_test);
-                }
-                if(!raw_mem_set)
-                  MC_UNSET_RAW_MEM;
-                return new_pair->other_num;
-              }
-            }
-            //}
-        }
-        cursor++;
-      }
-      xbt_dynar_insert_at(visited_pairs, min, &new_pair);
-    }else{
-      pair_test = (mc_visited_pair_t)xbt_dynar_get_as(visited_pairs, index, mc_visited_pair_t);
-      if(pair_test->nb_processes < new_pair->nb_processes){
-        xbt_dynar_insert_at(visited_pairs, index+1, &new_pair);
-      }else{
-        if(pair_test->heap_bytes_used < new_pair->heap_bytes_used)
-          xbt_dynar_insert_at(visited_pairs, index + 1, &new_pair);
-        else
-          xbt_dynar_insert_at(visited_pairs, index, &new_pair);
-      }
+  switch (l->type) {
+  case 0:{
+      int left_res =
+          MC_automaton_evaluate_label(l->u.or_and.left_exp,
+                                      atomic_propositions_values);
+      int right_res =
+          MC_automaton_evaluate_label(l->u.or_and.right_exp,
+                                      atomic_propositions_values);
+      return (left_res || right_res);
     }
-
-    if(xbt_dynar_length(visited_pairs) > _sg_mc_visited){
-      int min2 = mc_stats->expanded_pairs;
-      unsigned int cursor2 = 0;
-      unsigned int index2 = 0;
-      xbt_dynar_foreach(visited_pairs, cursor2, pair_test){
-        if(pair_test->num < min2){
-          index2 = cursor2;
-          min2 = pair_test->num;
-        }
-      }
-      xbt_dynar_remove_at(visited_pairs, index2, &pair_test);
-      pair_test->visited_removed = 1;
-      if(pair_test->acceptance_pair){
-        if(pair_test->acceptance_removed)
-          MC_visited_pair_delete(pair_test);
-      }else{
-        MC_visited_pair_delete(pair_test);
+  case 1:{
+      int left_res =
+          MC_automaton_evaluate_label(l->u.or_and.left_exp,
+                                      atomic_propositions_values);
+      int right_res =
+          MC_automaton_evaluate_label(l->u.or_and.right_exp,
+                                      atomic_propositions_values);
+      return (left_res && right_res);
+    }
+  case 2:{
+      int res =
+          MC_automaton_evaluate_label(l->u.exp_not, atomic_propositions_values);
+      return (!res);
+    }
+  case 3:{
+      unsigned int cursor = 0;
+      xbt_automaton_propositional_symbol_t p = NULL;
+      xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor,
+                        p) {
+        if (strcmp(p->pred, l->u.predicat) == 0)
+          return (int) xbt_dynar_get_as(atomic_propositions_values, cursor,
+                                        int);
       }
+      return -1;
     }
-
-  }
-
-  if(!raw_mem_set)
-    MC_UNSET_RAW_MEM;
-  
-  return -1;
-}
-
-static int MC_automaton_evaluate_label(xbt_automaton_exp_label_t l, xbt_dynar_t atomic_propositions_values){
-  
-  switch(l->type){
-  case 0 : {
-    int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp, atomic_propositions_values);
-    int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp, atomic_propositions_values);
-    return (left_res || right_res);
-  }
-  case 1 : {
-    int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp, atomic_propositions_values);
-    int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp, atomic_propositions_values);
-    return (left_res && right_res);
-  }
-  case 2 : {
-    int res = MC_automaton_evaluate_label(l->u.exp_not, atomic_propositions_values);
-    return (!res);
-  }
-  case 3 : { 
-    unsigned int cursor = 0;
-    xbt_automaton_propositional_symbol_t p = NULL;
-    xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, p){
-      if(strcmp(p->pred, l->u.predicat) == 0)
-        return (int)xbt_dynar_get_as(atomic_propositions_values, cursor, int);
+  case 4:{
+      return 2;
     }
-    return -1;
-  }
-  case 4 : {
-    return 2;
-  }
-  default : 
+  default:
     return -1;
   }
 }
 
+void MC_pre_modelcheck_liveness(void)
+{
 
-/********* DDFS Algorithm *********/
-
-
-void MC_ddfs_init(void){
-
-  initial_state_liveness->raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  XBT_DEBUG("**************************************************");
-  XBT_DEBUG("Double-DFS init");
-  XBT_DEBUG("**************************************************");
+  initial_global_state->raw_mem_set = (mmalloc_get_current_heap() == mc_heap);
 
   mc_pair_t initial_pair = NULL;
-  smx_process_t process; 
+  smx_process_t process;
 
   MC_wait_for_requests();
 
-  MC_ignore_heap(simix_global->process_to_run->data, 0);
-  MC_ignore_heap(simix_global->process_that_ran->data, 0);
-
-  MC_SET_RAW_MEM;
+  MC_SET_MC_HEAP;
 
-  acceptance_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), NULL); 
-  visited_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), NULL); 
+  acceptance_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), NULL);
+  visited_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), NULL);
   successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
 
-  initial_state_liveness->snapshot = MC_take_snapshot(0);
-  initial_state_liveness->prev_pair = 0;
+  initial_global_state->snapshot = MC_take_snapshot(0);
+  initial_global_state->prev_pair = 0;
+
+  MC_SET_STD_HEAP;
 
-  MC_UNSET_RAW_MEM; 
-  
   unsigned int cursor = 0;
   xbt_automaton_state_t automaton_state;
 
-  xbt_dynar_foreach(_mc_property_automaton->states, cursor, automaton_state){
-    if(automaton_state->type == -1){ /* Initial automaton state */
-      
-      MC_SET_RAW_MEM;
+  xbt_dynar_foreach(_mc_property_automaton->states, cursor, automaton_state) {
+    if (automaton_state->type == -1) {  /* Initial automaton state */
+
+      MC_SET_MC_HEAP;
 
       initial_pair = MC_pair_new();
       initial_pair->automaton_state = automaton_state;
       initial_pair->graph_state = MC_state_new();
       initial_pair->atomic_propositions = get_atomic_propositions_values();
 
-      /* Get enabled process and insert it in the interleave set of the graph_state */
-      xbt_swag_foreach(process, simix_global->process_list){
-        if(MC_process_is_enabled(process)){
+      /* Get enabled processes and insert them in the interleave set of the graph_state */
+      xbt_swag_foreach(process, simix_global->process_list) {
+        if (MC_process_is_enabled(process)) {
           MC_state_interleave_process(initial_pair->graph_state, process);
         }
       }
 
-      initial_pair->requests = MC_state_interleave_size(initial_pair->graph_state);
+      initial_pair->requests =
+          MC_state_interleave_size(initial_pair->graph_state);
       initial_pair->search_cycle = 0;
 
-      xbt_fifo_unshift(mc_stack_liveness, initial_pair);
+      xbt_fifo_unshift(mc_stack, initial_pair);
+
+      MC_SET_STD_HEAP;
 
-      MC_UNSET_RAW_MEM;
-      
-      MC_ddfs();
-      
-      if(cursor != 0){
-        MC_restore_snapshot(initial_state_liveness->snapshot);
-        MC_UNSET_RAW_MEM;
-      } 
+      MC_modelcheck_liveness();
+
+      if (cursor != 0) {
+        MC_restore_snapshot(initial_global_state->snapshot);
+        MC_SET_STD_HEAP;
+      }
     }
   }
 
-  if(initial_state_liveness->raw_mem_set)
-    MC_SET_RAW_MEM;
+  if (initial_global_state->raw_mem_set)
+    MC_SET_MC_HEAP;
   else
-    MC_UNSET_RAW_MEM;
-  
+    MC_SET_STD_HEAP;
+
 
 }
 
 
-void MC_ddfs(){
+void MC_modelcheck_liveness()
+{
 
   smx_process_t process;
   mc_pair_t current_pair = NULL;
 
-  if(xbt_fifo_size(mc_stack_liveness) == 0)
+  if (xbt_fifo_size(mc_stack) == 0)
     return;
 
   /* Get current pair */
-  current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness));
+  current_pair =
+      (mc_pair_t) xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack));
 
   /* Update current state in buchi automaton */
   _mc_property_automaton->current_state = current_pair->automaton_state;
 
-  XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d, interleave size %d, pair_num %d)", xbt_fifo_size(mc_stack_liveness), current_pair->search_cycle, MC_state_interleave_size(current_pair->graph_state), current_pair->num);
+  XBT_DEBUG
+      ("********************* ( Depth = %d, search_cycle = %d, interleave size %d, pair_num %d)",
+       xbt_fifo_size(mc_stack), current_pair->search_cycle,
+       MC_state_interleave_size(current_pair->graph_state), current_pair->num);
+
   mc_stats->visited_pairs++;
 
   int value;
@@ -475,23 +309,28 @@ void MC_ddfs(){
   xbt_dynar_t prop_values = NULL;
   mc_visited_pair_t reached_pair = NULL;
   int counter_example_depth = 0;
-  
-  if(xbt_fifo_size(mc_stack_liveness) < _sg_mc_max_depth){
 
-    if(current_pair->requests > 0){
+  if (xbt_fifo_size(mc_stack) < _sg_mc_max_depth) {
+
+    if (current_pair->requests > 0) {
 
-      if(current_pair->search_cycle){
+      if (current_pair->search_cycle) {
 
-        if((current_pair->automaton_state->type == 1) || (current_pair->automaton_state->type == 2)){ 
-          if((reached_pair = is_reached_acceptance_pair(current_pair->num, current_pair->automaton_state, current_pair->atomic_propositions)) == NULL){
+        if ((current_pair->automaton_state->type == 1)
+            || (current_pair->automaton_state->type == 2)) {
+          if ((reached_pair =
+               is_reached_acceptance_pair(current_pair->num,
+                                          current_pair->automaton_state,
+                                          current_pair->atomic_propositions)) ==
+              NULL) {
 
-            counter_example_depth = xbt_fifo_size(mc_stack_liveness);
+            counter_example_depth = xbt_fifo_size(mc_stack);
             XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
             XBT_INFO("|             ACCEPTANCE CYCLE            |");
             XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
             XBT_INFO("Counter-example that violates formula :");
-            MC_show_stack_liveness(mc_stack_liveness);
-            MC_dump_stack_liveness(mc_stack_liveness);
+            MC_show_stack_liveness(mc_stack);
+            MC_dump_stack_liveness(mc_stack);
             MC_print_statistics(mc_stats);
             XBT_INFO("Counter-example depth : %d", counter_example_depth);
             xbt_abort();
@@ -500,184 +339,213 @@ void MC_ddfs(){
         }
       }
 
-      if((visited_num = is_visited_pair(reached_pair, current_pair->num, current_pair->automaton_state, current_pair->atomic_propositions)) != -1){
-
-        MC_SET_RAW_MEM;
-        if(dot_output != NULL)
-          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_state_liveness->prev_pair, visited_num, initial_state_liveness->prev_req);
-        MC_UNSET_RAW_MEM;
-              
-      }else{  
-
-        while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
-
-          MC_SET_RAW_MEM;
-          if(dot_output != NULL){
-            if(initial_state_liveness->prev_pair != 0 && initial_state_liveness->prev_pair != current_pair->num){
-              fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_state_liveness->prev_pair, current_pair->num, initial_state_liveness->prev_req);
-              xbt_free(initial_state_liveness->prev_req);
+      if ((visited_num =
+           is_visited_pair(reached_pair, current_pair->num,
+                           current_pair->automaton_state,
+                           current_pair->atomic_propositions)) != -1) {
+
+        MC_SET_MC_HEAP;
+        if (dot_output != NULL)
+          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n",
+                  initial_global_state->prev_pair, visited_num,
+                  initial_global_state->prev_req);
+        MC_SET_STD_HEAP;
+
+      } else {
+
+        while ((req =
+                MC_state_get_request(current_pair->graph_state,
+                                     &value)) != NULL) {
+
+          MC_SET_MC_HEAP;
+          if (dot_output != NULL) {
+            if (initial_global_state->prev_pair != 0
+                && initial_global_state->prev_pair != current_pair->num) {
+              fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n",
+                      initial_global_state->prev_pair, current_pair->num,
+                      initial_global_state->prev_req);
+              xbt_free(initial_global_state->prev_req);
             }
-            initial_state_liveness->prev_pair = current_pair->num;
+            initial_global_state->prev_pair = current_pair->num;
           }
-          MC_UNSET_RAW_MEM;
+          MC_SET_STD_HEAP;
 
           /* Debug information */
-          if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
+          if (XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)) {
             req_str = MC_request_to_string(req, value);
             XBT_DEBUG("Execute: %s", req_str);
             xbt_free(req_str);
           }
 
-          MC_SET_RAW_MEM;
-          if(dot_output != NULL){
-            initial_state_liveness->prev_req = MC_request_get_dot_output(req, value);
-            if(current_pair->search_cycle)
-              fprintf(dot_output, "%d [shape=doublecircle];\n", current_pair->num);
+          MC_SET_MC_HEAP;
+          if (dot_output != NULL) {
+            initial_global_state->prev_req =
+                MC_request_get_dot_output(req, value);
+            if (current_pair->search_cycle)
+              fprintf(dot_output, "%d [shape=doublecircle];\n",
+                      current_pair->num);
           }
-          MC_UNSET_RAW_MEM; 
-          
-          MC_state_set_executed_request(current_pair->graph_state, req, value);  
+          MC_SET_STD_HEAP;
+
+          MC_state_set_executed_request(current_pair->graph_state, req, value);
           mc_stats->executed_transitions++;
 
           /* Answer the request */
           SIMIX_simcall_pre(req, value);
-          
+
           /* Wait for requests (schedules processes) */
           MC_wait_for_requests();
 
-          MC_SET_RAW_MEM;
+          MC_SET_MC_HEAP;
           prop_values = get_atomic_propositions_values();
-          MC_UNSET_RAW_MEM;
+          MC_SET_STD_HEAP;
 
           int new_pair = 0;
-         
+
           /* Evaluate enabled transition according to atomic propositions values */
-          cursor= 0;
-          xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
+          cursor = 0;
+          xbt_dynar_foreach(current_pair->automaton_state->out, cursor,
+                            transition_succ) {
 
-            res = MC_automaton_evaluate_label(transition_succ->label, prop_values);
+            res =
+                MC_automaton_evaluate_label(transition_succ->label,
+                                            prop_values);
 
-            if(res == 1){ // enabled transition in automaton
+            if (res == 1) {     // enabled transition in automaton
 
-              if(new_pair)
-                MC_replay_liveness(mc_stack_liveness, 1); 
+              if (new_pair)
+                MC_replay_liveness(mc_stack, 1);
 
-              MC_SET_RAW_MEM;
+              MC_SET_MC_HEAP;
 
               next_pair = MC_pair_new();
               next_pair->graph_state = MC_state_new();
               next_pair->automaton_state = transition_succ->dst;
               next_pair->atomic_propositions = get_atomic_propositions_values();
 
-              /* Get enabled process and insert it in the interleave set of the next graph_state */
-              xbt_swag_foreach(process, simix_global->process_list){
-                if(MC_process_is_enabled(process)){
+              /* Get enabled processes and insert them in the interleave set of the next graph_state */
+              xbt_swag_foreach(process, simix_global->process_list) {
+                if (MC_process_is_enabled(process)) {
                   MC_state_interleave_process(next_pair->graph_state, process);
                 }
               }
 
-              next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
-              
-              if(next_pair->automaton_state->type == 1 || next_pair->automaton_state->type == 2 || current_pair->search_cycle)
+              next_pair->requests =
+                  MC_state_interleave_size(next_pair->graph_state);
+
+              if (next_pair->automaton_state->type == 1
+                  || next_pair->automaton_state->type == 2
+                  || current_pair->search_cycle)
                 next_pair->search_cycle = 1;
-            
-              xbt_fifo_unshift(mc_stack_liveness, next_pair);
 
-              if(mc_stats->expanded_pairs%1000000 == 0)
+              xbt_fifo_unshift(mc_stack, next_pair);
+
+              if (mc_stats->expanded_pairs % 1000000 == 0)
                 XBT_INFO("Expanded pairs : %lu", mc_stats->expanded_pairs);
 
-              MC_UNSET_RAW_MEM;
+              MC_SET_STD_HEAP;
 
               new_pair = 1;
 
-              MC_ddfs();
+              MC_modelcheck_liveness();
 
             }
 
           }
 
           /* Then, evaluate true transitions (always true, whatever atomic propositions values) */
-          cursor = 0;   
-          xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
-      
-            res = MC_automaton_evaluate_label(transition_succ->label, prop_values);
-  
-            if(res == 2){ // true transition in automaton
-
-              if(new_pair)
-                MC_replay_liveness(mc_stack_liveness, 1); 
-            
-              MC_SET_RAW_MEM;
-            
+          cursor = 0;
+          xbt_dynar_foreach(current_pair->automaton_state->out, cursor,
+                            transition_succ) {
+
+            res =
+                MC_automaton_evaluate_label(transition_succ->label,
+                                            prop_values);
+
+            if (res == 2) {     // true transition in automaton
+
+              if (new_pair)
+                MC_replay_liveness(mc_stack, 1);
+
+              MC_SET_MC_HEAP;
+
               next_pair = MC_pair_new();
               next_pair->graph_state = MC_state_new();
               next_pair->automaton_state = transition_succ->dst;
               next_pair->atomic_propositions = get_atomic_propositions_values();
 
               /* Get enabled process and insert it in the interleave set of the next graph_state */
-              xbt_swag_foreach(process, simix_global->process_list){
-                if(MC_process_is_enabled(process)){
+              xbt_swag_foreach(process, simix_global->process_list) {
+                if (MC_process_is_enabled(process)) {
                   MC_state_interleave_process(next_pair->graph_state, process);
                 }
               }
 
-              next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
-            
-              if(next_pair->automaton_state->type == 1 || next_pair->automaton_state->type == 2 || current_pair->search_cycle)
+              next_pair->requests =
+                  MC_state_interleave_size(next_pair->graph_state);
+
+              if (next_pair->automaton_state->type == 1
+                  || next_pair->automaton_state->type == 2
+                  || current_pair->search_cycle)
                 next_pair->search_cycle = 1;
 
-              xbt_fifo_unshift(mc_stack_liveness, next_pair);
+              xbt_fifo_unshift(mc_stack, next_pair);
 
-              if(mc_stats->expanded_pairs%1000000 == 0)
+              if (mc_stats->expanded_pairs % 1000000 == 0)
                 XBT_INFO("Expanded pairs : %lu", mc_stats->expanded_pairs);
-            
-              MC_UNSET_RAW_MEM;
+
+              MC_SET_STD_HEAP;
 
               new_pair = 1;
 
-              MC_ddfs();
+              MC_modelcheck_liveness();
 
             }
 
           }
 
-          if(MC_state_interleave_size(current_pair->graph_state) > 0){
-            XBT_DEBUG("Backtracking to depth %d", xbt_fifo_size(mc_stack_liveness));
-            MC_replay_liveness(mc_stack_liveness, 0);
+          if (MC_state_interleave_size(current_pair->graph_state) > 0) {
+            XBT_DEBUG("Backtracking to depth %d", xbt_fifo_size(mc_stack));
+            MC_replay_liveness(mc_stack, 0);
           }
-        
+
         }
 
       }
+
     }
-    
-  }else{
-    
+
+  } else {
+
     XBT_WARN("/!\\ Max depth reached ! /!\\ ");
-    if(MC_state_interleave_size(current_pair->graph_state) > 0){
-      XBT_WARN("/!\\ But, there are still processes to interleave. Model-checker will not be able to ensure the soundness of the verification from now. /!\\ "); 
-      if(_sg_mc_max_depth == 1000)
-        XBT_WARN("Notice : the default value of max depth is 1000 but you can change it with cfg=model-check/max_depth:value.");
+    if (MC_state_interleave_size(current_pair->graph_state) > 0) {
+      XBT_WARN
+          ("/!\\ But, there are still processes to interleave. Model-checker will not be able to ensure the soundness of the verification from now. /!\\ ");
+      if (_sg_mc_max_depth == 1000)
+        XBT_WARN
+            ("Notice : the default value of max depth is 1000 but you can change it with cfg=model-check/max_depth:value.");
     }
-    
+
   }
 
-  if(xbt_fifo_size(mc_stack_liveness) == _sg_mc_max_depth ){
-    XBT_DEBUG("Pair %d (depth = %d) shifted in stack, maximum depth reached", current_pair->num, xbt_fifo_size(mc_stack_liveness) );
-  }else{
-    XBT_DEBUG("Pair %d (depth = %d) shifted in stack", current_pair->num, xbt_fifo_size(mc_stack_liveness) );
+  if (xbt_fifo_size(mc_stack) == _sg_mc_max_depth) {
+    XBT_DEBUG("Pair %d (depth = %d) shifted in stack, maximum depth reached",
+              current_pair->num, xbt_fifo_size(mc_stack));
+  } else {
+    XBT_DEBUG("Pair %d (depth = %d) shifted in stack", current_pair->num,
+              xbt_fifo_size(mc_stack));
   }
 
-  
-  MC_SET_RAW_MEM;
+
+  MC_SET_MC_HEAP;
   xbt_dynar_free(&prop_values);
-  current_pair = xbt_fifo_shift(mc_stack_liveness);
-  if(xbt_fifo_size(mc_stack_liveness) != _sg_mc_max_depth -1 && current_pair->requests > 0 && current_pair->search_cycle){
+  current_pair = xbt_fifo_shift(mc_stack);
+  if (xbt_fifo_size(mc_stack) != _sg_mc_max_depth - 1
+      && current_pair->requests > 0 && current_pair->search_cycle) {
     remove_acceptance_pair(current_pair->num);
   }
   MC_pair_delete(current_pair);
 
-  MC_UNSET_RAW_MEM;
+  MC_SET_STD_HEAP;
 
 }
index a3c2c4b..1d33a11 100644 (file)
  * @param snapshot Snapshot (or NULL)
  * @return Process address of the given member of the 'object' struct/class
  */
-void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot) {
-  if(!member->location.size) {
-    return ((char*) base) + member->offset;
+void *mc_member_resolve(const void *base, dw_type_t type, dw_type_t member,
+                        mc_snapshot_t snapshot)
+{
+  if (!member->location.size) {
+    return ((char *) base) + member->offset;
   }
 
   s_mc_expression_state_t state;
@@ -27,31 +29,12 @@ void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_s
   state.stack_size = 1;
   state.stack[0] = (uintptr_t) base;
 
-  if(mc_dwarf_execute_expression(member->location.size, member->location.ops, &state))
+  if (mc_dwarf_execute_expression
+      (member->location.size, member->location.ops, &state))
     xbt_die("Error evaluating DWARF expression");
-  if(state.stack_size==0)
+  if (state.stack_size == 0)
     xbt_die("No value on the stack");
   else
-    return (void*) state.stack[state.stack_size-1];
+    return (void *) state.stack[state.stack_size - 1];
 }
 
-/** Resolve snapshot in the snapshot address space
- *
- * @param  object Snapshot address of the struct/class
- * @param  type Type of the struct/class
- * @param  member Member description
- * @param  snapshot Snapshot (or NULL)
- * @return Snapshot address of the given member of the 'object' struct/class
- */
-void* mc_member_snapshot_resolve(const void* object, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot) {
-  if(!member->location.size) {
-    return (char*) object + member->offset;
-  } else {
-    // Translate the problem in the process address space:
-    void* real_area = (void*) mc_untranslate_address((void *)object, snapshot);
-    // Resolve the member in the process address space:
-    void* real_member = mc_member_resolve(real_area, type, member, snapshot);
-    // Translate back in the snapshot address space:
-    return mc_translate_address((uintptr_t)real_member, snapshot);
-  }
-}
index f734ec7..c629cf5 100644 (file)
@@ -15,23 +15,26 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory, mc,
 
 /* Pointers to each of the heap regions to use */
 void *std_heap = NULL;          /* memory erased each time the MC stuff rollbacks to the beginning. Almost everything goes here */
-void *raw_heap = NULL;          /* memory persistent over the MC rollbacks. Only MC stuff should go there */
+void *mc_heap = NULL;           /* memory persistent over the MC rollbacks. Only MC stuff should go there */
 
 /* Initialize the model-checker memory subsystem */
-/* It creates the two heap regions: std_heap and raw_heap */
+/* It creates the two heap regions: std_heap and mc_heap */
 void MC_memory_init()
 {
   /* Create the first region HEAP_OFFSET bytes after the heap break address */
   std_heap = mmalloc_get_default_md();
   xbt_assert(std_heap != NULL);
 
-#if defined HAVE_GNU_LD && !defined MMALLOC_WANT_OVERRIDE_LEGACY 
+#if defined HAVE_GNU_LD && !defined MMALLOC_WANT_OVERRIDE_LEGACY
   /* use the system malloc for the model-checker data */
-  raw_heap = NULL;
+  mc_heap = NULL;
 #else
   /* Create the second region a page after the first one ends + safety gap */
-  raw_heap = xbt_mheap_new(-1, (char*)(std_heap) + STD_HEAP_SIZE + xbt_pagesize);
-  xbt_assert(raw_heap != NULL);
+  mc_heap =
+      xbt_mheap_new_options(-1,
+                            (char *) (std_heap) + STD_HEAP_SIZE + xbt_pagesize,
+                            0);
+  xbt_assert(mc_heap != NULL);
 #endif
 }
 
@@ -42,6 +45,6 @@ void MC_memory_exit(void)
   MC_free_object_info(&mc_binary_info);
   MC_free_object_info(&mc_libsimgrid_info);
 
-  if (raw_heap)
-    xbt_mheap_destroy(raw_heap);
+  if (mc_heap)
+    xbt_mheap_destroy(mc_heap);
 }
diff --git a/src/mc/mc_mmu.h b/src/mc/mc_mmu.h
new file mode 100644 (file)
index 0000000..f188da7
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright (c) 2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef MC_MMU_H
+#define MC_MMU_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+extern int xbt_pagesize;
+extern int xbt_pagebits;
+
+/** @brief How many memory pages are necessary to store size bytes?
+ *
+ *  @param size Byte size
+ *  @return Number of memory pages
+ */
+static inline __attribute__ ((always_inline))
+size_t mc_page_count(size_t size)
+{
+  size_t page_count = size >> xbt_pagebits;
+  if (size & (xbt_pagesize-1)) {
+    page_count ++;
+  }
+  return page_count;
+}
+
+/** @brief Get the virtual memory page number of a given address
+ *
+ *  @param address Address
+ *  @return Virtual memory page number of the given address
+ */
+static inline __attribute__ ((always_inline))
+size_t mc_page_number(void* base, void* address)
+{
+  xbt_assert(address>=base, "The address is not in the range");
+  return ((uintptr_t) address - (uintptr_t) base) >> xbt_pagebits;
+}
+
+/** @brief Get the offset of an address within a memory page
+ *
+ *  @param address Address
+ *  @return Offset within the memory page
+ */
+static inline __attribute__ ((always_inline))
+size_t mc_page_offset(void* address)
+{
+  return ((uintptr_t) address) & (xbt_pagesize-1);
+}
+
+/** @brief Get the virtual address of a virtual memory page
+ *
+ *  @param base Address of the first page
+ *  @param page Index of the page
+ */
+static inline __attribute__ ((always_inline))
+void* mc_page_from_number(void* base, size_t page)
+{
+  return (void*) ((char*)base + (page << xbt_pagebits));
+}
+
+static inline __attribute__ ((always_inline))
+bool mc_same_page(void* a, void* b)
+{
+  return ((uintptr_t) a >> xbt_pagebits) == ((uintptr_t) b >> xbt_pagebits);
+}
+
+#endif
diff --git a/src/mc/mc_page_snapshot.cpp b/src/mc/mc_page_snapshot.cpp
new file mode 100644 (file)
index 0000000..2d09521
--- /dev/null
@@ -0,0 +1,213 @@
+#include "mc_page_store.h"
+#include "mc_mmu.h"
+#include "mc_private.h"
+
+#include <xbt/mmalloc.h>
+
+#define SOFT_DIRTY_BIT_NUMBER 55
+#define SOFT_DIRTY (((uint64_t)1) << SOFT_DIRTY_BIT_NUMBER)
+
+extern "C" {
+
+// ***** Region management:
+
+/** @brief Take a per-page snapshot of a region
+ *
+ *  @param data            The start of the region (must be at the beginning of a page)
+ *  @param pag_count       Number of pages of the region
+ *  @param pagemap         Linux kernel pagemap values fot this region (or NULL)
+ *  @param reference_pages Snapshot page numbers of the previous soft_dirty_reset (or NULL)
+ *  @return                Snapshot page numbers of this new snapshot
+ */
+size_t* mc_take_page_snapshot_region(void* data, size_t page_count, uint64_t* pagemap, size_t* reference_pages)
+{
+  size_t* pagenos = (size_t*) malloc(page_count * sizeof(size_t));
+
+  for (size_t i=0; i!=page_count; ++i) {
+    bool softclean = pagemap && !(pagemap[i] & SOFT_DIRTY);
+    if (softclean && reference_pages) {
+      // The page is softclean, it is the same page as the reference page:
+      pagenos[i] = reference_pages[i];
+      mc_model_checker->pages->ref_page(reference_pages[i]);
+    } else {
+      // Otherwise, we need to store the page the hard hard
+      // (by reading its content):
+      void* page = (char*) data + (i << xbt_pagebits);
+      pagenos[i] = mc_model_checker->pages->store_page(page);
+    }
+  }
+
+  return pagenos;
+}
+
+void mc_free_page_snapshot_region(size_t* pagenos, size_t page_count)
+{
+  for (size_t i=0; i!=page_count; ++i) {
+    mc_model_checker->pages->unref_page(pagenos[i]);
+  }
+}
+
+/** @brief Restore a snapshot of a region
+ *
+ *  If possible, the restoration will be incremental
+ *  (the modified pages will not be touched).
+ *
+ *  @param data            The start of the region (must be at the beginning of a page)
+ *  @param pag_count       Number of pages of the region
+ *  @param pagemap         Linux kernel pagemap values fot this region (or NULL)
+ *  @param reference_pages Snapshot page numbers of the previous soft_dirty_reset (or NULL)
+ */
+void mc_restore_page_snapshot_region(mc_mem_region_t region, size_t page_count, uint64_t* pagemap, mc_mem_region_t reference_region)
+{
+  for (size_t i=0; i!=page_count; ++i) {
+
+    bool softclean = pagemap && !(pagemap[i] & SOFT_DIRTY);
+    if (softclean && reference_region && reference_region->page_numbers[i] == region->page_numbers[i]) {
+      // The page is softclean and is the same as the reference one:
+      // the page is already in the target state.
+      continue;
+    }
+
+    // Otherwise, copy the page:
+    void* target_page = mc_page_from_number(region->start_addr, i);
+    const void* source_page = mc_model_checker->pages->get_page(region->page_numbers[i]);
+    memcpy(target_page, source_page, xbt_pagesize);
+  }
+}
+
+// ***** Soft dirty tracking
+
+/** @brief Like pread() but without partial reads */
+static size_t pread_whole(int fd, void* buf, size_t count, off_t offset) {
+  size_t res = 0;
+
+  char* data = (char*) buf;
+  while(count) {
+    ssize_t n = pread(fd, buf, count, offset);
+    // EOF
+    if (n==0)
+      return res;
+
+    // Error (or EINTR):
+    if (n==-1) {
+      if (errno == EINTR)
+        continue;
+      else
+        return -1;
+    }
+
+    // It might be a partial read:
+    count -= n;
+    data += n;
+    offset += n;
+    res += n;
+  }
+
+  return res;
+}
+
+static inline  __attribute__ ((always_inline))
+void mc_ensure_fd(int* fd, const char* path, int flags) {
+  if (*fd != -1)
+    return;
+  *fd = open(path, flags);
+  if (*fd == -1) {
+    xbt_die("Could not open file %s", path);
+  }
+}
+
+/** @brief Reset the soft-dirty bits
+ *
+ *  This is done after checkpointing and after checkpoint restoration
+ *  (if per page checkpoiting is used) in order to know which pages were
+ *  modified.
+ *
+ *  See https://www.kernel.org/doc/Documentation/vm/soft-dirty.txt
+ * */
+void mc_softdirty_reset() {
+  mc_ensure_fd(&mc_model_checker->fd_clear_refs, "/proc/self/clear_refs", O_WRONLY|O_CLOEXEC);
+  if( ::write(mc_model_checker->fd_clear_refs, "4\n", 2) != 2) {
+    xbt_die("Could not reset softdirty bits");
+  }
+}
+
+/** @brief Read memory page informations
+ *
+ *  For each virtual memory page of the process,
+ *  /proc/self/pagemap provides a 64 bit field of information.
+ *  We are interested in the soft-dirty bit: with this we can track which
+ *  pages were modified between snapshots/restorations and avoid
+ *  copying data which was not modified.
+ *
+ *  See https://www.kernel.org/doc/Documentation/vm/pagemap.txt
+ *
+ *  @param pagemap    Output buffer for pagemap informations
+ *  @param start_addr Address of the first page
+ *  @param page_count Number of pages
+ */
+static void mc_read_pagemap(uint64_t* pagemap, size_t page_start, size_t page_count)
+{
+  mc_ensure_fd(&mc_model_checker->fd_pagemap, "/proc/self/pagemap", O_RDONLY|O_CLOEXEC);
+  size_t bytesize = sizeof(uint64_t) * page_count;
+  off_t offset = sizeof(uint64_t) * page_start;
+  if (pread_whole(mc_model_checker->fd_pagemap, pagemap, bytesize, offset) != bytesize) {
+    xbt_die("Could not read pagemap");
+  }
+}
+
+// ***** High level API
+
+mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, size_t size, mc_mem_region_t ref_reg)
+{
+  mc_mem_region_t new_reg = xbt_new(s_mc_mem_region_t, 1);
+
+  new_reg->start_addr = start_addr;
+  new_reg->data = NULL;
+  new_reg->size = size;
+  new_reg->page_numbers = NULL;
+
+  xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize-1)) == 0,
+    "Not at the beginning of a page");
+  size_t page_count = mc_page_count(size);
+
+  uint64_t* pagemap = NULL;
+  if (_sg_mc_soft_dirty && mc_model_checker->parent_snapshot) {
+      pagemap = (uint64_t*) mmalloc_no_memset((xbt_mheap_t) mc_heap, sizeof(uint64_t) * page_count);
+      mc_read_pagemap(pagemap, mc_page_number(NULL, start_addr), page_count);
+  }
+
+  // Take incremental snapshot:
+  new_reg->page_numbers = mc_take_page_snapshot_region(start_addr, page_count, pagemap,
+    ref_reg==NULL ? NULL : ref_reg->page_numbers);
+
+  if(pagemap) {
+    mfree((xbt_mheap_t) mc_heap, pagemap);
+  }
+  return new_reg;
+}
+
+void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg)
+{
+  xbt_assert((((uintptr_t)reg->start_addr) & (xbt_pagesize-1)) == 0,
+    "Not at the beginning of a page");
+  size_t page_count = mc_page_count(reg->size);
+
+  uint64_t* pagemap = NULL;
+
+  // Read soft-dirty bits if necessary in order to know which pages have changed:
+  if (_sg_mc_soft_dirty && mc_model_checker->parent_snapshot) {
+    pagemap = (uint64_t*) mmalloc_no_memset((xbt_mheap_t) mc_heap, sizeof(uint64_t) * page_count);
+    mc_read_pagemap(pagemap, mc_page_number(NULL, reg->start_addr), page_count);
+  }
+
+  // Incremental per-page snapshot restoration:
+  mc_restore_page_snapshot_region(reg, page_count, pagemap, ref_reg);
+
+  // This is funny, the restoration can restore the state of the current heap,
+  // if this happen free(pagemap) would free from the wrong heap:
+  if(pagemap) {
+    mfree((xbt_mheap_t) mc_heap, pagemap);
+  }
+}
+
+}
diff --git a/src/mc/mc_page_store.cpp b/src/mc/mc_page_store.cpp
new file mode 100644 (file)
index 0000000..cac7e0f
--- /dev/null
@@ -0,0 +1,168 @@
+/* Copyright (c) 2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <unistd.h>
+#include <string.h> // memcpy, memcp
+
+#include <sys/mman.h>
+
+#include <boost/foreach.hpp>
+
+#include <xbt.h>
+
+#include "mc_page_store.h"
+
+#include "mc_mmu.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_page_snapshot, mc,
+                                "Logging specific to mc_page_snapshot");
+
+// ***** Utility:
+
+/** @brief Compte a hash for the given memory page
+ *
+ *  The page is used before inserting the page in the page store
+ *  in order to find duplicate of this pae in the page store.
+ *
+ *  @param data Memory page
+ *  @return hash off the page
+ */
+static inline  __attribute__ ((always_inline))
+uint64_t mc_hash_page(const void* data)
+{
+  const uint64_t* values = (const uint64_t*) data;
+  size_t n = xbt_pagesize / sizeof(uint64_t);
+
+  // This djb2:
+  uint64_t hash = 5381;
+  for (size_t i=0; i!=n; ++i) {
+    hash = ((hash << 5) + hash) + values[i];
+  }
+  return hash;
+}
+
+// ***** snapshot_page_manager
+
+s_mc_pages_store::s_mc_pages_store(size_t size) :
+  memory_(NULL), capacity_(0), top_index_(0)
+{
+  // Using mmap in order to be able to expand the region
+  // by relocating it somewhere else in the virtual memory
+  // space:
+  void * memory = ::mmap(NULL, size << xbt_pagebits, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, -1, 0);
+  if (memory==MAP_FAILED) {
+    xbt_die("Could not mmap initial snapshot pages.");
+  }
+
+  this->top_index_ = 0;
+  this->capacity_ = size;
+  this->memory_ = memory;
+  this->page_counts_.resize(size);
+}
+
+s_mc_pages_store::~s_mc_pages_store()
+{
+  ::munmap(this->memory_, this->capacity_ << xbt_pagebits);
+}
+
+void s_mc_pages_store::resize(size_t size)
+{
+  size_t old_bytesize = this->capacity_ << xbt_pagebits;
+  size_t new_bytesize = size << xbt_pagebits;
+
+  // Expand the memory region by moving it into another
+  // virtual memory address if necessary:
+  void* new_memory = mremap(this->memory_, old_bytesize, new_bytesize, MREMAP_MAYMOVE);
+  if (new_memory == MAP_FAILED) {
+    xbt_die("Could not mremap snapshot pages.");
+  }
+
+  this->capacity_ = size;
+  this->memory_ = new_memory;
+  this->page_counts_.resize(size, 0);
+}
+
+/** Allocate a free page
+ *
+ *  @return index of the free page
+ */
+size_t s_mc_pages_store::alloc_page()
+{
+  if (this->free_pages_.empty()) {
+
+    // Expand the region:
+    if (this->top_index_ == this->capacity_) {
+      // All the pages are allocated, we need add more pages:
+      this->resize(2 * this->capacity_);
+    }
+
+    // Use a page from the top:
+    return this->top_index_++;
+
+  } else {
+
+    // Use a page from free_pages_ (inside of the region):
+    size_t res = this->free_pages_[this->free_pages_.size() - 1];
+    this->free_pages_.pop_back();
+    return res;
+
+  }
+}
+
+void s_mc_pages_store::remove_page(size_t pageno)
+{
+  this->free_pages_.push_back(pageno);
+  const void* page = this->get_page(pageno);
+  uint64_t hash = mc_hash_page(page);
+  this->hash_index_[hash].erase(pageno);
+}
+
+/** Store a page in memory */
+size_t s_mc_pages_store::store_page(void* page)
+{
+  xbt_assert(mc_page_offset(page)==0, "Not at the beginning of a page");
+  xbt_assert(top_index_ <= this->capacity_, "top_index is not consistent");
+
+  // First, we check if a page with the same content is already in the page
+  // store:
+  //  1. compute the hash of the page;
+  //  2. find pages with the same hash using `hash_index_`;
+  //  3. find a page with the same content.
+  uint64_t hash = mc_hash_page(page);
+  page_set_type& page_set = this->hash_index_[hash];
+  BOOST_FOREACH (size_t pageno, page_set) {
+    const void* snapshot_page = this->get_page(pageno);
+    if (memcmp(page, snapshot_page, xbt_pagesize) == 0) {
+
+      // If a page with the same content is already in the page store it is
+      // reused and its reference count is incremented.
+      page_counts_[pageno]++;
+      return pageno;
+
+    }
+  }
+
+  // Otherwise, a new page is allocated in the page store and the content
+  // of the page is `memcpy()`-ed to this new page.
+  size_t pageno = alloc_page();
+  xbt_assert(this->page_counts_[pageno]==0, "Allocated page is already used");
+  void* snapshot_page = (void*) this->get_page(pageno);
+  memcpy(snapshot_page, page, xbt_pagesize);
+  page_set.insert(pageno);
+  page_counts_[pageno]++;
+  return pageno;
+}
+
+// ***** Main C API
+
+extern "C" {
+
+mc_pages_store_t mc_pages_store_new()
+{
+  return new s_mc_pages_store_t(500);
+}
+
+}
diff --git a/src/mc/mc_page_store.h b/src/mc/mc_page_store.h
new file mode 100644 (file)
index 0000000..453d103
--- /dev/null
@@ -0,0 +1,214 @@
+/* Copyright (c) 2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+#include <vector>
+
+#include <boost/utility.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
+#endif
+
+#include <xbt.h>
+
+#include "mc_mmu.h"
+
+#ifndef MC_PAGE_STORE_H
+#define MC_PAGE_STORE_H
+
+struct s_mc_pages_store;
+
+#ifdef __cplusplus
+
+/** @brief Storage for snapshot memory pages
+ *
+ * The first (lower) layer of the per-page snapshot mechanism is a page
+ * store: it's responsibility is to store immutable shareable
+ * reference-counted memory pages independently of the snapshoting
+ * logic. Snapshot management and representation, soft-dirty tracking is
+ * handled to an higher layer. READMORE
+ *
+ * Data structure:
+ *
+ *  * A pointer (`memory_`) to a (currently anonymous) `mmap()`ed memory
+ *    region holding the memory pages (the address of the first page).
+ *
+ *    We want to keep this memory region aligned on the memory pages (so
+ *    that we might be able to create non-linear memory mappings on those
+ *    pages in the future) and be able to expand it without coyping the
+ *    data (there will be a lot of pages here): we will be able to
+ *    efficiently expand the memory mapping using `mremap()`, moving it
+ *    to another virtual address if necessary.
+ *
+ *    Because we will move this memory mapping on the virtual address
+ *    space, only the index of the page will be stored in the snapshots
+ *    and the page will always be looked up by going through `memory`:
+ *
+ *         void* page = (char*) page_store->memory + page_index << pagebits;
+ *
+ *  * The number of pages mapped in virtual memory (`capacity_`). Once all
+ *    those pages are used, we need to expand the page store with
+ *    `mremap()`.
+ *
+ *  * A reference count for each memory page `page_counts_`. Each time a
+ *    snapshot references a page, the counter is incremented. If a
+ *    snapshot is freed, the reference count is decremented. When the
+ *    reference count, of a page reaches 0 it is added to a list of available
+ *    pages (`free_pages_`).
+ *
+ *  * A list of free pages `free_pages_` which can be reused. This avoids having
+ *    to scan the reference count list to find a free page.
+ *
+ *  * When we are expanding the memory map we do not want to add thousand of page
+ *    to the `free_pages_` list and remove them just afterwards. The `top_index_`
+ *    field is an index after which all pages are free and are not in the `free_pages_`
+ *    list.
+ *
+ *  * When we are adding a page, we need to check if a page with the same
+ *    content is already in the page store in order to reuse it. For this
+ *    reason, we maintain an index (`hash_index_`) mapping the hash of a
+ *    page to the list of page indices with this hash.
+ *    We use a fast (non cryptographic) hash so there may be conflicts:
+ *    we must be able to store multiple indices for the same hash.
+ *
+ */
+struct s_mc_pages_store {
+private: // Types
+  typedef uint64_t hash_type;
+  typedef boost ::unordered_set<size_t> page_set_type;
+  typedef boost::unordered_map<hash_type, page_set_type> pages_map_type;
+
+private: // Fields:
+  /** First page
+   *
+   *  mc_page_store_get_page expects that this is the first field.
+   * */
+  void* memory_;
+  /** Number of available pages in virtual memory */
+  size_t capacity_;
+  /** Top of the used pages (index of the next available page) */
+  size_t top_index_;
+  /** Page reference count */
+  std::vector<uint64_t> page_counts_;
+  /** Index of available pages before the top */
+  std::vector<size_t> free_pages_;
+  /** Index from page hash to page index */
+  pages_map_type hash_index_;
+
+private: // Methods
+  void resize(size_t size);
+  size_t alloc_page();
+  void remove_page(size_t pageno);
+
+public: // Constructors
+  explicit s_mc_pages_store(size_t size);
+  ~s_mc_pages_store();
+
+public: // Methods
+
+  /** @brief Decrement the reference count for a given page
+   *
+   * Decrement the reference count of this page. Used when a snapshot is
+   * destroyed.
+   *
+   * If the reference count reaches zero, the page is recycled:
+   * it is added to the `free_pages_` list and removed from the `hash_index_`.
+   *
+   * */
+  void unref_page(size_t pageno);
+
+  /** @brief Increment the refcount for a given page
+   *
+   * This method used to increase a reference count of a page if we know
+   * that the content of a page is the same as a page already in the page
+   * store.
+   *
+   * This will be the case if a page if soft clean: we know that is has not
+   * changed since the previous cnapshot/restoration and we can avoid
+   * hashing the page, comparing byte-per-byte to candidates.
+   * */
+  void ref_page(size_t pageno);
+
+  /** @brief Store a page in the page store */
+  size_t store_page(void* page);
+
+  /** @brief Get a page from its page number
+   *
+   *  @param Number of the memory page in the store
+   *  @return Start of the page
+   */
+  const void* get_page(size_t pageno) const;
+
+public: // Debug/test methods
+
+  /** @brief Get the number of references for a page */
+  size_t get_ref(size_t pageno);
+
+  /** @brief Get the number of used pages */
+  size_t size();
+
+  /** @brief Get the capacity of the page store
+   *
+   *  The capacity is expanded by a system call (mremap).
+   * */
+  size_t capacity();
+
+};
+
+inline __attribute__((always_inline))
+void s_mc_pages_store::unref_page(size_t pageno) {
+  if ((--this->page_counts_[pageno]) == 0) {
+    this->remove_page(pageno);
+  }
+}
+
+inline __attribute__((always_inline))
+void s_mc_pages_store::ref_page(size_t pageno) {
+  ++this->page_counts_[pageno];
+}
+
+inline __attribute__((always_inline))
+const void* s_mc_pages_store::get_page(size_t pageno) const {
+  return mc_page_from_number(this->memory_, pageno);
+}
+
+inline __attribute__((always_inline))
+size_t s_mc_pages_store::get_ref(size_t pageno)  {
+  return this->page_counts_[pageno];
+}
+
+inline __attribute__((always_inline))
+size_t s_mc_pages_store::size() {
+  return this->top_index_ - this->free_pages_.size();
+}
+
+inline __attribute__((always_inline))
+size_t s_mc_pages_store::capacity() {
+  return this->capacity_;
+}
+
+#endif
+
+SG_BEGIN_DECL()
+
+typedef struct s_mc_pages_store s_mc_pages_store_t, * mc_pages_store_t;
+mc_pages_store_t mc_pages_store_new();
+
+/**
+ */
+static inline __attribute__((always_inline))
+const void* mc_page_store_get_page(mc_pages_store_t page_store, size_t pageno)
+{
+  // This is page_store->memory_:
+  void* memory = *(void**)page_store;
+  return mc_page_from_number(memory, pageno);
+}
+
+SG_END_DECL()
+
+#endif
index 59f2764..29910e6 100644 (file)
@@ -6,7 +6,8 @@
 
 #include "mc_private.h"
 
-mc_pair_t MC_pair_new(){
+mc_pair_t MC_pair_new()
+{
   mc_pair_t p = NULL;
   p = xbt_new0(s_mc_pair_t, 1);
   p->num = ++mc_stats->expanded_pairs;
@@ -14,36 +15,8 @@ mc_pair_t MC_pair_new(){
   return p;
 }
 
-mc_visited_pair_t MC_visited_pair_new(int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions){
-  mc_visited_pair_t pair = NULL;
-  pair = xbt_new0(s_mc_visited_pair_t, 1);
-  pair->graph_state = MC_state_new();
-  pair->graph_state->system_state = MC_take_snapshot(pair_num);
-  pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
-  pair->nb_processes = xbt_swag_size(simix_global->process_list);
-  pair->automaton_state = automaton_state;
-  pair->num = pair_num;
-  pair->other_num = -1;
-  pair->acceptance_removed = 0;
-  pair->visited_removed = 0;
-  pair->acceptance_pair = 0;
-  pair->atomic_propositions = xbt_dynar_new(sizeof(int), NULL);
-  unsigned int cursor = 0;
-  int value;
-  xbt_dynar_foreach(atomic_propositions, cursor, value)
-    xbt_dynar_push_as(pair->atomic_propositions, int, value);
-  return pair;
-}
-
-void MC_visited_pair_delete(mc_visited_pair_t p){
-  p->automaton_state = NULL;
-  MC_state_delete(p->graph_state);
-  xbt_dynar_free(&(p->atomic_propositions));
-  xbt_free(p);
-  p = NULL;
-}
-
-void MC_pair_delete(mc_pair_t p){
+void MC_pair_delete(mc_pair_t p)
+{
   p->automaton_state = NULL;
   MC_state_delete(p->graph_state);
   xbt_dynar_free(&(p->atomic_propositions));
@@ -51,6 +24,7 @@ void MC_pair_delete(mc_pair_t p){
   p = NULL;
 }
 
-void mc_pair_free_voidp(void *p){
-  MC_pair_delete((mc_pair_t) * (void **)p);
+void mc_pair_free_voidp(void *p)
+{
+  MC_pair_delete((mc_pair_t) * (void **) p);
 }
index 0d45e74..2d62c91 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "simgrid_config.h"
 #include <stdio.h>
+#include <stdbool.h>
 #ifndef WIN32
 #include <sys/mman.h>
 #endif
 #include "xbt/function_types.h"
 #include "xbt/mmalloc.h"
 #include "../simix/smx_private.h"
+#include "../xbt/mmalloc/mmprivate.h"
 #include "xbt/automaton.h"
 #include "xbt/hash.h"
 #include "msg/msg.h"
 #include "msg/datatypes.h"
 #include "xbt/strbuff.h"
 #include "xbt/parmap.h"
+#include "mc_mmu.h"
+#include "mc_page_store.h"
+
+SG_BEGIN_DECL()
 
 typedef struct s_dw_frame s_dw_frame_t, *dw_frame_t;
 typedef struct s_mc_function_index_item s_mc_function_index_item_t, *mc_function_index_item_t;
@@ -42,20 +48,52 @@ typedef struct s_mc_mem_region{
   void *data;
   // Size of the data region:
   size_t size;
+  // For per-page snapshots, this is an array to the number of
+  size_t* page_numbers;
 } s_mc_mem_region_t, *mc_mem_region_t;
 
+static inline  __attribute__ ((always_inline))
+bool mc_region_contain(mc_mem_region_t region, void* p)
+{
+  return p >= region->start_addr &&
+    p < (void*)((char*) region->start_addr + region->size);
+}
+
+/** Ignored data
+ *
+ *  Some parts of the snapshot are ignored by zeroing them out: the real
+ *  values is stored here.
+ * */
+typedef struct s_mc_snapshot_ignored_data {
+  void* start;
+  size_t size;
+  void* data;
+} s_mc_snapshot_ignored_data_t, *mc_snapshot_ignored_data_t;
+
 typedef struct s_mc_snapshot{
   size_t heap_bytes_used;
   mc_mem_region_t regions[NB_REGIONS];
-  int nb_processes;
+  xbt_dynar_t enabled_processes;
   mc_mem_region_t* privatization_regions;
   int privatization_index;
   size_t *stack_sizes;
   xbt_dynar_t stacks;
   xbt_dynar_t to_ignore;
   uint64_t hash;
+  xbt_dynar_t ignored_data;
 } s_mc_snapshot_t, *mc_snapshot_t;
 
+mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot);
+
+static inline __attribute__ ((always_inline))
+mc_mem_region_t mc_get_region_hinted(void* addr, mc_snapshot_t snapshot, mc_mem_region_t region)
+{
+  if (mc_region_contain(region, addr))
+    return region;
+  else
+    return mc_get_snapshot_region(addr, snapshot);
+}
+
 /** Information about a given stack frame
  *
  */
@@ -72,8 +110,6 @@ typedef struct s_mc_stack_frame {
 
 typedef struct s_mc_snapshot_stack{
   xbt_dynar_t local_variables;
-  void *stack_pointer;
-  void *real_address;
   xbt_dynar_t stack_frames; // mc_stack_frame_t
 }s_mc_snapshot_stack_t, *mc_snapshot_stack_t;
 
@@ -92,35 +128,56 @@ typedef struct s_mc_checkpoint_ignore_region{
   size_t size;
 }s_mc_checkpoint_ignore_region_t, *mc_checkpoint_ignore_region_t;
 
+static void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot);
+
 mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall);
 mc_snapshot_t MC_take_snapshot(int num_state);
 void MC_restore_snapshot(mc_snapshot_t);
 void MC_free_snapshot(mc_snapshot_t);
 
-/** \brief Translate a pointer from process address space to snapshot address space
- *
- *  The address space contains snapshot of the main/application memory:
- *  this function finds the address in a given snaphot for a given
- *  real/application address.
- *
- *  For read only memory regions and other regions which are not int the
- *  snapshot, the address is not changed.
- *
- *  \param addr     Application address
- *  \param snapshot The snapshot of interest (if NULL no translation is done)
- *  \return         Translated address in the snapshot address space
- * */
-void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot);
+int mc_important_snapshot(mc_snapshot_t snapshot);
 
-/** \brief Translate a pointer from the snapshot address space to the application address space
- *
- *  This is the inverse of mc_translate_address.
+size_t* mc_take_page_snapshot_region(void* data, size_t page_count, uint64_t* pagemap, size_t* reference_pages);
+void mc_free_page_snapshot_region(size_t* pagenos, size_t page_count);
+void mc_restore_page_snapshot_region(mc_mem_region_t region, size_t page_count, uint64_t* pagemap, mc_mem_region_t reference_region);
+
+mc_mem_region_t mc_region_new_sparse(int type, void *start_addr, size_t size, mc_mem_region_t ref_reg);
+void mc_region_restore_sparse(mc_mem_region_t reg, mc_mem_region_t ref_reg);
+void mc_softdirty_reset();
+
+static inline __attribute__((always_inline))
+bool mc_snapshot_region_linear(mc_mem_region_t region) {
+  return !region || !region->data;
+}
+
+void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size);
+
+void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, void* target, size_t size);
+int mc_snapshot_region_memcp(
+  void* addr1, mc_mem_region_t region1,
+  void* addr2, mc_mem_region_t region2, size_t size);
+int mc_snapshot_memcp(
+  void* addr1, mc_snapshot_t snapshot1,
+  void* addr2, mc_snapshot_t snapshot2, size_t size);
+
+static void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot);
+
+/** @brief State of the model-checker (global variables for the model checker)
  *
- * \param addr    Address in the snapshot address space
- * \param snapsot Snapshot of interest (if NULL no translation is done)
- * \return        Translated address in the application address space
+ *  Each part of the state of the model chercker represented as a global
+ *  variable prevents some sharing between snapshots and must be ignored.
+ *  By moving as much state as possible in this structure allocated
+ *  on the model-chercker heap, we avoid those issues.
  */
-uintptr_t mc_untranslate_address(void* addr, mc_snapshot_t snapshot);
+typedef struct s_mc_model_checker {
+  // This is the parent snapshot of the current state:
+  mc_snapshot_t parent_snapshot;
+  mc_pages_store_t pages;
+  int fd_clear_refs;
+  int fd_pagemap;
+} s_mc_model_checker_t, *mc_model_checker_t;
+
+extern mc_model_checker_t mc_model_checker;
 
 extern xbt_dynar_t mc_checkpoint_ignore;
 
@@ -140,9 +197,11 @@ void MC_wait_for_requests(void);
 void MC_show_deadlock(smx_simcall_t req);
 void MC_show_stack_safety(xbt_fifo_t stack);
 void MC_dump_stack_safety(xbt_fifo_t stack);
-void MC_init(void);
 int SIMIX_pre_mc_random(smx_simcall_t simcall, int min, int max);
 
+extern xbt_fifo_t mc_stack;
+int get_search_interval(xbt_dynar_t list, void *ref, int *min, int *max);
+
 
 /********************************* Requests ***********************************/
 
@@ -159,6 +218,8 @@ char *MC_request_get_dot_output(smx_simcall_t req, int value);
 
 /******************************** States **************************************/
 
+extern mc_global_t initial_global_state;
+
 /* Possible exploration status of a process in a state */
 typedef enum {
   MC_NOT_INTERLEAVE=0,      /* Do not interleave (do not execute) */
@@ -221,7 +282,7 @@ void MC_print_statistics(mc_stats_t);
 /* you must wrap the code between MC_SET_RAW_MODE and MC_UNSET_RAW_MODE */
 
 extern void *std_heap;
-extern void *raw_heap;
+extern void *mc_heap;
 
 
 /* FIXME: Horrible hack! because the mmalloc library doesn't provide yet of */
@@ -236,8 +297,8 @@ extern void *raw_heap;
 /*   size_t bytes_free;            /\* Byte total of chunks in the free list. *\/ */
 /* }; */
 
-#define MC_SET_RAW_MEM    mmalloc_set_current_heap(raw_heap)
-#define MC_UNSET_RAW_MEM  mmalloc_set_current_heap(std_heap)
+#define MC_SET_MC_HEAP    mmalloc_set_current_heap(mc_heap)
+#define MC_SET_STD_HEAP  mmalloc_set_current_heap(std_heap)
 
 
 /******************************* MEMORY MAPPINGS ***************************/
@@ -295,7 +356,7 @@ void print_comparison_times(void);
 //#define MC_DEBUG 1
 #define MC_VERBOSE 1
 
-/********************************** DPOR for safety property **************************************/
+/********************************** Safety verification **************************************/
 
 typedef enum {
   e_mc_reduce_unset,
@@ -304,12 +365,10 @@ typedef enum {
 } e_mc_reduce_t;
 
 extern e_mc_reduce_t mc_reduce_kind;
-extern mc_global_t initial_state_safety;
-extern xbt_fifo_t mc_stack_safety;
 extern xbt_dict_t first_enabled_state;
 
-void MC_dpor_init(void);
-void MC_dpor(void);
+void MC_pre_modelcheck_safety(void);
+void MC_modelcheck_safety(void);
 
 typedef struct s_mc_visited_state{
   mc_snapshot_t system_state;
@@ -319,13 +378,14 @@ typedef struct s_mc_visited_state{
   int other_num; // dot_output for
 }s_mc_visited_state_t, *mc_visited_state_t;
 
+extern xbt_dynar_t visited_states;
+mc_visited_state_t is_visited_state(void);
+void visited_state_free(mc_visited_state_t state);
+void visited_state_free_voidp(void *s);
 
-/********************************** Double-DFS for liveness property **************************************/
+/********************************** Liveness verification **************************************/
 
-extern xbt_fifo_t mc_stack_liveness;
-extern mc_global_t initial_state_liveness;
 extern xbt_automaton_t _mc_property_automaton;
-extern int compare;
 
 typedef struct s_mc_pair{
   int num;
@@ -355,11 +415,14 @@ void mc_pair_free_voidp(void *p);
 mc_visited_pair_t MC_visited_pair_new(int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions);
 void MC_visited_pair_delete(mc_visited_pair_t p);
 
-void MC_ddfs_init(void);
-void MC_ddfs(void);
+void MC_pre_modelcheck_liveness(void);
+void MC_modelcheck_liveness(void);
 void MC_show_stack_liveness(xbt_fifo_t stack);
 void MC_dump_stack_liveness(xbt_fifo_t stack);
 
+extern xbt_dynar_t visited_pairs;
+int is_visited_pair(mc_visited_pair_t pair, int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions);
+
 
 /********************************** Variables with DWARF **********************************/
 
@@ -401,6 +464,7 @@ extern size_t mc_object_infos_size;
 
 void MC_find_object_address(memory_map_t maps, mc_object_info_t result);
 void MC_post_process_types(mc_object_info_t info);
+void MC_post_process_object_info(mc_object_info_t info);
 
 // ***** Expressions
 
@@ -450,7 +514,6 @@ struct s_dw_type{
 };
 
 void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot);
-void* mc_member_snapshot_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot);
 
 typedef struct s_dw_variable{
   Dwarf_Off dwarf_offset; /* Global offset of the field. */
@@ -556,7 +619,6 @@ typedef struct s_mc_comm_pattern{
   int num;
   smx_action_t comm;
   e_smx_comm_type_t type;
-  int completed;
   unsigned long src_proc;
   unsigned long dst_proc;
   const char *src_host;
@@ -564,13 +626,16 @@ typedef struct s_mc_comm_pattern{
   char *rdv;
   ssize_t data_size;
   void *data;
-  int matched_comm;
 }s_mc_comm_pattern_t, *mc_comm_pattern_t;
 
+extern xbt_dynar_t initial_communications_pattern;
 extern xbt_dynar_t communications_pattern;
 extern xbt_dynar_t incomplete_communications_pattern;
 
 void get_comm_pattern(xbt_dynar_t communications_pattern, smx_simcall_t request, int call);
+void complete_comm_pattern(xbt_dynar_t list, smx_action_t comm);
+void MC_pre_modelcheck_comm_determinism(void);
+void MC_modelcheck_comm_determinism(void);
 
 /* *********** Sets *********** */
 
@@ -590,5 +655,118 @@ bool mc_address_test(mc_address_set_t p, const void* value);
  * */
 uint64_t mc_hash_processes_state(int num_state, xbt_dynar_t stacks);
 
+/* *********** Snapshot *********** */
+
+static inline __attribute__((always_inline))
+void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t region)
+{
+    size_t pageno = mc_page_number(region->start_addr, (void*) addr);
+    size_t snapshot_pageno = region->page_numbers[pageno];
+    const void* snapshot_page = mc_page_store_get_page(mc_model_checker->pages, snapshot_pageno);
+    return (char*) snapshot_page + mc_page_offset((void*) addr);
+}
+
+/** \brief Translate a pointer from process address space to snapshot address space
+ *
+ *  The address space contains snapshot of the main/application memory:
+ *  this function finds the address in a given snaphot for a given
+ *  real/application address.
+ *
+ *  For read only memory regions and other regions which are not int the
+ *  snapshot, the address is not changed.
+ *
+ *  \param addr     Application address
+ *  \param snapshot The snapshot of interest (if NULL no translation is done)
+ *  \return         Translated address in the snapshot address space
+ * */
+static inline __attribute__((always_inline))
+void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot)
+{
+
+  // If not in a process state/clone:
+  if (!snapshot) {
+    return (uintptr_t *) addr;
+  }
+
+  mc_mem_region_t region = mc_get_snapshot_region((void*) addr, snapshot);
+
+  xbt_assert(mc_region_contain(region, (void*) addr), "Trying to read out of the region boundary.");
+
+  if (!region) {
+    return (void *) addr;
+  }
+
+  // Flat snapshot:
+  else if (region->data) {
+    uintptr_t offset = addr - (uintptr_t) region->start_addr;
+    return (void *) ((uintptr_t) region->data + offset);
+  }
+
+  // Per-page snapshot:
+  else if (region->page_numbers) {
+    return mc_translate_address_region(addr, region);
+  }
+
+  else {
+    xbt_die("No data for this memory region");
+  }
+}
+
+static inline __attribute__ ((always_inline))
+  void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot) {
+  if(snapshot==NULL)
+      xbt_die("snapshot is NULL");
+  void** addr = &((xbt_mheap_t)std_heap)->breakval;
+  return mc_snapshot_read_pointer(addr, snapshot);
+}
+
+static inline __attribute__ ((always_inline))
+void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot)
+{
+  void* res;
+  return *(void**) mc_snapshot_read(addr, snapshot, &res, sizeof(void*));
+}
+
+/** @brief Read memory from a snapshot region
+ *
+ *  @param addr    Process (non-snapshot) address of the data
+ *  @param region  Snapshot memory region where the data is located
+ *  @param target  Buffer to store the value
+ *  @param size    Size of the data to read in bytes
+ *  @return Pointer where the data is located (target buffer of original location)
+ */
+static inline __attribute__((always_inline))
+void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size)
+{
+  uintptr_t offset = (uintptr_t) addr - (uintptr_t) region->start_addr;
+
+  xbt_assert(addr >= region->start_addr && (char*) addr+size < (char*)region->start_addr+region->size,
+    "Trying to read out of the region boundary.");
+
+  // Linear memory region:
+  if (region->data) {
+    return (void*) ((uintptr_t) region->data + offset);
+  }
+
+  // Fragmented memory region:
+  else if (region->page_numbers) {
+    void* end = (char*) addr + size - 1;
+    if( mc_same_page(addr, end) ) {
+      // The memory is contained in a single page:
+      return mc_translate_address_region((uintptr_t) addr, region);
+    } else {
+      // The memory spans several pages:
+      return mc_snapshot_read_fragmented(addr, region, target, size);
+    }
+  }
+
+  else {
+    xbt_die("No data available for this region");
+  }
+}
+
+
+SG_END_DECL()
+
 #endif
 
index 9fb5ad5..56696d6 100644 (file)
@@ -9,63 +9,90 @@
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_request, mc,
                                 "Logging specific to MC (request)");
 
-static char* pointer_to_string(void* pointer);
-static charbuff_size_to_string(size_t size);
+static char *pointer_to_string(void *pointer);
+static char *buff_size_to_string(size_t size);
 
-int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
-  if(mc_reduce_kind == e_mc_reduce_none)
+int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2)
+{
+  if (mc_reduce_kind == e_mc_reduce_none)
     return TRUE;
 
   if (r1->issuer == r2->issuer)
     return FALSE;
 
   /* Wait with timeout transitions are not considered by the independance theorem, thus we consider them as dependant with all other transitions */
-  if((r1->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r1) > 0) || (r2->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r2) > 0))
+  if ((r1->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r1) > 0)
+      || (r2->call == SIMCALL_COMM_WAIT
+          && simcall_comm_wait__get__timeout(r2) > 0))
     return TRUE;
 
-  if(r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_IRECV)
+  if (r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_IRECV)
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_ISEND)
+  if (r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_ISEND)
     return FALSE;
 
-  if((r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
-     &&  r2->call == SIMCALL_COMM_WAIT){
+  if ((r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
+      && r2->call == SIMCALL_COMM_WAIT) {
 
-    smx_rdv_t rdv = r1->call == SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r1) : simcall_comm_irecv__get__rdv(r1);
+    smx_rdv_t rdv =
+        r1->call ==
+        SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r1) :
+        simcall_comm_irecv__get__rdv(r1);
 
-    if(rdv != simcall_comm_wait__get__comm(r2)->comm.rdv_cpy && simcall_comm_wait__get__timeout(r2) <= 0)
+    if (rdv != simcall_comm_wait__get__comm(r2)->comm.rdv_cpy
+        && simcall_comm_wait__get__timeout(r2) <= 0)
       return FALSE;
 
-    if((r1->issuer != simcall_comm_wait__get__comm(r2)->comm.src_proc) && (r1->issuer != simcall_comm_wait__get__comm(r2)->comm.dst_proc) && simcall_comm_wait__get__timeout(r2) <= 0)
+    if ((r1->issuer != simcall_comm_wait__get__comm(r2)->comm.src_proc)
+        && (r1->issuer != simcall_comm_wait__get__comm(r2)->comm.dst_proc)
+        && simcall_comm_wait__get__timeout(r2) <= 0)
       return FALSE;
 
-    if((r1->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND) 
-       && (simcall_comm_wait__get__comm(r2)->comm.src_buff != simcall_comm_isend__get__src_buff(r1)) && simcall_comm_wait__get__timeout(r2) <= 0)
+    if ((r1->call == SIMCALL_COMM_ISEND)
+        && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND)
+        && (simcall_comm_wait__get__comm(r2)->comm.src_buff !=
+            simcall_comm_isend__get__src_buff(r1))
+        && simcall_comm_wait__get__timeout(r2) <= 0)
       return FALSE;
 
-    if((r1->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE) 
-       && (simcall_comm_wait__get__comm(r2)->comm.dst_buff != simcall_comm_irecv__get__dst_buff(r1)) && simcall_comm_wait__get__timeout(r2) <= 0)
+    if ((r1->call == SIMCALL_COMM_IRECV)
+        && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE)
+        && (simcall_comm_wait__get__comm(r2)->comm.dst_buff !=
+            simcall_comm_irecv__get__dst_buff(r1))
+        && simcall_comm_wait__get__timeout(r2) <= 0)
       return FALSE;
   }
 
-  if((r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
-        &&  r1->call == SIMCALL_COMM_WAIT){
+  if ((r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
+      && r1->call == SIMCALL_COMM_WAIT) {
 
-    smx_rdv_t rdv = r2->call == SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r2) : simcall_comm_irecv__get__rdv(r2);
+    smx_rdv_t rdv =
+        r2->call ==
+        SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r2) :
+        simcall_comm_irecv__get__rdv(r2);
 
-    if(rdv != simcall_comm_wait__get__comm(r1)->comm.rdv_cpy && simcall_comm_wait__get__timeout(r1) <= 0)
+    if (rdv != simcall_comm_wait__get__comm(r1)->comm.rdv_cpy
+        && simcall_comm_wait__get__timeout(r1) <= 0)
       return FALSE;
 
-    if((r2->issuer != simcall_comm_wait__get__comm(r1)->comm.src_proc) && (r2->issuer != simcall_comm_wait__get__comm(r1)->comm.dst_proc) && simcall_comm_wait__get__timeout(r1) <= 0)
-        return FALSE;  
+    if ((r2->issuer != simcall_comm_wait__get__comm(r1)->comm.src_proc)
+        && (r2->issuer != simcall_comm_wait__get__comm(r1)->comm.dst_proc)
+        && simcall_comm_wait__get__timeout(r1) <= 0)
+      return FALSE;
 
-    if((r2->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_SEND) 
-       && (simcall_comm_wait__get__comm(r1)->comm.src_buff != simcall_comm_isend__get__src_buff(r2)) && simcall_comm_wait__get__timeout(r1) <= 0)
+    if ((r2->call == SIMCALL_COMM_ISEND)
+        && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_SEND)
+        && (simcall_comm_wait__get__comm(r1)->comm.src_buff !=
+            simcall_comm_isend__get__src_buff(r2))
+        && simcall_comm_wait__get__timeout(r1) <= 0)
       return FALSE;
 
-    if((r2->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE) 
-       && (simcall_comm_wait__get__comm(r1)->comm.dst_buff != simcall_comm_irecv__get__dst_buff(r2)) && simcall_comm_wait__get__timeout(r1) <= 0)
+    if ((r2->call == SIMCALL_COMM_IRECV)
+        && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE)
+        && (simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
+            simcall_comm_irecv__get__dst_buff(r2))
+        && simcall_comm_wait__get__timeout(r1) <= 0)
       return FALSE;
   }
 
@@ -73,37 +100,41 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
    * isend/irecv call is not stored in a buffer used in the
    * test call. */
   /*if(   (r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
-        &&  r2->call == SIMCALL_COMM_TEST)
-        return FALSE;*/
+     &&  r2->call == SIMCALL_COMM_TEST)
+     return FALSE; */
 
   /* FIXME: the following rule assumes that the result of the
    * isend/irecv call is not stored in a buffer used in the
    * test call.*/
   /*if(   (r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
-        && r1->call == SIMCALL_COMM_TEST)
-        return FALSE;*/
+     && r1->call == SIMCALL_COMM_TEST)
+     return FALSE; */
 
-  if(r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_ISEND
-     && simcall_comm_isend__get__rdv(r1) != simcall_comm_isend__get__rdv(r2))
+  if (r1->call == SIMCALL_COMM_ISEND && r2->call == SIMCALL_COMM_ISEND
+      && simcall_comm_isend__get__rdv(r1) != simcall_comm_isend__get__rdv(r2))
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_IRECV
-     && simcall_comm_irecv__get__rdv(r1) != simcall_comm_irecv__get__rdv(r2))
+  if (r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_IRECV
+      && simcall_comm_irecv__get__rdv(r1) != simcall_comm_irecv__get__rdv(r2))
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_WAIT && (r2->call == SIMCALL_COMM_WAIT || r2->call == SIMCALL_COMM_TEST)
-     && (simcall_comm_wait__get__comm(r1)->comm.src_proc == NULL
-         || simcall_comm_wait__get__comm(r1)->comm.dst_proc == NULL))
+  if (r1->call == SIMCALL_COMM_WAIT
+      && (r2->call == SIMCALL_COMM_WAIT || r2->call == SIMCALL_COMM_TEST)
+      && (simcall_comm_wait__get__comm(r1)->comm.src_proc == NULL
+          || simcall_comm_wait__get__comm(r1)->comm.dst_proc == NULL))
     return FALSE;
 
-  if(r2->call == SIMCALL_COMM_WAIT && (r1->call == SIMCALL_COMM_WAIT || r1->call == SIMCALL_COMM_TEST)
-     && (simcall_comm_wait__get__comm(r2)->comm.src_proc == NULL
-         || simcall_comm_wait__get__comm(r2)->comm.dst_proc == NULL))
+  if (r2->call == SIMCALL_COMM_WAIT
+      && (r1->call == SIMCALL_COMM_WAIT || r1->call == SIMCALL_COMM_TEST)
+      && (simcall_comm_wait__get__comm(r2)->comm.src_proc == NULL
+          || simcall_comm_wait__get__comm(r2)->comm.dst_proc == NULL))
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_WAIT
-     && simcall_comm_wait__get__comm(r1)->comm.src_buff == simcall_comm_wait__get__comm(r2)->comm.src_buff
-     && simcall_comm_wait__get__comm(r1)->comm.dst_buff == simcall_comm_wait__get__comm(r2)->comm.dst_buff)
+  if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_WAIT
+      && simcall_comm_wait__get__comm(r1)->comm.src_buff ==
+      simcall_comm_wait__get__comm(r2)->comm.src_buff
+      && simcall_comm_wait__get__comm(r1)->comm.dst_buff ==
+      simcall_comm_wait__get__comm(r2)->comm.dst_buff)
     return FALSE;
 
   if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_WAIT
@@ -111,31 +142,38 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
       && simcall_comm_wait__get__comm(r1)->comm.dst_buff != NULL
       && simcall_comm_wait__get__comm(r2)->comm.src_buff != NULL
       && simcall_comm_wait__get__comm(r2)->comm.dst_buff != NULL
-      && simcall_comm_wait__get__comm(r1)->comm.dst_buff != simcall_comm_wait__get__comm(r2)->comm.src_buff
-      && simcall_comm_wait__get__comm(r1)->comm.dst_buff != simcall_comm_wait__get__comm(r2)->comm.dst_buff
-      && simcall_comm_wait__get__comm(r2)->comm.dst_buff != simcall_comm_wait__get__comm(r1)->comm.src_buff)
+      && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
+      simcall_comm_wait__get__comm(r2)->comm.src_buff
+      && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
+      simcall_comm_wait__get__comm(r2)->comm.dst_buff
+      && simcall_comm_wait__get__comm(r2)->comm.dst_buff !=
+      simcall_comm_wait__get__comm(r1)->comm.src_buff)
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_TEST &&
-     (simcall_comm_test__get__comm(r1) == NULL
-      || simcall_comm_test__get__comm(r1)->comm.src_buff == NULL
-      || simcall_comm_test__get__comm(r1)->comm.dst_buff == NULL))
+  if (r1->call == SIMCALL_COMM_TEST &&
+      (simcall_comm_test__get__comm(r1) == NULL
+       || simcall_comm_test__get__comm(r1)->comm.src_buff == NULL
+       || simcall_comm_test__get__comm(r1)->comm.dst_buff == NULL))
     return FALSE;
 
-  if(r2->call == SIMCALL_COMM_TEST &&
-     (simcall_comm_test__get__comm(r2) == NULL
-      || simcall_comm_test__get__comm(r2)->comm.src_buff == NULL
-      || simcall_comm_test__get__comm(r2)->comm.dst_buff == NULL))
+  if (r2->call == SIMCALL_COMM_TEST &&
+      (simcall_comm_test__get__comm(r2) == NULL
+       || simcall_comm_test__get__comm(r2)->comm.src_buff == NULL
+       || simcall_comm_test__get__comm(r2)->comm.dst_buff == NULL))
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_TEST && r2->call == SIMCALL_COMM_WAIT
-     && simcall_comm_test__get__comm(r1)->comm.src_buff == simcall_comm_wait__get__comm(r2)->comm.src_buff
-     && simcall_comm_test__get__comm(r1)->comm.dst_buff == simcall_comm_wait__get__comm(r2)->comm.dst_buff)
+  if (r1->call == SIMCALL_COMM_TEST && r2->call == SIMCALL_COMM_WAIT
+      && simcall_comm_test__get__comm(r1)->comm.src_buff ==
+      simcall_comm_wait__get__comm(r2)->comm.src_buff
+      && simcall_comm_test__get__comm(r1)->comm.dst_buff ==
+      simcall_comm_wait__get__comm(r2)->comm.dst_buff)
     return FALSE;
 
-  if(r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_TEST
-     && simcall_comm_wait__get__comm(r1)->comm.src_buff == simcall_comm_test__get__comm(r2)->comm.src_buff
-     && simcall_comm_wait__get__comm(r1)->comm.dst_buff == simcall_comm_test__get__comm(r2)->comm.dst_buff)
+  if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_TEST
+      && simcall_comm_wait__get__comm(r1)->comm.src_buff ==
+      simcall_comm_test__get__comm(r2)->comm.src_buff
+      && simcall_comm_wait__get__comm(r1)->comm.dst_buff ==
+      simcall_comm_test__get__comm(r2)->comm.dst_buff)
     return FALSE;
 
   if (r1->call == SIMCALL_COMM_WAIT && r2->call == SIMCALL_COMM_TEST
@@ -143,9 +181,12 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
       && simcall_comm_wait__get__comm(r1)->comm.dst_buff != NULL
       && simcall_comm_test__get__comm(r2)->comm.src_buff != NULL
       && simcall_comm_test__get__comm(r2)->comm.dst_buff != NULL
-      && simcall_comm_wait__get__comm(r1)->comm.dst_buff != simcall_comm_test__get__comm(r2)->comm.src_buff
-      && simcall_comm_wait__get__comm(r1)->comm.dst_buff != simcall_comm_test__get__comm(r2)->comm.dst_buff
-      && simcall_comm_test__get__comm(r2)->comm.dst_buff != simcall_comm_wait__get__comm(r1)->comm.src_buff)
+      && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
+      simcall_comm_test__get__comm(r2)->comm.src_buff
+      && simcall_comm_wait__get__comm(r1)->comm.dst_buff !=
+      simcall_comm_test__get__comm(r2)->comm.dst_buff
+      && simcall_comm_test__get__comm(r2)->comm.dst_buff !=
+      simcall_comm_wait__get__comm(r1)->comm.src_buff)
     return FALSE;
 
   if (r1->call == SIMCALL_COMM_TEST && r2->call == SIMCALL_COMM_WAIT
@@ -153,16 +194,20 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
       && simcall_comm_test__get__comm(r1)->comm.dst_buff != NULL
       && simcall_comm_wait__get__comm(r2)->comm.src_buff != NULL
       && simcall_comm_wait__get__comm(r2)->comm.dst_buff != NULL
-      && simcall_comm_test__get__comm(r1)->comm.dst_buff != simcall_comm_wait__get__comm(r2)->comm.src_buff
-      && simcall_comm_test__get__comm(r1)->comm.dst_buff != simcall_comm_wait__get__comm(r2)->comm.dst_buff
-      && simcall_comm_wait__get__comm(r2)->comm.dst_buff != simcall_comm_test__get__comm(r1)->comm.src_buff)
+      && simcall_comm_test__get__comm(r1)->comm.dst_buff !=
+      simcall_comm_wait__get__comm(r2)->comm.src_buff
+      && simcall_comm_test__get__comm(r1)->comm.dst_buff !=
+      simcall_comm_wait__get__comm(r2)->comm.dst_buff
+      && simcall_comm_wait__get__comm(r2)->comm.dst_buff !=
+      simcall_comm_test__get__comm(r1)->comm.src_buff)
     return FALSE;
 
 
   return TRUE;
 }
 
-static char* pointer_to_string(void* pointer) {
+static char *pointer_to_string(void *pointer)
+{
 
   if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
     return bprintf("%p", pointer);
@@ -170,7 +215,8 @@ static char* pointer_to_string(void* pointer) {
   return xbt_strdup("(verbose only)");
 }
 
-static char* buff_size_to_string(size_t buff_size) {
+static char *buff_size_to_string(size_t buff_size)
+{
 
   if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
     return bprintf("%zu", buff_size);
@@ -185,77 +231,98 @@ char *MC_request_to_string(smx_simcall_t req, int value)
   smx_action_t act = NULL;
   size_t size = 0;
 
-  switch(req->call){
-    case SIMCALL_COMM_ISEND:
+  switch (req->call) {
+  case SIMCALL_COMM_ISEND:
     type = xbt_strdup("iSend");
     p = pointer_to_string(simcall_comm_isend__get__src_buff(req));
     bs = buff_size_to_string(simcall_comm_isend__get__src_buff_size(req));
-    if(req->issuer->smx_host)
-      args = bprintf("src=(%lu)%s (%s), buff=%s, size=%s", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host), req->issuer->name, p, bs);
+    if (req->issuer->smx_host)
+      args =
+          bprintf("src=(%lu)%s (%s), buff=%s, size=%s", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
+                  p, bs);
     else
-      args = bprintf("src=(%lu)%s, buff=%s, size=%s", req->issuer->pid, req->issuer->name, p, bs);
+      args =
+          bprintf("src=(%lu)%s, buff=%s, size=%s", req->issuer->pid,
+                  req->issuer->name, p, bs);
     break;
   case SIMCALL_COMM_IRECV:
-    size = simcall_comm_irecv__get__dst_buff_size(req) ? *simcall_comm_irecv__get__dst_buff_size(req) : 0;
+    size =
+        simcall_comm_irecv__get__dst_buff_size(req) ?
+        *simcall_comm_irecv__get__dst_buff_size(req) : 0;
     type = xbt_strdup("iRecv");
-    p = pointer_to_string(simcall_comm_irecv__get__dst_buff(req)); 
+    p = pointer_to_string(simcall_comm_irecv__get__dst_buff(req));
     bs = buff_size_to_string(size);
-    if(req->issuer->smx_host)
-      args = bprintf("dst=(%lu)%s (%s), buff=%s, size=%s", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host), req->issuer->name, p, bs);
+    if (req->issuer->smx_host)
+      args =
+          bprintf("dst=(%lu)%s (%s), buff=%s, size=%s", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
+                  p, bs);
     else
-      args = bprintf("dst=(%lu)%s, buff=%s, size=%s", req->issuer->pid, req->issuer->name, p, bs);
+      args =
+          bprintf("dst=(%lu)%s, buff=%s, size=%s", req->issuer->pid,
+                  req->issuer->name, p, bs);
     break;
   case SIMCALL_COMM_WAIT:
     act = simcall_comm_wait__get__comm(req);
-    if(value == -1){
+    if (value == -1) {
       type = xbt_strdup("WaitTimeout");
       p = pointer_to_string(act);
       args = bprintf("comm=%s", p);
-    }else{
+    } else {
       type = xbt_strdup("Wait");
       p = pointer_to_string(act);
-      args  = bprintf("comm=%s [(%lu)%s (%s)-> (%lu)%s (%s)]", p,
-                      act->comm.src_proc ? act->comm.src_proc->pid : 0,
-                      act->comm.src_proc ? MSG_host_get_name(act->comm.src_proc->smx_host) : "",
-                      act->comm.src_proc ? act->comm.src_proc->name : "",
-                      act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
-                      act->comm.dst_proc ? MSG_host_get_name(act->comm.dst_proc->smx_host) : "",
-                      act->comm.dst_proc ? act->comm.dst_proc->name : "");
+      args = bprintf("comm=%s [(%lu)%s (%s)-> (%lu)%s (%s)]", p,
+                     act->comm.src_proc ? act->comm.src_proc->pid : 0,
+                     act->comm.src_proc ? MSG_host_get_name(act->comm.src_proc->
+                                                            smx_host) : "",
+                     act->comm.src_proc ? act->comm.src_proc->name : "",
+                     act->comm.dst_proc ? act->comm.dst_proc->pid : 0,
+                     act->comm.dst_proc ? MSG_host_get_name(act->comm.dst_proc->
+                                                            smx_host) : "",
+                     act->comm.dst_proc ? act->comm.dst_proc->name : "");
     }
     break;
   case SIMCALL_COMM_TEST:
     act = simcall_comm_test__get__comm(req);
-    if(act->comm.src_proc == NULL || act->comm.dst_proc == NULL){
+    if (act->comm.src_proc == NULL || act->comm.dst_proc == NULL) {
       type = xbt_strdup("Test FALSE");
       p = pointer_to_string(act);
       args = bprintf("comm=%s", p);
-    }else{
+    } else {
       type = xbt_strdup("Test TRUE");
       p = pointer_to_string(act);
-      args  = bprintf("comm=%s [(%lu)%s (%s) -> (%lu)%s (%s)]", p,
-                      act->comm.src_proc->pid, act->comm.src_proc->name, MSG_host_get_name(act->comm.src_proc->smx_host),
-                      act->comm.dst_proc->pid, act->comm.dst_proc->name, MSG_host_get_name(act->comm.dst_proc->smx_host));
+      args = bprintf("comm=%s [(%lu)%s (%s) -> (%lu)%s (%s)]", p,
+                     act->comm.src_proc->pid, act->comm.src_proc->name,
+                     MSG_host_get_name(act->comm.src_proc->smx_host),
+                     act->comm.dst_proc->pid, act->comm.dst_proc->name,
+                     MSG_host_get_name(act->comm.dst_proc->smx_host));
     }
     break;
 
   case SIMCALL_COMM_WAITANY:
     type = xbt_strdup("WaitAny");
-    if(!xbt_dynar_is_empty(simcall_comm_waitany__get__comms(req))){
-      p = pointer_to_string(xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), value, smx_action_t));
-      args = bprintf("comm=%s (%d of %lu)", p, 
-                     value+1, xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
-    }else{
+    if (!xbt_dynar_is_empty(simcall_comm_waitany__get__comms(req))) {
+      p = pointer_to_string(xbt_dynar_get_as
+                            (simcall_comm_waitany__get__comms(req), value,
+                             smx_action_t));
+      args =
+          bprintf("comm=%s (%d of %lu)", p, value + 1,
+                  xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
+    } else {
       args = bprintf("comm at idx %d", value);
     }
     break;
 
   case SIMCALL_COMM_TESTANY:
-    if(value == -1){
+    if (value == -1) {
       type = xbt_strdup("TestAny FALSE");
       args = xbt_strdup("-");
-    }else{
+    } else {
       type = xbt_strdup("TestAny");
-      args = bprintf("(%d of %lu)", value+1, xbt_dynar_length(simcall_comm_testany__get__comms(req)));
+      args =
+          bprintf("(%d of %lu)", value + 1,
+                  xbt_dynar_length(simcall_comm_testany__get__comms(req)));
     }
     break;
 
@@ -278,10 +345,16 @@ char *MC_request_to_string(smx_simcall_t req, int value)
     THROW_UNIMPLEMENTED;
   }
 
-  if(args != NULL){
-    str = bprintf("[(%lu)%s (%s)] %s(%s)", req->issuer->pid , MSG_host_get_name(req->issuer->smx_host), req->issuer->name, type, args);
-  }else{
-    str = bprintf("[(%lu)%s (%s)] %s ", req->issuer->pid , MSG_host_get_name(req->issuer->smx_host), req->issuer->name, type);
+  if (args != NULL) {
+    str =
+        bprintf("[(%lu)%s (%s)] %s(%s)", req->issuer->pid,
+                MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
+                type, args);
+  } else {
+    str =
+        bprintf("[(%lu)%s (%s)] %s ", req->issuer->pid,
+                MSG_host_get_name(req->issuer->smx_host), req->issuer->name,
+                type);
   }
 
   xbt_free(args);
@@ -296,8 +369,8 @@ unsigned int MC_request_testany_fail(smx_simcall_t req)
   unsigned int cursor;
   smx_action_t action;
 
-  xbt_dynar_foreach(simcall_comm_testany__get__comms(req), cursor, action){
-    if(action->comm.src_proc && action->comm.dst_proc)
+  xbt_dynar_foreach(simcall_comm_testany__get__comms(req), cursor, action) {
+    if (action->comm.src_proc && action->comm.dst_proc)
       return FALSE;
   }
 
@@ -307,14 +380,14 @@ unsigned int MC_request_testany_fail(smx_simcall_t req)
 int MC_request_is_visible(smx_simcall_t req)
 {
   return req->call == SIMCALL_COMM_ISEND
-    || req->call == SIMCALL_COMM_IRECV
-    || req->call == SIMCALL_COMM_WAIT
-    || req->call == SIMCALL_COMM_WAITANY
-    || req->call == SIMCALL_COMM_TEST
-    || req->call == SIMCALL_COMM_TESTANY
-    || req->call == SIMCALL_MC_RANDOM
-    || req->call == SIMCALL_MC_SNAPSHOT
-    || req->call == SIMCALL_MC_COMPARE_SNAPSHOTS;
+      || req->call == SIMCALL_COMM_IRECV
+      || req->call == SIMCALL_COMM_WAIT
+      || req->call == SIMCALL_COMM_WAITANY
+      || req->call == SIMCALL_COMM_TEST
+      || req->call == SIMCALL_COMM_TESTANY
+      || req->call == SIMCALL_MC_RANDOM
+      || req->call == SIMCALL_MC_SNAPSHOT
+      || req->call == SIMCALL_MC_COMPARE_SNAPSHOTS;
 }
 
 int MC_request_is_enabled(smx_simcall_t req)
@@ -330,16 +403,17 @@ int MC_request_is_enabled(smx_simcall_t req)
     /* If it has a timeout it will be always be enabled, because even if the
      * communication is not ready, it can timeout and won't block.
      * On the other hand if it hasn't a timeout, check if the comm is ready.*/
-    if(simcall_comm_wait__get__timeout(req) >= 0){
-      if(_sg_mc_timeout == 1){
+    if (simcall_comm_wait__get__timeout(req) >= 0) {
+      if (_sg_mc_timeout == 1) {
         return TRUE;
-      }else{
+      } else {
         act = simcall_comm_wait__get__comm(req);
         return (act->comm.src_proc && act->comm.dst_proc);
       }
-    }else{
+    } else {
       act = simcall_comm_wait__get__comm(req);
-      if(act->comm.detached && act->comm.src_proc == NULL && act->comm.type == SIMIX_COMM_READY)
+      if (act->comm.detached && act->comm.src_proc == NULL
+          && act->comm.type == SIMIX_COMM_READY)
         return (act->comm.dst_proc != NULL);
       return (act->comm.src_proc && act->comm.dst_proc);
     }
@@ -348,7 +422,7 @@ int MC_request_is_enabled(smx_simcall_t req)
   case SIMCALL_COMM_WAITANY:
     /* Check if it has at least one communication ready */
     xbt_dynar_foreach(simcall_comm_waitany__get__comms(req), index, act) {
-      if (act->comm.src_proc && act->comm.dst_proc){
+      if (act->comm.src_proc && act->comm.dst_proc) {
         return TRUE;
       }
     }
@@ -374,12 +448,16 @@ int MC_request_is_enabled_by_idx(smx_simcall_t req, unsigned int idx)
     break;
 
   case SIMCALL_COMM_WAITANY:
-    act = xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), idx, smx_action_t);
+    act =
+        xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), idx,
+                         smx_action_t);
     return (act->comm.src_proc && act->comm.dst_proc);
     break;
 
   case SIMCALL_COMM_TESTANY:
-    act = xbt_dynar_get_as(simcall_comm_testany__get__comms(req), idx, smx_action_t);
+    act =
+        xbt_dynar_get_as(simcall_comm_testany__get__comms(req), idx,
+                         smx_action_t);
     return (act->comm.src_proc && act->comm.dst_proc);
     break;
 
@@ -390,100 +468,138 @@ int MC_request_is_enabled_by_idx(smx_simcall_t req, unsigned int idx)
 
 int MC_process_is_enabled(smx_process_t process)
 {
-  if (process->simcall.call != SIMCALL_NONE && MC_request_is_enabled(&process->simcall))
+  if (process->simcall.call != SIMCALL_NONE
+      && MC_request_is_enabled(&process->simcall))
     return TRUE;
 
   return FALSE;
 }
 
-char *MC_request_get_dot_output(smx_simcall_t req, int value){
+char *MC_request_get_dot_output(smx_simcall_t req, int value)
+{
 
   char *str = NULL, *label = NULL;
   smx_action_t act = NULL;
 
-  switch(req->call){
+  switch (req->call) {
   case SIMCALL_COMM_ISEND:
-    if(req->issuer->smx_host)
-      label = bprintf("[(%lu)%s] iSend", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (req->issuer->smx_host)
+      label =
+          bprintf("[(%lu)%s] iSend", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host));
     else
       label = bprintf("[(%lu)] iSend", req->issuer->pid);
     break;
-    
+
   case SIMCALL_COMM_IRECV:
-    if(req->issuer->smx_host)
-      label = bprintf("[(%lu)%s] iRecv", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (req->issuer->smx_host)
+      label =
+          bprintf("[(%lu)%s] iRecv", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host));
     else
       label = bprintf("[(%lu)] iRecv", req->issuer->pid);
     break;
-    
+
   case SIMCALL_COMM_WAIT:
     act = simcall_comm_wait__get__comm(req);
-    if(value == -1){
-      if(req->issuer->smx_host)
-        label = bprintf("[(%lu)%s] WaitTimeout", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (value == -1) {
+      if (req->issuer->smx_host)
+        label =
+            bprintf("[(%lu)%s] WaitTimeout", req->issuer->pid,
+                    MSG_host_get_name(req->issuer->smx_host));
       else
         label = bprintf("[(%lu)] WaitTimeout", req->issuer->pid);
-    }else{
-      if(req->issuer->smx_host)
-        label = bprintf("[(%lu)%s] Wait [(%lu)->(%lu)]", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host), act->comm.src_proc ? act->comm.src_proc->pid : 0, act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
+    } else {
+      if (req->issuer->smx_host)
+        label =
+            bprintf("[(%lu)%s] Wait [(%lu)->(%lu)]", req->issuer->pid,
+                    MSG_host_get_name(req->issuer->smx_host),
+                    act->comm.src_proc ? act->comm.src_proc->pid : 0,
+                    act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
       else
-        label = bprintf("[(%lu)] Wait [(%lu)->(%lu)]", req->issuer->pid, act->comm.src_proc ? act->comm.src_proc->pid : 0, act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
+        label =
+            bprintf("[(%lu)] Wait [(%lu)->(%lu)]", req->issuer->pid,
+                    act->comm.src_proc ? act->comm.src_proc->pid : 0,
+                    act->comm.dst_proc ? act->comm.dst_proc->pid : 0);
     }
     break;
-    
+
   case SIMCALL_COMM_TEST:
     act = simcall_comm_test__get__comm(req);
-    if(act->comm.src_proc == NULL || act->comm.dst_proc == NULL){
-      if(req->issuer->smx_host)
-        label = bprintf("[(%lu)%s] Test FALSE", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (act->comm.src_proc == NULL || act->comm.dst_proc == NULL) {
+      if (req->issuer->smx_host)
+        label =
+            bprintf("[(%lu)%s] Test FALSE", req->issuer->pid,
+                    MSG_host_get_name(req->issuer->smx_host));
       else
         label = bprintf("[(%lu)] Test FALSE", req->issuer->pid);
-    }else{
-      if(req->issuer->smx_host)
-        label = bprintf("[(%lu)%s] Test TRUE", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    } else {
+      if (req->issuer->smx_host)
+        label =
+            bprintf("[(%lu)%s] Test TRUE", req->issuer->pid,
+                    MSG_host_get_name(req->issuer->smx_host));
       else
         label = bprintf("[(%lu)] Test TRUE", req->issuer->pid);
     }
     break;
 
   case SIMCALL_COMM_WAITANY:
-    if(req->issuer->smx_host)
-      label = bprintf("[(%lu)%s] WaitAny [%d of %lu]", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host), value+1, xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
+    if (req->issuer->smx_host)
+      label =
+          bprintf("[(%lu)%s] WaitAny [%d of %lu]", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host), value + 1,
+                  xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
     else
-      label = bprintf("[(%lu)] WaitAny [%d of %lu]", req->issuer->pid, value+1, xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
+      label =
+          bprintf("[(%lu)] WaitAny [%d of %lu]", req->issuer->pid, value + 1,
+                  xbt_dynar_length(simcall_comm_waitany__get__comms(req)));
     break;
-    
+
   case SIMCALL_COMM_TESTANY:
-    if(value == -1){
-      if(req->issuer->smx_host)
-        label = bprintf("[(%lu)%s] TestAny FALSE", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (value == -1) {
+      if (req->issuer->smx_host)
+        label =
+            bprintf("[(%lu)%s] TestAny FALSE", req->issuer->pid,
+                    MSG_host_get_name(req->issuer->smx_host));
       else
         label = bprintf("[(%lu)] TestAny FALSE", req->issuer->pid);
-    }else{
-      if(req->issuer->smx_host)
-        label = bprintf("[(%lu)%s] TestAny TRUE [%d of %lu]", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host), value+1, xbt_dynar_length(simcall_comm_testany__get__comms(req)));
+    } else {
+      if (req->issuer->smx_host)
+        label =
+            bprintf("[(%lu)%s] TestAny TRUE [%d of %lu]", req->issuer->pid,
+                    MSG_host_get_name(req->issuer->smx_host), value + 1,
+                    xbt_dynar_length(simcall_comm_testany__get__comms(req)));
       else
-        label = bprintf("[(%lu)] TestAny TRUE [%d of %lu]", req->issuer->pid, value+1, xbt_dynar_length(simcall_comm_testany__get__comms(req)));
+        label =
+            bprintf("[(%lu)] TestAny TRUE [%d of %lu]", req->issuer->pid,
+                    value + 1,
+                    xbt_dynar_length(simcall_comm_testany__get__comms(req)));
     }
     break;
 
   case SIMCALL_MC_RANDOM:
-    if(req->issuer->smx_host)
-      label = bprintf("[(%lu)%s] MC_RANDOM (%d)", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host), value);
+    if (req->issuer->smx_host)
+      label =
+          bprintf("[(%lu)%s] MC_RANDOM (%d)", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host), value);
     else
       label = bprintf("[(%lu)] MC_RANDOM (%d)", req->issuer->pid, value);
     break;
 
   case SIMCALL_MC_SNAPSHOT:
-    if(req->issuer->smx_host)
-      label = bprintf("[(%lu)%s] MC_SNAPSHOT", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (req->issuer->smx_host)
+      label =
+          bprintf("[(%lu)%s] MC_SNAPSHOT", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host));
     else
       label = bprintf("[(%lu)] MC_SNAPSHOT", req->issuer->pid);
     break;
 
   case SIMCALL_MC_COMPARE_SNAPSHOTS:
-    if(req->issuer->smx_host)
-      label = bprintf("[(%lu)%s] MC_COMPARE_SNAPSHOTS", req->issuer->pid, MSG_host_get_name(req->issuer->smx_host));
+    if (req->issuer->smx_host)
+      label =
+          bprintf("[(%lu)%s] MC_COMPARE_SNAPSHOTS", req->issuer->pid,
+                  MSG_host_get_name(req->issuer->smx_host));
     else
       label = bprintf("[(%lu)] MC_COMPARE_SNAPSHOTS", req->issuer->pid);
     break;
@@ -492,7 +608,9 @@ char *MC_request_get_dot_output(smx_simcall_t req, int value){
     THROW_UNIMPLEMENTED;
   }
 
-  str = bprintf("label = \"%s\", color = %s, fontcolor = %s", label, colors[req->issuer->pid-1], colors[req->issuer->pid-1]);
+  str =
+      bprintf("label = \"%s\", color = %s, fontcolor = %s", label,
+              colors[req->issuer->pid - 1], colors[req->issuer->pid - 1]);
   xbt_free(label);
   return str;
 
diff --git a/src/mc/mc_safety.c b/src/mc/mc_safety.c
new file mode 100644 (file)
index 0000000..6f671f2
--- /dev/null
@@ -0,0 +1,369 @@
+/* Copyright (c) 2008-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "mc_private.h"
+
+#include "xbt/mmalloc/mmprivate.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_safety, mc,
+                                "Logging specific to MC safety verification ");
+
+xbt_dict_t first_enabled_state;
+
+/**
+ *  \brief Initialize the DPOR exploration algorithm
+ */
+void MC_pre_modelcheck_safety()
+{
+
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  mc_state_t initial_state = NULL;
+  smx_process_t process;
+
+  /* Create the initial state and push it into the exploration stack */
+  if (!mc_mem_set)
+    MC_SET_MC_HEAP;
+
+  if (_sg_mc_visited > 0)
+    visited_states =
+        xbt_dynar_new(sizeof(mc_visited_state_t), visited_state_free_voidp);
+
+  if (mc_reduce_kind == e_mc_reduce_dpor)
+    first_enabled_state = xbt_dict_new_homogeneous(&xbt_free_f);
+
+  initial_state = MC_state_new();
+
+  MC_SET_STD_HEAP;
+
+  XBT_DEBUG("**************************************************");
+  XBT_DEBUG("Initial state");
+
+  /* Wait for requests (schedules processes) */
+  MC_wait_for_requests();
+
+  MC_SET_MC_HEAP;
+
+  /* Get an enabled process and insert it in the interleave set of the initial state */
+  xbt_swag_foreach(process, simix_global->process_list) {
+    if (MC_process_is_enabled(process)) {
+      MC_state_interleave_process(initial_state, process);
+      if (mc_reduce_kind != e_mc_reduce_none)
+        break;
+    }
+  }
+
+  xbt_fifo_unshift(mc_stack, initial_state);
+
+  if (mc_reduce_kind == e_mc_reduce_dpor) {
+    /* To ensure the soundness of DPOR, we have to keep a list of 
+       processes which are still enabled at each step of the exploration. 
+       If max depth is reached, we interleave them in the state in which they have 
+       been enabled for the first time. */
+    xbt_swag_foreach(process, simix_global->process_list) {
+      if (MC_process_is_enabled(process)) {
+        char *key = bprintf("%lu", process->pid);
+        char *data = bprintf("%d", xbt_fifo_size(mc_stack));
+        xbt_dict_set(first_enabled_state, key, data, NULL);
+        xbt_free(key);
+      }
+    }
+  }
+
+  if (!mc_mem_set)
+    MC_SET_STD_HEAP;
+}
+
+
+/** \brief Model-check the application using a DFS exploration
+ *         with DPOR (Dynamic Partial Order Reductions)
+ */
+void MC_modelcheck_safety(void)
+{
+
+  char *req_str = NULL;
+  int value;
+  smx_simcall_t req = NULL, prev_req = NULL;
+  mc_state_t state = NULL, prev_state = NULL, next_state =
+      NULL, restored_state = NULL;
+  smx_process_t process = NULL;
+  xbt_fifo_item_t item = NULL;
+  mc_state_t state_test = NULL;
+  int pos;
+  mc_visited_state_t visited_state = NULL;
+  int enabled = 0;
+
+  while (xbt_fifo_size(mc_stack) > 0) {
+
+    /* Get current state */
+    state = (mc_state_t)
+        xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack));
+
+    XBT_DEBUG("**************************************************");
+    XBT_DEBUG
+        ("Exploration depth=%d (state=%p, num %d)(%u interleave, user_max_depth %d, first_enabled_state size : %d)",
+         xbt_fifo_size(mc_stack), state, state->num,
+         MC_state_interleave_size(state), user_max_depth_reached,
+         xbt_dict_size(first_enabled_state));
+
+    /* Update statistics */
+    mc_stats->visited_states++;
+
+    /* If there are processes to interleave and the maximum depth has not been reached
+       then perform one step of the exploration algorithm */
+    if (xbt_fifo_size(mc_stack) <= _sg_mc_max_depth && !user_max_depth_reached
+        && (req = MC_state_get_request(state, &value)) && visited_state == NULL) {
+
+      /* Debug information */
+      if (XBT_LOG_ISENABLED(mc_safety, xbt_log_priority_debug)) {
+        req_str = MC_request_to_string(req, value);
+        XBT_DEBUG("Execute: %s", req_str);
+        xbt_free(req_str);
+      }
+
+      MC_SET_MC_HEAP;
+      if (dot_output != NULL)
+        req_str = MC_request_get_dot_output(req, value);
+      MC_SET_STD_HEAP;
+
+      MC_state_set_executed_request(state, req, value);
+      mc_stats->executed_transitions++;
+
+      if (mc_reduce_kind == e_mc_reduce_dpor) {
+        MC_SET_MC_HEAP;
+        char *key = bprintf("%lu", req->issuer->pid);
+        xbt_dict_remove(first_enabled_state, key);
+        xbt_free(key);
+        MC_SET_STD_HEAP;
+      }
+
+      /* Answer the request */
+      SIMIX_simcall_pre(req, value);
+
+      /* Wait for requests (schedules processes) */
+      MC_wait_for_requests();
+
+      /* Create the new expanded state */
+      MC_SET_MC_HEAP;
+
+      next_state = MC_state_new();
+
+      if ((visited_state = is_visited_state()) == NULL) {
+
+        /* Get an enabled process and insert it in the interleave set of the next state */
+        xbt_swag_foreach(process, simix_global->process_list) {
+          if (MC_process_is_enabled(process)) {
+            MC_state_interleave_process(next_state, process);
+            if (mc_reduce_kind != e_mc_reduce_none)
+              break;
+          }
+        }
+
+        if (_sg_mc_checkpoint
+            && ((xbt_fifo_size(mc_stack) + 1) % _sg_mc_checkpoint == 0)) {
+          next_state->system_state = MC_take_snapshot(next_state->num);
+        }
+
+        if (dot_output != NULL)
+          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num,
+                  next_state->num, req_str);
+
+      } else {
+
+        if (dot_output != NULL)
+          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num,
+                  visited_state->other_num == -1 ? visited_state->num : visited_state->other_num, req_str);
+
+      }
+
+      xbt_fifo_unshift(mc_stack, next_state);
+
+      if (mc_reduce_kind == e_mc_reduce_dpor) {
+        /* Insert in dict all enabled processes, if not included yet */
+        xbt_swag_foreach(process, simix_global->process_list) {
+          if (MC_process_is_enabled(process)) {
+            char *key = bprintf("%lu", process->pid);
+            if (xbt_dict_get_or_null(first_enabled_state, key) == NULL) {
+              char *data = bprintf("%d", xbt_fifo_size(mc_stack));
+              xbt_dict_set(first_enabled_state, key, data, NULL);
+            }
+            xbt_free(key);
+          }
+        }
+      }
+
+      if (dot_output != NULL)
+        xbt_free(req_str);
+
+      MC_SET_STD_HEAP;
+
+      /* Let's loop again */
+
+      /* The interleave set is empty or the maximum depth is reached, let's back-track */
+    } else {
+
+      if ((xbt_fifo_size(mc_stack) > _sg_mc_max_depth) || user_max_depth_reached
+          || visited_state != NULL) {
+
+        if (user_max_depth_reached && visited_state == NULL)
+          XBT_DEBUG("User max depth reached !");
+        else if (visited_state == NULL)
+          XBT_WARN("/!\\ Max depth reached ! /!\\ ");
+        else
+          XBT_DEBUG("State already visited (equal to state %d), exploration stopped on this path.", visited_state->other_num == -1 ? visited_state->num : visited_state->other_num);
+
+        if (mc_reduce_kind == e_mc_reduce_dpor) {
+          /* Interleave enabled processes in the state in which they have been enabled for the first time */
+          xbt_swag_foreach(process, simix_global->process_list) {
+            if (MC_process_is_enabled(process)) {
+              char *key = bprintf("%lu", process->pid);
+              enabled =
+                  (int) strtoul(xbt_dict_get_or_null(first_enabled_state, key),
+                                0, 10);
+              xbt_free(key);
+              int cursor = xbt_fifo_size(mc_stack);
+              xbt_fifo_foreach(mc_stack, item, state_test, mc_state_t) {
+                if (cursor-- == enabled) {
+                  if (!MC_state_process_is_done(state_test, process)
+                      && state_test->num != state->num) {
+                    XBT_DEBUG("Interleave process %lu in state %d",
+                              process->pid, state_test->num);
+                    MC_state_interleave_process(state_test, process);
+                    break;
+                  }
+                }
+              }
+            }
+          }
+        }
+
+      } else {
+
+        XBT_DEBUG("There are no more processes to interleave. (depth %d)",
+                  xbt_fifo_size(mc_stack) + 1);
+
+      }
+
+      MC_SET_MC_HEAP;
+
+      /* Trash the current state, no longer needed */
+      xbt_fifo_shift(mc_stack);
+      MC_state_delete(state);
+      XBT_DEBUG("Delete state %d at depth %d", state->num,
+                xbt_fifo_size(mc_stack) + 1);
+
+      MC_SET_STD_HEAP;
+
+      visited_state = NULL;
+
+      /* Check for deadlocks */
+      if (MC_deadlock_check()) {
+        MC_show_deadlock(NULL);
+        return;
+      }
+
+      MC_SET_MC_HEAP;
+      /* Traverse the stack backwards until a state with a non empty interleave
+         set is found, deleting all the states that have it empty in the way.
+         For each deleted state, check if the request that has generated it 
+         (from it's predecesor state), depends on any other previous request 
+         executed before it. If it does then add it to the interleave set of the
+         state that executed that previous request. */
+
+      while ((state = xbt_fifo_shift(mc_stack)) != NULL) {
+        if (mc_reduce_kind == e_mc_reduce_dpor) {
+          req = MC_state_get_internal_request(state);
+          xbt_fifo_foreach(mc_stack, item, prev_state, mc_state_t) {
+            if (MC_request_depend
+                (req, MC_state_get_internal_request(prev_state))) {
+              if (XBT_LOG_ISENABLED(mc_safety, xbt_log_priority_debug)) {
+                XBT_DEBUG("Dependent Transitions:");
+                prev_req = MC_state_get_executed_request(prev_state, &value);
+                req_str = MC_request_to_string(prev_req, value);
+                XBT_DEBUG("%s (state=%d)", req_str, prev_state->num);
+                xbt_free(req_str);
+                prev_req = MC_state_get_executed_request(state, &value);
+                req_str = MC_request_to_string(prev_req, value);
+                XBT_DEBUG("%s (state=%d)", req_str, state->num);
+                xbt_free(req_str);
+              }
+
+              if (!MC_state_process_is_done(prev_state, req->issuer))
+                MC_state_interleave_process(prev_state, req->issuer);
+              else
+                XBT_DEBUG("Process %p is in done set", req->issuer);
+
+              break;
+
+            } else if (req->issuer ==
+                       MC_state_get_internal_request(prev_state)->issuer) {
+
+              XBT_DEBUG("Simcall %d and %d with same issuer", req->call,
+                        MC_state_get_internal_request(prev_state)->call);
+              break;
+
+            } else {
+
+              XBT_DEBUG
+                  ("Simcall %d, process %lu (state %d) and simcall %d, process %lu (state %d) are independant",
+                   req->call, req->issuer->pid, state->num,
+                   MC_state_get_internal_request(prev_state)->call,
+                   MC_state_get_internal_request(prev_state)->issuer->pid,
+                   prev_state->num);
+
+            }
+          }
+        }
+
+        if (MC_state_interleave_size(state)
+            && xbt_fifo_size(mc_stack) < _sg_mc_max_depth) {
+          /* We found a back-tracking point, let's loop */
+          XBT_DEBUG("Back-tracking to state %d at depth %d", state->num,
+                    xbt_fifo_size(mc_stack) + 1);
+          if (_sg_mc_checkpoint) {
+            if (state->system_state != NULL) {
+              MC_restore_snapshot(state->system_state);
+              xbt_fifo_unshift(mc_stack, state);
+              MC_SET_STD_HEAP;
+            } else {
+              pos = xbt_fifo_size(mc_stack);
+              item = xbt_fifo_get_first_item(mc_stack);
+              while (pos > 0) {
+                restored_state = (mc_state_t) xbt_fifo_get_item_content(item);
+                if (restored_state->system_state != NULL) {
+                  break;
+                } else {
+                  item = xbt_fifo_get_next_item(item);
+                  pos--;
+                }
+              }
+              MC_restore_snapshot(restored_state->system_state);
+              xbt_fifo_unshift(mc_stack, state);
+              MC_SET_STD_HEAP;
+              MC_replay(mc_stack, pos);
+            }
+          } else {
+            xbt_fifo_unshift(mc_stack, state);
+            MC_SET_STD_HEAP;
+            MC_replay(mc_stack, -1);
+          }
+          XBT_DEBUG("Back-tracking to state %d at depth %d done", state->num,
+                    xbt_fifo_size(mc_stack));
+          break;
+        } else {
+          XBT_DEBUG("Delete state %d at depth %d", state->num,
+                    xbt_fifo_size(mc_stack) + 1);
+          MC_state_delete(state);
+        }
+      }
+      MC_SET_STD_HEAP;
+    }
+  }
+  MC_print_statistics(mc_stats);
+  MC_SET_STD_HEAP;
+
+  return;
+}
diff --git a/src/mc/mc_snapshot.c b/src/mc/mc_snapshot.c
new file mode 100644 (file)
index 0000000..a7bd4df
--- /dev/null
@@ -0,0 +1,124 @@
+/* Copyright (c) 2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdbool.h>
+
+#include "mc_private.h"
+#include "mc_mmu.h"
+#include "mc_page_store.h"
+
+mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot)
+{
+  for (size_t i = 0; i != NB_REGIONS; ++i) {
+    mc_mem_region_t region = snapshot->regions[i];
+    void* start = region->start_addr;
+    void* end = (char*) start + region->size;
+
+    if (addr >= start && addr < end) {
+      return region;
+    }
+  }
+
+  return NULL;
+}
+
+/** @brief Read memory from a snapshot region broken across fragmented pages
+ *
+ *  @param addr    Process (non-snapshot) address of the data
+ *  @param region  Snapshot memory region where the data is located
+ *  @param target  Buffer to store the value
+ *  @param size    Size of the data to read in bytes
+ *  @return Pointer where the data is located (target buffer of original location)
+ */
+void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size)
+{
+  void* end = (char*) addr + size - 1;
+  size_t page_end = mc_page_number(NULL, end);
+  void* dest = target;
+
+  // Read each page:
+  while (mc_page_number(NULL, addr) != page_end) {
+    void* snapshot_addr = mc_translate_address_region((uintptr_t) addr, region);
+    void* next_page = mc_page_from_number(NULL, mc_page_number(NULL, addr) + 1);
+    size_t readable = (char*) next_page - (char*) addr;
+    memcpy(dest, snapshot_addr, readable);
+    addr = (char*) addr + readable;
+    dest = (char*) dest + readable;
+    size -= readable;
+  }
+
+  // Read the end:
+  void* snapshot_addr = mc_translate_address_region((uintptr_t)addr, region);
+  memcpy(dest, snapshot_addr, size);
+
+  return target;
+}
+
+/** @brief Read memory from a snapshot
+ *
+ *  @param addr     Process (non-snapshot) address of the data
+ *  @param snapshot Snapshot (or NULL is no snapshot)
+ *  @param target   Buffer to store the value
+ *  @param size     Size of the data to read in bytes
+ *  @return Pointer where the data is located (target buffer of original location)
+ */
+void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, void* target, size_t size)
+{
+  if (snapshot) {
+    mc_mem_region_t region = mc_get_snapshot_region(addr, snapshot);
+    return mc_snapshot_read_region(addr, region, target, size);
+  } else {
+    return addr;
+  }
+}
+
+/** Compare memory between snapshots (with known regions)
+ *
+ * @param addr1 Address in the first snapshot
+ * @param snapshot2 Region of the address in the first snapshot
+ * @param addr2 Address in the second snapshot
+ * @param snapshot2 Region of the address in the second snapshot
+ * @return same as memcmp
+ * */
+int mc_snapshot_region_memcp(
+  void* addr1, mc_mem_region_t region1,
+  void* addr2, mc_mem_region_t region2, size_t size)
+{
+  // Using alloca() for large allocations may trigger stack overflow:
+  // use malloc if the buffer is too big.
+
+  bool stack_alloc = size < 64;
+  void* buffer = stack_alloc ? alloca(2*size) : malloc(2*size);
+  void* buffer1 = mc_snapshot_read_region(addr1, region1, buffer, size);
+  void* buffer2 = mc_snapshot_read_region(addr2, region2, (char*) buffer + size, size);
+  int res;
+  if (buffer1 == buffer2) {
+    res =  0;
+  } else {
+    res = memcmp(buffer1, buffer2, size);
+  }
+  if (!stack_alloc) {
+    free(buffer);
+  }
+  return res;
+}
+
+/** Compare memory between snapshots
+ *
+ * @param addr1 Address in the first snapshot
+ * @param snapshot1 First snapshot
+ * @param addr2 Address in the second snapshot
+ * @param snapshot2 Second snapshot
+ * @return same as memcmp
+ * */
+int mc_snapshot_memcp(
+  void* addr1, mc_snapshot_t snapshot1,
+  void* addr2, mc_snapshot_t snapshot2, size_t size)
+{
+  mc_mem_region_t region1 = mc_get_snapshot_region(addr1, snapshot1);
+  mc_mem_region_t region2 = mc_get_snapshot_region(addr2, snapshot2);
+  return mc_snapshot_region_memcp(addr1, region1, addr2, region2, size);
+}
index 64dcb1a..d48d10c 100644 (file)
 mc_state_t MC_state_new()
 {
   mc_state_t state = NULL;
-  
+
   state = xbt_new0(s_mc_state_t, 1);
   state->max_pid = simix_process_maxpid;
   state->proc_status = xbt_new0(s_mc_procstate_t, state->max_pid);
   state->system_state = NULL;
   state->num = ++mc_stats->expanded_states;
-  
+
   return state;
 }
 
@@ -30,7 +30,7 @@ mc_state_t MC_state_new()
  */
 void MC_state_delete(mc_state_t state)
 {
-  if(state->system_state)
+  if (state->system_state)
     MC_free_snapshot(state->system_state);
   xbt_free(state->proc_status);
   xbt_free(state);
@@ -44,27 +44,30 @@ void MC_state_interleave_process(mc_state_t state, smx_process_t process)
 
 void MC_state_remove_interleave_process(mc_state_t state, smx_process_t process)
 {
-  if(state->proc_status[process->pid].state == MC_INTERLEAVE)
+  if (state->proc_status[process->pid].state == MC_INTERLEAVE)
     state->proc_status[process->pid].state = MC_DONE;
 }
 
 unsigned int MC_state_interleave_size(mc_state_t state)
 {
-  unsigned int i, size=0;
+  unsigned int i, size = 0;
 
-  for(i=0; i < state->max_pid; i++){
-    if((state->proc_status[i].state == MC_INTERLEAVE) || (state->proc_status[i].state == MC_MORE_INTERLEAVE))
+  for (i = 0; i < state->max_pid; i++) {
+    if ((state->proc_status[i].state == MC_INTERLEAVE)
+        || (state->proc_status[i].state == MC_MORE_INTERLEAVE))
       size++;
   }
 
   return size;
 }
 
-int MC_state_process_is_done(mc_state_t state, smx_process_t process){
+int MC_state_process_is_done(mc_state_t state, smx_process_t process)
+{
   return state->proc_status[process->pid].state == MC_DONE ? TRUE : FALSE;
 }
 
-void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req, int value)
+void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req,
+                                   int value)
 {
   state->executed_req = *req;
   state->req_num = value;
@@ -74,59 +77,63 @@ void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req, int valu
   /* The waitany and testany request are transformed into a wait or test request over the
    * corresponding communication action so it can be treated later by the dependence
    * function. */
-  switch(req->call){
-    case SIMCALL_COMM_WAITANY:
-      state->internal_req.call = SIMCALL_COMM_WAIT;
-      state->internal_req.issuer = req->issuer;
-      state->internal_comm = *xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), value, smx_action_t);
-      simcall_comm_wait__set__comm(&state->internal_req, &state->internal_comm);
-      simcall_comm_wait__set__timeout(&state->internal_req, 0);
-      break;
-
-    case SIMCALL_COMM_TESTANY:
-      state->internal_req.call = SIMCALL_COMM_TEST;
-      state->internal_req.issuer = req->issuer;
-
-      if(value > 0)
-        state->internal_comm = *xbt_dynar_get_as(simcall_comm_testany__get__comms(req), value, smx_action_t);
-
-      simcall_comm_test__set__comm(&state->internal_req, &state->internal_comm);
-      simcall_comm_test__set__result(&state->internal_req, value);
-      break;
-
-    case SIMCALL_COMM_WAIT:
-      state->internal_req = *req;
-      state->internal_comm = *(simcall_comm_wait__get__comm(req));
-      simcall_comm_wait__set__comm(&state->executed_req, &state->internal_comm);
-      simcall_comm_wait__set__comm(&state->internal_req, &state->internal_comm);
-      break;
-
-    case SIMCALL_COMM_TEST:
-      state->internal_req = *req;
-      state->internal_comm = *simcall_comm_test__get__comm(req);
-      simcall_comm_test__set__comm(&state->executed_req, &state->internal_comm);
-      simcall_comm_test__set__comm(&state->internal_req, &state->internal_comm);
-      break;
-
-    case SIMCALL_MC_RANDOM:
-      state->internal_req = *req;
-      if(value != simcall_mc_random__get__max(req)){
-        xbt_swag_foreach(process, simix_global->process_list){
-          procstate = &state->proc_status[process->pid];
-          if(process->pid == req->issuer->pid){
-            procstate->state = MC_MORE_INTERLEAVE;
-            break;
-          }        
+  switch (req->call) {
+  case SIMCALL_COMM_WAITANY:
+    state->internal_req.call = SIMCALL_COMM_WAIT;
+    state->internal_req.issuer = req->issuer;
+    state->internal_comm =
+        *xbt_dynar_get_as(simcall_comm_waitany__get__comms(req), value,
+                          smx_action_t);
+    simcall_comm_wait__set__comm(&state->internal_req, &state->internal_comm);
+    simcall_comm_wait__set__timeout(&state->internal_req, 0);
+    break;
+
+  case SIMCALL_COMM_TESTANY:
+    state->internal_req.call = SIMCALL_COMM_TEST;
+    state->internal_req.issuer = req->issuer;
+
+    if (value > 0)
+      state->internal_comm =
+          *xbt_dynar_get_as(simcall_comm_testany__get__comms(req), value,
+                            smx_action_t);
+
+    simcall_comm_test__set__comm(&state->internal_req, &state->internal_comm);
+    simcall_comm_test__set__result(&state->internal_req, value);
+    break;
+
+  case SIMCALL_COMM_WAIT:
+    state->internal_req = *req;
+    state->internal_comm = *(simcall_comm_wait__get__comm(req));
+    simcall_comm_wait__set__comm(&state->executed_req, &state->internal_comm);
+    simcall_comm_wait__set__comm(&state->internal_req, &state->internal_comm);
+    break;
+
+  case SIMCALL_COMM_TEST:
+    state->internal_req = *req;
+    state->internal_comm = *simcall_comm_test__get__comm(req);
+    simcall_comm_test__set__comm(&state->executed_req, &state->internal_comm);
+    simcall_comm_test__set__comm(&state->internal_req, &state->internal_comm);
+    break;
+
+  case SIMCALL_MC_RANDOM:
+    state->internal_req = *req;
+    if (value != simcall_mc_random__get__max(req)) {
+      xbt_swag_foreach(process, simix_global->process_list) {
+        procstate = &state->proc_status[process->pid];
+        if (process->pid == req->issuer->pid) {
+          procstate->state = MC_MORE_INTERLEAVE;
+          break;
         }
       }
-      break;
+    }
+    break;
 
-    default:
-      state->internal_req = *req;
-      break;
+  default:
+    state->internal_req = *req;
+    break;
   }
 }
+
 smx_simcall_t MC_state_get_executed_request(mc_state_t state, int *value)
 {
   *value = state->req_num;
@@ -145,78 +152,90 @@ smx_simcall_t MC_state_get_request(mc_state_t state, int *value)
   unsigned int start_count;
   smx_action_t act = NULL;
 
-  xbt_swag_foreach(process, simix_global->process_list){
+  xbt_swag_foreach(process, simix_global->process_list) {
     procstate = &state->proc_status[process->pid];
 
-    if(procstate->state == MC_INTERLEAVE || procstate->state == MC_MORE_INTERLEAVE){
-      if(MC_process_is_enabled(process)){
-        switch(process->simcall.call){
-          case SIMCALL_COMM_WAITANY:
-            *value = -1;
-            while(procstate->interleave_count < xbt_dynar_length(simcall_comm_waitany__get__comms(&process->simcall))){
-              if(MC_request_is_enabled_by_idx(&process->simcall, procstate->interleave_count++)){
-                *value = procstate->interleave_count-1;
-                break;
-              }
+    if (procstate->state == MC_INTERLEAVE
+        || procstate->state == MC_MORE_INTERLEAVE) {
+      if (MC_process_is_enabled(process)) {
+        switch (process->simcall.call) {
+        case SIMCALL_COMM_WAITANY:
+          *value = -1;
+          while (procstate->interleave_count <
+                 xbt_dynar_length(simcall_comm_waitany__get__comms
+                                  (&process->simcall))) {
+            if (MC_request_is_enabled_by_idx
+                (&process->simcall, procstate->interleave_count++)) {
+              *value = procstate->interleave_count - 1;
+              break;
             }
+          }
 
-            if(procstate->interleave_count >= xbt_dynar_length(simcall_comm_waitany__get__comms(&process->simcall)))
-              procstate->state = MC_DONE;
-
-            if(*value != -1)
-              return &process->simcall;
+          if (procstate->interleave_count >=
+              xbt_dynar_length(simcall_comm_waitany__get__comms
+                               (&process->simcall)))
+            procstate->state = MC_DONE;
 
-            break;
+          if (*value != -1)
+            return &process->simcall;
 
-          case SIMCALL_COMM_TESTANY:
-            start_count = procstate->interleave_count;
-            *value = -1;
-            while(procstate->interleave_count < xbt_dynar_length(simcall_comm_testany__get__comms(&process->simcall))){
-              if(MC_request_is_enabled_by_idx(&process->simcall, procstate->interleave_count++)){
-                *value = procstate->interleave_count - 1;
-                break;
-              }
+          break;
+
+        case SIMCALL_COMM_TESTANY:
+          start_count = procstate->interleave_count;
+          *value = -1;
+          while (procstate->interleave_count <
+                 xbt_dynar_length(simcall_comm_testany__get__comms
+                                  (&process->simcall))) {
+            if (MC_request_is_enabled_by_idx
+                (&process->simcall, procstate->interleave_count++)) {
+              *value = procstate->interleave_count - 1;
+              break;
             }
+          }
 
-            if(procstate->interleave_count >= xbt_dynar_length(simcall_comm_testany__get__comms(&process->simcall)))
-              procstate->state = MC_DONE;
+          if (procstate->interleave_count >=
+              xbt_dynar_length(simcall_comm_testany__get__comms
+                               (&process->simcall)))
+            procstate->state = MC_DONE;
 
-            if(*value != -1 || start_count == 0)
-              return &process->simcall;
+          if (*value != -1 || start_count == 0)
+            return &process->simcall;
 
-            break;
+          break;
 
-          case SIMCALL_COMM_WAIT:
-            act = simcall_comm_wait__get__comm(&process->simcall);
-            if(act->comm.src_proc && act->comm.dst_proc){
+        case SIMCALL_COMM_WAIT:
+          act = simcall_comm_wait__get__comm(&process->simcall);
+          if (act->comm.src_proc && act->comm.dst_proc) {
+            *value = 0;
+          } else {
+            if (act->comm.src_proc == NULL && act->comm.type == SIMIX_COMM_READY
+                && act->comm.detached == 1)
               *value = 0;
-            }else{
-              if(act->comm.src_proc == NULL && act->comm.type == SIMIX_COMM_READY && act->comm.detached == 1)
-                *value = 0;
-              else
-                *value = -1;
-            }
-            procstate->state = MC_DONE;
-            return &process->simcall;
+            else
+              *value = -1;
+          }
+          procstate->state = MC_DONE;
+          return &process->simcall;
 
-            break;
+          break;
 
-          case SIMCALL_MC_RANDOM:
-            if(procstate->state == MC_INTERLEAVE)
-              *value = 0;
-            else{
-              if(state->req_num < simcall_mc_random__get__max(&process->simcall))
-                *value = state->req_num + 1;
-            }
-            procstate->state = MC_DONE;
-            return &process->simcall;
-            break;
-          
-          default:
-            procstate->state = MC_DONE;
+        case SIMCALL_MC_RANDOM:
+          if (procstate->state == MC_INTERLEAVE)
             *value = 0;
-            return &process->simcall;
-            break;
+          else {
+            if (state->req_num < simcall_mc_random__get__max(&process->simcall))
+              *value = state->req_num + 1;
+          }
+          procstate->state = MC_DONE;
+          return &process->simcall;
+          break;
+
+        default:
+          procstate->state = MC_DONE;
+          *value = 0;
+          return &process->simcall;
+          break;
         }
       }
     }
diff --git a/src/mc/mc_visited.c b/src/mc/mc_visited.c
new file mode 100644 (file)
index 0000000..ac7c56b
--- /dev/null
@@ -0,0 +1,494 @@
+/* Copyright (c) 2011-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "mc_private.h"
+#include <unistd.h>
+#include <sys/wait.h>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_visited, mc,
+                                "Logging specific to state equaity detection mechanisms");
+
+xbt_dynar_t visited_pairs;
+xbt_dynar_t visited_states;
+
+void visited_state_free(mc_visited_state_t state)
+{
+  if (state) {
+    MC_free_snapshot(state->system_state);
+    xbt_free(state);
+  }
+}
+
+void visited_state_free_voidp(void *s)
+{
+  visited_state_free((mc_visited_state_t) * (void **) s);
+}
+
+/**
+ * \brief Save the current state
+ * \return Snapshot of the current state.
+ */
+static mc_visited_state_t visited_state_new()
+{
+  mc_visited_state_t new_state = NULL;
+  new_state = xbt_new0(s_mc_visited_state_t, 1);
+  new_state->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
+  new_state->nb_processes = xbt_swag_size(simix_global->process_list);
+  new_state->system_state = MC_take_snapshot(mc_stats->expanded_states);
+  new_state->num = mc_stats->expanded_states;
+  new_state->other_num = -1;
+  return new_state;
+}
+
+
+mc_visited_pair_t MC_visited_pair_new(int pair_num,
+                                      xbt_automaton_state_t automaton_state,
+                                      xbt_dynar_t atomic_propositions)
+{
+  mc_visited_pair_t pair = NULL;
+  pair = xbt_new0(s_mc_visited_pair_t, 1);
+  pair->graph_state = MC_state_new();
+  pair->graph_state->system_state = MC_take_snapshot(pair_num);
+  pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
+  pair->nb_processes = xbt_swag_size(simix_global->process_list);
+  pair->automaton_state = automaton_state;
+  pair->num = pair_num;
+  pair->other_num = -1;
+  pair->acceptance_removed = 0;
+  pair->visited_removed = 0;
+  pair->acceptance_pair = 0;
+  pair->atomic_propositions = xbt_dynar_new(sizeof(int), NULL);
+  unsigned int cursor = 0;
+  int value;
+  xbt_dynar_foreach(atomic_propositions, cursor, value)
+      xbt_dynar_push_as(pair->atomic_propositions, int, value);
+  return pair;
+}
+
+void MC_visited_pair_delete(mc_visited_pair_t p)
+{
+  p->automaton_state = NULL;
+  MC_state_delete(p->graph_state);
+  xbt_dynar_free(&(p->atomic_propositions));
+  xbt_free(p);
+  p = NULL;
+}
+
+/**
+ *  \brief Find a suitable subrange of candidate duplicates for a given state
+ *  \param list dynamic array of states/pairs with candidate duplicates of the current state;
+ *  \param ref current state/pair;
+ *  \param min (output) index of the beginning of the the subrange
+ *  \param max (output) index of the enf of the subrange
+ *
+ *  Given a suitably ordered array of states/pairs, this function extracts a subrange
+ *  (with index *min <= i <= *max) with candidate duplicates of the given state/pair.
+ *  This function uses only fast discriminating criterions and does not use the
+ *  full state/pair comparison algorithms.
+ *
+ *  The states/pairs in list MUST be ordered using a (given) weak order
+ *  (based on nb_processes and heap_bytes_used).
+ *  The subrange is the subrange of "equivalence" of the given state/pair.
+ */
+int get_search_interval(xbt_dynar_t list, void *ref, int *min, int *max)
+{
+
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  int cursor = 0, previous_cursor, next_cursor;
+  int nb_processes, heap_bytes_used, nb_processes_test, heap_bytes_used_test;
+  void *ref_test;
+
+  if (_sg_mc_liveness) {
+    nb_processes = ((mc_visited_pair_t) ref)->nb_processes;
+    heap_bytes_used = ((mc_visited_pair_t) ref)->heap_bytes_used;
+  } else {
+    nb_processes = ((mc_visited_state_t) ref)->nb_processes;
+    heap_bytes_used = ((mc_visited_state_t) ref)->heap_bytes_used;
+  }
+
+  int start = 0;
+  int end = xbt_dynar_length(list) - 1;
+
+  while (start <= end) {
+    cursor = (start + end) / 2;
+    if (_sg_mc_liveness) {
+      ref_test =
+        (mc_visited_pair_t) xbt_dynar_get_as(list, cursor, mc_visited_pair_t);
+      nb_processes_test = ((mc_visited_pair_t) ref_test)->nb_processes;
+      heap_bytes_used_test = ((mc_visited_pair_t) ref_test)->heap_bytes_used;
+    } else {
+      ref_test =
+        (mc_visited_state_t) xbt_dynar_get_as(list, cursor,
+                                              mc_visited_state_t);
+      nb_processes_test = ((mc_visited_state_t) ref_test)->nb_processes;
+      heap_bytes_used_test = ((mc_visited_state_t) ref_test)->heap_bytes_used;
+    }
+    if (nb_processes_test < nb_processes) {
+      start = cursor + 1;
+    } else if (nb_processes_test > nb_processes) {
+      end = cursor - 1;
+    } else {
+      if (heap_bytes_used_test < heap_bytes_used) {
+        start = cursor + 1;
+      } else if (heap_bytes_used_test > heap_bytes_used) {
+        end = cursor - 1;
+      } else {
+        *min = *max = cursor;
+        previous_cursor = cursor - 1;
+        while (previous_cursor >= 0) {
+          if (_sg_mc_liveness) {
+            ref_test =
+              (mc_visited_pair_t) xbt_dynar_get_as(list, previous_cursor,
+                                                   mc_visited_pair_t);
+            nb_processes_test = ((mc_visited_pair_t) ref_test)->nb_processes;
+            heap_bytes_used_test =
+              ((mc_visited_pair_t) ref_test)->heap_bytes_used;
+          } else {
+            ref_test =
+                (mc_visited_state_t) xbt_dynar_get_as(list, previous_cursor,
+                                                      mc_visited_state_t);
+            nb_processes_test = ((mc_visited_state_t) ref_test)->nb_processes;
+            heap_bytes_used_test =
+                ((mc_visited_state_t) ref_test)->heap_bytes_used;
+          }
+          if (nb_processes_test != nb_processes
+              || heap_bytes_used_test != heap_bytes_used)
+            break;
+          *min = previous_cursor;
+          previous_cursor--;
+        }
+        next_cursor = cursor + 1;
+        while (next_cursor < xbt_dynar_length(list)) {
+          if (_sg_mc_liveness) {
+            ref_test =
+                (mc_visited_pair_t) xbt_dynar_get_as(list, next_cursor,
+                                                     mc_visited_pair_t);
+            nb_processes_test = ((mc_visited_pair_t) ref_test)->nb_processes;
+            heap_bytes_used_test =
+                ((mc_visited_pair_t) ref_test)->heap_bytes_used;
+          } else {
+            ref_test =
+              (mc_visited_state_t) xbt_dynar_get_as(list, next_cursor,
+                                                    mc_visited_state_t);
+            nb_processes_test = ((mc_visited_state_t) ref_test)->nb_processes;
+            heap_bytes_used_test =
+              ((mc_visited_state_t) ref_test)->heap_bytes_used;
+          }
+          if (nb_processes_test != nb_processes
+              || heap_bytes_used_test != heap_bytes_used)
+            break;
+          *max = next_cursor;
+          next_cursor++;
+        }
+        if (!mc_mem_set)
+          MC_SET_STD_HEAP;
+        return -1;
+      }
+    }
+  }
+
+  if (!mc_mem_set)
+    MC_SET_STD_HEAP;
+
+  return cursor;
+}
+
+
+/**
+ * \brief Checks whether a given state has already been visited by the algorithm.
+ */
+
+mc_visited_state_t is_visited_state()
+{
+
+  if (_sg_mc_visited == 0)
+    return NULL;
+
+  /* If comm determinism verification, we cannot stop the exploration if some 
+     communications are not finished (at least, data are transfered). These communications 
+     are incomplete and they cannot be analyzed and compared with the initial pattern */
+  if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
+    int current_process = 1;
+    while (current_process < simix_process_maxpid) {
+      if (!xbt_dynar_is_empty((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, current_process, xbt_dynar_t)))
+        return NULL;
+      current_process++;
+    }
+  }
+
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  mc_visited_state_t new_state = visited_state_new();
+
+  if (xbt_dynar_is_empty(visited_states)) {
+
+    xbt_dynar_push(visited_states, &new_state);
+
+    if (!mc_mem_set)
+      MC_SET_STD_HEAP;
+
+    return NULL;
+
+  } else {
+
+    int min = -1, max = -1, index;
+    //int res;
+    mc_visited_state_t state_test;
+    int cursor;
+
+    index = get_search_interval(visited_states, new_state, &min, &max);
+
+    if (min != -1 && max != -1) {
+
+      // Parallell implementation
+      /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_states, min), (max-min)+1, new_state);
+         if(res != -1){
+         state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, (min+res)-1, mc_visited_state_t);
+         if(state_test->other_num == -1)
+         new_state->other_num = state_test->num;
+         else
+         new_state->other_num = state_test->other_num;
+         if(dot_output == NULL)
+         XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num);
+         else
+         XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num);
+         xbt_dynar_remove_at(visited_states, (min + res) - 1, NULL);
+         xbt_dynar_insert_at(visited_states, (min+res) - 1, &new_state);
+         if(!raw_mem_set)
+         MC_SET_STD_HEAP;
+         return new_state->other_num;
+         } */
+
+      cursor = min;
+      while (cursor <= max) {
+        state_test =
+            (mc_visited_state_t) xbt_dynar_get_as(visited_states, cursor,
+                                                  mc_visited_state_t);
+        if (snapshot_compare(state_test, new_state) == 0) {
+          // The state has been visited:
+
+          if (state_test->other_num == -1)
+            new_state->other_num = state_test->num;
+          else
+            new_state->other_num = state_test->other_num;
+          if (dot_output == NULL)
+            XBT_DEBUG("State %d already visited ! (equal to state %d)",
+                      new_state->num, state_test->num);
+          else
+            XBT_DEBUG
+                ("State %d already visited ! (equal to state %d (state %d in dot_output))",
+                 new_state->num, state_test->num, new_state->other_num);
+
+          /* Replace the old state with the new one (with a bigger num) 
+             (when the max number of visited states is reached,  the oldest 
+             one is removed according to its number (= with the min number) */
+          xbt_dynar_remove_at(visited_states, cursor, NULL);
+          xbt_dynar_insert_at(visited_states, cursor, &new_state);
+
+          if (!mc_mem_set)
+            MC_SET_STD_HEAP;
+          return state_test;
+        }
+        cursor++;
+      }
+
+      // The state has not been visited: insert the state in the dynamic array.
+      xbt_dynar_insert_at(visited_states, min, &new_state);
+
+    } else {
+
+      // The state has not been visited: insert the state in the dynamic array.
+      state_test =
+          (mc_visited_state_t) xbt_dynar_get_as(visited_states, index,
+                                                mc_visited_state_t);
+      if (state_test->nb_processes < new_state->nb_processes) {
+        xbt_dynar_insert_at(visited_states, index + 1, &new_state);
+      } else {
+        if (state_test->heap_bytes_used < new_state->heap_bytes_used)
+          xbt_dynar_insert_at(visited_states, index + 1, &new_state);
+        else
+          xbt_dynar_insert_at(visited_states, index, &new_state);
+      }
+
+    }
+
+    // We have reached the maximum number of stored states;
+    if (xbt_dynar_length(visited_states) > _sg_mc_visited) {
+
+      // Find the (index of the) older state (with the smallest num):
+      int min2 = mc_stats->expanded_states;
+      unsigned int cursor2 = 0;
+      unsigned int index2 = 0;
+      xbt_dynar_foreach(visited_states, cursor2, state_test){
+        if (!mc_important_snapshot(state_test->system_state) && state_test->num < min2) {
+          index2 = cursor2;
+          min2 = state_test->num;
+        }
+      }
+
+      // and drop it:
+      xbt_dynar_remove_at(visited_states, index2, NULL);
+    }
+
+    if (!mc_mem_set)
+      MC_SET_STD_HEAP;
+
+    return NULL;
+
+  }
+}
+
+/**
+ * \brief Checks whether a given pair has already been visited by the algorithm.
+ */
+int is_visited_pair(mc_visited_pair_t pair, int pair_num,
+                    xbt_automaton_state_t automaton_state,
+                    xbt_dynar_t atomic_propositions)
+{
+
+  if (_sg_mc_visited == 0)
+    return -1;
+
+  int mc_mem_set = (mmalloc_get_current_heap() == mc_heap);
+
+  MC_SET_MC_HEAP;
+
+  mc_visited_pair_t new_pair = NULL;
+
+  if (pair == NULL) {
+    new_pair =
+        MC_visited_pair_new(pair_num, automaton_state, atomic_propositions);
+  } else {
+    new_pair = pair;
+  }
+
+  if (xbt_dynar_is_empty(visited_pairs)) {
+
+    xbt_dynar_push(visited_pairs, &new_pair);
+
+  } else {
+
+    int min = -1, max = -1, index;
+    //int res;
+    mc_visited_pair_t pair_test;
+    int cursor;
+
+    index = get_search_interval(visited_pairs, new_pair, &min, &max);
+
+    if (min != -1 && max != -1) {       // Visited pair with same number of processes and same heap bytes used exists
+      /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_pairs, min), (max-min)+1, pair);
+         if(res != -1){
+         pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, (min+res)-1, mc_pair_t);
+         if(pair_test->other_num == -1)
+         pair->other_num = pair_test->num;
+         else
+         pair->other_num = pair_test->other_num;
+         if(dot_output == NULL)
+         XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
+         else
+         XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
+         xbt_dynar_remove_at(visited_pairs, (min + res) - 1, NULL);
+         xbt_dynar_insert_at(visited_pairs, (min+res) - 1, &pair);
+         pair_test->visited_removed = 1;
+         if(pair_test->stack_removed && pair_test->visited_removed){
+         if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
+         if(pair_test->acceptance_removed){
+         MC_pair_delete(pair_test);
+         }
+         }else{
+         MC_pair_delete(pair_test);
+         }
+         }
+         if(!raw_mem_set)
+         MC_SET_STD_HEAP;
+         return pair->other_num;
+         } */
+      cursor = min;
+      while (cursor <= max) {
+        pair_test =
+            (mc_visited_pair_t) xbt_dynar_get_as(visited_pairs, cursor,
+                                                 mc_visited_pair_t);
+        if (xbt_automaton_state_compare
+            (pair_test->automaton_state, new_pair->automaton_state) == 0) {
+          if (xbt_automaton_propositional_symbols_compare_value
+              (pair_test->atomic_propositions,
+               new_pair->atomic_propositions) == 0) {
+            if (snapshot_compare(pair_test, new_pair) == 0) {
+              if (pair_test->other_num == -1)
+                new_pair->other_num = pair_test->num;
+              else
+                new_pair->other_num = pair_test->other_num;
+              if (dot_output == NULL)
+                XBT_DEBUG("Pair %d already visited ! (equal to pair %d)",
+                          new_pair->num, pair_test->num);
+              else
+                XBT_DEBUG
+                    ("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))",
+                     new_pair->num, pair_test->num, new_pair->other_num);
+              xbt_dynar_remove_at(visited_pairs, cursor, NULL);
+              xbt_dynar_insert_at(visited_pairs, cursor, &new_pair);
+              pair_test->visited_removed = 1;
+              if (pair_test->acceptance_pair) {
+                if (pair_test->acceptance_removed == 1)
+                  MC_visited_pair_delete(pair_test);
+              } else {
+                MC_visited_pair_delete(pair_test);
+              }
+              if (!mc_mem_set)
+                MC_SET_STD_HEAP;
+              return new_pair->other_num;
+            }
+          }
+        }
+        cursor++;
+      }
+      xbt_dynar_insert_at(visited_pairs, min, &new_pair);
+    } else {
+      pair_test =
+          (mc_visited_pair_t) xbt_dynar_get_as(visited_pairs, index,
+                                               mc_visited_pair_t);
+      if (pair_test->nb_processes < new_pair->nb_processes) {
+        xbt_dynar_insert_at(visited_pairs, index + 1, &new_pair);
+      } else {
+        if (pair_test->heap_bytes_used < new_pair->heap_bytes_used)
+          xbt_dynar_insert_at(visited_pairs, index + 1, &new_pair);
+        else
+          xbt_dynar_insert_at(visited_pairs, index, &new_pair);
+      }
+    }
+
+    if (xbt_dynar_length(visited_pairs) > _sg_mc_visited) {
+      int min2 = mc_stats->expanded_pairs;
+      unsigned int cursor2 = 0;
+      unsigned int index2 = 0;
+      xbt_dynar_foreach(visited_pairs, cursor2, pair_test) {
+        if (!mc_important_snapshot(pair_test->graph_state->system_state) && pair_test->num < min2) {
+          index2 = cursor2;
+          min2 = pair_test->num;
+        }
+      }
+      xbt_dynar_remove_at(visited_pairs, index2, &pair_test);
+      pair_test->visited_removed = 1;
+      if (pair_test->acceptance_pair) {
+        if (pair_test->acceptance_removed)
+          MC_visited_pair_delete(pair_test);
+      } else {
+        MC_visited_pair_delete(pair_test);
+      }
+    }
+
+  }
+
+  if (!mc_mem_set)
+    MC_SET_STD_HEAP;
+
+  return -1;
+}
index 8e456dc..65878a0 100644 (file)
@@ -602,6 +602,18 @@ void sg_config_init(int *argc, char **argv)
                      xbt_cfgelm_int, 1, 1, _mc_cfg_cb_checkpoint, NULL);
     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
 
+    /* do stateful model-checking */
+    xbt_cfg_register(&_sg_cfg_set, "model-check/sparse-checkpoint",
+                     "Use sparse per-page snapshots.",
+                     xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_sparse_checkpoint, NULL);
+    xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/sparse-checkpoint", "no");
+
+    /* do stateful model-checking */
+    xbt_cfg_register(&_sg_cfg_set, "model-check/soft-dirty",
+                     "Use sparse per-page snapshots.",
+                     xbt_cfgelm_boolean, 1, 1, _mc_cfg_cb_soft_dirty, NULL);
+    xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/soft-dirty", "yes");
+
     /* do liveness model-checking */
     xbt_cfg_register(&_sg_cfg_set, "model-check/property",
                      "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
index 0b2b78c..3ff404a 100644 (file)
@@ -77,8 +77,8 @@ static void _XBT_CALL segvhandler(int signum, siginfo_t *siginfo, void *context)
   }
 #ifdef HAVE_MC
   if (MC_is_active()) {
-    if (mc_stack_safety) {
-      MC_dump_stack_safety(mc_stack_safety);
+    if (mc_stack) {
+      MC_dump_stack_safety(mc_stack);
     }
     MC_print_statistics(mc_stats);
   }
index 12da83c..ffc4381 100644 (file)
@@ -130,10 +130,14 @@ void smpi_process_destroy(void)
  */
 void smpi_process_finalize(void)
 {
+    // This leads to an explosion of the search graph
+    // which cannot be reduced:
+    if(MC_is_active())
+      return;
+
     int index = smpi_process_index();
     // wait for all pending asynchronous comms to finish
     xbt_barrier_wait(process_data[index_to_process_data[index]]->finalization_barrier);
-
 }
 
 /**
index ba67a7d..410bf81 100644 (file)
@@ -555,9 +555,6 @@ static void xbt_log_connect_categories(void)
   XBT_LOG_CONNECT(xbt);
   XBT_LOG_CONNECT(graphxml_parse);
   XBT_LOG_CONNECT(log);
-#if HAVE_MMALLOC
-  XBT_LOG_CONNECT(mm_diff);
-#endif
   XBT_LOG_CONNECT(module);
   XBT_LOG_CONNECT(peer);
   XBT_LOG_CONNECT(replay);
@@ -631,15 +628,19 @@ static void xbt_log_connect_categories(void)
 #ifdef HAVE_MC
   XBT_LOG_CONNECT(mc);
   XBT_LOG_CONNECT(mc_checkpoint);
+  XBT_LOG_CONNECT(mc_comm_determinism);
   XBT_LOG_CONNECT(mc_compare);
-  XBT_LOG_CONNECT(mc_dpor);
+  XBT_LOG_CONNECT(mc_diff);
   XBT_LOG_CONNECT(mc_dwarf);
   XBT_LOG_CONNECT(mc_global);
   XBT_LOG_CONNECT(mc_hash);
+  XBT_LOG_CONNECT(mc_ignore);
   XBT_LOG_CONNECT(mc_liveness);
   XBT_LOG_CONNECT(mc_memory);
   XBT_LOG_CONNECT(mc_memory_map);
   XBT_LOG_CONNECT(mc_request);
+  XBT_LOG_CONNECT(mc_safety);
+  XBT_LOG_CONNECT(mc_visited);
 #endif
 
   /* msg */
index 33de568..031bb3e 100644 (file)
@@ -21,4 +21,3 @@
 #include "mmorecore.c"
 #include "mm_legacy.c"
 #include "mm_module.c"
-#include "mm_diff.c"
diff --git a/src/xbt/mmalloc/mm_diff.c b/src/xbt/mmalloc/mm_diff.c
deleted file mode 100644 (file)
index af5bd88..0000000
+++ /dev/null
@@ -1,1485 +0,0 @@
-/* mm_diff - Memory snapshooting and comparison                             */
-
-/* Copyright (c) 2008-2014. The SimGrid Team.
- * All rights reserved.                                                     */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include "xbt/ex_interface.h" /* internals of backtrace setup */
-#include "xbt/str.h"
-#include "mc/mc.h"
-#include "xbt/mmalloc.h"
-#include "mc/datatypes.h"
-#include "mc/mc_private.h"
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
-                                "Logging specific to mm_diff in mmalloc");
-
-xbt_dynar_t mc_heap_comparison_ignore;
-xbt_dynar_t stacks_areas;
-void *maestro_stack_start, *maestro_stack_end;
-
-
-/********************************* Backtrace ***********************************/
-/******************************************************************************/
-
-static void mmalloc_backtrace_block_display(void* heapinfo, int block){
-
-  /* xbt_ex_t e; */
-
-  /* if (((malloc_info *)heapinfo)[block].busy_block.bt_size == 0) { */
-  /*   fprintf(stderr, "No backtrace available for that block, sorry.\n"); */
-  /*   return; */
-  /* } */
-
-  /* memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_block.bt),sizeof(void*)*XBT_BACKTRACE_SIZE); */
-  /* e.used = ((malloc_info *)heapinfo)[block].busy_block.bt_size; */
-
-  /* xbt_ex_setup_backtrace(&e); */
-  /* if (e.used == 0) { */
-  /*   fprintf(stderr, "(backtrace not set)\n"); */
-  /* } else if (e.bt_strings == NULL) { */
-  /*   fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet"); */
-  /* } else { */
-  /*   int i; */
-
-  /*   fprintf(stderr, "Backtrace of where the block %d was malloced (%d frames):\n", block ,e.used); */
-  /*   for (i = 0; i < e.used; i++)       /\* no need to display "xbt_backtrace_display" *\/{ */
-  /*     fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4); */
-  /*   } */
-  /* } */
-}
-
-static void mmalloc_backtrace_fragment_display(void* heapinfo, int block, int frag){
-
-  /* xbt_ex_t e; */
-
-  /* memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_frag.bt[frag]),sizeof(void*)*XBT_BACKTRACE_SIZE); */
-  /* e.used = XBT_BACKTRACE_SIZE; */
-
-  /* xbt_ex_setup_backtrace(&e); */
-  /* if (e.used == 0) { */
-  /*   fprintf(stderr, "(backtrace not set)\n"); */
-  /* } else if (e.bt_strings == NULL) { */
-  /*   fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet"); */
-  /* } else { */
-  /*   int i; */
-
-  /*   fprintf(stderr, "Backtrace of where the fragment %d in block %d was malloced (%d frames):\n", frag, block ,e.used); */
-  /*   for (i = 0; i < e.used; i++)       /\* no need to display "xbt_backtrace_display" *\/{ */
-  /*     fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4); */
-  /*   } */
-  /* } */
-
-}
-
-static void mmalloc_backtrace_display(void *addr){
-
-  /* size_t block, frag_nb; */
-  /* int type; */
-  
-  /* xbt_mheap_t heap = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit(); */
-
-  /* block = (((char*) (addr) - (char*) heap -> heapbase) / BLOCKSIZE + 1); */
-
-  /* type = heap->heapinfo[block].type; */
-
-  /* switch(type){ */
-  /* case -1 : /\* Free block *\/ */
-  /*   fprintf(stderr, "Asked to display the backtrace of a block that is free. I'm puzzled\n"); */
-  /*   xbt_abort(); */
-  /*   break;  */
-  /* case 0: /\* Large block *\/ */
-  /*   mmalloc_backtrace_block_display(heap->heapinfo, block); */
-  /*   break; */
-  /* default: /\* Fragmented block *\/ */
-  /*   frag_nb = RESIDUAL(addr, BLOCKSIZE) >> type; */
-  /*   if(heap->heapinfo[block].busy_frag.frag_size[frag_nb] == -1){ */
-  /*     fprintf(stderr , "Asked to display the backtrace of a fragment that is free. I'm puzzled\n"); */
-  /*     xbt_abort(); */
-  /*   } */
-  /*   mmalloc_backtrace_fragment_display(heap->heapinfo, block, frag_nb); */
-  /*   break; */
-  /* } */
-}
-
-
-static int compare_backtrace(int b1, int f1, int b2, int f2){
-  /*int i = 0;
-  if(f1 != -1){
-    for(i=0; i< XBT_BACKTRACE_SIZE; i++){
-      if(heapinfo1[b1].busy_frag.bt[f1][i] != heapinfo2[b2].busy_frag.bt[f2][i]){
-        //mmalloc_backtrace_fragment_display((void*)heapinfo1, b1, f1);
-        //mmalloc_backtrace_fragment_display((void*)heapinfo2, b2, f2);
-        return 1;
-      }
-    }
-  }else{
-    for(i=0; i< heapinfo1[b1].busy_block.bt_size; i++){
-      if(heapinfo1[b1].busy_block.bt[i] != heapinfo2[b2].busy_block.bt[i]){
-        //mmalloc_backtrace_block_display((void*)heapinfo1, b1);
-        //mmalloc_backtrace_block_display((void*)heapinfo2, b2);
-        return 1;
-      }
-    }
-    }*/
-  return 0;
-}
-
-
-/*********************************** Heap comparison ***********************************/
-/***************************************************************************************/
-
-typedef char* type_name;
-
-struct s_mm_diff {
-  void *s_heap, *heapbase1, *heapbase2;
-  malloc_info *heapinfo1, *heapinfo2;
-  size_t heaplimit;
-  // Number of blocks in the heaps:
-  size_t heapsize1, heapsize2;
-  xbt_dynar_t to_ignore1, to_ignore2;
-  s_heap_area_t *equals_to1, *equals_to2;
-  dw_type_t *types1, *types2;
-  size_t available;
-};
-
-#define equals_to1_(i,j) equals_to1[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
-#define equals_to2_(i,j) equals_to2[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
-#define types1_(i,j) types1[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
-#define types2_(i,j) types2[ MAX_FRAGMENT_PER_BLOCK*(i) + (j)]
-
-__thread struct s_mm_diff* mm_diff_info = NULL;
-
-/*********************************** Free functions ************************************/
-
-static void heap_area_pair_free(heap_area_pair_t pair){
-  xbt_free(pair);
-  pair = NULL;
-}
-
-static void heap_area_pair_free_voidp(void *d){
-  heap_area_pair_free((heap_area_pair_t) * (void **) d);
-}
-
-static void heap_area_free(heap_area_t area){
-  xbt_free(area);
-  area = NULL;
-}
-
-/************************************************************************************/
-
-static s_heap_area_t make_heap_area(int block, int fragment){
-  s_heap_area_t area;
-  area.valid = 1;
-  area.block = block;
-  area.fragment = fragment;
-  return area;
-}
-
-static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
-  
-  unsigned int cursor = 0;
-  heap_area_pair_t current_pair;
-
-  xbt_dynar_foreach(list, cursor, current_pair){
-    if(current_pair->block1 == block1 && current_pair->block2 == block2 && current_pair->fragment1 == fragment1 && current_pair->fragment2 == fragment2)
-      return 0; 
-  }
-  
-  return 1;
-}
-
-static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
-
-  if(is_new_heap_area_pair(list, block1, fragment1, block2, fragment2)){
-    heap_area_pair_t pair = NULL;
-    pair = xbt_new0(s_heap_area_pair_t, 1);
-    pair->block1 = block1;
-    pair->fragment1 = fragment1;
-    pair->block2 = block2;
-    pair->fragment2 = fragment2;
-    
-    xbt_dynar_push(list, &pair); 
-
-    return 1;
-  }
-
-  return 0;
-}
-
-static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address){
-
-  unsigned int cursor = 0;
-  int start = 0;
-  int end = xbt_dynar_length(ignore_list) - 1;
-  mc_heap_ignore_region_t region;
-
-  while(start <= end){
-    cursor = (start + end) / 2;
-    region = (mc_heap_ignore_region_t)xbt_dynar_get_as(ignore_list, cursor, mc_heap_ignore_region_t);
-    if(region->address == address)
-      return region->size;
-    if(region->address < address)
-      start = cursor + 1;
-    if(region->address > address)
-      end = cursor - 1;   
-  }
-
-  return -1;
-}
-
-static int is_stack(void *address){
-  unsigned int cursor = 0;
-  stack_region_t stack;
-
-  xbt_dynar_foreach(stacks_areas, cursor, stack){
-    if(address == stack->address)
-      return 1;
-  }
-
-  return 0;
-}
-
-static int is_block_stack(int block){
-  unsigned int cursor = 0;
-  stack_region_t stack;
-
-  xbt_dynar_foreach(stacks_areas, cursor, stack){
-    if(block == stack->block)
-      return 1;
-  }
-
-  return 0;
-}
-
-static void match_equals(struct s_mm_diff *state, xbt_dynar_t list){
-
-  unsigned int cursor = 0;
-  heap_area_pair_t current_pair;
-
-  xbt_dynar_foreach(list, cursor, current_pair){
-
-    if(current_pair->fragment1 != -1){
-
-      state->equals_to1_(current_pair->block1,current_pair->fragment1) = make_heap_area(current_pair->block2, current_pair->fragment2);
-      state->equals_to2_(current_pair->block2,current_pair->fragment2) = make_heap_area(current_pair->block1, current_pair->fragment1);
-      
-    }else{
-
-      state->equals_to1_(current_pair->block1,0) = make_heap_area(current_pair->block2, current_pair->fragment2);
-      state->equals_to2_(current_pair->block2,0) = make_heap_area(current_pair->block1, current_pair->fragment1);
-
-    }
-
-  }
-}
-
-/** Check whether two blocks are known to be matching
- *
- *  @param state  State used
- *  @param b1     Block of state 1
- *  @param b2     Block of state 2
- *  @return       if the blocks are known to be matching
- */
-static int equal_blocks(struct s_mm_diff *state, int b1, int b2){
-  
-  if(state->equals_to1_(b1,0).block == b2 && state->equals_to2_(b2,0).block == b1)
-    return 1;
-
-  return 0;
-}
-
-/** Check whether two fragments are known to be matching
- *
- *  @param state  State used
- *  @param b1     Block of state 1
- *  @param f1     Fragment of state 1
- *  @param b2     Block of state 2
- *  @param f2     Fragment of state 2
- *  @return       if the fragments are known to be matching
- */
-static int equal_fragments(struct s_mm_diff *state, int b1, int f1, int b2, int f2){
-  
-  if(state->equals_to1_(b1,f1).block == b2
-    && state->equals_to1_(b1,f1).fragment == f2
-    && state->equals_to2_(b2,f2).block == b1
-    && state->equals_to2_(b2,f2).fragment == f1)
-    return 1;
-
-  return 0;
-}
-
-int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, xbt_dynar_t i2){
-  if(mm_diff_info==NULL) {
-    mm_diff_info = xbt_new0(struct s_mm_diff, 1);
-    mm_diff_info->equals_to1 = NULL;
-    mm_diff_info->equals_to2 = NULL;
-    mm_diff_info->types1 = NULL;
-    mm_diff_info->types2 = NULL;
-  }
-  struct s_mm_diff *state = mm_diff_info;
-
-  if((((struct mdesc *)heap1)->heaplimit != ((struct mdesc *)heap2)->heaplimit)
-    || ((((struct mdesc *)heap1)->heapsize != ((struct mdesc *)heap2)->heapsize) ))
-    return -1;
-
-  state->heaplimit = ((struct mdesc *)heap1)->heaplimit;
-
-  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
-
-  state->heapbase1 = (char *)heap1 + BLOCKSIZE;
-  state->heapbase2 = (char *)heap2 + BLOCKSIZE;
-
-  state->heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)((struct mdesc *)heap1)->heapinfo - (char *)state->s_heap)));
-  state->heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)((struct mdesc *)heap2)->heapinfo - (char *)state->s_heap)));
-
-  state->heapsize1 = heap1->heapsize;
-  state->heapsize2 = heap2->heapsize;
-
-  state->to_ignore1 = i1;
-  state-> to_ignore2 = i2;
-
-  if(state->heaplimit > state->available) {
-    state->equals_to1 = realloc(state->equals_to1, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(s_heap_area_t));
-    state->types1 = realloc(state->types1, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(type_name *));
-    state->equals_to2 = realloc(state->equals_to2, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(s_heap_area_t));
-    state->types2 = realloc(state->types2, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(type_name *));
-    state->available = state->heaplimit;
-  }
-
-  memset(state->equals_to1, 0, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(s_heap_area_t));
-  memset(state->equals_to2, 0, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(s_heap_area_t));
-  memset(state->types1, 0, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(type_name *));
-  memset(state->types2, 0, state->heaplimit * MAX_FRAGMENT_PER_BLOCK * sizeof(type_name *));
-
-  if(MC_is_active()){
-    MC_ignore_global_variable("mm_diff_info");
-  }
-
-  return 0;
-
-}
-
-void reset_heap_information(){
-
-}
-
-int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_mheap_t heap1, xbt_mheap_t heap2){
-
-  struct s_mm_diff *state = mm_diff_info;
-
-  if(heap1 == NULL && heap2 == NULL){
-    XBT_DEBUG("Malloc descriptors null");
-    return 0;
-  }
-
-  /* Start comparison */
-  size_t i1, i2, j1, j2, k;
-  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
-  int nb_diff1 = 0, nb_diff2 = 0;
-
-  xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
-
-  int equal, res_compare = 0;
-
-  /* Check busy blocks*/
-
-  i1 = 1;
-
-  while(i1 <= state->heaplimit){
-
-    if(state->heapinfo1[i1].type == -1){ /* Free block */
-      i1++;
-      continue;
-    }
-
-    addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-
-    if(state->heapinfo1[i1].type == 0){  /* Large block */
-      
-      if(is_stack(addr_block1)){
-        for(k=0; k < state->heapinfo1[i1].busy_block.size; k++)
-          state->equals_to1_(i1+k,0) = make_heap_area(i1, -1);
-        for(k=0; k < state->heapinfo2[i1].busy_block.size; k++)
-          state->equals_to2_(i1+k,0) = make_heap_area(i1, -1);
-        i1 += state->heapinfo1[i1].busy_block.size;
-        continue;
-      }
-
-      if(state->equals_to1_(i1,0).valid){
-        i1++;
-        continue;
-      }
-    
-      i2 = 1;
-      equal = 0;
-      res_compare = 0;
-  
-      /* Try first to associate to same block in the other heap */
-      if(state->heapinfo2[i1].type == state->heapinfo1[i1].type){
-
-        if(state->equals_to2_(i1,0).valid == 0){
-
-          addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-        
-          res_compare = compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0);
-        
-          if(res_compare != 1){
-            for(k=1; k < state->heapinfo2[i1].busy_block.size; k++)
-              state->equals_to2_(i1+k,0) = make_heap_area(i1, -1);
-            for(k=1; k < state->heapinfo1[i1].busy_block.size; k++)
-              state->equals_to1_(i1+k,0) = make_heap_area(i1, -1);
-            equal = 1;
-            i1 += state->heapinfo1[i1].busy_block.size;
-          }
-        
-          xbt_dynar_reset(previous);
-        
-        }
-        
-      }
-
-      while(i2 <= state->heaplimit && !equal){
-
-        addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-           
-        if(i2 == i1){
-          i2++;
-          continue;
-        }
-
-        if(state->heapinfo2[i2].type != 0){
-          i2++;
-          continue;
-        }
-    
-        if(state->equals_to2_(i2,0).valid){
-          i2++;
-          continue;
-        }
-          
-        res_compare = compare_heap_area(addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0);
-        
-        if(res_compare != 1 ){
-          for(k=1; k < state->heapinfo2[i2].busy_block.size; k++)
-            state->equals_to2_(i2+k,0) = make_heap_area(i1, -1);
-          for(k=1; k < state->heapinfo1[i1].busy_block.size; k++)
-            state->equals_to1_(i1+k,0) = make_heap_area(i2, -1);
-          equal = 1;
-          i1 += state->heapinfo1[i1].busy_block.size;
-        }
-
-        xbt_dynar_reset(previous);
-
-        i2++;
-
-      }
-
-      if(!equal){
-        XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, state->heapinfo1[i1].busy_block.busy_size, addr_block1);
-        i1 = state->heaplimit + 1;
-        nb_diff1++;
-          //i1++;
-      }
-      
-    }else{ /* Fragmented block */
-
-      for(j1=0; j1 < (size_t) (BLOCKSIZE >> state->heapinfo1[i1].type); j1++){
-
-        if(state->heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
-          continue;
-
-        if(state->equals_to1_(i1,j1).valid)
-          continue;
-
-        addr_frag1 = (void*) ((char *)addr_block1 + (j1 << state->heapinfo1[i1].type));
-
-        i2 = 1;
-        equal = 0;
-        
-        /* Try first to associate to same fragment in the other heap */
-        if(state->heapinfo2[i1].type == state->heapinfo1[i1].type){
-
-          if(state->equals_to2_(i1,j1).valid == 0){
-
-            addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-            addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)state->s_heap)->heapinfo[i1].type));
-
-            res_compare = compare_heap_area(addr_frag1, addr_frag2, snapshot1, snapshot2, NULL, NULL, 0);
-
-            if(res_compare !=  1)
-              equal = 1;
-        
-            xbt_dynar_reset(previous);
-
-          }
-
-        }
-
-        while(i2 <= state->heaplimit && !equal){
-
-          if(state->heapinfo2[i2].type <= 0){
-            i2++;
-            continue;
-          }
-
-          for(j2=0; j2 < (size_t) (BLOCKSIZE >> state->heapinfo2[i2].type); j2++){
-
-            if(i2 == i1 && j2 == j1)
-              continue;
-           
-            if(state->equals_to2_(i2,j2).valid)
-              continue;
-                          
-            addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-            addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)state->s_heap)->heapinfo[i2].type));
-
-            res_compare = compare_heap_area(addr_frag1, addr_frag2, snapshot2, snapshot2, NULL, NULL, 0);
-            
-            if(res_compare != 1){
-              equal = 1;
-              xbt_dynar_reset(previous);
-              break;
-            }
-
-            xbt_dynar_reset(previous);
-
-          }
-
-          i2++;
-
-        }
-
-        if(!equal){
-          XBT_DEBUG("Block %zu, fragment %zu not found (size_used = %zd, address = %p)\n", i1, j1, state->heapinfo1[i1].busy_frag.frag_size[j1], addr_frag1);
-          i2 = state->heaplimit + 1;
-          i1 = state->heaplimit + 1;
-          nb_diff1++;
-          break;
-        }
-
-      }
-
-      i1++;
-      
-    }
-
-  }
-
-  /* All blocks/fragments are equal to another block/fragment ? */
-  size_t i = 1, j = 0;
-  void *real_addr_frag1 = NULL, *real_addr_block1 = NULL, *real_addr_block2 = NULL, *real_addr_frag2 = NULL;
-  while(i<=state->heaplimit){
-    if(state->heapinfo1[i].type == 0){
-      if(i1 == state->heaplimit){
-        if(state->heapinfo1[i].busy_block.busy_size > 0){
-          if(state->equals_to1_(i,0).valid == 0){
-            if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-              addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
-              XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, state->heapinfo1[i].busy_block.busy_size);
-              //mmalloc_backtrace_block_display((void*)heapinfo1, i);
-            }
-            nb_diff1++;
-          }
-        }
-      }
-    }
-    if(state->heapinfo1[i].type > 0){
-      addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
-      real_addr_block1 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)state->s_heap)->heapbase));
-      for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo1[i].type); j++){
-        if(i1== state->heaplimit){
-          if(state->heapinfo1[i].busy_frag.frag_size[j] > 0){
-            if(state->equals_to1_(i,j).valid == 0){
-              if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-                addr_frag1 = (void*) ((char *)addr_block1 + (j << state->heapinfo1[i].type));
-                real_addr_frag1 = (void*) ((char *)real_addr_block1 + (j << ((struct mdesc *)state->s_heap)->heapinfo[i].type));
-                XBT_DEBUG("Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag1, real_addr_frag1, state->heapinfo1[i].busy_frag.frag_size[j]);
-                //mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
-              }
-              nb_diff1++;
-            }
-          }
-        }
-      }
-    }
-    i++; 
-  }
-
-  if(i1 == state->heaplimit)
-    XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1);
-
-  i = 1;
-
-  while(i<=state->heaplimit){
-    if(state->heapinfo2[i].type == 0){
-      if(i1 == state->heaplimit){
-        if(state->heapinfo2[i].busy_block.busy_size > 0){
-          if(state->equals_to2_(i,0).valid == 0){
-            if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-              addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
-              XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, state->heapinfo2[i].busy_block.busy_size);
-              //mmalloc_backtrace_block_display((void*)heapinfo2, i);
-            }
-            nb_diff2++;
-          }
-        }
-      }
-    }
-    if(state->heapinfo2[i].type > 0){
-      addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
-      real_addr_block2 =  ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)((struct mdesc *)state->s_heap)->heapbase));
-      for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo2[i].type); j++){
-        if(i1 == state->heaplimit){
-          if(state->heapinfo2[i].busy_frag.frag_size[j] > 0){
-            if(state->equals_to2_(i,j).valid == 0){
-              if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
-                addr_frag2 = (void*) ((char *)addr_block2 + (j << state->heapinfo2[i].type));
-                real_addr_frag2 = (void*) ((char *)real_addr_block2 + (j << ((struct mdesc *)state->s_heap)->heapinfo[i].type));
-                XBT_DEBUG( "Block %zu, Fragment %zu (%p - %p) not found (size used = %zd)", i, j, addr_frag2, real_addr_frag2, state->heapinfo2[i].busy_frag.frag_size[j]);
-                //mmalloc_backtrace_fragment_display((void*)heapinfo2, i, j);
-              }
-              nb_diff2++;
-            }
-          }
-        }
-      }
-    }
-    i++; 
-  }
-
-  if(i1 == state->heaplimit)
-    XBT_DEBUG("Number of blocks/fragments not found in heap2 : %d", nb_diff2);
-
-  xbt_dynar_free(&previous);
-  real_addr_frag1 = NULL, real_addr_block1 = NULL, real_addr_block2 = NULL, real_addr_frag2 = NULL;
-
-  return ((nb_diff1 > 0) || (nb_diff2 > 0));
-}
-
-/**
- *
- * @param state
- * @param real_area1     Process address for state 1
- * @param real_area2     Process address for state 2
- * @param area1          Snapshot address for state 1
- * @param area2          Snapshot address for state 2
- * @param snapshot1      Snapshot of state 1
- * @param snapshot2      Snapshot of state 2
- * @param previous
- * @param size
- * @param check_ignore
- */
-static int compare_heap_area_without_type(struct s_mm_diff *state, void *real_area1, void *real_area2, void *area1, void *area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, int size, int check_ignore){
-
-  int i = 0;
-  void *addr_pointed1, *addr_pointed2;
-  int pointer_align, res_compare;
-  ssize_t ignore1, ignore2;
-
-  while(i<size){
-
-    if(check_ignore > 0){
-      if((ignore1 = heap_comparison_ignore_size(state->to_ignore1, (char *)real_area1 + i)) != -1){
-        if((ignore2 = heap_comparison_ignore_size(state->to_ignore2, (char *)real_area2 + i))  == ignore1){
-          if(ignore1 == 0){
-            check_ignore--;
-            return 0;
-          }else{
-            i = i + ignore2;
-            check_ignore--;
-            continue;
-          }
-        }
-      }
-    }
-
-    if(memcmp(((char *)area1) + i, ((char *)area2) + i, 1) != 0){
-
-      pointer_align = (i / sizeof(void*)) * sizeof(void*);
-      addr_pointed1 = *((void **)((char *)area1 + pointer_align));
-      addr_pointed2 = *((void **)((char *)area2 + pointer_align));
-      
-      if(addr_pointed1 > maestro_stack_start && addr_pointed1 < maestro_stack_end && addr_pointed2 > maestro_stack_start && addr_pointed2 < maestro_stack_end){
-        i = pointer_align + sizeof(void *);
-        continue;
-      }else if((addr_pointed1 > state->s_heap) && ((char *)addr_pointed1 < (char *)state->s_heap + STD_HEAP_SIZE)
-               && (addr_pointed2 > state->s_heap) && ((char *)addr_pointed2 < (char *)state->s_heap + STD_HEAP_SIZE)){
-        res_compare = compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, NULL, 0);
-        if(res_compare == 1){
-          return res_compare;
-        }
-        i = pointer_align + sizeof(void *);
-        continue;
-      }else{
-        return 1;
-      }
-      
-    }
-    
-    i++;
-
-  }
-
-  return 0;
-}
-
-/**
- *
- * @param state
- * @param real_area1     Process address for state 1
- * @param real_area2     Process address for state 2
- * @param area1          Snapshot address for state 1
- * @param area2          Snapshot address for state 2
- * @param snapshot1      Snapshot of state 1
- * @param snapshot2      Snapshot of state 2
- * @param previous
- * @param type_id
- * @param area_size      either a byte_size or an elements_count (?)
- * @param check_ignore
- * @param pointer_level
- * @return               0 (same), 1 (different), -1 (unknown)
- */
-static int compare_heap_area_with_type(struct s_mm_diff *state, void *real_area1, void *real_area2, void *area1, void *area2,
-                                       mc_snapshot_t snapshot1, mc_snapshot_t snapshot2,
-                                       xbt_dynar_t previous, dw_type_t type,
-                                       int area_size, int check_ignore, int pointer_level){
-
-  if(is_stack(real_area1) && is_stack(real_area2))
-    return 0;
-
-  ssize_t ignore1, ignore2;
-
-  if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(state->to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(state->to_ignore2, real_area2))  == ignore1)){
-    return 0;
-  }
-  
-  dw_type_t subtype, subsubtype;
-  int res, elm_size, i;
-  unsigned int cursor = 0;
-  dw_type_t member;
-  void *addr_pointed1, *addr_pointed2;;
-
-  switch(type->type){
-  case DW_TAG_unspecified_type:
-    return 1;
-
-  case DW_TAG_base_type:
-    if(type->name!=NULL && strcmp(type->name, "char") == 0){ /* String, hence random (arbitrary ?) size */
-      if(real_area1 == real_area2)
-        return -1;
-      else
-        return (memcmp(area1, area2, area_size) != 0);
-    }else{
-      if(area_size != -1 && type->byte_size != area_size)
-        return -1;
-      else{
-        return  (memcmp(area1, area2, type->byte_size) != 0);
-      }
-    }
-    break;
-  case DW_TAG_enumeration_type:
-    if(area_size != -1 && type->byte_size != area_size)
-      return -1;
-    else
-      return (memcmp(area1, area2, type->byte_size) != 0);
-    break;
-  case DW_TAG_typedef:
-  case DW_TAG_const_type:
-  case DW_TAG_volatile_type:
-    return compare_heap_area_with_type(state, real_area1, real_area2, area1, area2, snapshot1, snapshot2, previous, type->subtype, area_size, check_ignore, pointer_level);
-    break;
-  case DW_TAG_array_type:
-    subtype = type->subtype;
-    switch(subtype->type){
-    case DW_TAG_unspecified_type:
-      return 1;
-
-    case DW_TAG_base_type:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_pointer_type:
-    case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_class_type:
-    case DW_TAG_union_type:
-      if(subtype->full_type)
-        subtype = subtype->full_type;
-      elm_size = subtype->byte_size;
-      break;
-    // TODO, just remove the type indirection?
-    case DW_TAG_const_type:
-    case DW_TAG_typedef:
-    case DW_TAG_volatile_type:
-      subsubtype = subtype->subtype;
-      if(subsubtype->full_type)
-        subsubtype = subsubtype->full_type;
-      elm_size = subsubtype->byte_size;
-      break;
-    default : 
-      return 0;
-      break;
-    }
-    for(i=0; i<type->element_count; i++){
-      // TODO, add support for variable stride (DW_AT_byte_stride)
-      res = compare_heap_area_with_type(state, (char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), snapshot1, snapshot2, previous, type->subtype, subtype->byte_size, check_ignore, pointer_level);
-      if(res == 1)
-        return res;
-    }
-    break;
-  case DW_TAG_reference_type:
-  case DW_TAG_rvalue_reference_type:
-  case DW_TAG_pointer_type:
-    if(type->subtype && type->subtype->type == DW_TAG_subroutine_type){
-      addr_pointed1 = *((void **)(area1)); 
-      addr_pointed2 = *((void **)(area2));
-      return (addr_pointed1 != addr_pointed2);;
-    }else{
-      pointer_level++;
-      if(pointer_level > 1){ /* Array of pointers */
-        for(i=0; i<(area_size/sizeof(void *)); i++){ 
-          addr_pointed1 = *((void **)((char *)area1 + (i*sizeof(void *)))); 
-          addr_pointed2 = *((void **)((char *)area2 + (i*sizeof(void *)))); 
-          if(addr_pointed1 > state->s_heap && (char *)addr_pointed1 < (char*) state->s_heap + STD_HEAP_SIZE && addr_pointed2 > state->s_heap && (char *)addr_pointed2 < (char*) state->s_heap + STD_HEAP_SIZE)
-            res =  compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype, pointer_level);
-          else
-            res =  (addr_pointed1 != addr_pointed2);
-          if(res == 1)
-            return res;
-        }
-      }else{
-        addr_pointed1 = *((void **)(area1)); 
-        addr_pointed2 = *((void **)(area2));
-        if(addr_pointed1 > state->s_heap && (char *)addr_pointed1 < (char*) state->s_heap + STD_HEAP_SIZE && addr_pointed2 > state->s_heap && (char *)addr_pointed2 < (char*) state->s_heap + STD_HEAP_SIZE)
-          return compare_heap_area(addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype, pointer_level);
-        else
-          return  (addr_pointed1 != addr_pointed2);
-      }
-    }
-    break;
-  case DW_TAG_structure_type:
-  case DW_TAG_class_type:
-    if(type->full_type)
-      type = type->full_type;
-    if(area_size != -1 && type->byte_size != area_size){
-      if(area_size>type->byte_size && area_size%type->byte_size == 0){
-        for(i=0; i<(area_size/type->byte_size); i++){
-          res = compare_heap_area_with_type(state, (char *)real_area1 + (i*type->byte_size), (char *)real_area2 + (i*type->byte_size), (char *)area1 + (i*type->byte_size), (char *)area2 + (i*type->byte_size), snapshot1, snapshot2, previous, type, -1, check_ignore, 0);
-          if(res == 1)
-            return res;
-        }
-      }else{
-        return -1;
-      }
-    }else{
-      cursor = 0;
-      xbt_dynar_foreach(type->members, cursor, member){
-        // TODO, optimize this? (for the offset case)
-        char* real_member1 = mc_member_resolve(real_area1, type, member, snapshot1);
-        char* real_member2 = mc_member_resolve(real_area2, type, member, snapshot2);
-        char* member1 = mc_translate_address((uintptr_t)real_member1, snapshot1);
-        char* member2 = mc_translate_address((uintptr_t)real_member2, snapshot2);
-        res = compare_heap_area_with_type(state, real_member1, real_member2, member1, member2, snapshot1, snapshot2, previous, member->subtype, -1, check_ignore, 0);
-        if(res == 1){
-          return res;
-        }
-      }
-    }
-    break;
-  case DW_TAG_union_type:
-    return compare_heap_area_without_type(state, real_area1, real_area2, area1, area2, snapshot1, snapshot2, previous, type->byte_size, check_ignore);
-    break;
-  default:
-    break;
-  }
-
-  return 0;
-
-}
-
-/** Infer the type of a part of the block from the type of the block
- *
- * TODO, handle DW_TAG_array_type as well as arrays of the object ((*p)[5], p[5])
- *
- * TODO, handle subfields ((*p).bar.foo, (*p)[5].bar…)
- *
- * @param  type_id            DWARF type ID of the root address
- * @param  area_size
- * @return                    DWARF type ID for given offset
- */
-static dw_type_t get_offset_type(void* real_base_address, dw_type_t type, int offset, int area_size, mc_snapshot_t snapshot){
-
-  // Beginning of the block, the infered variable type if the type of the block:
-  if(offset==0)
-    return type;
-
-  switch(type->type){
-  case DW_TAG_structure_type :
-  case DW_TAG_class_type:
-    if(type->full_type)
-      type = type->full_type;
-    
-    if(area_size != -1 && type->byte_size != area_size){
-      if(area_size>type->byte_size && area_size%type->byte_size == 0)
-        return type;
-      else
-        return NULL;
-    }else{
-      unsigned int cursor = 0;
-      dw_type_t member;
-      xbt_dynar_foreach(type->members, cursor, member){ 
-
-        if(!member->location.size) {
-          // We have the offset, use it directly (shortcut):
-          if(member->offset == offset)
-            return member->subtype;
-        } else {
-          char* real_member = mc_member_resolve(real_base_address, type, member, snapshot);
-          if(real_member - (char*)real_base_address == offset)
-            return member->subtype;
-        }
-
-      }
-      return NULL;
-    }
-    break;
-  default:
-    /* FIXME : other cases ? */
-    return NULL;
-    break;
-  }
-}
-
-/**
- *
- * @param area1          Process address for state 1
- * @param area2          Process address for state 2
- * @param snapshot1      Snapshot of state 1
- * @param snapshot2      Snapshot of state 2
- * @param previous       Pairs of blocks already compared on the current path (or NULL)
- * @param type_id        Type of variable
- * @param pointer_level
- * @return 0 (same), 1 (different), -1
- */
-int compare_heap_area(void *area1, void* area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, dw_type_t type, int pointer_level){
-
-  struct s_mm_diff* state = mm_diff_info;
-
-  int res_compare;
-  ssize_t block1, frag1, block2, frag2;
-  ssize_t size;
-  int check_ignore = 0;
-
-  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2, *real_addr_block1, *real_addr_block2,  *real_addr_frag1, *real_addr_frag2;
-  void *area1_to_compare, *area2_to_compare;
-  int type_size = -1;
-  int offset1 =0, offset2 = 0;
-  int new_size1 = -1, new_size2 = -1;
-  dw_type_t new_type1 = NULL, new_type2 = NULL;
-
-  int match_pairs = 0;
-
-  if(previous == NULL){
-    previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
-    match_pairs = 1;
-  }
-
-  // Get block number:
-  block1 = ((char*)area1 - (char*)((xbt_mheap_t)state->s_heap)->heapbase) / BLOCKSIZE + 1;
-  block2 = ((char*)area2 - (char*)((xbt_mheap_t)state->s_heap)->heapbase) / BLOCKSIZE + 1;
-
-  // If either block is a stack block:
-  if(is_block_stack((int)block1) && is_block_stack((int)block2)){
-    add_heap_area_pair(previous, block1, -1, block2, -1);
-    if(match_pairs){
-      match_equals(state, previous);
-      xbt_dynar_free(&previous);
-    }
-    return 0;
-  }
-
-  // If either block is not in the expected area of memory:
-  if(((char *)area1 < (char*)((xbt_mheap_t)state->s_heap)->heapbase)  || (block1 > state->heapsize1) || (block1 < 1)
-    || ((char *)area2 < (char*)((xbt_mheap_t)state->s_heap)->heapbase) || (block2 > state->heapsize2) || (block2 < 1)){
-    if(match_pairs){
-      xbt_dynar_free(&previous);
-    }
-    return 1;
-  }
-
-  // Snapshot address of the block:
-  addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
-  addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
-
-  // Process address of the block:
-  real_addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-  real_addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)state->s_heap)->heapbase));
-
-  if(type){
-
-    if(type->full_type)
-      type = type->full_type;
-
-    // This assume that for "boring" types (volatile ...) byte_size is absent:
-    while(type->byte_size == 0 && type->subtype!=NULL)
-      type = type->subtype;
-
-    // Find type_size:
-    if((type->type == DW_TAG_pointer_type) || ((type->type == DW_TAG_base_type) && type->name!=NULL && (!strcmp(type->name, "char"))))
-      type_size = -1;
-    else
-      type_size = type->byte_size;
-
-  }
-  
-  if((state->heapinfo1[block1].type == -1) && (state->heapinfo2[block2].type == -1)){  /* Free block */
-
-    if(match_pairs){
-      match_equals(state, previous);
-      xbt_dynar_free(&previous);
-    }
-    return 0;
-
-  }else if((state->heapinfo1[block1].type == 0) && (state->heapinfo2[block2].type == 0)){ /* Complete block */
-    
-    // TODO, lookup variable type from block type as done for fragmented blocks
-
-    if(state->equals_to1_(block1,0).valid && state->equals_to2_(block2,0).valid){
-      if(equal_blocks(state, block1, block2)){
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return 0;
-      }
-    }
-
-    if(type_size != -1){
-      if(type_size != state->heapinfo1[block1].busy_block.busy_size
-        && type_size != state->heapinfo2[block2].busy_block.busy_size
-        && type->name!=NULL && !strcmp(type->name, "s_smx_context")){
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return -1;
-      }
-    }
-
-    if(state->heapinfo1[block1].busy_block.size != state->heapinfo2[block2].busy_block.size){
-      if(match_pairs){
-        xbt_dynar_free(&previous);
-      }
-      return 1;
-    }
-
-    if(state->heapinfo1[block1].busy_block.busy_size != state->heapinfo2[block2].busy_block.busy_size){
-      if(match_pairs){
-        xbt_dynar_free(&previous);
-      }
-      return 1;
-    }
-
-    if(!add_heap_area_pair(previous, block1, -1, block2, -1)){
-      if(match_pairs){
-        match_equals(state, previous);
-        xbt_dynar_free(&previous);
-      }
-      return 0;
-    }
-    size = state->heapinfo1[block1].busy_block.busy_size;
-    
-    // Remember (basic) type inference.
-    // The current data structure only allows us to do this for the whole block.
-    if (type != NULL && area1==real_addr_block1) {
-      state->types1_(block1,0) = type;
-    }
-    if (type != NULL && area2==real_addr_block2) {
-      state->types2_(block2,0) = type;
-    }
-
-    if(size <= 0){
-      if(match_pairs){
-        match_equals(state, previous);
-        xbt_dynar_free(&previous);
-      }
-      return 0;
-    }
-
-    frag1 = -1;
-    frag2 = -1;
-
-    area1_to_compare = addr_block1;
-    area2_to_compare = addr_block2;
-
-    if((state->heapinfo1[block1].busy_block.ignore > 0) && (state->heapinfo2[block2].busy_block.ignore == state->heapinfo1[block1].busy_block.ignore))
-      check_ignore = state->heapinfo1[block1].busy_block.ignore;
-      
-  }else if((state->heapinfo1[block1].type > 0) && (state->heapinfo2[block2].type > 0)){ /* Fragmented block */
-
-    // Fragment number:
-    frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> state->heapinfo1[block1].type;
-    frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> state->heapinfo2[block2].type;
-
-    // Snapshot address of the fragment:
-    addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << state->heapinfo1[block1].type));
-    addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << state->heapinfo2[block2].type));
-
-    // Process address of the fragment:
-    real_addr_frag1 = (void*) ((char *)real_addr_block1 + (frag1 << ((xbt_mheap_t)state->s_heap)->heapinfo[block1].type));
-    real_addr_frag2 = (void*) ((char *)real_addr_block2 + (frag2 << ((xbt_mheap_t)state->s_heap)->heapinfo[block2].type));
-
-    // Check the size of the fragments against the size of the type:
-    if(type_size != -1){
-      if(state->heapinfo1[block1].busy_frag.frag_size[frag1] == -1 || state->heapinfo2[block2].busy_frag.frag_size[frag2] == -1){
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return -1;
-      }
-      if(type_size != state->heapinfo1[block1].busy_frag.frag_size[frag1]|| type_size !=  state->heapinfo2[block2].busy_frag.frag_size[frag2]){
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return -1;
-      }
-    }
-
-    // Check if the blocks are already matched together:
-    if(state->equals_to1_(block1,frag1).valid && state->equals_to2_(block2,frag2).valid){
-      if(equal_fragments(state, block1, frag1, block2, frag2)){
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return 0;
-      }
-    }
-
-    // Compare the size of both fragments:
-    if(state->heapinfo1[block1].busy_frag.frag_size[frag1] != state->heapinfo2[block2].busy_frag.frag_size[frag2]){
-      if(type_size == -1){
-         if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return -1;
-      }else{
-        if(match_pairs){
-          xbt_dynar_free(&previous);
-        }
-        return 1;
-      }
-    }
-      
-    // Size of the fragment:
-    size = state->heapinfo1[block1].busy_frag.frag_size[frag1];
-
-    // Remember (basic) type inference.
-    // The current data structure only allows us to do this for the whole block.
-    if(type != NULL && area1==real_addr_frag1){
-      state->types1_(block1,frag1) = type;
-    }
-    if(type != NULL && area2==real_addr_frag2) {
-      state->types2_(block2,frag2) = type;
-    }
-
-    // The type of the variable is already known:
-    if(type) {
-      new_type1 = type;
-      new_type2 = type;
-    }
-
-    // Type inference from the block type.
-    else if(state->types1_(block1,frag1) != NULL || state->types2_(block2,frag2) != NULL) {
-
-      offset1 = (char *)area1 - (char *)real_addr_frag1;
-      offset2 = (char *)area2 - (char *)real_addr_frag2;
-
-      if(state->types1_(block1,frag1) != NULL && state->types2_(block2,frag2) != NULL){
-        new_type1 = get_offset_type(real_addr_frag1, state->types1_(block1,frag1), offset1, size, snapshot1);
-        new_type2 = get_offset_type(real_addr_frag2, state->types2_(block2,frag2), offset1, size, snapshot2);
-      }else if(state->types1_(block1,frag1) != NULL){
-        new_type1 = get_offset_type(real_addr_frag1, state->types1_(block1,frag1), offset1, size, snapshot1);
-        new_type2 = get_offset_type(real_addr_frag2, state->types1_(block1,frag1), offset2, size, snapshot2);
-      }else if(state->types2_(block2,frag2) != NULL){
-        new_type1 = get_offset_type(real_addr_frag1, state->types2_(block2,frag2), offset1, size, snapshot1);
-        new_type2 = get_offset_type(real_addr_frag2, state->types2_(block2,frag2), offset2, size, snapshot2);
-      }else{
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return -1;
-      }   
-
-      if(new_type1 !=  NULL && new_type2 !=  NULL && new_type1!=new_type2){
-
-          type = new_type1;
-          while(type->byte_size == 0 && type->subtype != NULL)
-            type = type->subtype;
-          new_size1 = type->byte_size;
-
-          type = new_type2;
-          while(type->byte_size == 0 && type->subtype != NULL)
-            type = type->subtype;
-          new_size2 = type->byte_size;
-
-      }else{
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return -1;
-      }
-    }
-
-    area1_to_compare = (char *)addr_frag1 + offset1;
-    area2_to_compare = (char *)addr_frag2 + offset2;
-    
-    if(new_size1 > 0 && new_size1 == new_size2){
-      type = new_type1;
-      size = new_size1;
-    }
-
-    if(offset1 == 0 && offset2 == 0){
-      if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
-        if(match_pairs){
-          match_equals(state, previous);
-          xbt_dynar_free(&previous);
-        }
-        return 0;
-      }
-    }
-
-    if(size <= 0){
-      if(match_pairs){
-        match_equals(state, previous);
-        xbt_dynar_free(&previous);
-      }
-      return 0;
-    }
-      
-    if((state->heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( state->heapinfo2[block2].busy_frag.ignore[frag2] == state->heapinfo1[block1].busy_frag.ignore[frag1]))
-      check_ignore = state->heapinfo1[block1].busy_frag.ignore[frag1];
-    
-  }else{
-
-    if(match_pairs){
-      xbt_dynar_free(&previous);
-    }
-    return 1;
-
-  }
-  
-
-  /* Start comparison*/
-  if(type){
-    res_compare = compare_heap_area_with_type(state, area1, area2, area1_to_compare, area2_to_compare, snapshot1, snapshot2, previous, type, size, check_ignore, pointer_level);
-  }else{
-    res_compare = compare_heap_area_without_type(state, area1, area2, area1_to_compare, area2_to_compare, snapshot1, snapshot2, previous, size, check_ignore);
-  }
-  if(res_compare == 1){
-    if(match_pairs)
-      xbt_dynar_free(&previous);
-    return res_compare;
-  }
-
-  if(match_pairs){
-    match_equals(state, previous);
-    xbt_dynar_free(&previous);
-  }
-
-  return 0;
-}
-
-/*********************************************** Miscellaneous ***************************************************/
-/****************************************************************************************************************/
-
-// Not used:
-static int get_pointed_area_size(void *area, int heap){
-
-  struct s_mm_diff *state = mm_diff_info;
-
-  int block, frag;
-  malloc_info *heapinfo;
-
-  if(heap == 1)
-    heapinfo = state->heapinfo1;
-  else
-    heapinfo = state->heapinfo2;
-
-  block = ((char*)area - (char*)((xbt_mheap_t)state->s_heap)->heapbase) / BLOCKSIZE + 1;
-
-  if(((char *)area < (char*)((xbt_mheap_t)state->s_heap)->heapbase)  || (block > state->heapsize1) || (block < 1))
-    return -1;
-
-  if(heapinfo[block].type == -1){ /* Free block */
-    return -1;  
-  }else if(heapinfo[block].type == 0){ /* Complete block */
-    return (int)heapinfo[block].busy_block.busy_size;
-  }else{
-    frag = ((uintptr_t) (ADDR2UINT (area) % (BLOCKSIZE))) >> heapinfo[block].type;
-    return (int)heapinfo[block].busy_frag.frag_size[frag];
-  }
-
-}
-
-// Not used:
-char *get_type_description(mc_object_info_t info, char *type_name){
-
-  xbt_dict_cursor_t dict_cursor;
-  char *type_origin;
-  dw_type_t type;
-
-  xbt_dict_foreach(info->types, dict_cursor, type_origin, type){
-    if(type->name && (strcmp(type->name, type_name) == 0) && type->byte_size > 0){
-      xbt_dict_cursor_free(&dict_cursor);
-      return type_origin;
-    }
-  }
-
-  xbt_dict_cursor_free(&dict_cursor);
-  return NULL;
-}
-
-
-#ifndef max
-#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
-#endif
-
-// Not used:
-int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
-
-  struct s_mm_diff *state = mm_diff_info;
-
-  if(heap1 == NULL && heap1 == NULL){
-    XBT_DEBUG("Malloc descriptors null");
-    return 0;
-  }
-
-  if(heap1->heaplimit != heap2->heaplimit){
-    XBT_DEBUG("Different limit of valid info table indices");
-    return 1;
-  }
-
-  /* Heap information */
-  state->heaplimit = ((struct mdesc *)heap1)->heaplimit;
-
-  state->s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - xbt_pagesize;
-
-  state->heapbase1 = (char *)heap1 + BLOCKSIZE;
-  state->heapbase2 = (char *)heap2 + BLOCKSIZE;
-
-  state->heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)state->s_heap)));
-  state->heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)state->s_heap)));
-
-  state->heapsize1 = heap1->heapsize;
-  state->heapsize2 = heap2->heapsize;
-
-  /* Start comparison */
-  size_t i, j, k;
-  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
-
-  int distance = 0;
-
-  /* Check busy blocks*/
-
-  i = 1;
-
-  while(i <= state->heaplimit){
-
-    addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase1));
-    addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)state->heapbase2));
-
-    if(state->heapinfo1[i].type != state->heapinfo2[i].type){
-  
-      distance += BLOCKSIZE;
-      XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, state->heapinfo1[i].type, state->heapinfo2[i].type, distance);
-      i++;
-    
-    }else{
-
-      if(state->heapinfo1[i].type == -1){ /* Free block */
-        i++;
-        continue;
-      }
-
-      if(state->heapinfo1[i].type == 0){ /* Large block */
-       
-        if(state->heapinfo1[i].busy_block.size != state->heapinfo2[i].busy_block.size){
-          distance += BLOCKSIZE * max(state->heapinfo1[i].busy_block.size, state->heapinfo2[i].busy_block.size);
-          i += max(state->heapinfo1[i].busy_block.size, state->heapinfo2[i].busy_block.size);
-          XBT_DEBUG("Different larger of cluster at block %zu : %zu - %zu -> distance = %d", i, state->heapinfo1[i].busy_block.size, state->heapinfo2[i].busy_block.size, distance);
-          continue;
-        }
-
-        /*if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
-          distance += max(heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size);
-          i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
-          XBT_DEBUG("Different size used oin large cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size, distance);
-          continue;
-          }*/
-
-        k = 0;
-
-        //while(k < (heapinfo1[i].busy_block.busy_size)){
-        while(k < state->heapinfo1[i].busy_block.size * BLOCKSIZE){
-          if(memcmp((char *)addr_block1 + k, (char *)addr_block2 + k, 1) != 0){
-            distance ++;
-          }
-          k++;
-        } 
-
-        i++;
-
-      }else { /* Fragmented block */
-
-        for(j=0; j < (size_t) (BLOCKSIZE >> state->heapinfo1[i].type); j++){
-
-          addr_frag1 = (void*) ((char *)addr_block1 + (j << state->heapinfo1[i].type));
-          addr_frag2 = (void*) ((char *)addr_block2 + (j << state->heapinfo2[i].type));
-
-          if(state->heapinfo1[i].busy_frag.frag_size[j] == 0 && state->heapinfo2[i].busy_frag.frag_size[j] == 0){
-            continue;
-          }
-          
-          
-          /*if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
-            distance += max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]);
-            XBT_DEBUG("Different size used in fragment %zu in block %zu : %d - %d -> distance = %d", j, i, heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j], distance); 
-            continue;
-            }*/
-   
-          k=0;
-
-          //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
-          while(k < (BLOCKSIZE / (BLOCKSIZE >> state->heapinfo1[i].type))){
-            if(memcmp((char *)addr_frag1 + k, (char *)addr_frag2 + k, 1) != 0){
-              distance ++;
-            }
-            k++;
-          }
-
-        }
-
-        i++;
-
-      }
-      
-    }
-
-  }
-
-  return distance;
-  
-}
-
index 3c8e301..68cd43f 100644 (file)
@@ -61,7 +61,7 @@ static int allocated_junk = 0; /* keep track of many blocks of our little area w
 static char junkareas[MAX_JUNK_AREAS][JUNK_SIZE];
 
 /* This version use mmalloc if there is a current heap, or the legacy implem if not */
-void *malloc(size_t n) {
+static void *malloc_or_calloc(size_t n, int setzero) {
   xbt_mheap_t mdp = __mmalloc_current_heap;
   void *ret;
 #ifdef MM_LEGACY_VERBOSE
@@ -73,14 +73,17 @@ void *malloc(size_t n) {
     LOCK(mdp);
     ret = mmalloc(mdp, n);
     UNLOCK(mdp);
+    // This was already done by mmalloc:
+    if (mdp->options & XBT_MHEAP_OPTION_MEMSET) {
+      setzero = 0;
+    }
 #ifdef MM_LEGACY_VERBOSE
     if (!warned_mmalloc) {
       fprintf(stderr,"Using mmalloc; enabling the model-checker in cmake may have a bad impact on your simulation performance\n");
       warned_mmalloc = 1;
     }
 #endif
-  } else {
-    if (!real_malloc) {
+  } else if (!real_malloc) {
       size_t needed_areas = n / JUNK_SIZE;
       if(needed_areas * JUNK_SIZE != n) needed_areas++;
       if (allocated_junk+needed_areas>=MAX_JUNK_AREAS) {
@@ -90,9 +93,10 @@ void *malloc(size_t n) {
       } else {
         size_t i = allocated_junk;
         allocated_junk += needed_areas;
-        return junkareas[i];
+        ret = junkareas[i];
       }
     }
+  else {
 #ifdef MM_LEGACY_VERBOSE
     if (!warned_raw) {
       fprintf(stderr,"Using system malloc after interception; you seem to be currently model-checking\n");
@@ -101,15 +105,20 @@ void *malloc(size_t n) {
 #endif
     ret = real_malloc(n);
   }
+  if (ret && setzero) {
+    memset(ret, 0, n);
+  }
   return ret;
 }
 
+void *malloc(size_t n)
+{
+  return malloc_or_calloc(n, 0);
+}
 
 void *calloc(size_t nmemb, size_t size)
 {
-  void *ret = malloc(nmemb*size);
-  memset(ret, 0, nmemb * size);
-  return ret;
+  return malloc_or_calloc(nmemb*size, 1);
 }
 
 void *realloc(void *p, size_t s)
index 8ee23eb..4839cfe 100644 (file)
    On failure returns NULL. */
 
 xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
+{
+  return xbt_mheap_new_options(fd, baseaddr, 0);
+}
+
+xbt_mheap_t xbt_mheap_new_options(int fd, void *baseaddr, int options)
 {
   struct mdesc mtemp;
   xbt_mheap_t mdp;
@@ -169,6 +174,7 @@ xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr)
   mdp->base = mdp->breakval = mdp->top = baseaddr;
   mdp->next_mdesc = NULL;
   mdp->refcount = 1;
+  mdp->options = options;
   
   /* If we have not been passed a valid open file descriptor for the file
      to map to, then we go for an anonymous map */
@@ -326,7 +332,7 @@ void *mmalloc_preinit(void)
   if (__mmalloc_default_mdp == NULL) {
     unsigned long mask = ~((unsigned long)xbt_pagesize - 1);
     void *addr = (void*)(((unsigned long)sbrk(0) + HEAP_OFFSET) & mask);
-    __mmalloc_default_mdp = xbt_mheap_new(-1, addr);
+    __mmalloc_default_mdp = xbt_mheap_new_options(-1, addr, XBT_MHEAP_OPTION_MEMSET);
     /* Fixme? only the default mdp in protected against forks */
     // This is mandated to protect the mmalloced areas through forks. Think of tesh.
     // Nah, removing the mutex isn't a good idea either for tesh
index 7376ca6..72ca5a0 100644 (file)
@@ -137,8 +137,9 @@ static void *register_morecore(struct mdesc *mdp, size_t size)
 /* Allocate memory from the heap.  */
 void *mmalloc(xbt_mheap_t mdp, size_t size) {
   void *res= mmalloc_no_memset(mdp,size);
-//  fprintf(stderr,"malloc(%zu)~>%p\n",size,res);
-  memset(res,0,size);
+  if (mdp->options & XBT_MHEAP_OPTION_MEMSET) {
+    memset(res,0,size);
+  }
   return res;
 }
 /* Spliting mmalloc this way is mandated by a trick in mrealloc, that gives
index 37e4ea7..abf6140 100644 (file)
@@ -202,6 +202,8 @@ struct mdesc {
   /* The version number of the mmalloc package that created this file. */
   unsigned char version;
 
+  unsigned int options;
+
   /* Some flag bits to keep track of various internal things. */
   unsigned int flags;
 
@@ -218,8 +220,7 @@ struct mdesc {
   /* Limit of valid info table indices.  */
   size_t heaplimit;
 
-  /* Block information table.
-     Allocated with malign/mfree (not mmalloc/mfree).  */
+  /* Block information table. */
   /* Table indexed by block number giving per-block information.  */
   malloc_info *heapinfo;
 
@@ -240,7 +241,9 @@ struct mdesc {
   void *breakval;
 
   /* The end of the current memory region for this malloc heap.  This is
-     the first location past the end of mapped memory. */
+     the first location past the end of mapped memory.
+     Compared to breakval, this value is rounded to the next memory page.
+      */
 
   void *top;
 
index 615ad8d..c355f49 100644 (file)
@@ -39,6 +39,7 @@ int xbt_initialized = 0;
 int _sg_do_clean_atexit = 1;
 
 int xbt_pagesize;
+int xbt_pagebits = 0;
 
 /* Declare xbt_preinit and xbt_postexit as constructor/destructor of the library.
  * This is crude and rather compiler-specific, unfortunately.
@@ -95,6 +96,13 @@ static void xbt_preinit(void) {
   GetSystemInfo(&si);
   xbt_pagesize = si.dwPageSize;
 #endif
+
+  xbt_pagebits = 0;
+  int x = xbt_pagesize;
+  while(x >>= 1) {
+    ++xbt_pagebits;
+  }
+
 #ifdef MMALLOC_WANT_OVERRIDE_LEGACY
   mmalloc_preinit();
 #endif
@@ -112,7 +120,6 @@ static void xbt_preinit(void) {
 #ifndef _WIN32
   srand48(seed);
 #endif
-
   atexit(xbt_postexit);
 }
 
diff --git a/teshsuite/mc/CMakeLists.txt b/teshsuite/mc/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8e986cf
--- /dev/null
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.6)
+
+if(HAVE_MC)
+  set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
+
+  add_executable(page_store page_store.cpp)
+  target_link_libraries(page_store simgrid)
+endif()
+
+set(tesh_files
+  ${tesh_files}
+  ${CMAKE_CURRENT_SOURCE_DIR}/page_store.tesh
+  PARENT_SCOPE
+  )
+set(testsuite_src
+  ${testsuite_src}
+  ${CMAKE_CURRENT_SOURCE_DIR}/page_store.cpp
+  PARENT_SCOPE
+  )
diff --git a/teshsuite/mc/page_store.cpp b/teshsuite/mc/page_store.cpp
new file mode 100644 (file)
index 0000000..592b9ba
--- /dev/null
@@ -0,0 +1,66 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "mc/mc_page_store.h"
+
+static int value = 0;
+
+static void new_content(void* data, size_t size)
+{
+  memset(data, ++value, size);
+}
+
+static void* getpage()
+{
+  return mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+}
+
+int main(int argc, char** argv)
+{
+  // Init
+  size_t pagesize = (size_t) getpagesize();
+  mc_pages_store_t store = new s_mc_pages_store(500);
+  void* data = getpage();
+
+  // Init:
+  xbt_assert(store->size()==0, "Bad size");
+
+  // Store the page once:
+  new_content(data, pagesize);
+  size_t pageno1 = store->store_page(data);
+  xbt_assert(store->get_ref(pageno1)==1, "Bad refcount");
+  const void* copy = store->get_page(pageno1);
+  xbt_assert(memcmp(data, copy, pagesize)==0, "Page data should be the same");
+  xbt_assert(store->size()==1, "Bad size");
+
+  // Store the same page again:
+  size_t pageno2 = store->store_page(data);
+  xbt_assert(pageno1==pageno2, "Page should be the same");
+  xbt_assert(store->get_ref(pageno1)==2, "Bad refcount");
+  xbt_assert(store->size()==1, "Bad size");
+
+  // Store a new page:
+  new_content(data, pagesize);
+  size_t pageno3 = store->store_page(data);
+  xbt_assert(pageno1 != pageno3, "New page should be different");
+  xbt_assert(store->size()==2, "Bad size");
+
+  // Unref pages:
+  store->unref_page(pageno1);
+  xbt_assert(store->get_ref(pageno1)==1, "Bad refcount");
+  xbt_assert(store->size()==2, "Bad size");
+  store->unref_page(pageno2);
+  xbt_assert(store->size()==1, "Bad size");
+
+  // Reallocate page:
+  new_content(data, pagesize);
+  size_t pageno4 = store->store_page(data);
+  xbt_assert(pageno1 == pageno4, "Page was not reused");
+  xbt_assert(store->get_ref(pageno4)==1, "Bad refcount");
+  xbt_assert(store->size()==2, "Bad size");
+
+  return 0;
+}
diff --git a/teshsuite/mc/page_store.tesh b/teshsuite/mc/page_store.tesh
new file mode 100644 (file)
index 0000000..f319a51
--- /dev/null
@@ -0,0 +1,3 @@
+#! ./tesh
+
+$ $SG_TEST_EXENV ${bindir:=.}/page_store