### 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)
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()
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
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
)
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
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 ")
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()
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)
> [ 0.000000] (0:@) Visited pairs = 21
> [ 0.000000] (0:@) Executed transitions = 20
> [ 0.000000] (0:@) Counter-example depth : 20
-
-
-
$ 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
$ $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
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
-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
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
-c-1.me
-c-2.me
-c-3.me
+node-1.acme.org
+node-2.acme.org
+node-3.acme.org
}
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();
--- /dev/null
+#! ./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
}
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();
--- /dev/null
+#! ./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
/** 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 */
#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
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);
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);
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 */
*/
#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 */
#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).
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
-/* 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
/********************************** 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;
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;
/********************************* 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);
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);
#include "xbt/module.h"
#include <xbt/mmalloc.h>
#include "../smpi/private.h"
+#include <alloca.h>
#include "xbt/mmalloc/mmprivate.h"
#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");
/************************************ 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);
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();
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++;
}
/** \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);
- }
+ }
}
}
*
* 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 char* name = 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++;
}
* \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;
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(¤t_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(¤t_variable->locations,
+ current_variable->object_info,
+ &(stack_frame->unw_cursor),
+ (void *) stack_frame->frame_base,
+ NULL);
} else {
xbt_die("No address");
}
}
}
-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();
}
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;
}
-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();
}
--- /dev/null
+/* 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;
+}
+++ /dev/null
-/* 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);
-
-}
--- /dev/null
+/* 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);
+
+}
+
+}
--- /dev/null
+/* 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
+++ /dev/null
-/* 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;
-}
-
-
-
-
* 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>
* \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
*
* \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
*
* \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)
*
* \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:
* \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:
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;
}
}
* \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:
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;
}
* \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));
}
* \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);
}
}
* \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
* \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)
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;
}
* \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:
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;
}
}
* \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;
}
* \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);
}
}
* \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;
}
case MC_DW_CLASS_BLOCK:
// Location expression:
{
- Dwarf_Op* expr;
+ 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);
}
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:
// 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);
}
* \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)
// Global Offset:
member->id = dwarf_dieoffset(&child);
- const char* name = 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);
* \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;
// Global Offset
type->id = dwarf_dieoffset(die);
- const char* prefix = "";
+ const char *prefix = "";
switch (type->type) {
case DW_TAG_structure_type:
prefix = "struct ";
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);
// 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:
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);
- char* key = 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 char* name = 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_Op* expr;
+ 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;
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) {
- char* old_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
- void* base = 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:
}
}
- 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) {
- char* key = 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");
- char* new_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;
}
}
* 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);
}
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;
+ }
+ }
+ }
+
+ }
+}
#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_Op* op = 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:
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;
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;
}
/** \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;
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");
* \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;
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);
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;
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;
}
}
"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 */
__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 */
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, ®ion);
- 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, ®ion);
- else
- xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, ®ion);
-
- 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, ®ion);
-
- 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, ®ion);
- }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, ®ion);
- }else{
- xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, ®ion);
- }
- }else if(current_region->addr < addr){
- xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, ®ion);
- }else{
- xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, ®ion);
- }
+ 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();
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)
{
//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;
}
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);
}
{
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;
}
*/
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;
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++;
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;
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++;
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);
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;
+
}
/**
*/
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;
}
{
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;
}
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;
+}
#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;
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]);
}
}
* \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:
}
-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;
}
// 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;
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;
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);
--- /dev/null
+/* 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, ®ion);
+ 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, ®ion);
+ else
+ xbt_dynar_insert_at(mc_heap_comparison_ignore, cursor, ®ion);
+
+ 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, ®ion);
+
+ 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, ®ion);
+ } 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, ®ion);
+ } else {
+ xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, ®ion);
+ }
+ } else if (current_region->addr < addr) {
+ xbt_dynar_insert_at(mc_checkpoint_ignore, cursor + 1, ®ion);
+ } else {
+ xbt_dynar_insert_at(mc_checkpoint_ignore, cursor, ®ion);
+ }
+ }
+
+ if (!raw_mem_set)
+ MC_SET_STD_HEAP;
+}
/********* 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);
}
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;
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;
}
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;
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();
}
}
- 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;
}
* @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;
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);
- }
-}
/* 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
}
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);
}
--- /dev/null
+/* 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
--- /dev/null
+#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);
+ }
+}
+
+}
--- /dev/null
+/* 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);
+}
+
+}
--- /dev/null
+/* 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
#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;
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));
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);
}
#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;
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
*
*/
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;
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;
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 ***********************************/
/******************************** 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) */
/* 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 */
/* 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 ***************************/
//#define MC_DEBUG 1
#define MC_VERBOSE 1
-/********************************** DPOR for safety property **************************************/
+/********************************** Safety verification **************************************/
typedef enum {
e_mc_reduce_unset,
} 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;
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;
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 **********************************/
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
};
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. */
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;
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 *********** */
* */
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
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_request, mc,
"Logging specific to MC (request)");
-static char* pointer_to_string(void* pointer);
-static char* buff_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;
}
* 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
&& 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
&& 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
&& 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);
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);
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;
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);
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;
}
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)
/* 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);
}
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;
}
}
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;
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;
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;
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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);
+}
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;
}
*/
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);
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;
/* 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;
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;
}
}
}
--- /dev/null
+/* 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;
+}
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.",
}
#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);
}
*/
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);
-
}
/**
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);
#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 */
#include "mmorecore.c"
#include "mm_legacy.c"
#include "mm_module.c"
-#include "mm_diff.c"
+++ /dev/null
-/* 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;
-
-}
-
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
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) {
} 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");
#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)
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;
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 */
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
/* 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
/* 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;
/* 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;
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;
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.
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
#ifndef _WIN32
srand48(seed);
#endif
-
atexit(xbt_postexit);
}
--- /dev/null
+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
+ )
--- /dev/null
+#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;
+}
--- /dev/null
+#! ./tesh
+
+$ $SG_TEST_EXENV ${bindir:=.}/page_store