Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
authormlaurent <mathieu.laurent@ens-rennes.fr>
Tue, 7 Nov 2023 12:20:10 +0000 (13:20 +0100)
committermlaurent <mathieu.laurent@ens-rennes.fr>
Tue, 7 Nov 2023 12:20:10 +0000 (13:20 +0100)
322 files changed:
.circleci/config.yml
.github/workflows/git.yml
.gitignore
.gitlab-ci.yml
BuildSimGrid.sh
CMakeLists.txt
COPYING
ChangeLog
MANIFEST.in
docs/source/Configuring_SimGrid.rst
docs/source/Installing_SimGrid.rst
docs/source/Plugins.rst
docs/source/Release_Notes.rst
docs/source/Tutorial_Model-checking.rst
examples/cpp/CMakeLists.txt
examples/cpp/activityset-testany/s4u-activityset-testany.cpp
examples/cpp/activityset-testany/s4u-activityset-testany.tesh
examples/cpp/activityset-waitall/s4u-activityset-waitall.cpp
examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.cpp
examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.tesh
examples/cpp/activityset-waitany/s4u-activityset-waitany.cpp
examples/cpp/activityset-waitany/s4u-activityset-waitany.tesh
examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp [new file with mode: 0644]
examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh [new file with mode: 0644]
examples/cpp/battery-connector/s4u-battery-connector.cpp [new file with mode: 0644]
examples/cpp/battery-connector/s4u-battery-connector.tesh [new file with mode: 0644]
examples/cpp/battery-degradation/s4u-battery-degradation.cpp
examples/cpp/battery-energy/s4u-battery-energy.cpp
examples/cpp/battery-simple/s4u-battery-simple.cpp
examples/cpp/chiller-simple/s4u-chiller-simple.cpp
examples/cpp/chiller-simple/s4u-chiller-simple.tesh
examples/cpp/io-dependent/s4u-io-dependent.cpp
examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness [deleted file]
examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner [deleted file]
examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh [deleted file]
examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp [deleted file]
examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh [deleted file]
examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness [deleted file]
examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp [deleted file]
examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh [deleted file]
examples/cpp/mc-failing-assert/s4u-mc-failing-assert-statequality.tesh [deleted file]
examples/cpp/mess-wait/s4u-mess-wait.cpp [new file with mode: 0644]
examples/cpp/mess-wait/s4u-mess-wait.tesh [new file with mode: 0644]
examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh
examples/cpp/synchro-mutex/s4u-mc-synchro-mutex-stateful.tesh [deleted file]
examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh
examples/cpp/task-storm/s4u-task-storm.cpp
examples/smpi/CMakeLists.txt
examples/smpi/mc/bugged1_liveness.c [deleted file]
examples/smpi/mc/hostfile_bugged1_liveness [deleted file]
examples/smpi/mc/hostfile_non_termination [deleted file]
examples/smpi/mc/mutual_exclusion.c
examples/smpi/mc/non_termination1.c [deleted file]
examples/smpi/mc/non_termination2.c [deleted file]
examples/smpi/mc/non_termination3.c [deleted file]
examples/smpi/mc/non_termination4.c [deleted file]
examples/smpi/mc/promela_bugged1_liveness [deleted file]
examples/sthread/CMakeLists.txt
examples/sthread/pthread-mc-mutex-recursive.tesh [new file with mode: 0644]
examples/sthread/pthread-mc-mutex-simple.tesh
examples/sthread/pthread-mc-mutex-simpledeadlock.tesh
examples/sthread/pthread-mc-producer-consumer.tesh
examples/sthread/pthread-mutex-recursive.c [new file with mode: 0644]
examples/sthread/pthread-mutex-recursive.tesh [new file with mode: 0644]
examples/sthread/pthread-mutex-simple.c
examples/sthread/pthread-mutex-simple.tesh
examples/sthread/pthread-mutex-simpledeadlock.c
examples/sthread/pthread-producer-consumer.tesh
examples/sthread/stdobject/stdobject.cpp
examples/sthread/stdobject/stdobject.tesh
examples/sthread/sthread-mutex-simple.tesh
include/simgrid/config.h.in
include/simgrid/forward.h
include/simgrid/modelchecker.h
include/simgrid/plugins/battery.hpp
include/simgrid/plugins/chiller.hpp
include/simgrid/plugins/solar_panel.hpp
include/simgrid/s4u.hpp
include/simgrid/s4u/Activity.hpp
include/simgrid/s4u/Engine.hpp
include/simgrid/s4u/Mess.hpp [new file with mode: 0644]
include/simgrid/s4u/MessageQueue.hpp [new file with mode: 0644]
include/simgrid/s4u/Mutex.hpp
include/smpi/smpi.h
include/smpi/smpi_extended_traces.h
include/smpi/smpi_extended_traces_fortran.h
include/xbt/automaton.h [deleted file]
include/xbt/automaton.hpp [deleted file]
sonar-project.properties
src/bindings/python/simgrid_python.cpp
src/internal_config.h.in
src/kernel/EngineImpl.cpp
src/kernel/EngineImpl.hpp
src/kernel/activity/CommImpl.cpp
src/kernel/activity/CommImpl.hpp
src/kernel/activity/MailboxImpl.hpp
src/kernel/activity/MessImpl.cpp [new file with mode: 0644]
src/kernel/activity/MessImpl.hpp [new file with mode: 0644]
src/kernel/activity/MessageQueueImpl.cpp [new file with mode: 0644]
src/kernel/activity/MessageQueueImpl.hpp [new file with mode: 0644]
src/kernel/activity/MutexImpl.cpp
src/kernel/activity/MutexImpl.hpp
src/kernel/actor/CommObserver.cpp
src/kernel/actor/CommObserver.hpp
src/kernel/actor/SimcallObserver.cpp
src/kernel/actor/SimcallObserver.hpp
src/kernel/context/Context.cpp
src/kernel/context/Context.hpp
src/kernel/context/ContextRaw.cpp
src/kernel/context/ContextSwapped.cpp
src/kernel/context/ContextUnix.cpp
src/kernel/resource/HostImpl.cpp
src/kernel/resource/models/network_ns3.cpp
src/mc/AddressSpace.hpp [deleted file]
src/mc/VisitedState.cpp [deleted file]
src/mc/VisitedState.hpp [deleted file]
src/mc/api/RemoteApp.cpp
src/mc/api/RemoteApp.hpp
src/mc/api/State.cpp
src/mc/api/State.hpp
src/mc/api/strategy/BasicStrategy.hpp
src/mc/compare.cpp [deleted file]
src/mc/explo/CommunicationDeterminismChecker.cpp
src/mc/explo/DFSExplorer.cpp
src/mc/explo/DFSExplorer.hpp
src/mc/explo/Exploration.cpp
src/mc/explo/Exploration.hpp
src/mc/explo/LivenessChecker.cpp [deleted file]
src/mc/explo/LivenessChecker.hpp [deleted file]
src/mc/explo/UdporChecker.cpp
src/mc/explo/odpor/ReversibleRaceCalculator.hpp
src/mc/explo/simgrid_mc.cpp
src/mc/explo/udpor/ExtensionSetCalculator.hpp
src/mc/explo/udpor/UnfoldingEvent.cpp
src/mc/explo/udpor/UnfoldingEvent.hpp
src/mc/explo/udpor/udpor_forward.hpp
src/mc/inspect/DwarfExpression.cpp [deleted file]
src/mc/inspect/DwarfExpression.hpp [deleted file]
src/mc/inspect/Frame.cpp [deleted file]
src/mc/inspect/Frame.hpp [deleted file]
src/mc/inspect/LocationList.cpp [deleted file]
src/mc/inspect/LocationList.hpp [deleted file]
src/mc/inspect/ObjectInformation.cpp [deleted file]
src/mc/inspect/ObjectInformation.hpp [deleted file]
src/mc/inspect/Type.hpp [deleted file]
src/mc/inspect/Variable.hpp [deleted file]
src/mc/inspect/mc_dwarf.cpp [deleted file]
src/mc/inspect/mc_dwarf.hpp [deleted file]
src/mc/inspect/mc_dwarf_attrnames.cpp [deleted file]
src/mc/inspect/mc_dwarf_tagnames.cpp [deleted file]
src/mc/inspect/mc_member.cpp [deleted file]
src/mc/inspect/mc_unw.cpp [deleted file]
src/mc/inspect/mc_unw.hpp [deleted file]
src/mc/inspect/mc_unw_vmread.cpp [deleted file]
src/mc/mc_base.cpp
src/mc/mc_client_api.cpp
src/mc/mc_config.cpp
src/mc/mc_config.hpp
src/mc/mc_environ.h
src/mc/mc_global.cpp
src/mc/mc_private.hpp
src/mc/remote/AppSide.cpp
src/mc/remote/AppSide.hpp
src/mc/remote/CheckerSide.cpp
src/mc/remote/CheckerSide.hpp
src/mc/remote/mc_protocol.h
src/mc/sosp/ChunkedData.cpp [deleted file]
src/mc/sosp/ChunkedData.hpp [deleted file]
src/mc/sosp/PageStore.cpp [deleted file]
src/mc/sosp/PageStore.hpp [deleted file]
src/mc/sosp/PageStore_test.cpp [deleted file]
src/mc/sosp/Region.cpp [deleted file]
src/mc/sosp/Region.hpp [deleted file]
src/mc/sosp/RemoteProcessMemory.cpp [deleted file]
src/mc/sosp/RemoteProcessMemory.hpp [deleted file]
src/mc/sosp/Snapshot.cpp [deleted file]
src/mc/sosp/Snapshot.hpp [deleted file]
src/mc/sosp/Snapshot_test.cpp [deleted file]
src/mc/transition/Transition.cpp
src/mc/transition/Transition.hpp
src/mc/transition/TransitionActor.cpp [moved from src/mc/transition/TransitionActorJoin.cpp with 68% similarity]
src/mc/transition/TransitionActor.hpp [moved from src/mc/transition/TransitionActorJoin.hpp with 71% similarity]
src/mc/transition/TransitionSynchro.cpp
src/plugins/battery.cpp
src/plugins/chiller.cpp
src/plugins/solar_panel.cpp
src/s4u/s4u_Activity.cpp
src/s4u/s4u_Actor.cpp
src/s4u/s4u_Engine.cpp
src/s4u/s4u_Io.cpp
src/s4u/s4u_Mess.cpp [new file with mode: 0644]
src/s4u/s4u_MessageQueue.cpp [new file with mode: 0644]
src/s4u/s4u_Mutex.cpp
src/s4u/s4u_Netzone.cpp
src/simgrid/sg_config.cpp
src/simgrid/sg_config.hpp
src/simgrid/sg_version.cpp
src/smpi/bindings/smpi_mpi.cpp
src/smpi/bindings/smpi_pmpi_request.cpp
src/smpi/internals/smpi_actor.cpp
src/smpi/internals/smpi_global.cpp
src/smpi/mpi/smpi_datatype.cpp
src/sthread/ObjectAccess.cpp
src/sthread/sthread.c
src/sthread/sthread.h
src/sthread/sthread_impl.cpp
src/xbt/automaton/automaton.c [deleted file]
src/xbt/automaton/automaton_lexer.yy.c [deleted file]
src/xbt/automaton/automatonparse_promela.c [deleted file]
src/xbt/automaton/parserPromela.lex [deleted file]
src/xbt/automaton/parserPromela.tab.cacc [deleted file]
src/xbt/automaton/parserPromela.tab.hacc [deleted file]
src/xbt/automaton/parserPromela.yacc [deleted file]
src/xbt/mmalloc/mfree.c [deleted file]
src/xbt/mmalloc/mm.c [deleted file]
src/xbt/mmalloc/mm_interface.c [deleted file]
src/xbt/mmalloc/mm_legacy.c [deleted file]
src/xbt/mmalloc/mm_module.c [deleted file]
src/xbt/mmalloc/mmalloc.c [deleted file]
src/xbt/mmalloc/mmalloc.h [deleted file]
src/xbt/mmalloc/mmalloc.info [deleted file]
src/xbt/mmalloc/mmalloc.texi [deleted file]
src/xbt/mmalloc/mmorecore.c [deleted file]
src/xbt/mmalloc/mmprivate.h [deleted file]
src/xbt/mmalloc/mrealloc.c [deleted file]
src/xbt/mmalloc/swag.c [deleted file]
src/xbt/mmalloc/swag.h [deleted file]
src/xbt/xbt_os_time.c
teshsuite/mc/CMakeLists.txt
teshsuite/mc/dwarf-expression/dwarf-expression.cpp [deleted file]
teshsuite/mc/dwarf-expression/dwarf-expression.tesh [deleted file]
teshsuite/mc/dwarf/dwarf.cpp [deleted file]
teshsuite/mc/dwarf/dwarf.tesh [deleted file]
teshsuite/mc/mcmini/barber_shop_deadlock.c [new file with mode: 0644]
teshsuite/mc/mcmini/barber_shop_deadlock.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/barber_shop_ok.c [new file with mode: 0644]
teshsuite/mc/mcmini/barber_shop_ok.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_mutex_deadlock.c [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_mutex_deadlock.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_mutex_ok.c [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_mutex_ok.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_semaphores_deadlock.c [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_semaphores_deadlock.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_semaphores_ok.c [new file with mode: 0644]
teshsuite/mc/mcmini/philosophers_semaphores_ok.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/producer_consumer_deadlock.c [new file with mode: 0644]
teshsuite/mc/mcmini/producer_consumer_deadlock.tesh [new file with mode: 0644]
teshsuite/mc/mcmini/producer_consumer_ok.c [new file with mode: 0644]
teshsuite/mc/mcmini/producer_consumer_ok.tesh [new file with mode: 0644]
teshsuite/mc/random-bug/random-bug.tesh
teshsuite/smpi/MBI/CMakeLists.txt
teshsuite/smpi/MBI/InputHazardGenerator.py
teshsuite/smpi/MBI/MBIutils.py
teshsuite/smpi/MBI/P2PBufferingGenerator.py
teshsuite/smpi/MBI/P2PSendrecvArgGenerator.py
teshsuite/smpi/MBI/generator_utils.py
teshsuite/smpi/MBI/simgrid.py
teshsuite/smpi/mpich3-test/CMakeLists.txt
teshsuite/smpi/mpich3-test/attr/CMakeLists.txt
teshsuite/smpi/mpich3-test/coll/CMakeLists.txt
teshsuite/smpi/mpich3-test/comm/CMakeLists.txt
teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt
teshsuite/smpi/mpich3-test/errhan/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/datatype/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/info/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/rma/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/topo/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/info/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/pt2pt/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/rma/CMakeLists.txt
teshsuite/smpi/mpich3-test/f90/util/CMakeLists.txt
teshsuite/smpi/mpich3-test/group/CMakeLists.txt
teshsuite/smpi/mpich3-test/info/CMakeLists.txt
teshsuite/smpi/mpich3-test/init/CMakeLists.txt
teshsuite/smpi/mpich3-test/io/CMakeLists.txt
teshsuite/smpi/mpich3-test/perf/CMakeLists.txt
teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt
teshsuite/smpi/mpich3-test/rma/CMakeLists.txt
teshsuite/smpi/mpich3-test/topo/CMakeLists.txt
teshsuite/xbt/CMakeLists.txt
teshsuite/xbt/mmalloc/mmalloc_32.tesh [deleted file]
teshsuite/xbt/mmalloc/mmalloc_64.tesh [deleted file]
teshsuite/xbt/mmalloc/mmalloc_test.cpp [deleted file]
tools/CMakeLists.txt
tools/cmake/CTestConfig.cmake
tools/cmake/DefinePackages.cmake
tools/cmake/Distrib.cmake
tools/cmake/Flags.cmake
tools/cmake/MaintainerMode.cmake
tools/cmake/MakeLib.cmake
tools/cmake/Modules/FindLibdw.cmake [deleted file]
tools/cmake/Modules/FindLibelf.cmake [deleted file]
tools/cmake/Modules/FindLibunwind.cmake [deleted file]
tools/cmake/Option.cmake
tools/cmake/Tests.cmake
tools/docker/Dockerfile.build-deps
tools/docker/Dockerfile.stable
tools/docker/Dockerfile.tuto-mc
tools/docker/Dockerfile.unstable
tools/generate-dwarf-functions [deleted file]
tools/jenkins/Coverage.sh
tools/jenkins/DynamicAnalysis.sh
tools/jenkins/Flags.sh
tools/jenkins/Sanitizers.sh
tools/jenkins/build.sh
tools/jenkins/ci-bigdft.sh
tools/jenkins/ci-starpu.sh
tools/jenkins/project_description.sh
tools/simgrid.supp
tools/tesh/catch-signal.tesh
tools/tesh/catch-timeout-output.tesh
tools/tesh/tesh.py

index abd99f5..b505615 100644 (file)
@@ -19,5 +19,5 @@ jobs:
           name: Configure, build and test da stuff
           command: |
             mkdir _build && cd _build
-            cmake -Denable_documentation=OFF -Denable_coverage=OFF -Denable_model-checking=OFF -Denable_compile_optimizations=OFF -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=OFF -Denable_compile_warnings=ON ..
+            cmake -Denable_documentation=OFF -Denable_coverage=OFF -Denable_model-checking=OFF -Denable_compile_optimizations=OFF -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF -Denable_compile_warnings=ON ..
             make -j4 tests && ctest -j4 --output-on-failure
index 39d03c2..eb6bc03 100644 (file)
@@ -39,8 +39,8 @@ jobs:
           mkdir build ; cd build
           cmake -GNinja -Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \
                 -Denable_compile_optimizations=ON -Denable_compile_warnings=ON \
-                -Denable_model-checking=OFF -Denable_smpi_MBI_testsuite=OFF \
-                -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON \
+                -Denable_model-checking=OFF -Denable_testsuite_smpi_MBI=OFF \
+                -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON \
                 -DCMAKE_DISABLE_SOURCE_CHANGES=ON  -DLTO_EXTRA_FLAG="auto" ..
           ninja tests
           ctest --output-on-failure -j$(nproc)
@@ -72,13 +72,12 @@ jobs:
 
       - name: build
         run: |
-          sudo apt-get update && sudo apt-get install ninja-build libboost-dev libboost-context-dev pybind11-dev
-          sudo apt-get install libunwind-dev libdw-dev libelf-dev libevent-dev
+          sudo apt-get update && sudo apt-get install ninja-build libboost-dev libboost-context-dev pybind11-dev libevent-dev
           mkdir build ; cd build
           cmake -GNinja -Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \
                 -Denable_compile_optimizations=ON -Denable_compile_warnings=ON \
-                -Denable_model-checking=ON -Denable_smpi_MBI_testsuite=OFF \
-                -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=OFF \
+                -Denable_model-checking=ON -Denable_testsuite_smpi_MBI=OFF \
+                -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF \
                 -Denable_ns3=OFF \
                 -DCMAKE_DISABLE_SOURCE_CHANGES=ON  -DLTO_EXTRA_FLAG="auto" ..
           ninja tests
index c4b7ab7..97d5571 100644 (file)
@@ -104,6 +104,10 @@ tags
 callgrind.out.*
 ### Examples and traces
 *.exe
+examples/c/activityset-testany/c-activityset-testany
+examples/c/activityset-waitall/c-activityset-waitall
+examples/c/activityset-waitallfor/c-activityset-waitallfor
+examples/c/activityset-waitany/c-activityset-waitany
 examples/c/actor-create/c-actor-create
 examples/c/actor-daemon/c-actor-daemon
 examples/c/actor-exiting/c-actor-exiting
@@ -143,6 +147,10 @@ examples/c/platform-failures/c-platform-failures
 examples/c/platform-properties/c-platform-properties
 examples/c/plugin-host-load/c-plugin-host-load
 examples/c/synchro-semaphore/c-synchro-semaphore
+examples/cpp/activityset-testany/s4u-activityset-testany
+examples/cpp/activityset-waitall/s4u-activityset-waitall
+examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor
+examples/cpp/activityset-waitany/s4u-activityset-waitany
 examples/cpp/actor-create/s4u-actor-create
 examples/cpp/actor-daemon/s4u-actor-daemon
 examples/cpp/actor-exiting/s4u-actor-exiting
@@ -175,8 +183,11 @@ examples/cpp/comm-waitall/s4u-comm-waitall
 examples/cpp/comm-waitany/s4u-comm-waitany
 examples/cpp/comm-waituntil/s4u-comm-waituntil
 examples/cpp/dag-comm/s4u-dag-comm
+examples/cpp/dag-tuto/s4u-dag-tuto
 examples/cpp/dag-failure/s4u-dag-failure
 examples/cpp/dag-from-dax/s4u-dag-from-dax
+examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple
+examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple
 examples/cpp/dag-from-dot/s4u-dag-from-dot
 examples/cpp/dag-io/s4u-dag-io
 examples/cpp/dag-scheduling/s4u-dag-scheduling
@@ -239,6 +250,13 @@ examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable
 examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil
 examples/cpp/synchro-mutex/s4u-synchro-mutex
 examples/cpp/synchro-semaphore/s4u-synchro-semaphore
+examples/cpp/task-dispatch/s4u-task-dispatch
+examples/cpp/task-io/s4u-task-io
+examples/cpp/task-microservice/s4u-task-microservice
+examples/cpp/task-parallelism/s4u-task-parallelism
+examples/cpp/task-simple/s4u-task-simple
+examples/cpp/task-storm/s4u-task-storm
+examples/cpp/task-switch-host/s4u-task-switch-host
 examples/cpp/torus-multicpu/
 examples/cpp/trace-categories/s4u-trace-categories
 examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables
index 89000b0..bbf969b 100644 (file)
@@ -11,7 +11,7 @@ ctest-debug:
   script:
   - apt-get --allow-releaseinfo-change update
   - apt install -y binutils xsltproc
-  - cmake -Denable_model-checking=OFF -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" .
+  - cmake -Denable_model-checking=OFF -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON -Denable_testsuite_McMini=ON -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" .
   - make -j$(nproc) VERBOSE=1 all tests
   - ctest -T Test -j$(nproc) --output-on-failure
   - xsltproc ./tools/jenkins/ctest2junit.xsl Testing/"$( head -n 1 < Testing/TAG )"/Test.xml > CTestResults.xml
@@ -31,7 +31,7 @@ ctest-modelchecking:
   script:
   - apt-get --allow-releaseinfo-change update
   - apt install -y binutils xsltproc clang
-  - cmake -Denable_model-checking=ON -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=OFF -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" -DCMAKE_C_COMPILER=/usr/bin/clang  -DCMAKE_CXX_COMPILER=/usr/bin/clang++ .
+  - cmake -Denable_model-checking=ON -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF -Denable_testsuite_McMini=OFF -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" -DCMAKE_C_COMPILER=/usr/bin/clang  -DCMAKE_CXX_COMPILER=/usr/bin/clang++ .
   - make -j$(nproc) VERBOSE=1 all tests
   - ctest -T Test -j$(nproc) --output-on-failure
   - xsltproc ./tools/jenkins/ctest2junit.xsl Testing/"$( head -n 1 < Testing/TAG )"/Test.xml > CTestResults.xml
index 66b309e..410d1dd 100755 (executable)
@@ -17,6 +17,7 @@ fi
 
 target=examples
 ncores=$(grep -c processor /proc/cpuinfo)
+halfcores=$(expr $ncores / 2 + 1)
 
 install_path=$(sed -n 's/^CMAKE_INSTALL_PREFIX:PATH=//p' CMakeCache.txt)
 if [ -e ${install_path} ] && [ -d ${install_path} ] && [ -x ${install_path} ] && [ -w ${install_path} ] ; then
@@ -32,7 +33,8 @@ fi
 (
   echo "install_path: ${install_path}"
   echo "Target: ${target}"
-  echo "Cores: ${ncores}"
-  (nice ${builder} -j${ncores} ${target} tests || make ${target} tests) && nice ctest -j${ncores} --output-on-failure ; date
+  echo "Cores to build: ${ncores}"
+  echo "Cores to test: ${halfcores}"
+  (nice ${builder} -j${ncores} ${target} tests || ${builder} ${target} tests) && nice ctest -j${halfcores} --output-on-failure ; date
 ) 2>&1 | tee BuildSimGrid.sh.log
 
index 1a4a245..47a5670 100644 (file)
@@ -35,12 +35,8 @@ include(GNUInstallDirs)
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
 #     Check for the compiler        #
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
-##
-## Check the C/C++ standard that we need
-##   See also tools/cmake/Flags.cmake that sets our paranoid warning flags
-INCLUDE(CheckCCompilerFlag)
-CHECK_C_COMPILER_FLAG(-fstack-cleaner HAVE_C_STACK_CLEANER)
 
+INCLUDE(CheckCCompilerFlag)
 ## Request full debugging flags
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
@@ -217,21 +213,25 @@ if(enable_ns3)
 endif()
 
 ### Check for Eigen library
-set(SIMGRID_HAVE_EIGEN3 OFF)
-find_package (Eigen3 3.3 CONFIG
-              HINTS ${EIGEN3_HINT})
-if (Eigen3_FOUND)
-  set(SIMGRID_HAVE_EIGEN3 ON) 
-  message(STATUS "Found Eigen3: ${EIGEN3_INCLUDE_DIR}")
-  include_directories(${EIGEN3_INCLUDE_DIR})
-  if ("3.3.4" VERSION_EQUAL EIGEN3_VERSION_STRING AND CMAKE_COMPILER_IS_GNUCC)
-    message(STATUS "Avoid build error of Eigen3 v3.3.4 using -Wno-error=int-in-bool-context")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=int-in-bool-context")
+if ((NOT DEFINED EIGEN3_HINT) OR (NOT EIGEN3_HINT STRLESS_EQUAL "OFF"))
+  set(SIMGRID_HAVE_EIGEN3 OFF)
+  find_package (Eigen3 3.3 CONFIG
+                HINTS ${EIGEN3_HINT})
+  if (Eigen3_FOUND)
+    set(SIMGRID_HAVE_EIGEN3 ON)
+    message(STATUS "Found Eigen3: ${EIGEN3_INCLUDE_DIR}")
+    include_directories(${EIGEN3_INCLUDE_DIR})
+    if ("3.3.4" VERSION_EQUAL EIGEN3_VERSION_STRING AND CMAKE_COMPILER_IS_GNUCC)
+      message(STATUS "Avoid build error of Eigen3 v3.3.4 using -Wno-error=int-in-bool-context")
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=int-in-bool-context")
+    endif()
+  else()
+    message(STATUS "Disabling model BMF because Eigen3 was not found. If it's installed, use EIGEN3_HINT to hint cmake about the location of Eigen3Config.cmake")
   endif()
+  mark_as_advanced(Eigen3_DIR)
 else()
-  message(STATUS "Disabling model BMF because Eigen3 was not found. If it's installed, use EIGEN3_HINT to hint cmake about the location of Eigen3Config.cmake")
+  message(STATUS "Disabling Eigen3 as requested by the user (EIGEN3_HINT is set to 'OFF')")
 endif()
-mark_as_advanced(Eigen3_DIR)
 
 # Check for our JSON dependency
 set(SIMGRID_HAVE_JSON 0)
@@ -341,7 +341,6 @@ if(NOT HAVE_SYSCONF)
   message(FATAL_ERROR "Cannot build without sysconf.")
 endif()
 CHECK_FUNCTION_EXISTS(process_vm_readv HAVE_PROCESS_VM_READV)
-CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP)
 CHECK_FUNCTION_EXISTS(mremap HAVE_MREMAP)
 
 CHECK_SYMBOL_EXISTS(vasprintf stdio.h HAVE_VASPRINTF)
@@ -354,14 +353,6 @@ else()
   set(SG_HAVE_SENDFILE 0)
 endif()
 
-if(enable_model-checking AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD")
-  message(FATAL_ERROR "Support for model-checking has not been enabled on ${CMAKE_SYSTEM}. Please use a Linux docker to use the model checker.")
-endif()
-
-if(enable_model-checking AND minimal-bindings)
-  message(FATAL_ERROR "Compile-time option 'minimal-bindings' cannot be enabled with 'model-checking'")
-endif()
-
 if(enable_mallocators)
   SET(SIMGRID_HAVE_MALLOCATOR 1)
 else()
@@ -369,43 +360,19 @@ else()
 endif()
 
 SET(SIMGRID_HAVE_MC OFF)
-SET(SIMGRID_HAVE_STATEFUL_MC OFF)
-SET(HAVE_MMALLOC 0)
-
-find_package(Libevent)
-if(Libevent_FOUND)
-  message(STATUS "Found libevent. The stateless model-checking can be enabled.")
-  include_directories(${LIBEVENT_INCLUDE_DIR})
-  set(SIMGRID_DEP "${SIMGRID_DEP} ${LIBEVENT_LIBRARIES}")
-  SET(SIMGRID_HAVE_MC ON)
-else()
-  message(STATUS "libevent not found. Please install libevent-dev to enable the SimGrid model checker.")
-endif()
-mark_as_advanced(LIBEVENT_LIBRARY)
-mark_as_advanced(LIBEVENT_THREADS_LIBRARY)
 
 if(enable_model-checking)
-  include(FindLibunwind)
-  find_package(Libdw)
-  find_package(Libelf)
-  if(HAVE_MMAP AND HAVE_LIBUNWIND AND Libdw_FOUND AND Libelf_FOUND AND Libevent_FOUND)
-    message(STATUS "All dependencies found. The stateful model-checking can be enabled.")
-    SET(SIMGRID_HAVE_STATEFUL_MC ON)
-    SET(HAVE_MMALLOC 1)
-    SET(SIMGRID_DEP "${SIMGRID_DEP} ${LIBUNWIND_LIBRARIES} ${LIBELF_LIBRARIES} ${LIBDW_LIBRARIES}")
-    include_directories(${LIBDW_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR})
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gdwarf-4")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gdwarf-4")
+  find_package(Libevent)
+  if(Libevent_FOUND)
+    message(STATUS "Found libevent. The stateless model-checking can be enabled.")
+    include_directories(${LIBEVENT_INCLUDE_DIR})
+    set(SIMGRID_DEP "${SIMGRID_DEP} ${LIBEVENT_LIBRARIES}")
+    SET(SIMGRID_HAVE_MC ON)
   else()
-    message(STATUS "Please install libunwind-dev libdw-dev libelf-dev libevent-dev to enable the stateful model checker.")
-    set(HAVE_MMALLOC 0)
+    message(STATUS "libevent not found. Please install libevent-dev to enable the SimGrid model checker.")
   endif()
-endif()
-mark_as_advanced(PATH_LIBDW_H)
-mark_as_advanced(PATH_LIBDW_LIB)
-
-if (SIMGRID_HAVE_STATEFUL_MC AND enable_ns3) 
-  message(WARNING "Activating both model-checking and ns-3 bindings is considered experimental.")
+  mark_as_advanced(LIBEVENT_LIBRARY)
+  mark_as_advanced(LIBEVENT_THREADS_LIBRARY)
 endif()
 
 if(enable_smpi)
@@ -798,11 +765,6 @@ endif()
 
 option(enable_python "Whether the Python bindings are activated." ${default_enable_python}) # ON by default if dependencies are met
 
-if("${CMAKE_SYSTEM}" MATCHES "FreeBSD" AND enable_model-checking AND enable_python)
-  message(WARNING "FreeBSD + Model-Checking + Python = too much for now. Disabling the Python bindings.")
-  set(enable_python FALSE)
-endif()
-
 if(enable_python)
   if(NOT Python3_Development_FOUND)
     message(FATAL_ERROR "Please install the development components of Python (python3-dev on Debian) to build the Python bindings (or disable that option).")
@@ -942,15 +904,15 @@ else()
 endif()
 message("        Compile Smpi ................: ${HAVE_SMPI}")
 message("          Smpi fortran ..............: ${SMPI_FORTRAN}")
-message("          MPICH3 testsuite ..........: ${enable_smpi_MPICH3_testsuite}")
-message("          MBI testsuite .............: ${enable_smpi_MBI_testsuite}")
+message("          MPICH3 testsuite ..........: ${enable_testsuite_smpi_MPICH3}")
+message("          MBI testsuite .............: ${enable_testsuite_smpi_MBI}")
 message("          Privatization .............: ${HAVE_PRIVATIZATION}")
 message("          PAPI support ..............: ${HAVE_PAPI}")
 message("        Compile Boost.Context support: ${HAVE_BOOST_CONTEXTS}")
 message("")
 message("        Model checking ..............: ${SIMGRID_HAVE_MC}")
-message("          Stateful model checking ...: ${SIMGRID_HAVE_STATEFUL_MC}")
-message("          MBI testsuite .............: ${enable_smpi_MBI_testsuite}")
+message("          MBI testsuite .............: ${enable_testsuite_smpi_MBI}")
+message("          McMini testsuite ..........: ${enable_testsuite_McMini}")
 message("")
 message("        Maintainer mode .............: ${enable_maintainer_mode}")
 message("        Documentation ...............: ${enable_documentation}")
@@ -964,4 +926,3 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}
 file(WRITE ${PROJECT_BINARY_DIR}/Testing/Notes/Build  "GIT version : ${GIT_VERSION}\n")
 file(APPEND ${PROJECT_BINARY_DIR}/Testing/Notes/Build "Release     : simgrid-${release_version}\n")
 
-INCLUDE(Dart)
diff --git a/COPYING b/COPYING
index f4b1b6d..c178bb3 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -173,13 +173,6 @@ Copyright: 1997, Rolf Rabenseifner. Computing Center University of Stuttgart
 License: other-reduce-rab
  The usage of this software is free, but this header must not be removed.
 
-Files: src/xbt/automaton/parserPromela.tab.cacc
-Copyright:
- Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
- Copyright (C) 2003-2023. The SimGrid team.
-License: GPL-3+ and LGPL-2.1-only
-Comment: Generated with the Bison processor generator (which is GPL-3+) using SimGrid configuration files (that are LGPL-2.1-only)
-
 Files: src/3rd-party/catch.hpp
 Copyright:
   Copyright (c) 2022 Two Blue Cubes Ltd.
index 893664d..c3dd61a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,15 +3,49 @@ SimGrid (3.34.1) not released (Target: fall 2023)
 S4U:
  - New class ActivitySet to ease wait_any()/test_any()/wait_all()
    - Deprecate {Comm,Io,Exec}::{wait_any,wait_all,test_any} and friends
- - New function NetZone::add_route(host1, host2, links) when you don't need gateways
-   Also add a variant with s4u::Link, when you don't want to specify the directions
-   on symmetric routes.
- - Introduce a Mailbox::get_async() with no payload parameter. You can use the new 
+ - Simplify a bit the declaration of multi-zoned platforms from C++
+   - New function NetZone::add_route(host1, host2, links) when you don't need gateways
+   - Also add a variant with s4u::Link, when you don't want to specify the directions
+     on symmetric routes.
+   - Zone's gateways can now be controlled directly.
+   - Add NetZone::add_route(zone1, zone2, links) specifying the route between zones
+ - Introduce a Mailbox::get_async() with no payload parameter. You can use the new
    Comm::get_payload() once the communication is over to retrieve the payload.
+ - Implement recursive mutexes. Simply pass true to the constructor to get one.
+ - Simplify the expression of horizontal scaling of Tasks.
+   - Each Task now consists of a dispatcher, a collector and one or more instances.
+   - The parallelism degree of each of these can be set.
+   - Several examples have been added or modified accordingly.
+ - Introduce a new MessageQueue abstraction and associated Mess simulated object.
+   The behavior of a MessageQueue is similar to that of a Mailbox, but intended for
+   control messages that do not incur any simulated cost. Information is automagically
+   transported over thin air between producer and consumer. See examples/cpp/mess-wait
+
+New S4U plugins:
+ - Add a JBOD (just a bunch of disks) concept. It's a sort of host with many disks.
+ - Revamp the battery plugin: rewrite completely the API, for a better usability.
+   The examples were updated accordingly.
+   The battery can now act as a simple connector (see battery-connector example).
+ - Revamp of the Photovoltaic plugin: now called SolarPanel and complete rewrite of the API
+ - Add chiller plugin: enable the management of chillers consuming electrical energy
+   to compensate heat generated by hosts.
+ - Add a battery-chiller-solar example combining several plugins to evaluate the amount
+   of brown energy (from the electrical grid) and green energy (from the solar panel)
+   during a given computation.
 
 SMPI:
  - New SMPI_app_instance_join(): wait for the completion of a started MPI instance
  - MPI_UNIVERSE_SIZE now initialized to the total amount of hosts in the platform
+ - Memory usage due to SMPI for non-MPI actors greatly reduced.
+
+sthread:
+ - Allow to use on valgrind-observed processes
+ - Install sthread on user's disk.
+ - Implement recursive pthreads.
+ - Add some McMini codes to test sthread further (controlled with enable_testsuite_McMini).
+
+Model checking:
+ - More informative backtraces on assertion failure.
 
 Python:
  - Make the host_load plugin available from Python. See examples/python/plugin-host-load
@@ -19,17 +53,22 @@ Python:
  - Comm::waitall/waitany/testany() are gone. Please use ActivitySet() instead.
  - Comm::waitallfor() is gone too. Its semantic was unclear on timeout anyway.
  - Io::waitany() and waitanyfor() are gone. Please use ActivitySet() instead.
+ - Add the bindings of the host load plugin
 
 C API:
  - Introduce sg_activity_set_t and deprecate wait_all/wait_any/test_any for
    Exec, Io and Comm.
 
-Plugins:
- - Revamp the battery plugin: rewrite completely the API, for a better usability.
-   The examples were updated accordingly.
- - Revamp of the Photovoltaic plugin: now called SolarPanel and complete rewrite of the API 
- - Add chiller plugin: enable the management of chillers consuming electrical energy
-   to compensate heat generated by hosts.
+Kernel:
+ - optimize an internal data structure (replace boost::circular_buffer_space_optimized by
+   std::deque to store pending and unmatched Comms in Mailboxes). It is actually a revert
+   to what was used a few years back. The boost structure had a lower memory footprint than
+   deques, but it appeared that their "space_optimized" character was generating a huge lot
+   of refcount changes on the stored Comms.
+
+General:
+ - Fix errors with ns-3 v3.36+
+ - Many other small bug fixes, in particular in MC and sthread.
 
 ----------------------------------------------------------------------------
 
index 1b8ad27..322f765 100644 (file)
@@ -166,6 +166,10 @@ include examples/cpp/app-masterworkers/s4u-app-masterworkers.tesh
 include examples/cpp/app-masterworkers/s4u-app-masterworkers_d.xml
 include examples/cpp/app-token-ring/s4u-app-token-ring.cpp
 include examples/cpp/app-token-ring/s4u-app-token-ring.tesh
+include examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp
+include examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh
+include examples/cpp/battery-connector/s4u-battery-connector.cpp
+include examples/cpp/battery-connector/s4u-battery-connector.tesh
 include examples/cpp/battery-degradation/plot_battery_degradation.py
 include examples/cpp/battery-degradation/s4u-battery-degradation.cpp
 include examples/cpp/battery-degradation/s4u-battery-degradation.tesh
@@ -310,16 +314,8 @@ include examples/cpp/io-priority/s4u-io-priority.cpp
 include examples/cpp/io-priority/s4u-io-priority.tesh
 include examples/cpp/maestro-set/s4u-maestro-set.cpp
 include examples/cpp/maestro-set/s4u-maestro-set.tesh
-include examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness
-include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner
-include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh
-include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp
-include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh
 include examples/cpp/mc-bugged1/s4u-mc-bugged1.cpp
 include examples/cpp/mc-bugged1/s4u-mc-bugged1.tesh
-include examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness
-include examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp
-include examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh
 include examples/cpp/mc-bugged2/s4u-mc-bugged2.cpp
 include examples/cpp/mc-bugged2/s4u-mc-bugged2.tesh
 include examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.cpp
@@ -327,9 +323,10 @@ include examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.tesh
 include examples/cpp/mc-electric-fence/s4u-mc-electric-fence.cpp
 include examples/cpp/mc-electric-fence/s4u-mc-electric-fence.tesh
 include examples/cpp/mc-failing-assert/s4u-mc-failing-assert-nodpor.tesh
-include examples/cpp/mc-failing-assert/s4u-mc-failing-assert-statequality.tesh
 include examples/cpp/mc-failing-assert/s4u-mc-failing-assert.cpp
 include examples/cpp/mc-failing-assert/s4u-mc-failing-assert.tesh
+include examples/cpp/mess-wait/s4u-mess-wait.cpp
+include examples/cpp/mess-wait/s4u-mess-wait.tesh
 include examples/cpp/network-factors/s4u-network-factors.cpp
 include examples/cpp/network-factors/s4u-network-factors.tesh
 include examples/cpp/network-nonlinear/s4u-network-nonlinear.cpp
@@ -348,8 +345,6 @@ include examples/cpp/network-ns3/s4u-network-ns3-timed.tesh
 include examples/cpp/network-ns3/s4u-network-ns3.cpp
 include examples/cpp/network-wifi/s4u-network-wifi.cpp
 include examples/cpp/network-wifi/s4u-network-wifi.tesh
-include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp
-include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh
 include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp
 include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh
 include examples/cpp/platform-failures/s4u-platform-failures.cpp
@@ -380,6 +375,8 @@ include examples/cpp/replay-io/s4u-replay-io.txt
 include examples/cpp/replay-io/s4u-replay-io_d.xml
 include examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp
 include examples/cpp/routing-get-clusters/s4u-routing-get-clusters.tesh
+include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp
+include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh
 include examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh
 include examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp
 include examples/cpp/synchro-barrier/s4u-synchro-barrier.tesh
@@ -387,7 +384,6 @@ include examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-
 include examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.tesh
 include examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp
 include examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.tesh
-include examples/cpp/synchro-mutex/s4u-mc-synchro-mutex-stateful.tesh
 include examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh
 include examples/cpp/synchro-mutex/s4u-synchro-mutex.cpp
 include examples/cpp/synchro-mutex/s4u-synchro-mutex.tesh
@@ -526,22 +522,14 @@ include examples/smpi/gemm/gemm.c
 include examples/smpi/gemm/gemm.tesh
 include examples/smpi/hostfile
 include examples/smpi/mc/bugged1.c
-include examples/smpi/mc/bugged1_liveness.c
 include examples/smpi/mc/bugged2.c
 include examples/smpi/mc/hostfile_bugged1
-include examples/smpi/mc/hostfile_bugged1_liveness
 include examples/smpi/mc/hostfile_bugged2
 include examples/smpi/mc/hostfile_mutual_exclusion
-include examples/smpi/mc/hostfile_non_termination
 include examples/smpi/mc/hostfile_only_send_deterministic
 include examples/smpi/mc/mutual_exclusion.c
-include examples/smpi/mc/non_termination1.c
-include examples/smpi/mc/non_termination2.c
-include examples/smpi/mc/non_termination3.c
-include examples/smpi/mc/non_termination4.c
 include examples/smpi/mc/only_send_deterministic.c
 include examples/smpi/mc/only_send_deterministic.tesh
-include examples/smpi/mc/promela_bugged1_liveness
 include examples/smpi/mc/sendsend.c
 include examples/smpi/mc/sendsend.tesh
 include examples/smpi/replay/actions0.txt
@@ -643,9 +631,12 @@ include examples/smpi/trace_call_location/trace_call_location.c
 include examples/smpi/trace_call_location/trace_call_location.tesh
 include examples/smpi/trace_simple/trace_simple.c
 include examples/smpi/trace_simple/trace_simple.tesh
+include examples/sthread/pthread-mc-mutex-recursive.tesh
 include examples/sthread/pthread-mc-mutex-simple.tesh
 include examples/sthread/pthread-mc-mutex-simpledeadlock.tesh
 include examples/sthread/pthread-mc-producer-consumer.tesh
+include examples/sthread/pthread-mutex-recursive.c
+include examples/sthread/pthread-mutex-recursive.tesh
 include examples/sthread/pthread-mutex-simple.c
 include examples/sthread/pthread-mutex-simple.tesh
 include examples/sthread/pthread-mutex-simpledeadlock.c
@@ -663,10 +654,22 @@ include teshsuite/kernel/context-defaults/factory_thread.tesh
 include teshsuite/kernel/context-defaults/factory_ucontext.tesh
 include teshsuite/kernel/stack-overflow/stack-overflow.cpp
 include teshsuite/kernel/stack-overflow/stack-overflow.tesh
-include teshsuite/mc/dwarf-expression/dwarf-expression.cpp
-include teshsuite/mc/dwarf-expression/dwarf-expression.tesh
-include teshsuite/mc/dwarf/dwarf.cpp
-include teshsuite/mc/dwarf/dwarf.tesh
+include teshsuite/mc/mcmini/barber_shop_deadlock.c
+include teshsuite/mc/mcmini/barber_shop_deadlock.tesh
+include teshsuite/mc/mcmini/barber_shop_ok.c
+include teshsuite/mc/mcmini/barber_shop_ok.tesh
+include teshsuite/mc/mcmini/philosophers_mutex_deadlock.c
+include teshsuite/mc/mcmini/philosophers_mutex_deadlock.tesh
+include teshsuite/mc/mcmini/philosophers_mutex_ok.c
+include teshsuite/mc/mcmini/philosophers_mutex_ok.tesh
+include teshsuite/mc/mcmini/philosophers_semaphores_deadlock.c
+include teshsuite/mc/mcmini/philosophers_semaphores_deadlock.tesh
+include teshsuite/mc/mcmini/philosophers_semaphores_ok.c
+include teshsuite/mc/mcmini/philosophers_semaphores_ok.tesh
+include teshsuite/mc/mcmini/producer_consumer_deadlock.c
+include teshsuite/mc/mcmini/producer_consumer_deadlock.tesh
+include teshsuite/mc/mcmini/producer_consumer_ok.c
+include teshsuite/mc/mcmini/producer_consumer_ok.tesh
 include teshsuite/mc/mutex-handling/mutex-handling.cpp
 include teshsuite/mc/mutex-handling/mutex-handling.tesh
 include teshsuite/mc/mutex-handling/without-mutex-handling.tesh
@@ -1610,9 +1613,6 @@ include teshsuite/xbt/log_large/log_large.tesh
 include teshsuite/xbt/log_usage/log_usage.c
 include teshsuite/xbt/log_usage/log_usage.tesh
 include teshsuite/xbt/log_usage/log_usage_ndebug.tesh
-include teshsuite/xbt/mmalloc/mmalloc_32.tesh
-include teshsuite/xbt/mmalloc/mmalloc_64.tesh
-include teshsuite/xbt/mmalloc/mmalloc_test.cpp
 include teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.cpp
 include teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.tesh
 include teshsuite/xbt/parmap_bench/parmap_bench.cpp
@@ -1623,7 +1623,6 @@ include teshsuite/xbt/signals/signals.cpp
 include teshsuite/xbt/signals/signals.tesh
 include tools/address_sanitizer.supp
 include tools/fix-paje-trace.sh
-include tools/generate-dwarf-functions
 include tools/graphicator/graphicator.cpp
 include tools/graphicator/graphicator.tesh
 include tools/normalize-pointers.py
@@ -1966,6 +1965,8 @@ include include/simgrid/s4u/Host.hpp
 include include/simgrid/s4u/Io.hpp
 include include/simgrid/s4u/Link.hpp
 include include/simgrid/s4u/Mailbox.hpp
+include include/simgrid/s4u/Mess.hpp
+include include/simgrid/s4u/MessageQueue.hpp
 include include/simgrid/s4u/Mutex.hpp
 include include/simgrid/s4u/NetZone.hpp
 include include/simgrid/s4u/Semaphore.hpp
@@ -1990,8 +1991,6 @@ include include/xbt/Extendable.hpp
 include include/xbt/PropertyHolder.hpp
 include include/xbt/asserts.h
 include include/xbt/asserts.hpp
-include include/xbt/automaton.h
-include include/xbt/automaton.hpp
 include include/xbt/backtrace.hpp
 include include/xbt/base.h
 include include/xbt/config.h
@@ -2062,6 +2061,10 @@ include src/kernel/activity/IoImpl.cpp
 include src/kernel/activity/IoImpl.hpp
 include src/kernel/activity/MailboxImpl.cpp
 include src/kernel/activity/MailboxImpl.hpp
+include src/kernel/activity/MessImpl.cpp
+include src/kernel/activity/MessImpl.hpp
+include src/kernel/activity/MessageQueueImpl.cpp
+include src/kernel/activity/MessageQueueImpl.hpp
 include src/kernel/activity/MutexImpl.cpp
 include src/kernel/activity/MutexImpl.hpp
 include src/kernel/activity/SemaphoreImpl.cpp
@@ -2187,9 +2190,6 @@ include src/kernel/xml/sg_platf.cpp
 include src/kernel/xml/simgrid.dtd
 include src/kernel/xml/simgrid_dtd.c
 include src/kernel/xml/simgrid_dtd.h
-include src/mc/AddressSpace.hpp
-include src/mc/VisitedState.cpp
-include src/mc/VisitedState.hpp
 include src/mc/api/ActorState.hpp
 include src/mc/api/ClockVector.cpp
 include src/mc/api/ClockVector.hpp
@@ -2202,15 +2202,12 @@ include src/mc/api/strategy/MaxMatchComm.hpp
 include src/mc/api/strategy/MinMatchComm.hpp
 include src/mc/api/strategy/Strategy.hpp
 include src/mc/api/strategy/UniformStrategy.hpp
-include src/mc/compare.cpp
 include src/mc/datatypes.h
 include src/mc/explo/CommunicationDeterminismChecker.cpp
 include src/mc/explo/DFSExplorer.cpp
 include src/mc/explo/DFSExplorer.hpp
 include src/mc/explo/Exploration.cpp
 include src/mc/explo/Exploration.hpp
-include src/mc/explo/LivenessChecker.cpp
-include src/mc/explo/LivenessChecker.hpp
 include src/mc/explo/UdporChecker.cpp
 include src/mc/explo/UdporChecker.hpp
 include src/mc/explo/odpor/ClockVector_test.cpp
@@ -2250,24 +2247,6 @@ include src/mc/explo/udpor/maximal_subsets_iterator.cpp
 include src/mc/explo/udpor/maximal_subsets_iterator.hpp
 include src/mc/explo/udpor/udpor_forward.hpp
 include src/mc/explo/udpor/udpor_tests_private.hpp
-include src/mc/inspect/DwarfExpression.cpp
-include src/mc/inspect/DwarfExpression.hpp
-include src/mc/inspect/Frame.cpp
-include src/mc/inspect/Frame.hpp
-include src/mc/inspect/LocationList.cpp
-include src/mc/inspect/LocationList.hpp
-include src/mc/inspect/ObjectInformation.cpp
-include src/mc/inspect/ObjectInformation.hpp
-include src/mc/inspect/Type.hpp
-include src/mc/inspect/Variable.hpp
-include src/mc/inspect/mc_dwarf.cpp
-include src/mc/inspect/mc_dwarf.hpp
-include src/mc/inspect/mc_dwarf_attrnames.cpp
-include src/mc/inspect/mc_dwarf_tagnames.cpp
-include src/mc/inspect/mc_member.cpp
-include src/mc/inspect/mc_unw.cpp
-include src/mc/inspect/mc_unw.hpp
-include src/mc/inspect/mc_unw_vmread.cpp
 include src/mc/mc.h
 include src/mc/mc_base.cpp
 include src/mc/mc_base.hpp
@@ -2291,22 +2270,10 @@ include src/mc/remote/CheckerSide.cpp
 include src/mc/remote/CheckerSide.hpp
 include src/mc/remote/RemotePtr.hpp
 include src/mc/remote/mc_protocol.h
-include src/mc/sosp/ChunkedData.cpp
-include src/mc/sosp/ChunkedData.hpp
-include src/mc/sosp/PageStore.cpp
-include src/mc/sosp/PageStore.hpp
-include src/mc/sosp/PageStore_test.cpp
-include src/mc/sosp/Region.cpp
-include src/mc/sosp/Region.hpp
-include src/mc/sosp/RemoteProcessMemory.cpp
-include src/mc/sosp/RemoteProcessMemory.hpp
-include src/mc/sosp/Snapshot.cpp
-include src/mc/sosp/Snapshot.hpp
-include src/mc/sosp/Snapshot_test.cpp
 include src/mc/transition/Transition.cpp
 include src/mc/transition/Transition.hpp
-include src/mc/transition/TransitionActorJoin.cpp
-include src/mc/transition/TransitionActorJoin.hpp
+include src/mc/transition/TransitionActor.cpp
+include src/mc/transition/TransitionActor.hpp
 include src/mc/transition/TransitionAny.cpp
 include src/mc/transition/TransitionAny.hpp
 include src/mc/transition/TransitionComm.cpp
@@ -2346,6 +2313,8 @@ include src/s4u/s4u_Host.cpp
 include src/s4u/s4u_Io.cpp
 include src/s4u/s4u_Link.cpp
 include src/s4u/s4u_Mailbox.cpp
+include src/s4u/s4u_Mess.cpp
+include src/s4u/s4u_MessageQueue.cpp
 include src/s4u/s4u_Mutex.cpp
 include src/s4u/s4u_Netzone.cpp
 include src/s4u/s4u_Semaphore.cpp
@@ -2551,13 +2520,6 @@ include src/sthread/sthread.h
 include src/sthread/sthread_impl.cpp
 include src/xbt/OsSemaphore.hpp
 include src/xbt/PropertyHolder.cpp
-include src/xbt/automaton/automaton.c
-include src/xbt/automaton/automaton_lexer.yy.c
-include src/xbt/automaton/automatonparse_promela.c
-include src/xbt/automaton/parserPromela.lex
-include src/xbt/automaton/parserPromela.tab.cacc
-include src/xbt/automaton/parserPromela.tab.hacc
-include src/xbt/automaton/parserPromela.yacc
 include src/xbt/backtrace.cpp
 include src/xbt/config.cpp
 include src/xbt/config_test.cpp
@@ -2577,20 +2539,6 @@ include src/xbt/mallocator.c
 include src/xbt/mallocator_private.h
 include src/xbt/memory_map.cpp
 include src/xbt/memory_map.hpp
-include src/xbt/mmalloc/mfree.c
-include src/xbt/mmalloc/mm.c
-include src/xbt/mmalloc/mm_interface.c
-include src/xbt/mmalloc/mm_legacy.c
-include src/xbt/mmalloc/mm_module.c
-include src/xbt/mmalloc/mmalloc.c
-include src/xbt/mmalloc/mmalloc.h
-include src/xbt/mmalloc/mmalloc.info
-include src/xbt/mmalloc/mmalloc.texi
-include src/xbt/mmalloc/mmorecore.c
-include src/xbt/mmalloc/mmprivate.h
-include src/xbt/mmalloc/mrealloc.c
-include src/xbt/mmalloc/swag.c
-include src/xbt/mmalloc/swag.h
 include src/xbt/parmap.cpp
 include src/xbt/parmap.hpp
 include src/xbt/random.cpp
@@ -2666,10 +2614,7 @@ include tools/cmake/Flags.cmake
 include tools/cmake/MaintainerMode.cmake
 include tools/cmake/MakeLib.cmake
 include tools/cmake/Modules/FindGraphviz.cmake
-include tools/cmake/Modules/FindLibdw.cmake
-include tools/cmake/Modules/FindLibelf.cmake
 include tools/cmake/Modules/FindLibevent.cmake
-include tools/cmake/Modules/FindLibunwind.cmake
 include tools/cmake/Modules/FindNS3.cmake
 include tools/cmake/Modules/FindPAPI.cmake
 include tools/cmake/Modules/FindValgrind.cmake
index 72d4c51..c0ecf2c 100644 (file)
@@ -108,18 +108,14 @@ Existing Configuration Items
 - **maxmin/concurrency-limit:** :ref:`cfg=maxmin/concurrency-limit`
 
 - **model-check:** :ref:`options_modelchecking`
-- **model-check/checkpoint:** :ref:`cfg=model-check/checkpoint`
 - **model-check/communications-determinism:** :ref:`cfg=model-check/communications-determinism`
 - **model-check/dot-output:** :ref:`cfg=model-check/dot-output`
 - **model-check/max-depth:** :ref:`cfg=model-check/max-depth`
-- **model-check/property:** :ref:`cfg=model-check/property`
 - **model-check/reduction:** :ref:`cfg=model-check/reduction`
 - **model-check/replay:** :ref:`cfg=model-check/replay`
 - **model-check/send-determinism:** :ref:`cfg=model-check/send-determinism`
 - **model-check/setenv:** :ref:`cfg=model-check/setenv`
-- **model-check/termination:** :ref:`cfg=model-check/termination`
 - **model-check/timeout:** :ref:`cfg=model-check/timeout`
-- **model-check/visited:** :ref:`cfg=model-check/visited`
 
 - **network/bandwidth-factor:** :ref:`cfg=network/bandwidth-factor`
 - **network/crosstraffic:** :ref:`cfg=network/crosstraffic`
@@ -527,8 +523,6 @@ Note that with the default host model this option is activated by default.
 Simulating Asynchronous Send
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-(this configuration item is experimental and may change or disappear)
-
 It is possible to specify that messages below a certain size (in bytes) will be
 sent as soon as the call to MPI_Send is issued, without waiting for
 the correspondent receive. This threshold can be configured through
@@ -647,38 +641,6 @@ The ``smpi/buffering`` (only valid with MC) option gives an easier interface to
 - **zero:** means that buffering should be disabled. All communications are actually blocking.
 - **infty:** means that buffering should be made infinite. All communications are non-blocking.
 
-.. _cfg=model-check/property:
-
-Specifying a liveness property
-..............................
-
-**Option** ``model-check/property`` **Default:** unset
-
-If you want to specify liveness properties, you have to pass them on
-the command line, specifying the name of the file containing the
-property, as formatted by the `ltl2ba <https://github.com/utwente-fmt/ltl2ba>`_ program.
-Note that ltl2ba is not part of SimGrid and must be installed separately.
-
-.. code-block:: console
-
-   $ simgrid-mc ./my_program --cfg=model-check/property:<filename>
-
-.. _cfg=model-check/checkpoint:
-
-Going for Stateful Verification
-...............................
-
-By default, the system is backtracked to its initial state to explore
-another path, instead of backtracking to the exact step before the fork
-that we want to explore (this is called stateless verification). This
-is done this way because saving intermediate states can rapidly
-exhaust the available memory. If you want, you can change the value of
-the ``model-check/checkpoint`` item. For example,
-``--cfg=model-check/checkpoint:1`` asks to take a checkpoint every
-step.  Beware, this will certainly explode your memory. Larger values
-are probably better, make sure to experiment a bit to find the right
-setting for your specific system.
-
 .. _cfg=model-check/reduction:
 
 Specifying the kind of reduction
@@ -691,7 +653,7 @@ explosion. You can activate some reduction technique with
 ``--cfg=model-check/reduction:<technique>``. For now, this
 configuration variable can take 2 values:
 
- - **none:** Do not apply any kind of reduction (mandatory for liveness properties, as our current DPOR algorithm breaks cycles)
+ - **none:** Do not apply any kind of reduction
  - **dpor:** Apply Dynamic Partial Ordering Reduction. Only valid if you verify local safety properties (default value for
    safety checks).
  - **sdpor:** Source-set DPOR, as described in "Source Sets: A Foundation for Optimal Dynamic Partial Order Reduction"
@@ -699,15 +661,9 @@ configuration variable can take 2 values:
  - **odpor:** Optimal DPOR, as described in "Source Sets: A Foundation for Optimal Dynamic Partial Order Reduction"
     by Abdulla et al.
 
-Another way to mitigate the state space explosion is to search for
-cycles in the exploration with the :ref:`cfg=model-check/visited`
-configuration. Note that DPOR and state-equality reduction may not
-play well together. You should choose between them.
-
 Our current DPOR implementation could be improved in may ways. We are
 currently improving its efficiency (both in term of reduction ability
-and computational speed), and future work could make it compatible
-with liveness properties.
+and computational speed).
 
 .. _cfg=model-check/strategy:
 
@@ -730,45 +686,6 @@ DFS exploration.
  - **uniform**: this is a boring random strategy where choices are based on a uniform sampling of possible choices.
    Surprisingly, it gives really really good results.
 
-.. _cfg=model-check/visited:
-
-Size of Cycle Detection Set (state equality reduction)
-......................................................
-
-Mc SimGrid can be asked to search for cycles during the exploration,
-i.e. situations where a new explored state is in fact the same state
-than a previous one.. This can prove useful to mitigate the state
-space explosion with safety properties, and this is the crux when
-searching for counter-examples to the liveness properties.
-
-Note that this feature may break the current implementation of the
-DPOR reduction technique.
-
-The ``model-check/visited`` item is the maximum number of states, which
-are stored in memory. If the maximum number of snapshotted state is
-reached, some states will be removed from the memory and some cycles
-might be missed. Small values can lead to incorrect verifications, but
-large values can exhaust your memory and be CPU intensive as each new
-state must be compared to that amount of older saved states.
-
-The default settings depend on the kind of exploration. With safety
-checking, no state is snapshotted and cycles cannot be detected. With
-liveness checking, all states are snapshotted because missing a cycle
-could hinder the exploration soundness.
-
-.. _cfg=model-check/termination:
-
-Non-Termination Detection
-.........................
-
-The ``model-check/termination`` configuration item can be used to
-report if a non-termination execution path has been found. This is a
-path with a cycle, which means that the program might never terminate.
-
-This only works in safety mode, not in liveness mode.
-
-This options is disabled by default.
-
 .. _cfg=model-check/dot-output:
 
 Dot Output
@@ -776,8 +693,7 @@ Dot Output
 
 If set, the ``model-check/dot-output`` configuration item is the name
 of a file in which to write a dot file of the path leading to the
-property violation discovered (safety or liveness violation), as well
-as the cycle for liveness properties. This dot file can then be fed to the
+property violation discovered (safety violation). This dot file can then be fed to the
 graphviz dot tool to generate a corresponding graphical representation.
 
 .. _cfg=model-check/max-depth:
@@ -852,7 +768,7 @@ this path reported by the model checker, enabling the usage of classical
 debugging tools.
 
 When the model checker finds an interesting path in the application
-execution graph (where a safety or liveness property is violated), it
+execution graph (where a safety property is violated), it
 generates an identifier for this path. Here is an example of the output:
 
 .. code-block:: console
index 477b53e..39cc872 100644 (file)
@@ -43,6 +43,17 @@ email.
 .. _simgrid AUR package: https://aur.archlinux.org/packages/simgrid/
 .. _AUR official documentation: https://wiki.archlinux.org/title/Arch_User_Repository
 
+Binaries from macOS
+^^^^^^^^^^^^^^^^^^^
+
+SimGrid can be found in the Homebrew package manager. Troubleshooting:
+
+warning: dylib (libsimgrid.dylib) was built for newer macOS version (14.0) than being linked (13.3)
+  This was reported with the SimGrid version from Homebrew on a Mac book air M1 (ARM).
+  The solution is simply to export this variable before the compilation of your binaries:
+
+  ``export MACOSX_DEPLOYMENT_TARGET=14.0``
+
 .. _deprecation_policy:
 
 Version numbering and deprecation
@@ -102,13 +113,11 @@ python bindings (optional):
   - On Debian / Ubuntu: ``apt install pybind11-dev python3-dev``
 Model-checking mandatory dependencies
   - On Debian / Ubuntu: ``apt install libevent-dev``
-Model-checking optional dependencies
-  - On Debian / Ubuntu: ``apt install libunwind-dev libdw-dev libelf-dev``
 Eigen3 (optional)
   - On Debian / Ubuntu: ``apt install libeigen3-dev``
   - On CentOS / Fedora: ``dnf install eigen3-devel``
   - On macOS with homebrew: ``brew install eigen``
-  - Use EIGEN3_HINT to specify where it's installed if cmake doesn't find it automatically.
+  - Use EIGEN3_HINT to specify where it's installed if cmake doesn't find it automatically. Set EIGEN3_HINT=OFF to disable detection even if it could be found.
 JSON (optional, for the DAG wfcommons loader)
   - On Debian / Ubuntu: ``apt install nlohmann-json3-dev``
   - Use nlohmann_json_HINT to specify where it's installed if cmake doesn't find it automatically.
@@ -243,10 +252,9 @@ enable_mallocators (ON/off)
   Activates our internal memory caching mechanism. This produces faster
   code, but it may fool the debuggers.
 
-enable_model-checking (on/OFF)
-  Activates the liveness verification mode. This will hinder simulation speed even when the model checker is not activated at run
-  time, because some optimizations such as LTO must be disabled at compile time. You need to have the :ref:`required
-  build-dependencies <install_src_deps>` to activate this option.
+enable_model-checking (ON/off)
+  Activates the verification mode. This should not impact the performance of your simulations if you build it but don't use it,
+  but you can still disable it to save some compilation time.
 
 enable_ns3 (on/OFF)
   Activates the ns-3 bindings. See section :ref:`models_ns3`.
@@ -254,10 +262,13 @@ enable_ns3 (on/OFF)
 enable_smpi (ON/off)
   Allows one to run MPI code on top of SimGrid.
 
-enable_smpi_MBI_testsuite (on/OFF)
-  Adds many extra tests for the model checker module.
+enable_testsuite_McMini (on/OFF)
+  Adds several extra tests for the model checker module (targeting threaded applications).
+
+enable_testsuite_smpi_MBI (on/OFF)
+  Adds many extra tests for the model checker module (targeting MPI applications).
 
-enable_smpi_MPICH3_testsuite (on/OFF)
+enable_testsuite_smpi_MPICH3 (on/OFF)
   Adds many extra tests for the MPI module.
 
 minimal-bindings (on/OFF)
@@ -269,6 +280,7 @@ NS3_HINT (empty by default)
 
 EIGEN3_HINT (empty by default)
   Alternative path into which Eigen3 should be searched for.
+  Providing the value OFF as an hint will disable the detection alltogether.
 
 SIMGRID_PYTHON_LIBDIR (auto-detected)
   Where to install the Python module library. By default, it is set to the cmake Python3_SITEARCH variable if installing to /usr,
@@ -401,7 +413,7 @@ Windows-specific instructions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The best solution to get SimGrid working on windows is to install the
-Ubuntu subsystem of Windows 10. All of SimGrid (but the liveness model checker)
+Ubuntu subsystem of Windows 10. All of SimGrid 
 works in this setting. Native builds never really worked, and they are
 disabled starting with SimGrid v3.33.
 
index 659e67c..c40e5e6 100644 (file)
@@ -25,6 +25,7 @@ documents some of the plugins distributed with SimGrid:
   - :ref:`WiFi Energy <plugin_link_energy_wifi>`: models the energy dissipation of wifi links.
   - :ref:`Battery <plugin_battery>`: models batteries that get discharged by the energy consumption of a given host.
   - :ref:`Solar Panel <plugin_solar_panel>`: models solar panels which energy production depends on the solar irradiance.
+  - :ref:`Chiller <plugin_chiller>`: models chillers which dissipate heat by consuming energy.
 
 You can activate these plugins with the :ref:`--cfg=plugin <cfg=plugin>` command
 line option, for example with ``--cfg=plugin:host_energy``. You can get the full
@@ -231,11 +232,11 @@ Solar Panel
 
 .. doxygengroup:: plugin_solar_panel
 
+.. _plugin_chiller:
+
 Chiller
 =======
 
 .. doxygengroup:: plugin_chiller
 
-   .. doxygentypedef:: ChillerPtr
-
 ..  LocalWords:  SimGrid
index 55b0d5a..346f563 100644 (file)
@@ -626,9 +626,10 @@ reacting to every signals of a class, and then filtering on the object you want.
 completion) are now specialized by activity class. That is, callbacks registered in Exec::on_suspend_cb will not be fired for
 Comms nor Ios
 
-Two new useful plugins were added: The :ref:`battery plugin<plugin_battery>` can be used to create batteries that get discharged
-by the energy consumption of a given host, while the :ref:`solar panel plugin <plugin_solar_panel>` can be used to create
-solar panels which energy production depends on the solar irradiance. These plugins could probably be better integrated
+Three new useful plugins were added: The :ref:`battery plugin<plugin_battery>` can be used to create batteries that get discharged
+by the energy consumption of a given host, the :ref:`solar panel plugin <plugin_solar_panel>` can be used to create
+solar panels which energy production depends on the solar irradiance and the :ref:`chiller plugin <plugin_chiller>` can be used to
+create chillers and compensate the heat generated by hosts. These plugins could probably be better integrated
 in the framework, but our goal is to include in SimGrid the building blocks upon which everybody would agree, while the model
 elements that are more arguable are provided as plugins, in the hope that the users will carefully assess the plugins and adapt
 them to their specific needs before usage. Here for example, there is several models of batteries (the one provided does not
@@ -667,7 +668,13 @@ This feature is not very usable yet, as you have to manually annotate your code,
 
 Version 3.35 (TBD)
 ------------------
-
+**On the interface front**, we introduced a new MessageQueue abstraction and associated Mess simulated object. The behavior of a
+MessageQueue is similar to that of a Mailbox, but intended for control messages that do not incur any simulated cost.
+Information is automagically transported over thin air between producer and consumer. Internally, the implementation is very
+similar to Mailboxes and Comms, only simpler. The motivation for this new abstraction came from a scalability issue observed in
+the WRENCH framework, which is heavily based on control messages. When the simulated size of these messages is set to 0, it creates
+very short lived network actions (i.e., lasting for only the route latency) that tend to overwhelm the LMM. Switching from Mailbox
+to MessageQueue for such information exchange avoid this problem and greatly improves the scalability of WRENCH-based simulators.
 
 .. |br| raw:: html
 
index 03bf0a0..4e01642 100644 (file)
@@ -4,7 +4,7 @@ Formal Verification and Model-checking
 ======================================
 
 SimGrid can not only predict the performance of your application, but also assess its correctness through formal methods. Mc SimGrid is
-a full-featured model-checker that is embedded in the SimGrid framework. It can be used to formally verify safety and liveness
+a full-featured model-checker that is embedded in the SimGrid framework. It can be used to formally verify safety 
 properties on codes running on top of SimGrid, be it :ref:`simple algorithms <usecase_simalgo>` or :ref:`full MPI applications
 <usecase_smpi>`.
 
@@ -31,7 +31,7 @@ barrier, etc). Since it does not explicitly observe memory accesses, Mc SimGrid
 multithreaded programs. It can however be used to detect misuses of the synchronization functions, such as the ones resulting in
 deadlocks.
 
-Mc SimGrid can be used to verify classical `safety and liveness properties <https://en.wikipedia.org/wiki/Linear_time_property>`_, but
+Mc SimGrid can be used to verify classical `safety properties <https://en.wikipedia.org/wiki/Linear_time_property>`_, but
 also `communication determinism <https://hal.inria.fr/hal-01953167/document>`_, a property that allows more efficient solutions toward
 fault-tolerance. It can alleviate the state space explosion problem through `Dynamic Partial Ordering Reduction (DPOR)
 <https://en.wikipedia.org/wiki/Partial_order_reduction>`_ and `state equality <https://hal.inria.fr/hal-01900120/document>`_. Note that
@@ -308,11 +308,6 @@ If you want to run such analysis on your own code, out of the provided docker, t
 - SimGrid should naturally :ref:`be compiled <install_src>` with model-checking support. This requires a full set of dependencies
   (documented on the :ref:`relevant page <install_src>`) and should not be activated by default as there is a small performance penalty for
   codes using a SimGrid with MC enabled (even if you don't activate the model-checking at run time).
-- You should pass some specific flags to the linker when compiling your application: ``-Wl,-znorelro -Wl,-znoseparate-code`` In the
-  docker, the provided CMakeLists.txt provides them for you when compiling the provided code. ``smpicc`` and friends also add this
-  parameter automatically.
-- If you get error messages complaining about the Dwarf version used, try adding ``-gdwarf-4`` to you CFLAGS and CXXFLAGS.
-  If you find a situation where this flag is needed in ``smpicc``, please report this issue.
 - Also install ``libboost-stacktrace-dev`` to display nice backtraces from the application side (the one from the model-checking side is
   available in any case, but it contains less details).
 - Mc SimGrid uses the ``ptrace`` system call to spy on the verified application. Some versions of Docker forbid the use of this call by
@@ -324,11 +319,12 @@ Going further
 -------------
 
 This tutorial is not complete yet, as there is nothing on reduction
-techniques nor on liveness properties. For now, the best source of
+techniques. For now, the best source of
 information on these topics is `this old tutorial
 <https://simgrid.org/tutorials/simgrid-mc-101.pdf>`_ and `that old
 presentation
-<http://people.irisa.fr/Martin.Quinson/blog/2018/0123/McSimGrid-Boston.pdf>`_.
+<http://people.irisa.fr/Martin.Quinson/blog/2018/0123/McSimGrid-Boston.pdf>`_. But be warned that these source of 
+information are very old: the liveness verification was removed in v3.35, even if these docs still mention it.
 
 .. |br| raw:: html
 
index b917540..0361ccb 100644 (file)
@@ -34,67 +34,6 @@ else()
   endforeach()
 endif()
 
-set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/synchro-mutex/s4u-mc-synchro-mutex-stateful.tesh)
-if(SIMGRID_HAVE_STATEFUL_MC)
-  if(HAVE_C_STACK_CLEANER)
-    add_executable       (s4u-mc-bugged1-liveness-cleaner-on  EXCLUDE_FROM_ALL s4u-mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp)
-    target_link_libraries(s4u-mc-bugged1-liveness-cleaner-on  simgrid)
-    set_target_properties(s4u-mc-bugged1-liveness-cleaner-on  PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fstack-cleaner")
-    add_dependencies(tests-mc s4u-mc-bugged1-liveness-cleaner-on)
-
-    add_executable       (s4u-mc-bugged1-liveness-cleaner-off EXCLUDE_FROM_ALL s4u-mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp)
-    target_link_libraries(s4u-mc-bugged1-liveness-cleaner-off simgrid)
-    set_target_properties(s4u-mc-bugged1-liveness-cleaner-off PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fno-stack-cleaner")
-    add_dependencies(tests-mc s4u-mc-bugged1-liveness-cleaner-off)
-  endif()
-
-  ADD_TESH(s4u-mc-synchro-mutex-stateful
-     --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/synchro-mutex
-     --setenv libdir=${CMAKE_BINARY_DIR}/lib
-     --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
-     --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/synchro-mutex
-     --cd ${CMAKE_CURRENT_SOURCE_DIR}/synchro-mutex
-      ${CMAKE_HOME_DIRECTORY}/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex-stateful.tesh)
-
-  # Model-checking liveness
-  if(HAVE_UCONTEXT_CONTEXTS AND SIMGRID_PROCESSOR_x86_64)
-    # liveness model-checking works only on 64bits (for now ...)
-    set(_mc-bugged1-liveness_factories "ucontext")
-    add_dependencies(tests-mc s4u-mc-bugged1-liveness)
-    set(_mc-bugged2-liveness_factories "ucontext")
-
-    # This example never ends, disable it for now
-    set(_mc-bugged2-liveness_disable 1)
-
-    if ("${CMAKE_SYSTEM}" MATCHES "Linux")
-      # timeout under FreeBSD (test never stops)
-      ADD_TESH(s4u-mc-bugged1-liveness-visited-ucontext --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness
-                                                        --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
-                                                        --cd ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness
-                                                        ${CMAKE_HOME_DIRECTORY}/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh)
-    endif()
-    IF(HAVE_C_STACK_CLEANER)
-      add_dependencies(tests-mc s4u-mc-bugged1-liveness-stack-cleaner)
-      # This test checks if the stack cleaner is making a difference:
-      ADD_TEST(s4u-mc-bugged1-liveness-stack-cleaner ${CMAKE_HOME_DIRECTORY}/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner
-                                                     ${CMAKE_HOME_DIRECTORY}/examples/cpp/mc-bugged1-liveness/
-                                                     ${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness/)
-    ENDIF()
-  else()
-    set(_mc-bugged1-liveness_disable 1)
-    set(_mc-bugged2-liveness_disable 1)
-  endif()
-
-  if(enable_coverage)
-    ADD_TEST(cover-mc-bugged1-liveness ${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness ${CMAKE_HOME_DIRECTORY}/examples/platforms/small_platform.xml 1 1001)
-  endif()
-
-else()
-  foreach (example mc-bugged1-liveness mc-bugged2-liveness)
-    set(_${example}_disable 1)
-  endforeach()
-endif()
-
 # Hijack some regular tests to run them on top of the MC
 foreach (example synchro-barrier synchro-mutex synchro-semaphore)
   set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/s4u-mc-${example}.tesh)
@@ -157,7 +96,7 @@ foreach (example activityset-testany activityset-waitany activityset-waitall act
                  actor-create actor-daemon actor-exiting actor-join actor-kill
                  actor-lifetime actor-migrate actor-suspend actor-yield actor-stacksize
                  app-bittorrent app-chainsend app-token-ring
-                 battery-degradation battery-simple battery-energy
+                 battery-chiller-solar battery-connector battery-degradation battery-simple battery-energy
                  chiller-simple
                  comm-pingpong comm-ready comm-suspend comm-wait comm-waituntil
                  comm-dependent comm-host2host comm-failure comm-throttling
@@ -169,7 +108,8 @@ foreach (example activityset-testany activityset-waitany activityset-waitall act
                  exec-async exec-basic exec-dvfs exec-remote exec-waitfor exec-dependent exec-unassigned
                  exec-ptask-multicore exec-ptask-multicore-latency exec-cpu-nonlinear exec-cpu-factors exec-failure exec-threads
                  maestro-set
-                 mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-bugged2-liveness mc-centralized-mutex mc-electric-fence mc-failing-assert
+                 mc-bugged1 mc-bugged2 mc-centralized-mutex mc-electric-fence mc-failing-assert
+                 mess-wait
                  network-ns3 network-ns3-wifi network-wifi
                  io-async io-priority io-degradation io-file-system io-file-remote io-disk-raw io-dependent
                  task-dispatch task-io task-microservice task-parallelism task-simple task-storm task-switch-host task-variable-load
@@ -263,18 +203,6 @@ endforeach()
 
 # Test non-DPOR reductions on a given MC test
 foreach(example mc-failing-assert)
-# State equality is not tested because it would take about 15 hours to run that test on my machine.
-# We should first optimize mmalloc_heap_differ() which takes ~4sec for each pair to compare (maybe {175 x 174/ 2} pairs here)
-# See the comment on mmalloc_heap_differ() in compare.cpp for more info on why it's hard to optimize.
-#
-#  if(SIMGRID_HAVE_STATEFUL_MC)
-#    ADD_TESH(s4u-${example}-statequality  --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example}
-#                                      --setenv libdir=${CMAKE_BINARY_DIR}/lib
-#                                      --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
-#                                      --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example}
-#                                      --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example}
-#                                      ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-statequality.tesh)
-#  endif()
 
   if(SIMGRID_HAVE_MC)
     ADD_TESH(s4u-${example}-nodpor    --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example}
@@ -284,7 +212,6 @@ foreach(example mc-failing-assert)
                                       --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example}
                                       ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-nodpor.tesh)
   endif()
-  set(tesh_files    ${tesh_files}   ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-statequality.tesh)
   set(tesh_files    ${tesh_files}   ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-nodpor.tesh)
 endforeach()
 
@@ -316,10 +243,8 @@ endif()
 
 # Add all extra files to the archive
 ####################################
-set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp        PARENT_SCOPE)
-set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh  PARENT_SCOPE)
+set(examples_src  ${examples_src}    PARENT_SCOPE)
+set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh  PARENT_SCOPE)
 set(xml_files     ${xml_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-actor-create_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/actor-lifetime/s4u-actor-lifetime_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/s4u-app-bittorrent_d.xml
@@ -340,10 +265,7 @@ set(xml_files     ${xml_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-a
                                   ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/onelink_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/one_cluster_d.xml                PARENT_SCOPE)
 set(bin_files     ${bin_files}    ${CMAKE_CURRENT_SOURCE_DIR}/battery-degradation/plot_battery_degradation.py
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/promela_bugged1_liveness
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged2-liveness/promela_bugged2_liveness PARENT_SCOPE)
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py  PARENT_SCOPE)
 set(txt_files     ${txt_files}    ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dax/simple_dax_with_cycle.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dax/smalldax.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dax-simple/dag.xml
index 8128c24..d782094 100644 (file)
@@ -7,26 +7,26 @@
 #include <cstdlib>
 #include <iostream>
 #include <string>
+
 namespace sg4 = simgrid::s4u;
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_testany, "Messages specific for this s4u example");
 
 static void bob()
 {
-  sg4::Mailbox* mbox    = sg4::Mailbox::by_name("mbox");
-  const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
+  sg4::Mailbox* mbox        = sg4::Mailbox::by_name("mbox");
+  sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue");
+  const sg4::Disk* disk     = sg4::Host::current()->get_disks().front();
   std::string* payload;
+  std::string* message;
 
   XBT_INFO("Create my asynchronous activities");
   auto exec = sg4::this_actor::exec_async(5e9);
   auto comm = mbox->get_async(&payload);
+  auto mess = mqueue->get_async(&message);
   auto io   = disk->read_async(3e8);
 
-  sg4::ActivitySet pending_activities;
-  pending_activities.push(exec);
-  pending_activities.push(comm);
-  pending_activities.push(io);
-
+  sg4::ActivitySet pending_activities({exec, comm, mess, io});
   XBT_INFO("Sleep_for a while");
   sg4::this_actor::sleep_for(1);
 
@@ -36,6 +36,8 @@ static void bob()
     if (completed_one != nullptr) {
       if (boost::dynamic_pointer_cast<sg4::Comm>(completed_one))
         XBT_INFO("Completed a Comm");
+      if (boost::dynamic_pointer_cast<sg4::Mess>(completed_one))
+        XBT_INFO("Completed a Mess");
       if (boost::dynamic_pointer_cast<sg4::Exec>(completed_one))
         XBT_INFO("Completed an Exec");
       if (boost::dynamic_pointer_cast<sg4::Io>(completed_one))
@@ -47,6 +49,7 @@ static void bob()
   }
   XBT_INFO("Last activity is complete");
   delete payload;
+  delete message;
 }
 
 static void alice()
@@ -56,6 +59,14 @@ static void alice()
   sg4::Mailbox::by_name("mbox")->put(payload, 6e8);
 }
 
+static void carl()
+{
+  sg4::this_actor::sleep_for(1.99);
+  auto* payload = new std::string("Control Message");
+  XBT_INFO("Send '%s'", payload->c_str());
+  sg4::MessageQueue::by_name("mqueue")->put(payload);
+}
+
 int main(int argc, char* argv[])
 {
   sg4::Engine e(&argc, argv);
@@ -64,6 +75,7 @@ int main(int argc, char* argv[])
 
   sg4::Actor::create("bob", e.host_by_name("bob"), bob);
   sg4::Actor::create("alice", e.host_by_name("alice"), alice);
+  sg4::Actor::create("carl", e.host_by_name("carl"), carl);
 
   e.run();
 
index c590b36..029e90b 100644 (file)
@@ -7,6 +7,8 @@ $ ${bindir:=.}/s4u-activityset-testany ${platfdir}/hosts_with_disks.xml "--log=r
 > [1.00] [  bob] Test for completed activities
 > [1.00] [  bob] Nothing matches, test again in 0.5s
 > [1.50] [  bob] Nothing matches, test again in 0.5s
+> [1.99] [ carl] Send 'Control Message'
+> [2.00] [  bob] Completed a Mess
 > [2.00] [  bob] Nothing matches, test again in 0.5s
 > [2.50] [  bob] Nothing matches, test again in 0.5s
 > [3.00] [  bob] Completed an I/O
index efbc3a0..2c9cf1a 100644 (file)
@@ -9,28 +9,30 @@
 #include <string>
 namespace sg4 = simgrid::s4u;
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waittany, "Messages specific for this s4u example");
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitall, "Messages specific for this s4u example");
 
 static void bob()
 {
   sg4::Mailbox* mbox    = sg4::Mailbox::by_name("mbox");
+  sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue");
   const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
   std::string* payload;
+  std::string* message;
 
   XBT_INFO("Create my asynchronous activities");
   auto exec = sg4::this_actor::exec_async(5e9);
   auto comm = mbox->get_async(&payload);
   auto io   = disk->read_async(3e8);
+  auto mess = mqueue->get_async(&message);
 
-  sg4::ActivitySet pending_activities({boost::dynamic_pointer_cast<sg4::Activity>(exec),
-                                       boost::dynamic_pointer_cast<sg4::Activity>(comm),
-                                       boost::dynamic_pointer_cast<sg4::Activity>(io)});
+  sg4::ActivitySet pending_activities({exec, comm, io, mess});
 
   XBT_INFO("Wait for asynchronous activities to complete, all in one shot.");
   pending_activities.wait_all();
 
   XBT_INFO("All activities are completed.");
   delete payload;
+  delete message;
 }
 
 static void alice()
@@ -40,6 +42,12 @@ static void alice()
   sg4::Mailbox::by_name("mbox")->put(payload, 6e8);
 }
 
+static void carl()
+{
+  auto* payload = new std::string("Control Message");
+  sg4::MessageQueue::by_name("mqueue")->put(payload);
+}
+
 int main(int argc, char* argv[])
 {
   sg4::Engine e(&argc, argv);
@@ -48,6 +56,7 @@ int main(int argc, char* argv[])
 
   sg4::Actor::create("bob", e.host_by_name("bob"), bob);
   sg4::Actor::create("alice", e.host_by_name("alice"), alice);
+  sg4::Actor::create("carl", e.host_by_name("carl"), carl);
 
   e.run();
 
index 971d774..a322cc4 100644 (file)
@@ -9,20 +9,23 @@
 #include <string>
 namespace sg4 = simgrid::s4u;
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waittany, "Messages specific for this s4u example");
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitallfor, "Messages specific for this s4u example");
 
 static void bob()
 {
   sg4::Mailbox* mbox    = sg4::Mailbox::by_name("mbox");
+  sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue");
   const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
   std::string* payload;
+  std::string* message;
 
   XBT_INFO("Create my asynchronous activities");
   auto exec = sg4::this_actor::exec_async(5e9);
   auto comm = mbox->get_async(&payload);
   auto io   = disk->read_async(3e8);
+  auto mess = mqueue->get_async(&message);
 
-  sg4::ActivitySet pending_activities({exec, comm, io});
+  sg4::ActivitySet pending_activities({exec, comm, io, mess});
 
   XBT_INFO("Wait for asynchronous activities to complete");
   while (not pending_activities.empty()) {
@@ -34,6 +37,8 @@ static void bob()
     while (auto completed_one = pending_activities.test_any()) {
       if (boost::dynamic_pointer_cast<sg4::Comm>(completed_one))
         XBT_INFO("Completed a Comm");
+      if (boost::dynamic_pointer_cast<sg4::Mess>(completed_one))
+        XBT_INFO("Completed a Mess");
       if (boost::dynamic_pointer_cast<sg4::Exec>(completed_one))
         XBT_INFO("Completed an Exec");
       if (boost::dynamic_pointer_cast<sg4::Io>(completed_one))
@@ -42,6 +47,7 @@ static void bob()
   }
   XBT_INFO("Last activity is complete");
   delete payload;
+  delete message;
 }
 
 static void alice()
@@ -51,6 +57,14 @@ static void alice()
   sg4::Mailbox::by_name("mbox")->put(payload, 6e8);
 }
 
+static void carl()
+{
+  sg4::this_actor::sleep_for(1.99);
+  auto* payload = new std::string("Control Message");
+  XBT_INFO("Send '%s'", payload->c_str());
+  sg4::MessageQueue::by_name("mqueue")->put(payload);
+}
+
 int main(int argc, char* argv[])
 {
   sg4::Engine e(&argc, argv);
@@ -59,6 +73,7 @@ int main(int argc, char* argv[])
 
   sg4::Actor::create("bob", e.host_by_name("bob"), bob);
   sg4::Actor::create("alice", e.host_by_name("alice"), alice);
+  sg4::Actor::create("carl", e.host_by_name("carl"), carl);
 
   e.run();
 
index 014c4f0..ce8db4a 100644 (file)
@@ -5,7 +5,9 @@ $ ${bindir:=.}/s4u-activityset-waitallfor ${platfdir}/hosts_with_disks.xml "--lo
 > [0.000000] [  bob] Create my asynchronous activities
 > [0.000000] [  bob] Wait for asynchronous activities to complete
 > [1.000000] [  bob] Not all activities are terminated yet.
+> [1.990000] [ carl] Send 'Control Message'
 > [2.000000] [  bob] Not all activities are terminated yet.
+> [2.000000] [  bob] Completed a Mess
 > [3.000000] [  bob] Not all activities are terminated yet.
 > [3.000000] [  bob] Completed an I/O
 > [4.000000] [  bob] Not all activities are terminated yet.
index 6f081b3..6c8baef 100644 (file)
@@ -9,22 +9,23 @@
 #include <string>
 namespace sg4 = simgrid::s4u;
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waittany, "Messages specific for this s4u example");
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitany, "Messages specific for this s4u example");
 
 static void bob()
 {
   sg4::Mailbox* mbox    = sg4::Mailbox::by_name("mbox");
+  sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue");
   const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
   std::string* payload;
+  std::string* message;
 
   XBT_INFO("Create my asynchronous activities");
   auto exec = sg4::this_actor::exec_async(5e9);
   auto comm = mbox->get_async(&payload);
   auto io   = disk->read_async(3e8);
+  auto mess = mqueue->get_async(&message);
 
-  sg4::ActivitySet pending_activities({boost::dynamic_pointer_cast<sg4::Activity>(exec),
-                                       boost::dynamic_pointer_cast<sg4::Activity>(comm),
-                                       boost::dynamic_pointer_cast<sg4::Activity>(io)});
+  sg4::ActivitySet pending_activities({exec, comm, io, mess});
 
   XBT_INFO("Wait for asynchronous activities to complete");
   while (not pending_activities.empty()) {
@@ -32,6 +33,8 @@ static void bob()
     if (completed_one != nullptr) {
       if (boost::dynamic_pointer_cast<sg4::Comm>(completed_one))
         XBT_INFO("Completed a Comm");
+      if (boost::dynamic_pointer_cast<sg4::Mess>(completed_one))
+        XBT_INFO("Completed a Mess");
       if (boost::dynamic_pointer_cast<sg4::Exec>(completed_one))
         XBT_INFO("Completed an Exec");
       if (boost::dynamic_pointer_cast<sg4::Io>(completed_one))
@@ -40,6 +43,7 @@ static void bob()
   }
   XBT_INFO("Last activity is complete");
   delete payload;
+  delete message;
 }
 
 static void alice()
@@ -49,6 +53,14 @@ static void alice()
   sg4::Mailbox::by_name("mbox")->put(payload, 6e8);
 }
 
+static void carl()
+{
+  sg4::this_actor::sleep_for(2);
+  auto* payload = new std::string("Control Message");
+  XBT_INFO("Send '%s'", payload->c_str());
+  sg4::MessageQueue::by_name("mqueue")->put(payload);
+}
+
 int main(int argc, char* argv[])
 {
   sg4::Engine e(&argc, argv);
@@ -57,6 +69,7 @@ int main(int argc, char* argv[])
 
   sg4::Actor::create("bob", e.host_by_name("bob"), bob);
   sg4::Actor::create("alice", e.host_by_name("alice"), alice);
+  sg4::Actor::create("carl", e.host_by_name("carl"), carl);
 
   e.run();
 
index b9ecf1e..e665de5 100644 (file)
@@ -4,6 +4,8 @@ $ ${bindir:=.}/s4u-activityset-waitany ${platfdir}/hosts_with_disks.xml "--log=r
 > [0.000000] [alice] Send 'Message'
 > [0.000000] [  bob] Create my asynchronous activities
 > [0.000000] [  bob] Wait for asynchronous activities to complete
+> [2.000000] [ carl] Send 'Control Message'
+> [2.000000] [  bob] Completed a Mess
 > [3.000000] [  bob] Completed an I/O
 > [5.000000] [  bob] Completed an Exec
 > [5.197828] [  bob] Completed a Comm
diff --git a/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp b/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp
new file mode 100644 (file)
index 0000000..00fff06
--- /dev/null
@@ -0,0 +1,124 @@
+/* Copyright (c) 2017-2023. 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. */
+
+/* This example combine the battery plugin, the chiller plugin and the solar
+   panel plugin. It illustrates how to use them together to evaluate the amount
+   of brown energy (from the electrical grid) and green energy (from the solar
+   panel) consumed by several machines.
+
+   In this scenario we have two host placed in a room.
+   The room is maintained at 24°C by a chiller, powered by the electrical grid
+   and consumes brown energy.
+   The two hosts are powered by a battery when available, and the electrical
+   grid otherwise. The battery is charged by a solar panel.
+
+   We simulate two days from 00h00 to 00h00.
+   The solar panel generates power from 8h to 20h with a peak at 14h.
+   During the simulation, when the charge of the battery goes:
+    - below 75% the solar panel is connected to the battery
+    - above 80% the solar panel is disconnected from the battery
+    - below 20% the hosts are disconnected from the battery
+    - above 25% the hosts are connected to the battery
+
+   The two hosts are always idle, except from 12h to 16h on the first day.
+*/
+
+#include "simgrid/plugins/battery.hpp"
+#include "simgrid/plugins/chiller.hpp"
+#include "simgrid/plugins/energy.h"
+#include "simgrid/plugins/solar_panel.hpp"
+#include "simgrid/s4u.hpp"
+#include <math.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(battery_chiller_solar, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
+namespace sp  = simgrid::plugins;
+
+static void irradiance_manager(sp::SolarPanelPtr solar_panel)
+{
+  int time         = 0;
+  int time_step    = 10;
+  double amplitude = 1000 / 2.0;
+  double period    = 24 * 60 * 60;
+  double shift     = 16 * 60 * 60;
+  double irradiance;
+  while (true) {
+    irradiance = amplitude * sin(2 * M_PI * (time + shift) / period);
+    irradiance = irradiance < 0 ? 0 : irradiance;
+    solar_panel->set_solar_irradiance(irradiance);
+    sg4::this_actor::sleep_for(time_step);
+    time += time_step;
+  }
+}
+
+static void host_job_manager(double start, double duration)
+{
+  sg4::this_actor::sleep_until(start);
+  sg4::this_actor::get_host()->execute(duration * sg4::this_actor::get_host()->get_speed());
+}
+
+static void end_manager(sp::BatteryPtr b)
+{
+  sg4::this_actor::sleep_until(86400 * 2);
+  for (auto& handler : b->get_handlers())
+    b->delete_handler(handler);
+}
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+  sg_host_energy_plugin_init();
+
+  auto myhost1 = e.host_by_name("MyHost1");
+  auto myhost2 = e.host_by_name("MyHost2");
+
+  auto battery     = sp::Battery::init("Battery", 0.2, -1e3, 1e3, 0.9, 0.9, 2000, 1000);
+  auto chiller     = sp::Chiller::init("Chiller", 50, 1006, 0.2, 0.9, 24, 24, 1e3);
+  auto solar_panel = sp::SolarPanel::init("Solar Panel", 1.1, 0.9, 0, 0, 1e3);
+  chiller->add_host(myhost1);
+  chiller->add_host(myhost2);
+  solar_panel->on_this_power_change_cb(
+      [battery](sp::SolarPanel* s) { battery->set_load("Solar Panel", s->get_power() * -1); });
+
+  // These handlers connect/disconnect the solar panel and the hosts depending on the state of charge of the battery
+  battery->schedule_handler(0.8, sp::Battery::CHARGE, sp::Battery::Handler::PERSISTANT,
+                            [battery]() { battery->set_load("Solar Panel", false); });
+  battery->schedule_handler(0.75, sp::Battery::DISCHARGE, sp::Battery::Handler::PERSISTANT,
+                            [battery]() { battery->set_load("Solar Panel", true); });
+  battery->schedule_handler(0.2, sp::Battery::DISCHARGE, sp::Battery::Handler::PERSISTANT,
+                            [battery, &myhost1, &myhost2]() {
+                              battery->connect_host(myhost1, false);
+                              battery->connect_host(myhost2, false);
+                            });
+  battery->schedule_handler(0.25, sp::Battery::CHARGE, sp::Battery::Handler::PERSISTANT,
+                            [battery, &myhost1, &myhost2]() {
+                              battery->connect_host(myhost1);
+                              battery->connect_host(myhost2);
+                            });
+
+  /* Handlers create simulation events preventing the simulation from finishing
+     To avoid this behaviour this actor sleeps for 2 days and then delete all handlers
+  */
+  sg4::Actor::create("end_manager", myhost1, end_manager, battery);
+
+  // This actor updates the solar irradiance of the solar panel
+  sg4::Actor::create("irradiance_manager", myhost1, irradiance_manager, solar_panel)->daemonize();
+
+  // These actors start a job on a host for a specific duration
+  sg4::Actor::create("host_job_manager", myhost1, host_job_manager, 12 * 60 * 60, 4 * 60 * 60);
+  sg4::Actor::create("host_job_manager", myhost2, host_job_manager, 12 * 60 * 60, 4 * 60 * 60);
+
+  e.run();
+  XBT_INFO("State of charge of the battery: %0.1f%%", battery->get_state_of_charge() * 100);
+  XBT_INFO(
+      "Energy consumed by the hosts (green / brown): %.2fMJ "
+      "/ %.2fMJ",
+      battery->get_energy_provided() / 1e6,
+      (sg_host_get_consumed_energy(myhost1) + sg_host_get_consumed_energy(myhost2) - battery->get_energy_provided()) /
+          1e6);
+  XBT_INFO("Energy consumed by the chiller (brown): %.2fMJ", chiller->get_energy_consumed() / 1e6);
+  return 0;
+}
diff --git a/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh b/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh
new file mode 100644 (file)
index 0000000..f2cddf4
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-battery-chiller-solar ${platfdir}/energy_platform.xml
+> [172800.000000] [host_energy/INFO] Total energy consumption: 53568000.000000 Joules (used hosts: 36288000.000000 Joules; unused/idle hosts: 17280000.000000)
+> [172800.000000] [battery_chiller_solar/INFO] State of charge of the battery: 20.4%
+> [172800.000000] [battery_chiller_solar/INFO] Energy consumed by the hosts (green / brown): 21.60MJ / 14.69MJ
+> [172800.000000] [battery_chiller_solar/INFO] Energy consumed by the chiller (brown): 48.38MJ
+> [172800.000000] [host_energy/INFO] Energy consumption of host MyHost1: 17568000.000000 Joules
+> [172800.000000] [host_energy/INFO] Energy consumption of host MyHost2: 18720000.000000 Joules
+> [172800.000000] [host_energy/INFO] Energy consumption of host MyHost3: 17280000.000000 Joules
\ No newline at end of file
diff --git a/examples/cpp/battery-connector/s4u-battery-connector.cpp b/examples/cpp/battery-connector/s4u-battery-connector.cpp
new file mode 100644 (file)
index 0000000..b3a8588
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (c) 2017-2023. 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. */
+
+/* This example shows how to use the battery as a connector.
+   A connector has no capacity and only delivers as much power as it receives
+   with a transfer efficiency of 100%.
+   A solar panel is connected to the connector and power a host.
+*/
+
+#include "simgrid/plugins/battery.hpp"
+#include "simgrid/plugins/chiller.hpp"
+#include "simgrid/plugins/energy.h"
+#include "simgrid/plugins/solar_panel.hpp"
+#include "simgrid/s4u.hpp"
+#include <math.h>
+#include <simgrid/s4u/Actor.hpp>
+#include <xbt/log.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(battery_chiller_solar, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
+namespace sp  = simgrid::plugins;
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+  sg_host_energy_plugin_init();
+
+  auto myhost1 = e.host_by_name("MyHost1");
+
+  auto connector     = sp::Battery::init();
+  auto solar_panel = sp::SolarPanel::init("Solar Panel", 1, 1, 200, 0, 1e3);
+
+  connector->set_load("Solar Panel", solar_panel->get_power() * -1);
+  connector->connect_host(myhost1);
+
+  solar_panel->on_this_power_change_cb([connector](sp::SolarPanel *s) {
+    connector->set_load("Solar Panel", s->get_power() * -1);
+  });
+
+  sg4::Actor::create("manager", myhost1, [&myhost1, & solar_panel, &connector]{
+    XBT_INFO("Solar Panel power = %.2fW, MyHost1 power = %.2fW. The Solar Panel provides more than needed.", solar_panel->get_power(), sg_host_get_current_consumption(myhost1));
+    simgrid::s4u::this_actor::sleep_for(100);
+    XBT_INFO("Energy consumption MyHost1: %.2fkJ, Energy from the Solar Panel %.2fkJ", sg_host_get_consumed_energy(myhost1) / 1e3, connector->get_energy_provided() / 1e3);
+
+    solar_panel->set_solar_irradiance(100);
+    XBT_INFO("Solar Panel power = %.2fW, MyHost1 power = %.2fW. The Solar Panel provides exactly what is needed.", solar_panel->get_power(), sg_host_get_current_consumption(myhost1));
+    double last_measure_host_energy = sg_host_get_consumed_energy(myhost1);
+    double last_measure_connector_energy = connector->get_energy_provided();
+
+    simgrid::s4u::this_actor::sleep_for(100);
+    XBT_INFO("Energy consumption MyHost1: %.2fkJ, Energy from the Solar Panel %.2fkJ", (sg_host_get_consumed_energy(myhost1) - last_measure_host_energy) / 1e3, (connector->get_energy_provided() - last_measure_connector_energy) / 1e3);
+
+    XBT_INFO("MyHost1 executes something for 100s. The Solar Panel does not provide enough energy.");
+    last_measure_host_energy = sg_host_get_consumed_energy(myhost1);
+    last_measure_connector_energy = connector->get_energy_provided();
+    myhost1->execute(100 * myhost1->get_speed());
+    XBT_INFO("Energy MyHost1: %.2fkJ, Energy from the Solar Panel %.2fkJ", (sg_host_get_consumed_energy(myhost1) - last_measure_host_energy) / 1e3, (connector->get_energy_provided() - last_measure_connector_energy) / 1e3);
+  });
+
+  e.run();
+  return 0;
+}
diff --git a/examples/cpp/battery-connector/s4u-battery-connector.tesh b/examples/cpp/battery-connector/s4u-battery-connector.tesh
new file mode 100644 (file)
index 0000000..2dd264d
--- /dev/null
@@ -0,0 +1,13 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-battery-connector ${platfdir}/energy_platform.xml
+> [MyHost1:manager:(1) 0.000000] [battery_chiller_solar/INFO] Solar Panel power = 200.00W, MyHost1 power = 100.00W. The Solar Panel provides more than needed.
+> [MyHost1:manager:(1) 100.000000] [battery_chiller_solar/INFO] Energy consumption MyHost1: 10.00kJ, Energy from the Solar Panel 10.00kJ
+> [MyHost1:manager:(1) 100.000000] [battery_chiller_solar/INFO] Solar Panel power = 100.00W, MyHost1 power = 100.00W. The Solar Panel provides exactly what is needed.
+> [MyHost1:manager:(1) 200.000000] [battery_chiller_solar/INFO] Energy consumption MyHost1: 10.00kJ, Energy from the Solar Panel 10.00kJ
+> [MyHost1:manager:(1) 200.000000] [battery_chiller_solar/INFO] MyHost1 executes something for 100s. The Solar Panel does not provide enough energy.
+> [MyHost1:manager:(1) 300.000000] [battery_chiller_solar/INFO] Energy MyHost1: 12.00kJ, Energy from the Solar Panel 10.00kJ
+> [300.000000] [host_energy/INFO] Total energy consumption: 92000.000000 Joules (used hosts: 32000.000000 Joules; unused/idle hosts: 60000.000000)
+> [300.000000] [host_energy/INFO] Energy consumption of host MyHost1: 32000.000000 Joules
+> [300.000000] [host_energy/INFO] Energy consumption of host MyHost2: 30000.000000 Joules
+> [300.000000] [host_energy/INFO] Energy consumption of host MyHost3: 30000.000000 Joules
\ No newline at end of file
index 9510404..4973587 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(battery_degradation, "Messages specific for this s4u example");
 
-static void manager()
+int main(int argc, char* argv[])
 {
+  simgrid::s4u::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+
   auto battery = simgrid::plugins::Battery::init("Battery", 0.8, -200, 200, 0.9, 0.9, 10, 100);
 
-  battery->set_load("load", 100);
+  battery->set_load("load", 100.0);
 
   auto handler1 = battery->schedule_handler(
-      0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [battery]() {
+      0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [&battery]() {
         XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), battery->get_state_of_charge());
         XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), battery->get_state_of_health());
-        battery->set_load("load", -100);
+        battery->set_load("load", -100.0);
       });
 
   std::shared_ptr<simgrid::plugins::Battery::Handler> handler2;
   handler2 = battery->schedule_handler(
       0.8, simgrid::plugins::Battery::CHARGE, simgrid::plugins::Battery::Handler::PERSISTANT,
-      [battery, handler1, handler2]() {
+      [&battery, &handler1, &handler2]() {
         XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), battery->get_state_of_charge());
         XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), battery->get_state_of_health());
         if (battery->get_state_of_health() < 0.1) {
           battery->delete_handler(handler1);
           battery->delete_handler(handler2);
         }
-        battery->set_load("load", 100);
+        battery->set_load("load", 100.0);
       });
-}
-
-int main(int argc, char* argv[])
-{
-  simgrid::s4u::Engine e(&argc, argv);
-  e.load_platform(argv[1]);
-
-  simgrid::s4u::Actor::create("manager", e.host_by_name("MyHost1"), manager);
 
   e.run();
   return 0;
index c50ef02..6db8812 100644 (file)
@@ -21,7 +21,7 @@ static void manager()
 
   battery->schedule_handler(
       0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT,
-      [battery, &host1, &host2, &host3]() {
+      [&battery, &host1, &host2, &host3]() {
         XBT_INFO("Handler -> Battery low: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
                  battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
                  battery->get_energy_provided(), battery->get_energy_consumed());
index 04eb4f6..61a4186 100644 (file)
@@ -28,7 +28,7 @@ int main(int argc, char* argv[])
   XBT_INFO("Set load to %fW", load_w);
 
   battery->schedule_handler(
-      0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [battery, &load_w]() {
+      0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [&battery, &load_w]() {
         XBT_INFO("Discharged state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
                  battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
                  battery->get_energy_provided(), battery->get_energy_consumed());
@@ -37,7 +37,7 @@ int main(int argc, char* argv[])
       });
 
   battery->schedule_handler(
-      0.8, simgrid::plugins::Battery::CHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [battery]() {
+      0.8, simgrid::plugins::Battery::CHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [&battery]() {
         XBT_INFO("Charged state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ",
                  battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(),
                  battery->get_energy_provided(), battery->get_energy_consumed());
@@ -45,5 +45,6 @@ int main(int argc, char* argv[])
       });
 
   e.run();
+
   return 0;
 }
\ No newline at end of file
index c5a45b3..db48b65 100644 (file)
@@ -6,59 +6,44 @@
 #include "simgrid/plugins/chiller.hpp"
 #include "simgrid/plugins/energy.h"
 #include "simgrid/s4u.hpp"
-#include <xbt/log.h>
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(chiller_simple, "Messages specific for this s4u example");
 namespace sg4 = simgrid::s4u;
 
-static void manager(simgrid::plugins::ChillerPtr c)
+static void display_chiller(simgrid::plugins::ChillerPtr c)
 {
-  XBT_INFO("Initial state: ");
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-
-  XBT_INFO("The machines slowly heat up the room.");
-  simgrid::s4u::this_actor::sleep_until(400);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-  simgrid::s4u::this_actor::sleep_until(800);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-  simgrid::s4u::this_actor::sleep_until(1000);
-  XBT_INFO("The Chiller now compensates the heat generated by the machines.");
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-  simgrid::s4u::this_actor::sleep_until(1200);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+  XBT_INFO("%s: Power: %.2fW T_in: %.2f°C Energy consumed: %.2fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
            c->get_energy_consumed());
+}
 
-  XBT_INFO("Let's compute something.");
-  sg4::this_actor::exec_async(1e10);
-  simgrid::s4u::this_actor::sleep_until(1250);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
+static void manager(simgrid::plugins::ChillerPtr c)
+{
+  display_chiller(c);
 
-  simgrid::s4u::this_actor::sleep_until(1300);
-  XBT_INFO("Computation done.");
+  simgrid::s4u::this_actor::sleep_for(c->get_time_to_goal_temp());
+  XBT_INFO("The input temperature is now equal to the goal temperature. After this point the Chiller will compensate "
+           "heat with electrical power.");
+  display_chiller(c);
 
-  simgrid::s4u::this_actor::sleep_until(1400);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_for(1);
+  display_chiller(c);
 
+  XBT_INFO("Let's compute something.");
+  sg4::this_actor::execute(1e10);
+  XBT_INFO("Computation done.");
+  display_chiller(c);
   XBT_INFO("Now let's stress the chiller by decreasing the goal temperature to 23°C.");
   c->set_goal_temp(23);
-  simgrid::s4u::this_actor::sleep_until(1600);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-  simgrid::s4u::this_actor::sleep_until(1800);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-  simgrid::s4u::this_actor::sleep_until(2000);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
-  simgrid::s4u::this_actor::sleep_until(2200);
-  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
-           c->get_energy_consumed());
+
+  simgrid::s4u::this_actor::sleep_for(1);
+  display_chiller(c);
+
+  simgrid::s4u::this_actor::sleep_for(c->get_time_to_goal_temp());
+  XBT_INFO("The input temperature is back to the goal temperature.");
+  display_chiller(c);
+
+  simgrid::s4u::this_actor::sleep_for(1);
+  display_chiller(c);
 }
 
 int main(int argc, char* argv[])
@@ -71,7 +56,7 @@ int main(int argc, char* argv[])
   chiller->add_host(e.host_by_name("MyHost1"));
   chiller->add_host(e.host_by_name("MyHost2"));
   chiller->add_host(e.host_by_name("MyHost3"));
-  sg4::Actor::create("sender", e.host_by_name("MyHost1"), manager, chiller);
+  sg4::Actor::create("manager", e.host_by_name("MyHost1"), manager, chiller);
 
   e.run();
   return 0;
index c1d4c27..33e196f 100644 (file)
@@ -1,24 +1,19 @@
 #!/usr/bin/env tesh
 
 $ ${bindir:=.}/s4u-chiller-simple ${platfdir}/energy_platform.xml
-> [MyHost1:sender:(1) 0.000000] [chiller_simple/INFO] Initial state: 
-> [MyHost1:sender:(1) 0.000000] [chiller_simple/INFO] Chiller: Power: 0.000000W T_in: 23.000000°C Energy consumed: 0.000000J
-> [MyHost1:sender:(1) 0.000000] [chiller_simple/INFO] The machines slowly heat up the room.
-> [MyHost1:sender:(1) 400.000000] [chiller_simple/INFO] Chiller: Power: 0.000000W T_in: 23.486875°C Energy consumed: 0.000000J
-> [MyHost1:sender:(1) 800.000000] [chiller_simple/INFO] Chiller: Power: 0.000000W T_in: 23.973749°C Energy consumed: 0.000000J
-> [MyHost1:sender:(1) 1000.000000] [chiller_simple/INFO] The Chiller now compensates the heat generated by the machines.
-> [MyHost1:sender:(1) 1000.000000] [chiller_simple/INFO] Chiller: Power: 356.866667W T_in: 24.000000°C Energy consumed: 71373.333333J
-> [MyHost1:sender:(1) 1200.000000] [chiller_simple/INFO] Chiller: Power: 400.000000W T_in: 24.000000°C Energy consumed: 151373.333333J
-> [MyHost1:sender:(1) 1200.000000] [chiller_simple/INFO] Let's compute something.
-> [MyHost1:sender:(1) 1250.000000] [chiller_simple/INFO] Chiller: Power: 426.666667W T_in: 24.000000°C Energy consumed: 172706.666667J
-> [MyHost1:sender:(1) 1300.000000] [chiller_simple/INFO] Computation done.
-> [MyHost1:sender:(1) 1400.000000] [chiller_simple/INFO] Chiller: Power: 400.000000W T_in: 24.000000°C Energy consumed: 234040.000000J
-> [MyHost1:sender:(1) 1400.000000] [chiller_simple/INFO] Now let's stress the chiller by decreasing the goal temperature to 23°C.
-> [MyHost1:sender:(1) 1600.000000] [chiller_simple/INFO] Chiller: Power: 1000.000000W T_in: 23.634844°C Energy consumed: 434040.000000J
-> [MyHost1:sender:(1) 1800.000000] [chiller_simple/INFO] Chiller: Power: 1000.000000W T_in: 23.269688°C Energy consumed: 634040.000000J
-> [MyHost1:sender:(1) 2000.000000] [chiller_simple/INFO] Chiller: Power: 843.133333W T_in: 23.000000°C Energy consumed: 802666.666667J
-> [MyHost1:sender:(1) 2200.000000] [chiller_simple/INFO] Chiller: Power: 400.000000W T_in: 23.000000°C Energy consumed: 882666.666667J
-> [2200.000000] [host_energy/INFO] Total energy consumption: 662000.000000 Joules (used hosts: 222000.000000 Joules; unused/idle hosts: 440000.000000)
-> [2200.000000] [host_energy/INFO] Energy consumption of host MyHost1: 222000.000000 Joules
-> [2200.000000] [host_energy/INFO] Energy consumption of host MyHost2: 220000.000000 Joules
-> [2200.000000] [host_energy/INFO] Energy consumption of host MyHost3: 220000.000000 Joules
+> [MyHost1:manager:(1) 0.000000] [chiller_simple/INFO] Chiller: Power: 0.00W T_in: 23.00°C Energy consumed: 0.00J
+> [MyHost1:manager:(1) 821.566667] [chiller_simple/INFO] The input temperature is now equal to the goal temperature. After this point the Chiller will compensate heat with electrical power.
+> [MyHost1:manager:(1) 821.566667] [chiller_simple/INFO] Chiller: Power: 0.00W T_in: 24.00°C Energy consumed: 0.00J
+> [MyHost1:manager:(1) 822.566667] [chiller_simple/INFO] Chiller: Power: 400.00W T_in: 24.00°C Energy consumed: 400.00J
+> [MyHost1:manager:(1) 822.566667] [chiller_simple/INFO] Let's compute something.
+> [MyHost1:manager:(1) 922.566667] [chiller_simple/INFO] Computation done.
+> [MyHost1:manager:(1) 922.566667] [chiller_simple/INFO] Chiller: Power: 426.67W T_in: 24.00°C Energy consumed: 43066.67J
+> [MyHost1:manager:(1) 922.566667] [chiller_simple/INFO] Now let's stress the chiller by decreasing the goal temperature to 23°C.
+> [MyHost1:manager:(1) 923.566667] [chiller_simple/INFO] Chiller: Power: 1000.00W T_in: 24.00°C Energy consumed: 44066.67J
+> [MyHost1:manager:(1) 1470.277778] [chiller_simple/INFO] The input temperature is back to the goal temperature.
+> [MyHost1:manager:(1) 1470.277778] [chiller_simple/INFO] Chiller: Power: 1000.00W T_in: 23.00°C Energy consumed: 590777.78J
+> [MyHost1:manager:(1) 1471.277778] [chiller_simple/INFO] Chiller: Power: 400.00W T_in: 23.00°C Energy consumed: 591177.78J
+> [1471.277778] [host_energy/INFO] Total energy consumption: 443383.333333 Joules (used hosts: 149127.777778 Joules; unused/idle hosts: 294255.555556)
+> [1471.277778] [host_energy/INFO] Energy consumption of host MyHost1: 149127.777778 Joules
+> [1471.277778] [host_energy/INFO] Energy consumption of host MyHost2: 147127.777778 Joules
+> [1471.277778] [host_energy/INFO] Energy consumption of host MyHost3: 147127.777778 Joules
\ No newline at end of file
index 4772376..f64c4c2 100644 (file)
@@ -17,10 +17,7 @@ static void test()
   sg4::IoPtr carl_read = sg4::Host::by_name("carl")->get_disks().front()->io_init(4000000, sg4::Io::OpType::READ);
   sg4::ExecPtr carl_compute = sg4::Host::by_name("carl")->exec_init(1e9);
 
-  sg4::ActivitySet pending_activities ({boost::dynamic_pointer_cast<sg4::Activity>(bob_compute),
-                                        boost::dynamic_pointer_cast<sg4::Activity>(bob_write),
-                                        boost::dynamic_pointer_cast<sg4::Activity>(carl_read),
-                                        boost::dynamic_pointer_cast<sg4::Activity>(carl_compute)});
+  sg4::ActivitySet pending_activities ({bob_compute, bob_write, carl_read, carl_compute});
 
   // Name the activities (for logging purposes only)
   bob_compute->set_name("bob compute");
diff --git a/examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness b/examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness
deleted file mode 100644 (file)
index 96b491d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-never { /* !G(r->Fcs) */
-T0_init :    /* init */
-       if
-       :: (1) -> goto T0_init
-       :: (!cs && r) -> goto accept_S2
-       fi;
-accept_S2 :    /* 1 */
-       if
-       :: (!cs) -> goto accept_S2
-       fi;
-}
diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner
deleted file mode 100755 (executable)
index 0552ca2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env sh
-# Run the same test compiled with -fstack-cleaner / f-no-stack-cleaner
-# and compare the output.
-
-srcdir="$1"
-bindir="$2"
-
-cd "$srcdir"
-
-die() {
-  echo "$@" >&2
-  exit 1
-}
-
-assert() {
-  if ! eval "$1"; then
-    die "Assertion failed: $*"
-  fi
-}
-
-# If we don't have timeout, fake it:
-if ! which timeout > /dev/null; then
-  timeout() {
-    shift
-    "$@"
-  }
-fi
-
-run() {
-  state=$1
-  shift
-  timeout 30s ${bindir:=.}/bugged1_liveness_cleaner_$state \
-    ${srcdir:=.}/../../platforms/platform.xml \
-    ${srcdir:=.}/deploy_bugged1_liveness.xml \
-    "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" \
-    --cfg=contexts/factory:ucontext \
-    --cfg=contexts/stack-size:256
-  assert 'test $? = 134'
-}
-
-get_states() {
-  echo "$1" | grep "Expanded pairs = " | sed "s/^.*Expanded pairs = //" | head -n1
-}
-
-RES_ON="$(run on 2>&1 1>/dev/null)"
-RES_OFF="$(run off 2>&1 1>/dev/null)"
-
-STATES_ON=$(get_states "$RES_ON")
-STATES_OFF=$(get_states "$RES_OFF")
-
-# Both runs finished:
-assert 'test -n "$STATES_ON"'
-assert 'test -n "$STATES_OFF"'
-
-# We expect 21 visited pairs with the stack cleaner:
-assert 'test "$STATES_ON" = 21'
-
-# We expect more states without the stack cleaner:
-assert 'test "$STATES_ON" -lt "$STATES_OFF"'
diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh
deleted file mode 100644 (file)
index e956f9c..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env tesh
-
-! expect return 2
-! timeout 30
-! output display
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1-liveness ${platfdir:=.}/small_platform.xml 1 --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack-size:256  --cfg=model-check/property:promela_bugged1_liveness
-> [  0.000000] (0:maestro@) Check the liveness property promela_bugged1_liveness
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (3:client@Fafard) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS already used. Queue the request.
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1)
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS already used. Queue the request.
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1)
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS already used. Queue the request.
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1)
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (1:coordinator@Tremblay) CS already used. Queue the request.
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1)
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (3:client@Fafard) Propositions changed : r=1, cs=0
-> [  0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1)
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (0:maestro@) Pair 58 already reached (equal to pair 46) !
-> [  0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [  0.000000] (0:maestro@) |             ACCEPTANCE CYCLE            |
-> [  0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [  0.000000] (0:maestro@) Counter-example that violates formula :
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) Expanded pairs = 58
-> [  0.000000] (0:maestro@) Visited pairs = 202
-> [  0.000000] (0:maestro@) Executed transitions = 208
-> [  0.000000] (0:maestro@) Counter-example depth : 51
diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp
deleted file mode 100644 (file)
index ad4d30a..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2012-2023. 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. */
-
-/***************** Centralized Mutual Exclusion Algorithm *******************/
-/* This example implements a centralized mutual exclusion algorithm.        */
-/* Bug : CS requests of client 1 not satisfied                              */
-/* LTL property checked : G(r->F(cs)); (r=request of CS, cs=CS ok)          */
-/****************************************************************************/
-
-#ifdef GARBAGE_STACK
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#endif
-
-#include <simgrid/modelchecker.h>
-#include <simgrid/s4u.hpp>
-#include <xbt/dynar.h>
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(bugged1_liveness, "my log messages");
-namespace sg4 = simgrid::s4u;
-
-class Message {
-public:
-  enum class Kind { GRANT, REQUEST, RELEASE };
-  Kind kind                             = Kind::GRANT;
-  sg4::Mailbox* return_mailbox          = nullptr;
-  explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
-};
-
-int r  = 0;
-int cs = 0;
-
-#ifdef GARBAGE_STACK
-/** Do not use a clean stack */
-static void garbage_stack(void)
-{
-  const size_t size = 256;
-  int fd            = open("/dev/urandom", O_RDONLY);
-  char foo[size];
-  read(fd, foo, size);
-  close(fd);
-}
-#endif
-
-static void coordinator()
-{
-  bool CS_used = false;
-  std::queue<sg4::Mailbox*> requests;
-
-  sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator");
-
-  while (true) {
-    auto m = mbox->get_unique<Message>();
-    if (m->kind == Message::Kind::REQUEST) {
-      if (CS_used) {
-        XBT_INFO("CS already used. Queue the request.");
-        requests.push(m->return_mailbox);
-      } else {
-        if (m->return_mailbox->get_name() != "1") {
-          XBT_INFO("CS idle. Grant immediately");
-          m->return_mailbox->put(new Message(Message::Kind::GRANT, mbox), 1000);
-          CS_used = true;
-        }
-      }
-    } else {
-      if (not requests.empty()) {
-        XBT_INFO("CS release. Grant to queued requests (queue size: %zu)", requests.size());
-        sg4::Mailbox* req = requests.front();
-        requests.pop();
-        if (req->get_name() != "1") {
-          req->put(new Message(Message::Kind::GRANT, mbox), 1000);
-        } else {
-          requests.push(req);
-          CS_used = false;
-        }
-      } else {
-        XBT_INFO("CS release. resource now idle");
-        CS_used = false;
-      }
-    }
-  }
-}
-
-static void client(int id)
-{
-  aid_t my_pid = sg4::this_actor::get_pid();
-
-  sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id));
-
-  while (true) {
-    XBT_INFO("Ask the request");
-    sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
-
-    if (id == 1) {
-      r  = 1;
-      cs = 0;
-      XBT_INFO("Propositions changed : r=1, cs=0");
-    }
-
-    auto grant = my_mailbox->get_unique<Message>();
-    xbt_assert(grant->kind == Message::Kind::GRANT);
-
-    if (id == 1) {
-      cs = 1;
-      r  = 0;
-      XBT_INFO("Propositions changed : r=0, cs=1");
-    }
-
-    XBT_INFO("%d got the answer. Sleep a bit and release it", id);
-
-    sg4::this_actor::sleep_for(1);
-
-    sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::RELEASE, my_mailbox), 1000);
-
-    sg4::this_actor::sleep_for(static_cast<double>(my_pid));
-
-    if (id == 1) {
-      cs = 0;
-      r  = 0;
-      XBT_INFO("Propositions changed : r=0, cs=0");
-    }
-  }
-}
-
-static void raw_client(int id)
-{
-#ifdef GARBAGE_STACK
-  // At this point the stack of the callee (client) is probably filled with
-  // zeros and uninitialized variables will contain 0. This call will place
-  // random byes in the stack of the callee:
-  garbage_stack();
-#endif
-  client(id);
-}
-
-int main(int argc, char* argv[])
-{
-  sg4::Engine e(&argc, argv);
-
-  MC_automaton_new_propositional_symbol_pointer("r", &r);
-  MC_automaton_new_propositional_symbol_pointer("cs", &cs);
-
-  e.load_platform(argv[1]);
-
-  sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator)
-      ->set_kill_time(argc > 3 ? std::stod(argv[3]) : -1.0);
-  if (std::stod(argv[2]) == 0) {
-    sg4::Actor::create("client", e.host_by_name("Boivin"), raw_client, 1);
-    sg4::Actor::create("client", e.host_by_name("Fafard"), raw_client, 2);
-  } else { // "Visited" case
-    sg4::Actor::create("client", e.host_by_name("Boivin"), raw_client, 2);
-    sg4::Actor::create("client", e.host_by_name("Fafard"), raw_client, 1);
-  }
-  e.run();
-
-  return 0;
-}
diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh
deleted file mode 100644 (file)
index 5f0999c..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env tesh
-
-! expect return 2
-! timeout 20
-! output display
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1-liveness ${platfdir:=.}/small_platform.xml 0 --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack-size:256 --cfg=model-check/property:promela_bugged1_liveness
-> [  0.000000] (0:maestro@) Check the liveness property promela_bugged1_liveness
-> [  0.000000] (2:client@Boivin) Ask the request
-> [  0.000000] (3:client@Fafard) Ask the request
-> [  0.000000] (2:client@Boivin) Propositions changed : r=1, cs=0
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (3:client@Fafard) 2 got the answer. Sleep a bit and release it
-> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
-> [  0.000000] (3:client@Fafard) Ask the request
-> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately
-> [  0.000000] (0:maestro@) Pair 22 already reached (equal to pair 10) !
-> [  0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [  0.000000] (0:maestro@) |             ACCEPTANCE CYCLE            |
-> [  0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [  0.000000] (0:maestro@) Counter-example that violates formula :
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] iRecv(dst=(3)Fafard (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (3)Fafard (client)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (3)Fafard (client)])
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only))
-> [  0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)])
-> [  0.000000] (0:maestro@) Expanded pairs = 22
-> [  0.000000] (0:maestro@) Visited pairs = 20
-> [  0.000000] (0:maestro@) Executed transitions = 20
-> [  0.000000] (0:maestro@) Counter-example depth : 21
diff --git a/examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness b/examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness
deleted file mode 100644 (file)
index 5361f88..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-never { /* !(!(GFcs)) */
-T0_init :    /* init */
-       if
-       :: (cs) -> goto accept_S1
-       :: (1) -> goto T0_init
-       fi;
-accept_S1 :    /* 1 */
-       if
-       :: (cs) -> goto accept_S1
-       :: (1) -> goto T0_init
-       fi;
-}
diff --git a/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp b/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp
deleted file mode 100644 (file)
index fcc6878..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (c) 2012-2023. 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. */
-
-/***************************** Bugged2 ****************************************/
-/* This example implements a centralized mutual exclusion algorithm.          */
-/* One client stay always in critical section                                 */
-/* LTL property checked : !(GFcs)                                             */
-/******************************************************************************/
-
-#include <simgrid/modelchecker.h>
-#include <simgrid/s4u.hpp>
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(bugged2_liveness, "my log messages");
-namespace sg4 = simgrid::s4u;
-
-class Message {
-public:
-  enum class Kind { GRANT, NOT_GRANT, REQUEST };
-  Kind kind                             = Kind::GRANT;
-  sg4::Mailbox* return_mailbox          = nullptr;
-  explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
-};
-
-int cs = 0;
-
-static void coordinator()
-{
-  bool CS_used = false; // initially the CS is idle
-  std::queue<sg4::Mailbox*> requests;
-
-  sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator");
-
-  while (true) {
-    auto m = mbox->get_unique<Message>();
-    if (m->kind == Message::Kind::REQUEST) {
-      if (CS_used) {
-        XBT_INFO("CS already used.");
-        m->return_mailbox->put(new Message(Message::Kind::NOT_GRANT, mbox), 1000);
-      } else { // can serve it immediately
-        XBT_INFO("CS idle. Grant immediately");
-        m->return_mailbox->put(new Message(Message::Kind::GRANT, mbox), 1000);
-        CS_used = true;
-      }
-    } else { // that's a release. Check if someone was waiting for the lock
-      XBT_INFO("CS release. resource now idle");
-      CS_used = false;
-    }
-  }
-}
-
-static void client(int id)
-{
-  aid_t my_pid = sg4::this_actor::get_pid();
-
-  sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id));
-
-  while (true) {
-    XBT_INFO("Client (%d) asks the request", id);
-    sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
-
-    auto grant = my_mailbox->get_unique<Message>();
-
-    if (grant->kind == Message::Kind::GRANT) {
-      XBT_INFO("Client (%d) got the answer (grant). Sleep a bit and release it", id);
-      if (id == 1)
-        cs = 1;
-    } else {
-      XBT_INFO("Client (%d) got the answer (not grant). Try again", id);
-    }
-
-    sg4::this_actor::sleep_for(my_pid);
-  }
-}
-
-int main(int argc, char* argv[])
-{
-  sg4::Engine e(&argc, argv);
-
-  MC_automaton_new_propositional_symbol_pointer("cs", &cs);
-
-  e.load_platform(argv[1]);
-
-  sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator);
-  sg4::Actor::create("client", e.host_by_name("Fafard"), client, 1);
-  sg4::Actor::create("client", e.host_by_name("Boivin"), client, 2);
-
-  e.run();
-
-  return 0;
-}
diff --git a/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh b/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh
deleted file mode 100644 (file)
index 28329f6..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env tesh
-
-! expect return 2
-! timeout 20
-! output ignore
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged2-liveness ${platfdir:=.}/small_platform.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack-size:256 --cfg=model-check/property:promela_bugged2_liveness
diff --git a/examples/cpp/mc-failing-assert/s4u-mc-failing-assert-statequality.tesh b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert-statequality.tesh
deleted file mode 100644 (file)
index cb54584..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env tesh
-
-! expect return 1
-! timeout 300
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/visited:10000 -- ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml --log=root.thresh:critical
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/visited' to '20'
-> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
-> [0.000000] [mc_ModelChecker/INFO] **************************
-> [0.000000] [mc_ModelChecker/INFO] *** PROPERTY NOT VALID ***
-> [0.000000] [mc_ModelChecker/INFO] **************************
-> [0.000000] [mc_ModelChecker/INFO] Counter-example execution trace:
-> [0.000000] [mc_ModelChecker/INFO]   1: iRecv(mbox=0)
-> [0.000000] [mc_ModelChecker/INFO]   3: iSend(mbox=0)
-> [0.000000] [mc_ModelChecker/INFO]   1: WaitComm(from 3 to 1, mbox=0, no timeout)
-> [0.000000] [mc_ModelChecker/INFO]   1: iRecv(mbox=0)
-> [0.000000] [mc_ModelChecker/INFO]   2: iSend(mbox=0)
-> [0.000000] [mc_ModelChecker/INFO]   1: WaitComm(from 2 to 1, mbox=0, no timeout)
-> [0.000000] [mc_ModelChecker/INFO] Path = 1;3;1;1;2;1
-> [0.000000] [mc_dfs/INFO] DFS exploration ended. 18 unique states visited; 4 backtracks (22 transition replays, 0 states visited overall)
diff --git a/examples/cpp/mess-wait/s4u-mess-wait.cpp b/examples/cpp/mess-wait/s4u-mess-wait.cpp
new file mode 100644 (file)
index 0000000..086dc47
--- /dev/null
@@ -0,0 +1,79 @@
+/* Copyright (c) 2023. 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. */
+
+/* This example shows how to use simgrid::s4u::this_actor::wait() to wait for a given communication.
+ *
+ * As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+ * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
+ *
+ * The sender then loops until there is no ongoing communication.
+ */
+
+#include "simgrid/s4u.hpp"
+#include <cstdlib>
+#include <iostream>
+#include <string>
+namespace sg4 = simgrid::s4u;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_mess_wait, "Messages specific for this s4u example");
+
+static void sender(int messages_count)
+{
+  sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("control");
+
+  sg4::this_actor::sleep_for(0.5);
+
+  for (int i = 0; i < messages_count; i++) {
+    std::string msg_content = "Message " + std::to_string(i);
+    // Copy the data we send: the 'msg_content' variable is not a stable storage location.
+    // It will be destroyed when this actor leaves the loop, ie before the receiver gets the data
+    auto* payload = new std::string(msg_content);
+
+    /* Create a control message and put it in the message queue */
+    sg4::MessPtr mess = mqueue->put_async(payload);
+    XBT_INFO("Send '%s' to '%s'", msg_content.c_str(), mqueue->get_cname());
+    mess->wait();
+  }
+
+  /* Send message to let the receiver know that it should stop */
+  XBT_INFO("Send 'finalize' to 'receiver'");
+  mqueue->put(new std::string("finalize"));
+}
+
+/* Receiver actor expects 1 argument: its ID */
+static void receiver()
+{
+  sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("control");
+
+  sg4::this_actor::sleep_for(1);
+
+  XBT_INFO("Wait for my first message");
+  for (bool cont = true; cont;) {
+    std::string* received;
+    sg4::MessPtr mess = mqueue->get_async<std::string>(&received);
+
+    sg4::this_actor::sleep_for(0.1);
+    mess->wait();
+
+    XBT_INFO("I got a '%s'.", received->c_str());
+    if (*received == "finalize")
+      cont = false; // If it's a finalize message, we're done.
+    delete received;
+  }
+}
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+
+  e.load_platform(argv[1]);
+
+  sg4::Actor::create("sender", e.host_by_name("Tremblay"), sender, 3);
+  sg4::Actor::create("receiver", e.host_by_name("Fafard"), receiver);
+
+  e.run();
+
+  return 0;
+}
diff --git a/examples/cpp/mess-wait/s4u-mess-wait.tesh b/examples/cpp/mess-wait/s4u-mess-wait.tesh
new file mode 100644 (file)
index 0000000..fe7bcee
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-mess-wait ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+> [  0.500000] (1:sender@Tremblay) Send 'Message 0' to 'control'
+> [  1.000000] (2:receiver@Fafard) Wait for my first message
+> [  1.000000] (1:sender@Tremblay) Send 'Message 1' to 'control'
+> [  1.100000] (2:receiver@Fafard) I got a 'Message 0'.
+> [  1.100000] (1:sender@Tremblay) Send 'Message 2' to 'control'
+> [  1.200000] (2:receiver@Fafard) I got a 'Message 1'.
+> [  1.200000] (1:sender@Tremblay) Send 'finalize' to 'receiver'
+> [  1.300000] (2:receiver@Fafard) I got a 'Message 2'.
+> [  1.400000] (2:receiver@Fafard) I got a 'finalize'.
\ No newline at end of file
index b17f900..9ed6eb7 100644 (file)
@@ -18,21 +18,21 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
+> [Checker]  #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
+> [Checker]  #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 1: BARRIER_WAIT(barrier: 0) (stack depth: 3, state: 3, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=3)
+> [Checker]  #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
+> [Checker]  #1 BARRIER_WAIT(barrier: 0) (state=3)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: BARRIER_WAIT(barrier: 0) (stack depth: 4, state: 4, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=3)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=4)
+> [Checker]  #1 BARRIER_WAIT(barrier: 0) (state=3)
+> [Checker]  #2 BARRIER_WAIT(barrier: 0) (state=4)
 > [Checker] Dependent Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=4)
+> [Checker]  #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
+> [Checker]  #2 BARRIER_WAIT(barrier: 0) (state=4)
 > [Checker] 0 actors remain, but none of them need to be interleaved (depth 6).
 > [Checker] Execution came to an end at 1;2;1;2 (state: 5, depth: 5)
 > [Checker] Backtracking from 1;2;1;2
@@ -50,40 +50,40 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
+> [Checker]  #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
+> [Checker]  #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 3: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 3, state: 3, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
+> [Checker]  #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
+> [Checker]  #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
+> [Checker]  #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
+> [Checker]  #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 1: BARRIER_WAIT(barrier: 0) (stack depth: 4, state: 4, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=4)
+> [Checker]  #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
+> [Checker]  #1 BARRIER_WAIT(barrier: 0) (state=4)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: BARRIER_WAIT(barrier: 0) (stack depth: 5, state: 5, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=4)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=5)
+> [Checker]  #1 BARRIER_WAIT(barrier: 0) (state=4)
+> [Checker]  #2 BARRIER_WAIT(barrier: 0) (state=5)
 > [Checker] Dependent Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=5)
+> [Checker]  #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3)
+> [Checker]  #2 BARRIER_WAIT(barrier: 0) (state=5)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 3: BARRIER_WAIT(barrier: 0) (stack depth: 6, state: 6, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=5)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=6)
+> [Checker]  #2 BARRIER_WAIT(barrier: 0) (state=5)
+> [Checker]  #3 BARRIER_WAIT(barrier: 0) (state=6)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=4)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=6)
+> [Checker]  #1 BARRIER_WAIT(barrier: 0) (state=4)
+> [Checker]  #3 BARRIER_WAIT(barrier: 0) (state=6)
 > [Checker] Dependent Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
-> [Checker]   BARRIER_WAIT(barrier: 0) (state=6)
+> [Checker]  #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
+> [Checker]  #3 BARRIER_WAIT(barrier: 0) (state=6)
 > [Checker] 0 actors remain, but none of them need to be interleaved (depth 8).
 > [Checker] Execution came to an end at 1;2;3;1;2;3 (state: 7, depth: 7)
 > [Checker] Backtracking from 1;2;3;1;2;3
@@ -91,8 +91,8 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.
 > [Checker]   <2,BARRIER_ASYNC_LOCK(barrier: 0)>
 > [Checker] Execute 3: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
-> [Checker]   BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
+> [Checker]  #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1)
+> [Checker]  #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=2)
 > [Checker] 3 actors remain, but none of them need to be interleaved (depth 4).
 > [Checker] Backtracking from 1;3
 > [Checker] DFS exploration ended. 8 unique states visited; 1 backtracks (1 transition replays, 10 states visited overall)
\ No newline at end of file
diff --git a/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex-stateful.tesh b/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex-stateful.tesh
deleted file mode 100644 (file)
index d2a7187..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env tesh
-
-p This file tests the cfg=model-check/checkpoint option for DFS explorer
-
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/checkpoint:5 -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:2 --log=s4u_test.thres:critical
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/checkpoint' to '5'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'actors' to '2'
-> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
-> [0.000000] [mc_dfs/INFO] DFS exploration ended. 66 unique states visited; 11 backtracks (22 transition replays, 99 states visited overall)
-
-p The stats without checkpoints is:               130 unique states visited; 27 backtracks (308 transition replays, 151 states visited overall)
-p But it runs much faster (0.6 sec vs. 1.6 sec), damn slow checkpointing code.
index f7f1a55..5f726fe 100644 (file)
@@ -14,24 +14,24 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 4, state: 4, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3)
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4)
+> [Checker]  #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3)
+> [Checker]  #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   MUTEX_WAIT(mutex: 0, owner: 1) (state=2)
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4)
+> [Checker]  #1 MUTEX_WAIT(mutex: 0, owner: 1) (state=2)
+> [Checker]  #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1)
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4)
+> [Checker]  #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1)
+> [Checker]  #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 5, state: 5, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3)
-> [Checker]   MUTEX_WAIT(mutex: 0, owner: 2) (state=5)
+> [Checker]  #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3)
+> [Checker]  #2 MUTEX_WAIT(mutex: 0, owner: 2) (state=5)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 6, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3)
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: -1) (state=6)
+> [Checker]  #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3)
+> [Checker]  #2 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=6)
 > [Checker] 0 actors remain, but none of them need to be interleaved (depth 8).
 > [Checker] Execution came to an end at 1;1;1;2;2;2 (state: 7, depth: 7)
 > [Checker] Backtracking from 1;1;1;2;2;2
@@ -39,11 +39,11 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.
 > [Checker]   <1,MUTEX_UNLOCK(mutex: 0, owner: -1)>
 > [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (stack depth: 3, state: 3, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   MUTEX_WAIT(mutex: 0, owner: 1) (state=2)
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=3)
+> [Checker]  #1 MUTEX_WAIT(mutex: 0, owner: 1) (state=2)
+> [Checker]  #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=3)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1)
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=3)
+> [Checker]  #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1)
+> [Checker]  #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=3)
 > [Checker] 2 actors remain, but none of them need to be interleaved (depth 5).
 > [Checker] Backtracking from 1;1;2
 > [Checker] Sleep set actually containing:
@@ -52,28 +52,28 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 2, state: 9, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1)
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9)
+> [Checker]  #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1)
+> [Checker]  #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 3, state: 10, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9)
-> [Checker]   MUTEX_WAIT(mutex: 0, owner: 2) (state=10)
+> [Checker]  #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9)
+> [Checker]  #2 MUTEX_WAIT(mutex: 0, owner: 2) (state=10)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner: 1) (stack depth: 4, state: 11, 0 interleaves)
 > [Checker] INDEPENDENT Transitions:
-> [Checker]   MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9)
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11)
+> [Checker]  #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9)
+> [Checker]  #2 MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 5, state: 12, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11)
-> [Checker]   MUTEX_WAIT(mutex: 0, owner: 1) (state=12)
+> [Checker]  #2 MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11)
+> [Checker]  #1 MUTEX_WAIT(mutex: 0, owner: 1) (state=12)
 > [Checker] Sleep set actually containing:
 > [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 13, 0 interleaves)
 > [Checker] Dependent Transitions:
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11)
-> [Checker]   MUTEX_UNLOCK(mutex: 0, owner: -1) (state=13)
+> [Checker]  #2 MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11)
+> [Checker]  #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=13)
 > [Checker] 0 actors remain, but none of them need to be interleaved (depth 8).
 > [Checker] Execution came to an end at 2;1;2;2;1;1 (state: 14, depth: 7)
 > [Checker] Backtracking from 2;1;2;2;1;1
index 0a0ab71..ca0f61e 100644 (file)
@@ -111,11 +111,13 @@ int main(int argc, char* argv[])
     auto data = t->get_token_from(SA_to_B1)->get_data<double>();
     t->deque_token_from(SA_to_B1);
     t->set_amount(*data * 10);
+    delete data;
   });
   B2->on_this_start_cb([&SA_to_B2](sg4::Task* t) {
     auto data = t->get_token_from(SA_to_B2)->get_data<double>();
     t->deque_token_from(SA_to_B2);
     t->set_amount(*data * 10);
+    delete data;
   });
 
   // Enqueue firings for tasks without predecessors
index c2b3186..e590108 100644 (file)
@@ -3,10 +3,9 @@ set(_replay_sources    ${CMAKE_CURRENT_SOURCE_DIR}/replay/replay.cpp)
 set(_ampi_test_sources ${CMAKE_CURRENT_SOURCE_DIR}/ampi_test/ampi_test.cpp)
 
 # These tests are only used when MC is actived
-set(MC_tests bugged1 bugged2 bugged1_liveness only_send_deterministic mutual_exclusion non_termination1
-             non_termination2 non_termination3 non_termination4 sendsend)
+set(MC_tests bugged1 bugged2 only_send_deterministic mutual_exclusion sendsend)
 foreach(x ${MC_tests})
-  if(NOT SIMGRID_HAVE_STATEFUL_MC)
+  if(NOT SIMGRID_HAVE_MC)
     set(_${x}_disable 1)
   endif()
   set(_${x}_sources ${CMAKE_CURRENT_SOURCE_DIR}/mc/${x}.c)
@@ -65,13 +64,10 @@ set(tesh_files    ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/energy/energy.tes
                                    ${CMAKE_CURRENT_SOURCE_DIR}/replay/replay.tesh                          PARENT_SCOPE)
 set(bin_files     ${bin_files}     ${CMAKE_CURRENT_SOURCE_DIR}/hostfile
                                    ${CMAKE_CURRENT_SOURCE_DIR}/energy/hostfile
-                                   ${CMAKE_CURRENT_SOURCE_DIR}/mc/promela_bugged1_liveness
-                                   ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_bugged1_liveness
                                    ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_bugged1
                                    ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_bugged2
                                    ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_only_send_deterministic
                                    ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_mutual_exclusion
-                                   ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_non_termination
                                    ${CMAKE_CURRENT_SOURCE_DIR}/simple-execute/hostfile_griffon             PARENT_SCOPE)
 set(txt_files     ${txt_files}     ${CMAKE_CURRENT_SOURCE_DIR}/replay/actions0.txt
                                    ${CMAKE_CURRENT_SOURCE_DIR}/replay/actions1.txt
@@ -91,7 +87,7 @@ set(txt_files     ${txt_files}     ${CMAKE_CURRENT_SOURCE_DIR}/replay/actions0.t
 
 if(enable_smpi)
   # MC is currently broken with threads (deadlock => timeout)
-  if(SIMGRID_HAVE_STATEFUL_MC)
+  if(SIMGRID_HAVE_MC)
     add_dependencies(tests-mc smpimain)
     add_dependencies(tests-mc smpi_only_send_deterministic)
     ADD_TESH(smpi-mc-only-send-determinism --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi/mc --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_BINARY_DIR}/examples/smpi/mc ${CMAKE_HOME_DIRECTORY}/examples/smpi/mc/only_send_deterministic.tesh)
diff --git a/examples/smpi/mc/bugged1_liveness.c b/examples/smpi/mc/bugged1_liveness.c
deleted file mode 100644 (file)
index 0b215f9..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 2013-2023. 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. */
-
-/***************** Centralized Mutual Exclusion Algorithm *********************/
-/* This example implements a centralized mutual exclusion algorithm.          */
-/* Bug : CS requests of process 1 not satisfied                                      */
-/* LTL property checked : G(r->F(cs)); (r=request of CS, cs=CS ok)            */
-/******************************************************************************/
-
-/* Run :
-  /usr/bin/time -f "clock:%e user:%U sys:%S swapped:%W exitval:%x max:%Mk" "$@" \
-    ../../../smpi_script/bin/smpirun -hostfile hostfile_bugged1_liveness -platform ../../platforms/cluster_backbone.xml \
-    --cfg=contexts/factory:ucontext --cfg=model-check/reduction:none \
-    --cfg=model-check/property:promela_bugged1_liveness --cfg=smpi/send-is-detached-thresh:0 \
-    --cfg=contexts/stack-size:128 --cfg=model-check/visited:100000 --cfg=model-check/max-depth:100000 ./bugged1_liveness
-*/
-
-#include <stdio.h>
-#include <mpi.h>
-#include <simgrid/modelchecker.h>
-#include <xbt/dynar.h>
-
-#define GRANT_TAG 0
-#define REQUEST_TAG 1
-#define RELEASE_TAG 2
-
-int r;
-int cs;
-
-int main(int argc, char **argv){
-  int size;
-  int rank;
-  int recv_buff;
-  MPI_Status status;
-  xbt_dynar_t requests = xbt_dynar_new(sizeof(int), NULL);
-
-  /* Initialize MPI */
-  int err = MPI_Init(&argc, &argv);
-  if(err !=  MPI_SUCCESS){
-    printf("MPI initialization failed !\n");
-    exit(1);
-  }
-
-  MC_automaton_new_propositional_symbol_pointer("r", &r);
-  MC_automaton_new_propositional_symbol_pointer("cs", &cs);
-
-  MC_ignore(&status.count, sizeof status.count);
-
-  /* Get number of processes */
-  MPI_Comm_size(MPI_COMM_WORLD, &size);
-  /* Get id of this process */
-  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-  if(rank == 0){ /* Coordinator */
-    int CS_used = 0;
-    while(1){
-      MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-      if(status.MPI_TAG == REQUEST_TAG){
-        if(CS_used){
-          printf("CS already used.\n");
-          xbt_dynar_push(requests, &recv_buff);
-        }else{
-          if(recv_buff != size - 1){
-            printf("CS idle. Grant immediately.\n");
-            MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD);
-            CS_used = 1;
-          }
-        }
-      }else{
-        if(!xbt_dynar_is_empty(requests)){
-          printf("CS release. Grant to queued requests (queue size: %lu)", xbt_dynar_length(requests));
-          xbt_dynar_shift(requests, &recv_buff);
-          if(recv_buff != size - 1){
-            MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD);
-            CS_used = 1;
-          }else{
-            xbt_dynar_push(requests, &recv_buff);
-            CS_used = 0;
-          }
-        }else{
-          printf("CS release. Resource now idle.\n");
-          CS_used = 0;
-        }
-      }
-    }
-  }else{ /* Client */
-    while(1){
-      printf("%d asks the request.\n", rank);
-      MPI_Send(&rank, 1, MPI_INT, 0, REQUEST_TAG, MPI_COMM_WORLD);
-      if(rank == size - 1){
-        r = 1;
-        cs = 0;
-      }
-      MPI_Recv(&recv_buff, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-      if(status.MPI_TAG == GRANT_TAG && rank == size - 1){
-        cs = 1;
-        r = 0;
-      }
-      printf("%d got the answer. Release it.\n", rank);
-      MPI_Send(&rank, 1, MPI_INT, 0, RELEASE_TAG, MPI_COMM_WORLD);
-      if(rank == size - 1){
-        r = 0;
-        cs = 0;
-      }
-    }
-  }
-
-  MPI_Finalize();
-
-  return 0;
-}
diff --git a/examples/smpi/mc/hostfile_bugged1_liveness b/examples/smpi/mc/hostfile_bugged1_liveness
deleted file mode 100644 (file)
index edbbeb8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-node-1.simgrid.org
-node-2.simgrid.org
-node-3.simgrid.org
diff --git a/examples/smpi/mc/hostfile_non_termination b/examples/smpi/mc/hostfile_non_termination
deleted file mode 100644 (file)
index c1627f2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-node-1.simgrid.org
-node-2.simgrid.org
\ No newline at end of file
index 0fb0a75..235860c 100644 (file)
@@ -27,8 +27,6 @@ int main(int argc, char **argv){
     exit(1);
   }
 
-  MC_ignore(&status.count, sizeof status.count);
-
   /* Get number of processes */
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   /* Get id of this process */
diff --git a/examples/smpi/mc/non_termination1.c b/examples/smpi/mc/non_termination1.c
deleted file mode 100644 (file)
index a0ce7dd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2015-2023. 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 <stdio.h>
-#include <mpi.h>
-#include <simgrid/modelchecker.h>
-
-int x = 5;
-int y = 8;
-
-int main(int argc, char **argv) {
-  int recv_buff;
-  int size;
-  int rank;
-  MPI_Status status;
-
-  MPI_Init(&argc, &argv);
-
-  MPI_Comm_size(MPI_COMM_WORLD, &size);   /* Get nr of tasks */
-  MPI_Comm_rank(MPI_COMM_WORLD, &rank);   /* Get id of this process */
-
-  MC_ignore(&status.count, sizeof status.count);
-
-  if (rank == 0) {
-    while (1) {
-      MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-    }
-  } else {
-    while (1) {
-      int old_x = x;
-      x = -y;
-      y = old_x;
-      printf("x = %d, y = %d\n", x, y);
-      MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-    }
-  }
-
-  MPI_Finalize();
-
-  return 0;
-}
diff --git a/examples/smpi/mc/non_termination2.c b/examples/smpi/mc/non_termination2.c
deleted file mode 100644 (file)
index 5ccafb6..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2015-2023. 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 <stdio.h>
-#include <mpi.h>
-#include <simgrid/modelchecker.h>
-
-int x;
-
-int main(int argc, char **argv) {
-  int recv_buff;
-  int size;
-  int rank;
-  MPI_Status status;
-
-  MPI_Init(&argc, &argv);
-
-  MPI_Comm_size(MPI_COMM_WORLD, &size);   /* Get nr of tasks */
-  MPI_Comm_rank(MPI_COMM_WORLD, &rank);   /* Get id of this process */
-
-  MC_ignore(&status.count, sizeof status.count);
-
-  if (rank == 0) {
-    while (1) {
-      MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-    }
-  } else {
-    while (1) {
-      x = 2;
-      MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-    }
-  }
-
-  MPI_Finalize();
-
-  return 0;
-}
diff --git a/examples/smpi/mc/non_termination3.c b/examples/smpi/mc/non_termination3.c
deleted file mode 100644 (file)
index 309f4d4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2015-2023. 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 <stdio.h>
-#include <mpi.h>
-#include <simgrid/modelchecker.h>
-
-int x = 0;
-int y = 0;
-
-int main(int argc, char **argv) {
-  int recv_x;
-  int recv_y;
-  int size;
-  int rank;
-  MPI_Status status;
-
-  MPI_Init(&argc, &argv);
-
-  MPI_Comm_size(MPI_COMM_WORLD, &size);   /* Get nr of tasks */
-  MPI_Comm_rank(MPI_COMM_WORLD, &rank);   /* Get id of this process */
-
-  MC_ignore(&status.count, sizeof status.count);
-
-  if (rank == 0) {
-    while (x<5) {
-      MPI_Recv(&recv_x, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-      MPI_Recv(&recv_y, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-    }
-  } else {
-    while (x<5) {
-      int old_x = x;
-      x = old_x - y;
-      MPI_Send(&x, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-      y = old_x + y;
-      MPI_Send(&y, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-    }
-  }
-
-  MPI_Finalize();
-
-  return 0;
-}
diff --git a/examples/smpi/mc/non_termination4.c b/examples/smpi/mc/non_termination4.c
deleted file mode 100644 (file)
index 7facb28..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2015-2023. 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 <stdio.h>
-#include <mpi.h>
-#include <simgrid/modelchecker.h>
-
-int x = 20;
-
-int main(int argc, char **argv) {
-  int recv_x = 1;
-  int size;
-  int rank;
-  MPI_Status status;
-
-  MPI_Init(&argc, &argv);
-
-  MPI_Comm_size(MPI_COMM_WORLD, &size);   /* Get nr of tasks */
-  MPI_Comm_rank(MPI_COMM_WORLD, &rank);   /* Get id of this process */
-
-  MC_ignore(&status.count, sizeof status.count);
-
-  if(rank==0){
-    while (recv_x>=0) {
-      MPI_Recv(&recv_x, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-    }
-  }else{
-    while (x >= 0) {
-      if (MC_random(0,1) == 0) {
-        x -= 1;
-      } else {
-        x += 1;
-      }
-      printf("x=%d\n", x);
-      MPI_Send(&x, 1, MPI_INT, 0, 42, MPI_COMM_WORLD);
-    }
-  }
-
-  MPI_Finalize();
-
-  return 0;
-}
diff --git a/examples/smpi/mc/promela_bugged1_liveness b/examples/smpi/mc/promela_bugged1_liveness
deleted file mode 100644 (file)
index 96b491d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-never { /* !G(r->Fcs) */
-T0_init :    /* init */
-       if
-       :: (1) -> goto T0_init
-       :: (!cs && r) -> goto accept_S2
-       fi;
-accept_S2 :    /* 1 */
-       if
-       :: (!cs) -> goto accept_S2
-       fi;
-}
index 98811c2..a3d8681 100644 (file)
@@ -5,16 +5,13 @@ find_package(Threads REQUIRED)
 #########################################################################
 
 foreach(x
-        mutex-simple
+        mutex-simple mutex-recursive
        producer-consumer)
 
   if("${CMAKE_SYSTEM}" MATCHES "Linux")
     add_executable       (pthread-${x} EXCLUDE_FROM_ALL pthread-${x}.c)
     set_target_properties(pthread-${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
     target_link_libraries(pthread-${x} PRIVATE Threads::Threads)
-    if(SIMGRID_HAVE_STATEFUL_MC) # Only needed to introspect the binary
-      target_link_libraries(pthread-${x} PUBLIC "-Wl,-znorelro -Wl,-znoseparate-code") # TODO: convert to target_link_option once CMAKE_VERSION is >3.13
-    endif()
 
     add_dependencies(tests pthread-${x})
     ADD_TESH_FACTORIES(pthread-${x} "^thread" --setenv libdir=${CMAKE_BINARY_DIR}/lib --cd ${CMAKE_BINARY_DIR}/examples/sthread ${CMAKE_CURRENT_SOURCE_DIR}/pthread-${x}.tesh)
@@ -42,9 +39,6 @@ foreach(x
     add_executable       (pthread-${x} EXCLUDE_FROM_ALL pthread-${x}.c)
     set_target_properties(pthread-${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
     target_link_libraries(pthread-${x} PRIVATE Threads::Threads)
-    if(SIMGRID_HAVE_STATEFUL_MC) # Only needed to introspect the binary
-      target_link_libraries(pthread-${x} PUBLIC "-Wl,-znorelro -Wl,-znoseparate-code") # TODO: convert to target_link_option once CMAKE_VERSION is >3.13
-    endif()
 
     if(SIMGRID_HAVE_MC)
       add_dependencies(tests-mc pthread-${x})
@@ -67,9 +61,6 @@ foreach(example
     add_executable       (${example} EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.cpp)
     set_target_properties(${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
     target_link_libraries(${example} PRIVATE Threads::Threads)
-    if(SIMGRID_HAVE_STATEFUL_MC) # Only needed to introspect the binary
-      target_link_libraries(${example} PUBLIC "-fPIC -Wl,-znorelro -Wl,-znoseparate-code") # TODO: convert to target_link_option once CMAKE_VERSION is >3.13
-    endif()
     set_target_properties(${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${example})
 
     if(SIMGRID_HAVE_MC)
diff --git a/examples/sthread/pthread-mc-mutex-recursive.tesh b/examples/sthread/pthread-mc-mutex-recursive.tesh
new file mode 100644 (file)
index 0000000..4857129
--- /dev/null
@@ -0,0 +1,14 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-recursive
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
+> Got the lock on the default mutex.
+> Failed to relock the default mutex.
+> Got the lock on the recursive mutex.
+> Got the lock again on the recursive mutex.
+> Got the lock on the default mutex.
+> Failed to relock the default mutex.
+> Got the lock on the recursive mutex.
+> Got the lock again on the recursive mutex.
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 17 unique states visited; 1 backtracks (3 transition replays, 21 states visited overall)
index 55ecc95..b352717 100644 (file)
@@ -2,8 +2,7 @@
 # We ignore the LD_PRELOAD lines from the expected output because they contain the build path
 ! ignore .*LD_PRELOAD.*
 
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsgmalloc.so:${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simple
-> [0.000000] [sthread/INFO] Starting the simulation.
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simple
 > All threads are started.
 > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
 > The thread 0 is terminating.
@@ -12,4 +11,4 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-chec
 > The thread 1 is terminating.
 > The thread 0 is terminating.
 > User's main is terminating.
-> [0.000000] [mc_dfs/INFO] DFS exploration ended. 18 unique states visited; 2 backtracks (2 transition replays, 22 states visited overall)
\ No newline at end of file
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 18 unique states visited; 2 backtracks (2 transition replays, 22 states visited overall)
index 2de4e42..8a23f34 100644 (file)
@@ -5,8 +5,7 @@
 # We ignore the LD_PRELOAD lines from the expected output because they contain the build path
 ! ignore .*LD_PRELOAD.*
 
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsgmalloc.so:${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simpledeadlock
-> [0.000000] [sthread/INFO] Starting the simulation.
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simpledeadlock
 > All threads are started.
 > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
 > The thread 0 is terminating.
index a9f5a72..508d8da 100644 (file)
@@ -1,19 +1,16 @@
 # We ignore the LD_PRELOAD lines from the expected output because they contain the build path
 ! ignore .*LD_PRELOAD.*
 
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsgmalloc.so:${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q  -C 1 -P 1
-> [0.000000] [sthread/INFO] Starting the simulation.
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q  -C 1 -P 1
 > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
 > [0.000000] [mc_dfs/INFO] DFS exploration ended. 786 unique states visited; 97 backtracks (2049 transition replays, 2932 states visited overall)
 
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:sdpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsgmalloc.so:${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q  -C 1 -P 1
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:sdpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q  -C 1 -P 1
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'sdpor'
-> [0.000000] [sthread/INFO] Starting the simulation.
 > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: sdpor.
 > [0.000000] [mc_dfs/INFO] DFS exploration ended. 1186 unique states visited; 157 backtracks (3403 transition replays, 4746 states visited overall)
 
-$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsgmalloc.so:${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q  -C 1 -P 1
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q  -C 1 -P 1
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
-> [0.000000] [sthread/INFO] Starting the simulation.
 > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
 > [0.000000] [mc_dfs/INFO] DFS exploration ended. 39 unique states visited; 0 backtracks (0 transition replays, 39 states visited overall)
diff --git a/examples/sthread/pthread-mutex-recursive.c b/examples/sthread/pthread-mutex-recursive.c
new file mode 100644 (file)
index 0000000..482cf3e
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (c) 2002-2023. 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. */
+
+/* Code with both recursive and non-recursive mutexes */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// Structure to hold the mutex's name and pointer to the actual mutex
+typedef struct {
+  const char* name;
+  pthread_mutex_t* mutex;
+} ThreadData;
+
+static void* thread_function(void* arg)
+{
+  ThreadData* data       = (ThreadData*)arg;
+  pthread_mutex_t* mutex = data->mutex;
+  const char* name       = data->name;
+
+  pthread_mutex_lock(mutex);
+  fprintf(stderr, "Got the lock on the %s mutex.\n", name);
+
+  // Attempt to relock the mutex - This behavior depends on the mutex type
+  if (pthread_mutex_trylock(mutex) == 0) {
+    fprintf(stderr, "Got the lock again on the %s mutex.\n", name);
+    pthread_mutex_unlock(mutex);
+  } else {
+    fprintf(stderr, "Failed to relock the %s mutex.\n", name);
+  }
+
+  pthread_mutex_unlock(mutex);
+
+  // pthread_exit(NULL); TODO: segfaulting
+  return NULL;
+}
+
+int main()
+{
+  pthread_t thread1, thread2;
+  pthread_mutex_t mutex_dflt = PTHREAD_MUTEX_INITIALIZER; // Non-recursive mutex
+
+  pthread_mutexattr_t attr;
+  pthread_mutexattr_init(&attr);
+  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+  pthread_mutex_t mutex_rec;
+  pthread_mutex_init(&mutex_rec, &attr);
+
+  ThreadData data1 = {"default", &mutex_dflt};
+  ThreadData data2 = {"recursive", &mutex_rec};
+
+  pthread_create(&thread1, NULL, thread_function, &data1);
+  pthread_create(&thread2, NULL, thread_function, &data2);
+
+  pthread_join(thread1, NULL);
+  pthread_join(thread2, NULL);
+
+  pthread_mutex_destroy(&mutex_dflt);
+  pthread_mutex_destroy(&mutex_rec);
+
+  return 0;
+}
diff --git a/examples/sthread/pthread-mutex-recursive.tesh b/examples/sthread/pthread-mutex-recursive.tesh
new file mode 100644 (file)
index 0000000..0879b2c
--- /dev/null
@@ -0,0 +1,6 @@
+$ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-mutex-recursive
+> Got the lock on the default mutex.
+> Failed to relock the default mutex.
+> Got the lock on the recursive mutex.
+> Got the lock again on the recursive mutex.
+> [0.000000] [sthread/INFO] All threads exited. Terminating the simulation.
index 1d39141..a7dea6b 100644 (file)
@@ -1,3 +1,8 @@
+/* Copyright (c) 2002-2023. 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. */
+
 /* Simple test code with no bug  */
 
 #include <pthread.h>
index 29d66a9..f4b3f3c 100644 (file)
@@ -1,5 +1,4 @@
 $ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-mutex-simple
-> [0.000000] [sthread/INFO] Starting the simulation.
 > All threads are started.
 > The thread 0 is terminating.
 > The thread 1 is terminating.
index 09be6c1..92a04a1 100644 (file)
@@ -1,3 +1,8 @@
+/* Copyright (c) 2002-2023. 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. */
+
 /* Simple test code that may deadlock:
 
    Thread 1 locks mutex1 then mutex2 while thread 2 locks in reverse order.
index a54bed0..471fbe8 100644 (file)
@@ -1,5 +1,4 @@
 $ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-producer-consumer
-> [0.000000] [sthread/INFO] Starting the simulation.
 > Producer 1: Insert Item 0 at 0
 > Producer 2: Insert Item 0 at 1
 > Consumer 1: Remove Item 0 from 0
@@ -15,7 +14,6 @@ $ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.
 > [0.000000] [sthread/INFO] All threads exited. Terminating the simulation.
 
 $ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-producer-consumer -c 2 -C 1 -p 2 -P 1
-> [0.000000] [sthread/INFO] Starting the simulation.
 > Producer 1: Insert Item 0 at 0
 > Consumer 1: Remove Item 0 from 0
 > Producer 1: Insert Item 1 at 1
index 06e49c8..246095e 100644 (file)
@@ -6,13 +6,15 @@
 std::vector<int> v = {1, 2, 3, 5, 8, 13};
 
 extern "C" {
-extern int sthread_access_begin(void* addr, const char* objname, const char* file, int line) __attribute__((weak));
-extern void sthread_access_end(void* addr, const char* objname, const char* file, int line) __attribute__((weak));
+extern int sthread_access_begin(void* addr, const char* objname, const char* file, int line, const char* func)
+    __attribute__((weak));
+extern void sthread_access_end(void* addr, const char* objname, const char* file, int line, const char* func)
+    __attribute__((weak));
 }
 
 #define STHREAD_ACCESS(obj)                                                                                            \
-  for (bool first = sthread_access_begin(static_cast<void*>(obj), #obj, __FILE__, __LINE__) || true; first;            \
-       sthread_access_end(static_cast<void*>(obj), #obj, __FILE__, __LINE__), first = false)
+  for (bool first = sthread_access_begin(static_cast<void*>(obj), #obj, __FILE__, __LINE__, __FUNCTION__) || true;     \
+       first; sthread_access_end(static_cast<void*>(obj), #obj, __FILE__, __LINE__, __FUNCTION__), first = false)
 
 static void thread_code()
 {
index 457238c..602c3f4 100644 (file)
@@ -5,7 +5,6 @@
 ! ignore .*LD_PRELOAD.*
 
 $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/stdobject "--log=root.fmt:[%11.6r]%e(%a@%h)%e%m%n" --log=no_loc
-> [   0.000000] (maestro@) Starting the simulation.
 > starting two helpers...
 > waiting for helpers to finish...
 > [   0.000000] (maestro@) Start a DFS exploration. Reduction is: dpor.
@@ -16,7 +15,7 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-c
 > v = { 1, 2, 3, 5, 8, 13, 21, 21, }; 
 > [   0.000000] (maestro@) thread 1 takes &v
 > [   0.000000] (maestro@) thread 2 takes &v
-> [   0.000000] (maestro@) Unprotected concurent access to &v: thread 1 vs thread 2 (locations hidden because of --log=no_loc).
+> [   0.000000] (maestro@) Unprotected concurent access to &v: thread 1 from 1 location vs thread 2 (locations hidden because of --log=no_loc).
 > [   0.000000] (maestro@) **************************
 > [   0.000000] (maestro@) *** PROPERTY NOT VALID ***
 > [   0.000000] (maestro@) **************************
index ffa04c1..67afd1a 100644 (file)
@@ -1,5 +1,4 @@
 $ ./sthread-mutex-simple
-> [0.000000] [sthread/INFO] Starting the simulation.
 > All threads are started.
 > The thread 0 is terminating.
 > The thread 1 is terminating.
index bb4f27e..6ef3fd7 100644 (file)
@@ -13,8 +13,6 @@
 #cmakedefine01 SIMGRID_HAVE_MALLOCATOR
 /* Was the model-checking compiled in? */
 #cmakedefine01 SIMGRID_HAVE_MC
-/* Was the stateful model-checking compiled in? */
-#cmakedefine01 SIMGRID_HAVE_STATEFUL_MC
 /* Was the ns-3 support compiled in? */
 #cmakedefine01 SIMGRID_HAVE_NS3
 #cmakedefine NS3_MINOR_VERSION @NS3_MINOR_VERSION@
index 2c1da4f..ec54ec4 100644 (file)
@@ -76,6 +76,14 @@ class SplitDuplexLink;
 
 class Mailbox;
 
+class Mess;
+/** Smart pointer to a simgrid::s4u::Mess */
+using MessPtr = boost::intrusive_ptr<Mess>;
+XBT_PUBLIC void intrusive_ptr_release(Mess* c);
+XBT_PUBLIC void intrusive_ptr_add_ref(Mess* c);
+
+class MessageQueue;
+
 class Mutex;
 XBT_PUBLIC void intrusive_ptr_release(const Mutex* m);
 XBT_PUBLIC void intrusive_ptr_add_ref(const Mutex* m);
@@ -123,6 +131,7 @@ using ActorCodeFactory = std::function<ActorCode(std::vector<std::string> args)>
 
 class Simcall;
 class SimcallObserver;
+class MutexObserver;
 class ObjectAccessSimcallObserver;
 class ObjectAccessSimcallItem;
 } // namespace actor
@@ -152,6 +161,8 @@ namespace activity {
   using ExecImplPtr = boost::intrusive_ptr<ExecImpl>;
   class IoImpl;
   using IoImplPtr = boost::intrusive_ptr<IoImpl>;
+  class MessImpl;
+  using MessImplPtr = boost::intrusive_ptr<MessImpl>;
   class MutexImpl;
   using MutexImplPtr = boost::intrusive_ptr<MutexImpl>;
   class MutexAcquisitionImpl;
@@ -170,6 +181,7 @@ namespace activity {
   using SleepImplPtr = boost::intrusive_ptr<SleepImpl>;
 
   class MailboxImpl;
+  class MessageQueueImpl;
 }
 namespace context {
 class Context;
@@ -232,6 +244,7 @@ using s4u_Link              = simgrid::s4u::Link;
 using s4u_File              = simgrid::s4u::File;
 using s4u_ConditionVariable = simgrid::s4u::ConditionVariable;
 using s4u_Mailbox           = simgrid::s4u::Mailbox;
+using s4u_MessageQueue      = simgrid::s4u::MessageQueue;
 using s4u_Mutex             = simgrid::s4u::Mutex;
 using s4u_Semaphore         = simgrid::s4u::Semaphore;
 using s4u_Disk              = simgrid::s4u::Disk;
@@ -252,6 +265,7 @@ typedef struct s4u_Link s4u_Link;
 typedef struct s4u_File s4u_File;
 typedef struct s4u_ConditionVariable s4u_ConditionVariable;
 typedef struct s4u_Mailbox s4u_Mailbox;
+typedef struct s4u_MessageQueue s4u_MessageQueue;
 typedef struct s4u_Mutex s4u_Mutex;
 typedef struct s4u_Semaphore s4u_Semaphore;
 typedef struct s4u_Disk s4u_Disk;
@@ -271,6 +285,8 @@ typedef s4u_ConditionVariable* sg_cond_t;
 typedef const s4u_ConditionVariable* const_sg_cond_t;
 typedef s4u_Mailbox* sg_mailbox_t;
 typedef const s4u_Mailbox* const_sg_mailbox_t;
+typedef s4u_MessageQueue* sg_messagequeue_t;
+typedef const s4u_MessageQueue* const_sg_messagequeue_t;
 typedef s4u_Mutex* sg_mutex_t;
 typedef const s4u_Mutex* const_sg_mutex_t;
 typedef s4u_Semaphore* sg_sem_t;
index 2c308dd..09566a3 100644 (file)
@@ -23,13 +23,6 @@ XBT_PUBLIC void MC_assert(int);
  *  It is off in simulation or when replaying MC traces (see MC_record_replay_is_active()) */
 XBT_PUBLIC int MC_is_active();
 
-XBT_PUBLIC void MC_automaton_new_propositional_symbol_pointer(const char* id, int* value);
-
-XBT_PUBLIC void MC_ignore(void* addr, size_t size);
-XBT_PUBLIC void MC_unignore(void* addr, size_t size);
-XBT_PUBLIC void MC_ignore_heap(void* address, size_t size);
-XBT_PUBLIC void MC_unignore_heap(void* address, size_t size);
-
 SG_END_DECL
 
 #endif /* SIMGRID_MODELCHECKER_H */
index 7f0c361..058428b 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef SIMGRID_PLUGINS_BATTERY_HPP_
 #define SIMGRID_PLUGINS_BATTERY_HPP_
 
+#include <cmath>
 #include <memory>
 #include <simgrid/kernel/resource/Model.hpp>
 #include <simgrid/s4u/Activity.hpp>
@@ -87,23 +88,24 @@ private:
   static std::shared_ptr<BatteryModel> battery_model_;
 
   std::string name_;
-  double nominal_charge_power_w_;
-  double nominal_discharge_power_w_;
-  double charge_efficiency_;
-  double discharge_efficiency_;
-  double initial_capacity_wh_;
-  double energy_budget_j_;
-
-  std::map<const s4u::Host*, bool> host_loads_     = {};
-  std::map<const std::string, double> named_loads_ = {};
+  double nominal_charge_power_w_    = -INFINITY;
+  double nominal_discharge_power_w_ = INFINITY;
+  double charge_efficiency_         = 1;
+  double discharge_efficiency_      = 1;
+  double initial_capacity_wh_       = 0;
+  double energy_budget_j_           = 0;
+
+  std::map<const s4u::Host*, bool> host_loads_                      = {};
+  std::map<const std::string, std::pair<bool, double>> named_loads_ = {};
   std::vector<std::shared_ptr<Handler>> handlers_;
 
-  double capacity_wh_;
-  double energy_stored_j_;
+  double capacity_wh_       = 0;
+  double energy_stored_j_   = 0;
   double energy_provided_j_ = 0;
   double energy_consumed_j_ = 0;
   double last_updated_      = 0;
 
+  explicit Battery();
   explicit Battery(const std::string& name, double state_of_charge, double nominal_charge_power_w,
                    double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency,
                    double initial_capacity_wh, int cycles);
@@ -124,10 +126,12 @@ private:
 #endif
 
 public:
+  static BatteryPtr init();
   static BatteryPtr init(const std::string& name, double state_of_charge, double nominal_charge_power_w,
                          double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency,
                          double initial_capacity_wh, int cycles);
   void set_load(const std::string& name, double power_w);
+  void set_load(const std::string& name, bool active);
   void connect_host(s4u::Host* host, bool active = true);
   double get_state_of_charge();
   double get_state_of_health();
index b60e03d..8f9611b 100644 (file)
@@ -68,6 +68,9 @@ private:
   friend void intrusive_ptr_add_ref(Chiller* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); }
 #endif
 
+  inline static xbt::signal<void(Chiller*)> on_power_change;
+  xbt::signal<void(Chiller*)> on_this_power_change;
+
 public:
   static ChillerPtr init(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha,
                          double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w);
@@ -93,9 +96,9 @@ public:
   double get_max_power() { return max_power_w_; }
   bool is_active() { return active_; }
   double get_temp_in() { return temp_in_c_; }
-  double get_temp_out() { return temp_out_c_; }
   double get_power() { return power_w_; }
   double get_energy_consumed() { return energy_consumed_j_; }
+  double get_time_to_goal_temp();
 };
 
 } // namespace simgrid::plugins
index b9097b4..0ba319c 100644 (file)
@@ -16,37 +16,18 @@ using SolarPanelPtr = boost::intrusive_ptr<SolarPanel>;
 XBT_PUBLIC void intrusive_ptr_release(SolarPanel* o);
 XBT_PUBLIC void intrusive_ptr_add_ref(SolarPanel* o);
 
-class SolarPanelModel : public kernel::resource::Model {
-  std::vector<SolarPanelPtr> solar_panels_;
-
-public:
-  explicit SolarPanelModel();
-
-  void add_solar_panel(SolarPanelPtr b);
-  void update_actions_state(double now, double delta) override;
-  double next_occurring_event(double now) override;
-};
-
 class SolarPanel {
 
-  friend SolarPanelModel;
-
-private:
-  static std::shared_ptr<SolarPanelModel> solar_panel_model_;
-
   std::string name_;
   double area_m2_;
   double conversion_efficiency_;
   double solar_irradiance_w_per_m2_;
   double min_power_w_;
   double max_power_w_;
-
-  double power_w_      = 0;
-  double last_updated_ = 0;
+  double power_w_ = -1;
 
   explicit SolarPanel(std::string name, double area_m2, double conversion_efficiency, double solar_irradiance_w_per_m2,
                       double min_power_w, double max_power_w);
-  static void init_plugin();
   void update();
 
   std::atomic_int_fast32_t refcount_{0};
@@ -61,6 +42,9 @@ private:
   friend void intrusive_ptr_add_ref(SolarPanel* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); }
 #endif
 
+  static xbt::signal<void(SolarPanel*)> on_power_change;
+  xbt::signal<void(SolarPanel*)> on_this_power_change;
+
 public:
   static SolarPanelPtr init(const std::string& name, double area_m2, double conversion_efficiency,
                             double solar_irradiance_w_per_m2, double min_power_w, double max_power_w);
@@ -72,14 +56,20 @@ public:
   SolarPanelPtr set_min_power(double power_w);
   SolarPanelPtr set_max_power(double power_w);
 
-  std::string get_name() { return name_; }
-  const char* get_cname() { return name_.c_str(); }
-  double get_area() { return area_m2_; }
-  double get_conversion_efficiency() { return conversion_efficiency_; }
-  double get_solar_irradiance() { return solar_irradiance_w_per_m2_; }
-  double get_min_power() { return min_power_w_; }
-  double get_max_power() { return max_power_w_; }
-  double get_power() { return power_w_; }
+  std::string get_name() const { return name_; }
+  const char* get_cname() const { return name_.c_str(); }
+  double get_area() const { return area_m2_; }
+  double get_conversion_efficiency() const { return conversion_efficiency_; }
+  double get_solar_irradiance() const { return solar_irradiance_w_per_m2_; }
+  double get_min_power() const { return min_power_w_; }
+  double get_max_power() const { return max_power_w_; }
+  double get_power() const { return power_w_; }
+
+  /** Add a callback fired after this solar panel power changed. */
+  void on_this_power_change_cb(const std::function<void(SolarPanel*)>& func) { on_this_power_change.connect(func); };
+  /** Add a callback fired after a solar panel power changed.
+   * Triggered after the on_this_power_change function.**/
+  static void on_power_change_cb(const std::function<void(SolarPanel*)>& cb) { on_power_change.connect(cb); }
 };
 } // namespace simgrid::plugins
 #endif
index b285322..8ddbf1a 100644 (file)
@@ -19,6 +19,8 @@
 #include <simgrid/s4u/Host.hpp>
 #include <simgrid/s4u/Link.hpp>
 #include <simgrid/s4u/Mailbox.hpp>
+#include <simgrid/s4u/Mess.hpp>
+#include <simgrid/s4u/MessageQueue.hpp>
 #include <simgrid/s4u/Mutex.hpp>
 #include <simgrid/s4u/NetZone.hpp>
 #include <simgrid/s4u/Semaphore.hpp>
index ef51321..8b9f485 100644 (file)
@@ -38,6 +38,7 @@ class XBT_PUBLIC Activity : public xbt::Extendable<Activity> {
   friend Comm;
   friend Exec;
   friend Io;
+  friend Mess;
   friend kernel::activity::ActivityImpl;
   friend std::vector<ActivityPtr> create_DAG_from_dot(const std::string& filename);
   friend std::vector<ActivityPtr> create_DAG_from_DAX(const std::string& filename);
index d92987d..fbef8cc 100644 (file)
@@ -155,6 +155,7 @@ public:
   Link* link_by_name_or_null(const std::string& name) const;
 
   Mailbox* mailbox_by_name_or_create(const std::string& name) const;
+  MessageQueue* message_queue_by_name_or_create(const std::string& name) const;
 
   size_t get_actor_count() const;
   std::vector<ActorPtr> get_all_actors() const;
diff --git a/include/simgrid/s4u/Mess.hpp b/include/simgrid/s4u/Mess.hpp
new file mode 100644 (file)
index 0000000..81dcee9
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (c) 2023. 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 SIMGRID_S4U_MESS_HPP
+#define SIMGRID_S4U_MESS_HPP
+
+#include <simgrid/forward.h>
+#include <simgrid/s4u/Activity.hpp>
+
+#include <string>
+#include <vector>
+
+namespace simgrid::s4u {
+
+class XBT_PUBLIC Mess : public Activity_T<Mess> {
+#ifndef DOXYGEN
+  friend MessageQueue; // Factory of messages
+  friend kernel::activity::MessImpl;
+#endif
+  MessageQueue* queue_  = nullptr;
+  void* payload_        = nullptr;
+  size_t dst_buff_size_ = 0;
+  void* dst_buff_       = nullptr;
+
+  Mess() = default;
+  Mess* do_start() override;
+
+  static xbt::signal<void(Mess const&)> on_send;
+  xbt::signal<void(Mess const&)> on_this_send;
+  static xbt::signal<void(Mess const&)> on_recv;
+  xbt::signal<void(Mess const&)> on_this_recv;
+
+  /* These ensure that the on_completion signals are really thrown */
+  void fire_on_completion_for_real() const { Activity_T<Mess>::fire_on_completion(); }
+  void fire_on_this_completion_for_real() const { Activity_T<Mess>::fire_on_this_completion(); }
+
+public:
+#ifndef DOXYGEN
+  Mess(Mess const&) = delete;
+  Mess& operator=(Mess const&) = delete;
+#endif
+
+  MessPtr set_queue(MessageQueue* queue);
+  MessageQueue* get_queue() const { return queue_; }
+
+  /** Retrieve the payload associated to the communication. You can only do that once the comm is (gracefully)
+   * terminated */
+  void* get_payload() const { return payload_; }
+  MessPtr set_payload(void* data);
+  MessPtr set_dst_data(void** buff, size_t size);
+  Actor* get_sender() const;
+  Actor* get_receiver() const;
+
+  bool is_assigned() const override { return true; };
+
+  Mess* wait_for(double timeout) override;
+
+  kernel::actor::ActorImpl* sender_   = nullptr;
+  kernel::actor::ActorImpl* receiver_ = nullptr;
+};
+} // namespace simgrid::s4u
+
+#endif /* SIMGRID_S4U_MESS_HPP */
diff --git a/include/simgrid/s4u/MessageQueue.hpp b/include/simgrid/s4u/MessageQueue.hpp
new file mode 100644 (file)
index 0000000..dc00941
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright (c) 2023. 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 SIMGRID_S4U_MESSAGEQUEUE_HPP
+#define SIMGRID_S4U_MESSAGEQUEUE_HPP
+
+#include <simgrid/forward.h>
+#include <simgrid/s4u/Mess.hpp>
+#include <smpi/forward.hpp>
+
+#include <string>
+
+namespace simgrid::s4u {
+
+class XBT_PUBLIC MessageQueue {
+#ifndef DOXYGEN
+  friend Mess;
+  friend kernel::activity::MessageQueueImpl;
+#endif
+
+  kernel::activity::MessageQueueImpl* const pimpl_;
+
+  explicit MessageQueue(kernel::activity::MessageQueueImpl * mqueue) : pimpl_(mqueue) {}
+  ~MessageQueue() = default;
+
+protected:
+  kernel::activity::MessageQueueImpl* get_impl() const { return pimpl_; }
+
+public:
+  /** @brief Retrieves the name of that message queue as a C++ string */
+  const std::string& get_name() const;
+  /** @brief Retrieves the name of that message queue as a C string */
+  const char* get_cname() const;
+
+  /** \static Retrieve the message queye associated to the given name. Message queues are created on demand. */
+  static MessageQueue* by_name(const std::string& name);
+
+  /** Returns whether the message queue contains queued messages */
+  bool empty() const;
+
+  /* Returns the number of queued messages */
+  size_t size() const;
+
+  /** Gets the first element in the queue (without dequeuing it), or nullptr if none is there */
+  kernel::activity::MessImplPtr front() const;
+
+  /** Creates (but don't start) a data transmission to that message queue */
+  MessPtr put_init();
+  /** Creates (but don't start) a data transmission to that message queue.
+   *
+   * Please note that if you send a pointer to some data, you must ensure that your data remains live until
+   * consumption, or the receiver will get a pointer to a garbled memory area.
+   */
+  MessPtr put_init(void* payload);
+  /** Creates and start a data transmission to that mailbox.
+   *
+   * Please note that if you send a pointer to some data, you must ensure that your data remains live until
+   * consumption, or the receiver will get a pointer to a garbled memory area.
+   */
+  MessPtr put_async(void* payload);
+
+  /** Blocking data transmission.
+   *
+   * Please note that if you send a pointer to some data, you must ensure that your data remains live until
+   * consumption, or the receiver will get a pointer to a garbled memory area.
+   */
+  void put(void* payload);
+  /** Blocking data transmission with timeout */
+  void put(void* payload, double timeout);
+
+  /** Creates (but don't start) a data reception onto that message queue. */
+  MessPtr get_init();
+  /** Creates and start an async data reception to that message queue */
+  template <typename T> MessPtr get_async(T** data);
+  /** Creates and start an async data reception to that mailbox. Since the data location is not provided, you'll have to
+   * use Mess::get_payload once the messaging operation terminates */
+  MessPtr get_async();
+
+  /** Blocking data reception */
+  template <typename T> T* get();
+  template <typename T> std::unique_ptr<T> get_unique() { return std::unique_ptr<T>(get<T>()); }
+
+  /** Blocking data reception with timeout */
+  template <typename T> T* get(double timeout);
+  template <typename T> std::unique_ptr<T> get_unique(double timeout) { return std::unique_ptr<T>(get<T>(timeout)); }
+};
+
+template <typename T> MessPtr MessageQueue::get_async(T** data)
+{
+  MessPtr res = get_init()->set_dst_data(reinterpret_cast<void**>(data), sizeof(void*));
+  res->start();
+  return res;
+}
+
+template <typename T> T* MessageQueue::get()
+{
+  T* res = nullptr;
+  get_async<T>(&res)->wait();
+  return res;
+}
+
+template <typename T> T* MessageQueue::get(double timeout)
+{
+  T* res = nullptr;
+  get_async<T>(&res)->wait_for(timeout);
+  return res;
+}
+} // namespace simgrid::s4u
+
+#endif /* SIMGRID_S4U_MESSAGEQUEUE_HPP */
index 7791cd7..06f04c2 100644 (file)
@@ -12,6 +12,8 @@
 namespace simgrid::s4u {
 
 /** @brief A classical mutex, but blocking in the simulation world.
+ *
+ * S4U mutexes are not recursive. If an actor tries to lock the same object twice, it deadlocks with itself.
  *
  * @beginrst
  * It is strictly impossible to use a real mutex, such as
@@ -48,7 +50,8 @@ class XBT_PUBLIC Mutex {
 
 public:
   /** \static Constructs a new mutex */
-  static MutexPtr create();
+  static MutexPtr create(bool recursive = false);
+
   void lock();
   void unlock();
   bool try_lock();
index 453a6ef..84cd4ce 100644 (file)
@@ -1123,7 +1123,16 @@ MPI_CALL(XBT_PUBLIC int, MPI_Ineighbor_alltoallw,
           const MPI_Aint* recvdisps, const MPI_Datatype* recvtypes, MPI_Comm comm, MPI_Request *request));
 MPI_CALL(XBT_PUBLIC int, MPI_Status_f2c, (MPI_Fint *f_status, MPI_Status *c_status));
 MPI_CALL(XBT_PUBLIC int, MPI_Status_c2f, (MPI_Status *c_status, MPI_Fint *f_status));
-
+MPI_CALL(XBT_PUBLIC int, MPI_Parrived, (MPI_Request request, int partition, int *flag));
+MPI_CALL(XBT_PUBLIC int, MPI_Pready, (int partitions, MPI_Request request));
+MPI_CALL(XBT_PUBLIC int, MPI_Pready_range, (int partition_low, int partition_high, MPI_Request request));
+MPI_CALL(XBT_PUBLIC int, MPI_Pready_list, (int length, int partition_list[], MPI_Request request));
+MPI_CALL(XBT_PUBLIC int, MPI_Precv_init, (void* buf, int partitions, MPI_Count count,
+                                  MPI_Datatype datatype, int source, int tag, MPI_Comm comm,
+                                  MPI_Info info, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Psend_init, (const void* buf, int partitions, MPI_Count count,
+                                  MPI_Datatype datatype, int dest, int tag, MPI_Comm comm,
+                                  MPI_Info info, MPI_Request *request));
 
 
 //FIXME: End of all the not yet implemented stuff
index aa3d055..1e1fefb 100644 (file)
 #define MPI_Ineighbor_alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ineighbor_alltoallw"), MPI_Ineighbor_alltoallw(__VA_ARGS__))
 #define MPI_Status_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_f2c"), MPI_Status_f2c(__VA_ARGS__))
 #define MPI_Status_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_c2f"), MPI_Status_c2f(__VA_ARGS__))
+#define MPI_Parrived(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Parrived"), MPI_Parrived(__VA_ARGS__))
+#define MPI_Pready(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pready"), MPI_Pready(__VA_ARGS__))
+#define MPI_Pready_range(...)                                                                                          \
+  (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pready_range"), MPI_Pready_range(__VA_ARGS__))
+#define MPI_Pready_list(...)                                                                                           \
+  (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pready_list"), MPI_Pready_list(__VA_ARGS__))
+#define MPI_Precv_init(...)                                                                                            \
+  (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Precv_init"), MPI_Precv_init(__VA_ARGS__))
+#define MPI_Psend_init(...)                                                                                            \
+  (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Psend_init"), MPI_Psend_init(__VA_ARGS__))
index be47ad1..4684b6b 100644 (file)
 #define MPI_STATUS_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_F2C"); call MPI_Status_f2c
 #define mpi_status_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_status_c2f"); call MPI_Status_c2f
 #define MPI_STATUS_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_C2F"); call MPI_Status_c2f
+#define mpi_parrived                                                                                                   \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "mpi_parrived");                                                    \
+  call MPI_Parrived
+#define MPI_PARRIVED                                                                                                   \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_PARRIVED");                                                    \
+  call MPI_Parrived
+#define mpi_pready                                                                                                     \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "mpi_pready");                                                      \
+  call MPI_Pready
+#define MPI_PREADY                                                                                                     \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_PREADY");                                                      \
+  call MPI_Pready
+#define mpi_pready_range                                                                                               \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "mpi_pready_range");                                                \
+  call MPI_Pready_range
+#define MPI_PREADY_RANGE                                                                                               \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_PREADY_RANGE");                                                \
+  call MPI_Pready_range
+#define mpi_pready_list                                                                                                \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "mpi_pready_list");                                                 \
+  call MPI_Pready_list
+#define MPI_PREADY_LIST                                                                                                \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_PREADY_LIST");                                                 \
+  call MPI_Pready_list
+#define mpi_precv_init                                                                                                 \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "mpi_precv_init");                                                  \
+  call MPI_Precv_init
+#define MPI_PRECV_INIT                                                                                                 \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_PRECV_INIT");                                                  \
+  call MPI_Precv_init
+#define mpi_psend_init                                                                                                 \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "mpi_psend_init");                                                  \
+  call MPI_Psend_init
+#define MPI_PSEND_INIT                                                                                                 \
+  smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_PSEND_INIT");                                                  \
+  call MPI_Psend_init
diff --git a/include/xbt/automaton.h b/include/xbt/automaton.h
deleted file mode 100644 (file)
index 582b2fd..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright (c) 2011-2023. 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 XBT_AUTOMATON_H
-#define XBT_AUTOMATON_H
-
-#include <xbt/dynar.h>
-
-SG_BEGIN_DECL
-
-typedef struct xbt_automaton_state {
-  char* id;
-  int type; /* -1 = init, 0 = inter, 1 = final */
-  xbt_dynar_t in;
-  xbt_dynar_t out;
-} s_xbt_automaton_state;
-
-typedef struct xbt_automaton_state* xbt_automaton_state_t;
-typedef const struct xbt_automaton_state* const_xbt_automaton_state_t;
-
-typedef struct xbt_automaton {
-  xbt_dynar_t propositional_symbols;
-  xbt_dynar_t transitions;
-  xbt_dynar_t states;
-  xbt_automaton_state_t current_state;
-} s_xbt_automaton;
-
-typedef struct xbt_automaton* xbt_automaton_t;
-typedef const struct xbt_automaton* const_xbt_automaton_t;
-
-typedef struct xbt_automaton_exp_label{
-  enum{AUT_OR=0, AUT_AND=1, AUT_NOT=2, AUT_PREDICAT=3, AUT_ONE=4} type;
-  union{
-    struct{
-      struct xbt_automaton_exp_label* left_exp;
-      struct xbt_automaton_exp_label* right_exp;
-    }or_and;
-    struct xbt_automaton_exp_label* exp_not;
-    char* predicat;
-  }u;
-} s_xbt_automaton_exp_label;
-
-typedef struct xbt_automaton_exp_label* xbt_automaton_exp_label_t;
-typedef const struct xbt_automaton_exp_label* const_xbt_automaton_exp_label_t;
-
-typedef struct xbt_automaton_transition {
-  xbt_automaton_state_t src;
-  xbt_automaton_state_t dst;
-  xbt_automaton_exp_label_t label;
-} s_xbt_automaton_transition;
-
-typedef struct xbt_automaton_transition* xbt_automaton_transition_t;
-typedef const struct xbt_automaton_transition* const_xbt_automaton_transition_t;
-
-typedef struct xbt_automaton_propositional_symbol* xbt_automaton_propositional_symbol_t;
-typedef const struct xbt_automaton_propositional_symbol* const_xbt_automaton_propositional_symbol_t;
-
-typedef int (*xbt_automaton_propositional_symbol_callback_type)(void*);
-typedef void (*xbt_automaton_propositional_symbol_free_function_type)(void*);
-
-XBT_PUBLIC xbt_automaton_t xbt_automaton_new(void);
-XBT_PUBLIC void xbt_automaton_load(xbt_automaton_t automaton, const char* file);
-XBT_PUBLIC xbt_automaton_state_t xbt_automaton_state_new(const_xbt_automaton_t a, int type, const char* id);
-XBT_PUBLIC xbt_automaton_transition_t xbt_automaton_transition_new(const_xbt_automaton_t a, xbt_automaton_state_t src,
-                                                                   xbt_automaton_state_t dst,
-                                                                   xbt_automaton_exp_label_t label);
-XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_or(xbt_automaton_exp_label_t left,
-                                                                    xbt_automaton_exp_label_t right);
-XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_and(xbt_automaton_exp_label_t left,
-                                                                     xbt_automaton_exp_label_t right);
-XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_not(xbt_automaton_exp_label_t exp_not);
-XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_predicat(const char* p);
-XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_one(void);
-XBT_PUBLIC xbt_dynar_t xbt_automaton_get_states(const_xbt_automaton_t a);
-XBT_PUBLIC xbt_dynar_t xbt_automaton_get_transitions(const_xbt_automaton_t a);
-XBT_PUBLIC xbt_automaton_transition_t xbt_automaton_get_transition(const_xbt_automaton_t a,
-                                                                   const_xbt_automaton_state_t src,
-                                                                   const_xbt_automaton_state_t dst);
-XBT_PUBLIC xbt_automaton_state_t xbt_automaton_transition_get_source(const_xbt_automaton_transition_t t);
-XBT_PUBLIC xbt_automaton_state_t xbt_automaton_transition_get_destination(const_xbt_automaton_transition_t t);
-XBT_PUBLIC void xbt_automaton_transition_set_source(xbt_automaton_transition_t t, xbt_automaton_state_t src);
-XBT_PUBLIC void xbt_automaton_transition_set_destination(xbt_automaton_transition_t t, xbt_automaton_state_t dst);
-XBT_PUBLIC xbt_dynar_t xbt_automaton_state_get_out_transitions(const_xbt_automaton_state_t s);
-XBT_PUBLIC xbt_dynar_t xbt_automaton_state_get_in_transitions(const_xbt_automaton_state_t s);
-XBT_PUBLIC xbt_automaton_state_t xbt_automaton_state_exists(const_xbt_automaton_t a, const char* id);
-XBT_PUBLIC void xbt_automaton_display(const_xbt_automaton_t a);
-XBT_PUBLIC void xbt_automaton_exp_label_display(const_xbt_automaton_exp_label_t l);
-
-// xbt_automaton_propositional_symbol constructors:
-XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new(const_xbt_automaton_t a,
-                                                                                       const char* id,
-                                                                                       int (*fct)(void));
-XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_pointer(const_xbt_automaton_t a,
-                                                                                               const char* id,
-                                                                                               int* value);
-XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_callback(
-    const_xbt_automaton_t a, const char* id, xbt_automaton_propositional_symbol_callback_type callback, void* data,
-    xbt_automaton_propositional_symbol_free_function_type free_function);
-
-// xbt_automaton_propositional_symbol accessors:
-XBT_PUBLIC xbt_automaton_propositional_symbol_callback_type
-xbt_automaton_propositional_symbol_get_callback(const_xbt_automaton_propositional_symbol_t symbol);
-XBT_PUBLIC void* xbt_automaton_propositional_symbol_get_data(const_xbt_automaton_propositional_symbol_t symbol);
-XBT_PUBLIC const char* xbt_automaton_propositional_symbol_get_name(const_xbt_automaton_propositional_symbol_t symbol);
-
-// xbt_automaton_propositional_symbol methods!
-XBT_PUBLIC int xbt_automaton_propositional_symbol_evaluate(const_xbt_automaton_propositional_symbol_t symbol);
-
-XBT_PUBLIC xbt_automaton_state_t xbt_automaton_get_current_state(const_xbt_automaton_t a);
-XBT_PUBLIC int xbt_automaton_state_compare(const_xbt_automaton_state_t s1, const_xbt_automaton_state_t s2);
-XBT_PUBLIC int xbt_automaton_propositional_symbols_compare_value(const_xbt_dynar_t s1, const_xbt_dynar_t s2);
-XBT_PUBLIC int xbt_automaton_transition_compare(const_xbt_automaton_transition_t t1,
-                                                const_xbt_automaton_transition_t t2);
-XBT_PUBLIC int xbt_automaton_exp_label_compare(const_xbt_automaton_exp_label_t l1, const_xbt_automaton_exp_label_t l2);
-XBT_PUBLIC void xbt_automaton_state_free_voidp(void* s);
-XBT_PUBLIC void xbt_automaton_state_free(xbt_automaton_state_t s);
-XBT_PUBLIC void xbt_automaton_transition_free_voidp(void* t);
-XBT_PUBLIC void xbt_automaton_exp_label_free_voidp(void* e);
-XBT_PUBLIC void xbt_automaton_propositional_symbol_free_voidp(void* ps);
-XBT_PUBLIC void xbt_automaton_free(xbt_automaton_t a);
-
-SG_END_DECL
-
-#endif
diff --git a/include/xbt/automaton.hpp b/include/xbt/automaton.hpp
deleted file mode 100644 (file)
index 18a7d6b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2015-2023. 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 XBT_AUTOMATON_HPP
-#define XBT_AUTOMATON_HPP
-
-#include <utility>
-
-#include <xbt/automaton.h>
-
-namespace simgrid::xbt {
-
-/** Add a proposition to an automaton (the C++ way)
- *
- *  This API hides all the callback and dynamic allocation hell from
- *  the used which can use C++ style functors and lambda expressions.
- */
-template <class F> xbt_automaton_propositional_symbol_t add_proposition(const_xbt_automaton_t a, const char* id, F f)
-{
-  auto* callback = new F(std::move(f));
-  return xbt_automaton_propositional_symbol_new_callback(
-      a, id, [](auto* cb) -> int { return (*(F*)cb)(); }, callback, [](auto* cb) -> void { delete (F*)cb; });
-}
-
-} // namespace simgrid::xbt
-#endif
index 03c0472..a6d28f5 100644 (file)
@@ -127,13 +127,13 @@ sonar.issue.ignore.multicriteria.s5.ruleKey=cpp:S995
 sonar.issue.ignore.multicriteria.s5.resourceKey=src/smpi/bindings/*.cpp
 
 # Exclude some files from the analysis:
-#  - the tests that we borrowed elsewhere (MPICH and MBI)
+#  - the tests that we borrowed elsewhere (MPICH, MBI, McMini)
 #  - Flex-generated files
 #  - Collectives that we borrowed elsewhere (mpich, openMPI and other implems)
 #  - the NAS, that are included in our examples
 #  - The Catch2 library, that is included in our unit tests
 #  - The xxHash library, used by the MC
-sonar.exclusions=src/3rd-party/*,teshsuite/smpi/mpich3-test/**,teshsuite/smpi/MBI/**,**/*_dtd.c,**/*_dtd.h,**/*yy.c,src/xbt/automaton/parserPromela.tab.*,src/smpi/colls/**/*,examples/smpi/NAS/*,examples/smpi/gemm/gemm.c
+sonar.exclusions=src/3rd-party/*,teshsuite/smpi/mpich3-test/**,teshsuite/smpi/MBI/**,teshsuite/mc/mcmini/**,**/*_dtd.c,**/*_dtd.h,**/*yy.c,src/smpi/colls/**/*,examples/smpi/NAS/*,examples/smpi/gemm/gemm.c
 
 # Exclude our examples from the duplication detection.
 # Examples are expected to be somehow repetitive
index 2f2ef70..53065f0 100644 (file)
@@ -750,7 +750,8 @@ PYBIND11_MODULE(simgrid, m)
   py::class_<Mutex, MutexPtr>(m, "Mutex",
                               "A classical mutex, but blocking in the simulation world."
                               "See the C++ documentation for details.")
-      .def(py::init<>(&Mutex::create), py::call_guard<py::gil_scoped_release>(), "Mutex constructor.")
+      .def(py::init<>(&Mutex::create), py::call_guard<py::gil_scoped_release>(),
+           "Mutex constructor (pass True as a parameter to get a recursive Mutex).", py::arg("recursive") = false)
       .def("lock", &Mutex::lock, py::call_guard<py::gil_scoped_release>(), "Block until the mutex is acquired.")
       .def("try_lock", &Mutex::try_lock, py::call_guard<py::gil_scoped_release>(),
            "Try to acquire the mutex. Return true if the mutex was acquired, false otherwise.")
index b2ecf6e..59761d5 100644 (file)
@@ -59,8 +59,6 @@
 #define PTH_STACKGROWTH @PTH_STACKGROWTH@
 
 /* MC variables */
-/* Did we compile mmalloc in? */
-#cmakedefine01 HAVE_MMALLOC
 /* process_vm_readv: transfer data between process address spaces */
 #cmakedefine01 HAVE_PROCESS_VM_READV
 
@@ -82,8 +80,6 @@
 /* Other function checks */
 /* Function dlfunc */
 #cmakedefine01 HAVE_DLFUNC
-/* Function mmap */
-#cmakedefine01 HAVE_MMAP
 /* Function mremap */
 #cmakedefine01 HAVE_MREMAP
 /* Function vasprintf */
index 9fa412e..8b7b60a 100644 (file)
@@ -155,6 +155,9 @@ EngineImpl::~EngineImpl()
   for (auto const& [_, mailbox] : mailboxes_)
     delete mailbox;
 
+  for (auto const& [_, queue] : mqueues_)
+    delete queue;
+
   /* Kill all actors (but maestro) */
   maestro_->kill_all();
   run_all_actors();
@@ -453,6 +456,9 @@ void EngineImpl::display_all_actor_status() const
       if (boost::dynamic_pointer_cast<kernel::activity::CommImpl>(actor->waiting_synchro_) != nullptr)
         synchro_description = "communication";
 
+      if (boost::dynamic_pointer_cast<kernel::activity::MessImpl>(actor->waiting_synchro_) != nullptr)
+        synchro_description = "message";
+
       if (boost::dynamic_pointer_cast<kernel::activity::SleepImpl>(actor->waiting_synchro_) != nullptr)
         synchro_description = "sleeping";
 
index 4c25e54..149c0c2 100644 (file)
@@ -16,6 +16,7 @@
 #include "src/kernel/activity/ExecImpl.hpp"
 #include "src/kernel/activity/IoImpl.hpp"
 #include "src/kernel/activity/MailboxImpl.hpp"
+#include "src/kernel/activity/MessageQueueImpl.hpp"
 #include "src/kernel/activity/SleepImpl.hpp"
 #include "src/kernel/activity/Synchro.hpp"
 #include "src/kernel/actor/ActorImpl.hpp"
@@ -33,6 +34,7 @@ namespace simgrid::kernel {
 class EngineImpl {
   std::unordered_map<std::string, routing::NetPoint*> netpoints_;
   std::unordered_map<std::string, activity::MailboxImpl*> mailboxes_;
+  std::unordered_map<std::string, activity::MessageQueueImpl*> mqueues_;
 
   std::unordered_map<std::string, actor::ActorCodeFactory> registered_functions; // Maps function names to actor code
   actor::ActorCodeFactory default_function; // Function to use as a fallback when the provided name matches nothing
index 25a7661..72f114d 100644 (file)
@@ -23,17 +23,6 @@ namespace simgrid::kernel::activity {
 
 unsigned CommImpl::next_id_ = 0;
 
-/* In stateful MC, we need to ignore some private memory that is not relevant to the application state */
-void CommImpl::setup_mc()
-{
-  MC_ignore(&CommImpl::next_id_, sizeof(CommImpl::next_id_));
-}
-
-CommImpl::CommImpl()
-{
-  MC_ignore((void*)&id_, sizeof(id_));
-}
-
 std::function<void(CommImpl*, void*, size_t)> CommImpl::copy_data_callback_ = [](kernel::activity::CommImpl* comm,
                                                                                  void* buff, size_t buff_size) {
   xbt_assert((buff_size == sizeof(void*)), "Cannot copy %zu bytes: must be sizeof(void*)", buff_size);
@@ -124,8 +113,6 @@ CommImpl::~CommImpl()
   } else if (mbox_) {
     mbox_->remove(this);
   }
-
-  MC_unignore((void*)&id_, sizeof(id_));
 }
 
 /**  @brief Starts the simulation of a communication synchro. */
index f3d9839..4f249a4 100644 (file)
@@ -36,7 +36,7 @@ class XBT_PUBLIC CommImpl : public ActivityImpl_T<CommImpl> {
   const unsigned id_ = ++next_id_; // ID of this comm (for MC) -- 0 as an ID denotes "invalid/unknown comm"
 
 public:
-  CommImpl();
+  CommImpl() = default;
 
   static void set_copy_data_callback(const std::function<void(CommImpl*, void*, size_t)>& callback);
 
@@ -83,9 +83,6 @@ looking if a given communication matches my needs. For that, myself must match t
 expectations of the other side, too. See  */
   std::function<void(CommImpl*, void*, size_t)> copy_data_fun;
 
-  /* In stateful MC, we need to ignore some private memory that is not relevant to the application state */
-  static void setup_mc();
-
   /* Model actions */
   timeout_action_type src_timeout_{nullptr, [](resource::Action* a) { a->unref(); }}; /* timeout set by the sender */
   timeout_action_type dst_timeout_{nullptr, [](resource::Action* a) { a->unref(); }}; /* timeout set by the receiver */
index d37e756..172bda4 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef SIMGRID_KERNEL_ACTIVITY_MAILBOX_HPP
 #define SIMGRID_KERNEL_ACTIVITY_MAILBOX_HPP
 
+#include "simgrid/config.h" /* FIXME: KILLME. This makes the ABI config-dependent, but mandatory for the hack below */
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Mailbox.hpp"
 #include "src/kernel/activity/CommImpl.hpp"
@@ -19,6 +20,7 @@ class MailboxImpl {
   s4u::Mailbox piface_;
   std::string name_;
   actor::ActorImplPtr permanent_receiver_; // actor to which the mailbox is attached
+
   std::deque<CommImplPtr> comm_queue_;
   // messages already received in the permanent receive mode
   std::deque<CommImplPtr> done_comm_queue_;
diff --git a/src/kernel/activity/MessImpl.cpp b/src/kernel/activity/MessImpl.cpp
new file mode 100644 (file)
index 0000000..28679c2
--- /dev/null
@@ -0,0 +1,187 @@
+/* Copyright (c) 2023. 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 <simgrid/Exception.hpp>
+#include <simgrid/s4u/Host.hpp>
+
+#include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/activity/MessImpl.hpp"
+#include "src/kernel/activity/MessageQueueImpl.hpp"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_mess, kernel, "Kernel message synchronization");
+
+namespace simgrid::kernel::activity {
+
+MessImpl::~MessImpl()
+{
+  if (queue_)
+    queue_->remove(this);
+}
+
+MessImpl& MessImpl::set_type(MessImplType type)
+{
+  type_ = type;
+  return *this;
+}
+
+MessImpl& MessImpl::set_queue(MessageQueueImpl* queue)
+{
+  queue_ = queue;
+  return *this;
+}
+
+MessImpl& MessImpl::set_payload(void* payload)
+{
+  payload_ = payload;
+  return *this;
+}
+
+MessImpl& MessImpl::set_dst_buff(unsigned char* buff, size_t* size)
+{
+  dst_buff_      = buff;
+  dst_buff_size_ = size;
+  return *this;
+}
+
+MessImpl* MessImpl::start()
+{
+  if (get_state() == State::READY) {
+    XBT_DEBUG("Starting message exchange %p from '%s' to '%s' (state: %s)", this, src_actor_->get_host()->get_cname(),
+              dst_actor_->get_host()->get_cname(), get_state_str());
+    set_state(State::RUNNING);
+    finish();
+  }
+  return this;
+}
+
+ActivityImplPtr MessImpl::iput(actor::MessIputSimcall* observer)
+{
+  auto* queue = observer->get_queue();
+  XBT_DEBUG("put from message queue %p", queue);
+
+  /* Prepare a synchro describing us, so that it gets passed to the user-provided filter of other side */
+  MessImplPtr this_mess(new MessImpl());
+  this_mess->set_type(MessImplType::PUT);
+
+  /* Look for message synchro matching our needs.
+   *
+   * If it is not found then push our communication into the rendez-vous point */
+  MessImplPtr other_mess = queue->find_matching_message(MessImplType::GET);
+
+  if (not other_mess) {
+    other_mess = std::move(this_mess);
+    queue->push(other_mess);
+  } else {
+    XBT_DEBUG("Get already pushed");
+    other_mess->set_state(State::READY);
+  }
+
+  observer->set_message(other_mess.get());
+  observer->get_issuer()->activities_.insert(other_mess);
+
+  /* Setup synchro */
+  other_mess->src_actor_ = observer->get_issuer();
+  other_mess->payload_ = observer->get_payload();
+  other_mess->start();
+
+  return other_mess;
+}
+
+ActivityImplPtr MessImpl::iget(actor::MessIgetSimcall* observer)
+{
+  MessImplPtr this_mess(new MessImpl());
+  this_mess->set_type(MessImplType::GET);
+
+  auto* queue = observer->get_queue();
+  XBT_DEBUG("get from message queue %p. this_synchro=%p", queue, this_mess.get());
+
+  MessImplPtr other_mess = queue->find_matching_message(MessImplType::PUT);
+
+  if (other_mess == nullptr) {
+    XBT_DEBUG("Get pushed first (%zu comm enqueued so far)", queue->size());
+    other_mess = std::move(this_mess);
+    queue->push(other_mess);
+  } else {
+    XBT_DEBUG("Match my %p with the existing %p", this_mess.get(), other_mess.get());
+
+    other_mess->set_state(State::READY);
+  }
+
+  observer->get_issuer()->activities_.insert(other_mess);
+  observer->set_message(other_mess.get());
+
+  /* Setup synchro */
+  other_mess->set_dst_buff(observer->get_dst_buff(), observer->get_dst_buff_size());
+  other_mess->dst_actor_ = observer->get_issuer();
+
+  other_mess->start();
+
+  return other_mess;
+}
+
+void MessImpl::wait_for(actor::ActorImpl* issuer, double timeout)
+{
+  XBT_DEBUG("MessImpl::wait_for(%g), %p, state %s", timeout, this, get_state_str());
+
+  /* Associate this simcall to the wait synchro */
+  register_simcall(&issuer->simcall_);
+  ActivityImpl::wait_for(issuer, timeout);
+}
+
+void MessImpl::finish()
+{
+  XBT_DEBUG("MessImpl::finish() comm %p, state %s, src_proc %p, dst_proc %p", this, get_state_str(),
+            src_actor_.get(), dst_actor_.get());
+
+  if (get_iface()) {
+    const auto& piface = static_cast<const s4u::Mess&>(*get_iface());
+    set_iface(nullptr); // reset iface to protect against multiple trigger of the on_completion signals
+    piface.fire_on_completion_for_real();
+    piface.fire_on_this_completion_for_real();
+  }
+
+  /* Update synchro state */
+  if (get_state() == State::RUNNING) {
+    set_state(State::DONE);
+  }
+
+  /* If the synchro is still in a rendez-vous point then remove from it */
+  if (queue_)
+    queue_->remove(this);
+
+  if (get_state() == State::DONE && payload_ != nullptr)
+    *(void**)(dst_buff_) = payload_;
+
+  while (not simcalls_.empty()) {
+    actor::Simcall* simcall = simcalls_.front();
+    simcalls_.pop_front();
+
+    /* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
+     * list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
+     * simcall */
+
+    if (simcall->call_ == actor::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+      continue;                                       // if actor handling comm is killed
+
+    handle_activity_waitany(simcall);
+
+    /* Check out for errors */
+
+    if (not simcall->issuer_->get_host()->is_on()) {
+      simcall->issuer_->set_wannadie();
+    } else {
+      // Do not answer to dying actors
+      if (not simcall->issuer_->wannadie()) {
+        set_exception(simcall->issuer_);
+        simcall->issuer_->simcall_answer();
+      }
+    }
+
+    simcall->issuer_->waiting_synchro_ = nullptr;
+    simcall->issuer_->activities_.erase(this);
+  }
+}
+
+} // namespace simgrid::kernel::activity
diff --git a/src/kernel/activity/MessImpl.hpp b/src/kernel/activity/MessImpl.hpp
new file mode 100644 (file)
index 0000000..fad011c
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (c) 2023. 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 SIMGRID_KERNEL_ACTIVITY_MESS_HPP
+#define SIMGRID_KERNEL_ACTIVITY_MESS_HPP
+
+#include "src/kernel/activity/ActivityImpl.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
+#include "src/kernel/actor/CommObserver.hpp"
+
+namespace simgrid::kernel::activity {
+
+enum class MessImplType { PUT, GET };
+
+class XBT_PUBLIC MessImpl : public ActivityImpl_T<MessImpl> {
+  ~MessImpl() override;
+
+  MessageQueueImpl* queue_ = nullptr;
+  void* payload_           = nullptr;
+  MessImplType type_       = MessImplType::PUT;
+  unsigned char* dst_buff_ = nullptr;
+  size_t* dst_buff_size_   = nullptr;
+
+public:
+  MessImpl& set_type(MessImplType type);
+  MessImplType get_type() const { return type_; }
+  MessImpl& set_payload(void* payload);
+  void* get_payload() { return payload_; }
+
+  MessImpl& set_queue(MessageQueueImpl* queue);
+  MessageQueueImpl* get_queue() const { return queue_; }
+  MessImpl& set_dst_buff(unsigned char* buff, size_t* size);
+
+  static ActivityImplPtr iput(actor::MessIputSimcall* observer);
+  static ActivityImplPtr iget(actor::MessIgetSimcall* observer);
+
+  void wait_for(actor::ActorImpl* issuer, double timeout) override;
+
+  MessImpl* start();
+  void set_exception(actor::ActorImpl* issuer) override {};
+  void finish() override;
+
+  actor::ActorImplPtr src_actor_ = nullptr;
+  actor::ActorImplPtr dst_actor_ = nullptr;
+};
+} // namespace simgrid::kernel::activity
+
+#endif
diff --git a/src/kernel/activity/MessageQueueImpl.cpp b/src/kernel/activity/MessageQueueImpl.cpp
new file mode 100644 (file)
index 0000000..714f86b
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (c) 2023. 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 "src/kernel/activity/MessageQueueImpl.hpp"
+
+#include <unordered_map>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_mq, kernel, "Message queue implementation");
+
+namespace simgrid::kernel::activity {
+
+unsigned MessageQueueImpl::next_id_ = 0;
+
+void MessageQueueImpl::push(const MessImplPtr& mess)
+{
+  mess->set_queue(this);
+  this->queue_.push_back(std::move(mess));
+}
+
+void MessageQueueImpl::remove(const MessImplPtr& mess)
+{
+  xbt_assert(mess->get_queue() == this, "Message %p is in queue %s, not queue %s", mess.get(),
+             (mess->get_queue() ? mess->get_queue()->get_cname() : "(null)"), get_cname());
+
+  mess->set_queue(nullptr);
+  auto it = std::find(queue_.begin(), queue_.end(), mess);
+  if (it != queue_.end())
+    queue_.erase(it);
+  else
+    xbt_die("Message %p not found in queue %s", mess.get(), get_cname());
+}
+
+MessImplPtr MessageQueueImpl::find_matching_message(MessImplType type)
+{
+  auto iter = std::find_if(queue_.begin(), queue_.end(), [&type](const MessImplPtr& mess)
+  {
+    return (mess->get_type() == type);
+  });
+  if (iter == queue_.end()) {
+    XBT_DEBUG("No matching message synchro found");
+    return nullptr;
+  }
+
+  const MessImplPtr& mess = *iter;
+  XBT_DEBUG("Found a matching message synchro %p", mess.get());
+  mess->set_queue(nullptr);
+  MessImplPtr mess_cpy = mess;
+  queue_.erase(iter);
+  return mess_cpy;
+}
+
+} // namespace simgrid::kernel::activity
diff --git a/src/kernel/activity/MessageQueueImpl.hpp b/src/kernel/activity/MessageQueueImpl.hpp
new file mode 100644 (file)
index 0000000..4bc010f
--- /dev/null
@@ -0,0 +1,52 @@
+/* Copyright (c) 2023. 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 SIMGRID_KERNEL_ACTIVITY_MESSAGEQUEUE_HPP
+#define SIMGRID_KERNEL_ACTIVITY_MESSAGEQUEUE_HPP
+
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/MessageQueue.hpp"
+#include "src/kernel/activity/MessImpl.hpp"
+
+namespace simgrid::kernel::activity {
+
+/** @brief Implementation of the s4u::MessageQueue */
+
+class MessageQueueImpl {
+  s4u::MessageQueue piface_;
+  std::string name_;
+  std::deque<MessImplPtr> queue_;
+
+  friend s4u::Engine;
+  friend s4u::MessageQueue;
+  friend s4u::MessageQueue* s4u::Engine::message_queue_by_name_or_create(const std::string& name) const;
+  friend s4u::MessageQueue* s4u::MessageQueue::by_name(const std::string& name);
+
+  static unsigned next_id_; // Next ID to be given
+  const unsigned id_ = next_id_++;
+  explicit MessageQueueImpl(const std::string& name) : piface_(this), name_(name) {}
+  MessageQueueImpl(const MailboxImpl&) = delete;
+  MessageQueueImpl& operator=(const MailboxImpl&) = delete;
+
+public:
+  /** @brief Public interface */
+  unsigned get_id() const { return id_; }
+
+  const s4u::MessageQueue* get_iface() const { return &piface_; }
+  s4u::MessageQueue* get_iface() { return &piface_; }
+
+  const std::string& get_name() const { return name_; }
+  const char* get_cname() const { return name_.c_str(); }
+  void push(const MessImplPtr& mess);
+  void remove(const MessImplPtr& mess);
+  bool empty() const { return queue_.empty(); }
+  size_t size() const { return queue_.size(); }
+  const MessImplPtr& front() const { return queue_.front(); }
+
+  MessImplPtr find_matching_message(MessImplType type);
+};
+} // namespace simgrid::kernel::activity
+
+#endif
index 43a511b..c981c3e 100644 (file)
@@ -47,13 +47,41 @@ unsigned MutexImpl::next_id_ = 0;
 
 MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer)
 {
-  auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true);
-
-  if (owner_ != nullptr) {
-    /* Somebody is using the mutex; register the acquisition */
+  /* If the mutex is recursive */
+  if (is_recursive_) {
+    if (owner_ == issuer) {
+      recursive_depth++;
+      auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true);
+      res->grant();
+      return res;
+    } else if (owner_ == nullptr) { // Free
+      owner_          = issuer;
+      recursive_depth = 1;
+      auto res        = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true);
+      res->grant();
+      return res;
+    }
+
+    for (auto acq : ongoing_acquisitions_)
+      if (acq->get_issuer() == issuer) {
+        acq->recursive_depth_++;
+        return acq;
+      }
+
+    // Not yet in the ongoing acquisition list. Get in there
+    auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true);
     ongoing_acquisitions_.push_back(res);
-  } else {
+    return res;
+  }
+
+  // None-recursive mutex
+  auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true);
+  if (owner_ == nullptr) { // Lock is free, take it
     owner_  = issuer;
+    recursive_depth = 1;
+    res->grant();
+  } else { // Somebody is using the mutex; register the acquisition
+    ongoing_acquisitions_.push_back(res);
   }
   return res;
 }
@@ -65,14 +93,14 @@ MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer)
  */
 bool MutexImpl::try_lock(actor::ActorImpl* issuer)
 {
-  XBT_IN("(%p, %p)", this, issuer);
-  if (owner_ != nullptr) {
-    XBT_OUT();
-    return false;
+  if (owner_ == issuer && is_recursive_) {
+    recursive_depth++;
+    return true;
   }
+  if (owner_ != nullptr)
+    return false;
 
-  owner_  = issuer;
-  XBT_OUT();
+  owner_ = issuer;
   return true;
 }
 
@@ -88,12 +116,20 @@ void MutexImpl::unlock(actor::ActorImpl* issuer)
   xbt_assert(issuer == owner_, "Cannot release that mutex: you're not the owner. %s is (pid:%ld).",
              owner_ != nullptr ? owner_->get_cname() : "(nobody)", owner_ != nullptr ? owner_->get_pid() : -1);
 
+  if (is_recursive_) {
+    recursive_depth--;
+    if (recursive_depth > 0) // Still owning the lock
+      return;
+  }
+
   if (not ongoing_acquisitions_.empty()) {
     /* Give the ownership to the first waiting actor */
     auto acq = ongoing_acquisitions_.front();
     ongoing_acquisitions_.pop_front();
 
     owner_ = acq->get_issuer();
+    acq->grant();
+    recursive_depth = acq->recursive_depth_;
     if (acq == owner_->waiting_synchro_)
       acq->finish();
     // else, the issuer is not blocked on this acquisition so no need to release it
index 3eebec2..9d9242b 100644 (file)
@@ -42,11 +42,18 @@ namespace simgrid::kernel::activity {
 class XBT_PUBLIC MutexAcquisitionImpl : public ActivityImpl_T<MutexAcquisitionImpl> {
   actor::ActorImpl* issuer_ = nullptr;
   MutexImpl* mutex_         = nullptr;
+  int recursive_depth_      = 1;
+  // TODO: use granted_ this instead of owner_ == self to test().
+  // This is mandatory to get double-lock on non-recursive locks to properly deadlock
+  bool granted_ = false;
+
+  friend MutexImpl;
 
 public:
   MutexAcquisitionImpl(actor::ActorImpl* issuer, MutexImpl* mutex) : issuer_(issuer), mutex_(mutex) {}
   MutexImplPtr get_mutex() { return mutex_; }
   actor::ActorImpl* get_issuer() { return issuer_; }
+  void grant() { granted_ = true; }
 
   bool test(actor::ActorImpl* issuer = nullptr) override;
   void wait_for(actor::ActorImpl* issuer, double timeout) override;
@@ -63,11 +70,13 @@ class XBT_PUBLIC MutexImpl {
   std::deque<MutexAcquisitionImplPtr> ongoing_acquisitions_;
   static unsigned next_id_;
   unsigned id_ = next_id_++;
+  bool is_recursive_  = false;
+  int recursive_depth = 0;
 
   friend MutexAcquisitionImpl;
 
 public:
-  MutexImpl() : piface_(this) {}
+  MutexImpl(bool recursive = false) : piface_(this), is_recursive_(recursive) {}
   MutexImpl(MutexImpl const&) = delete;
   MutexImpl& operator=(MutexImpl const&) = delete;
 
index 6f13e3e..d860c8c 100644 (file)
@@ -6,6 +6,7 @@
 #include "simgrid/s4u/Host.hpp"
 #include "src/kernel/activity/CommImpl.hpp"
 #include "src/kernel/activity/MailboxImpl.hpp"
+#include "src/kernel/activity/MessageQueueImpl.hpp"
 #include "src/kernel/actor/ActorImpl.hpp"
 #include "src/kernel/actor/SimcallObserver.hpp"
 #include "src/mc/mc_config.hpp"
@@ -221,8 +222,8 @@ void CommIsendSimcall::serialize(std::stringstream& stream) const
 }
 std::string CommIsendSimcall::to_string() const
 {
-  return "CommAsyncSend(comm_id: " + std::to_string(comm_->get_id()) + " mbox:" + std::to_string(mbox_->get_id()) +
-         " tag: " + std::to_string(tag_) + ")";
+  return "CommAsyncSend(comm_id: " + std::to_string((comm_ ? comm_->get_id() : 0)) + " mbox:" +
+         std::to_string(mbox_->get_id()) + " tag: " + std::to_string(tag_) + ")";
 }
 
 void CommIrecvSimcall::serialize(std::stringstream& stream) const
@@ -233,10 +234,35 @@ void CommIrecvSimcall::serialize(std::stringstream& stream) const
   XBT_DEBUG("RecvObserver comm:%p mbox:%u tag:%d", comm_, mbox_->get_id(), tag_);
   stream << ' ' << fun_call_;
 }
+
 std::string CommIrecvSimcall::to_string() const
 {
-  return "CommAsyncRecv(comm_id: " + std::to_string(comm_->get_id()) + " mbox:" + std::to_string(mbox_->get_id()) +
-         " tag: " + std::to_string(tag_) + ")";
+  return "CommAsyncRecv(comm_id: " + std::to_string((comm_ ? comm_->get_id() : 0)) + " mbox:" +
+         std::to_string(mbox_->get_id()) + " tag: " + std::to_string(tag_) + ")";
+}
+
+void MessIputSimcall::serialize(std::stringstream& stream) const
+{
+  stream << mess_  << ' ' << queue_;
+  XBT_DEBUG("PutObserver mess:%p queue:%p", mess_, queue_);
 }
 
+std::string MessIputSimcall::to_string() const
+{
+  return "MessAsyncPut(queue:" + queue_->get_name() + ")";
+}
+
+void MessIgetSimcall::serialize(std::stringstream& stream) const
+{
+  stream << mess_ << ' ' << queue_;
+  XBT_DEBUG("GettObserver mess:%p queue:%p", mess_, queue_);
+}
+
+std::string MessIgetSimcall::to_string() const
+{
+  return "MessAsyncGet(queue:" + queue_->get_name() + ")";
+}
+
+
+
 } // namespace simgrid::kernel::actor
index ab03651..161e095 100644 (file)
@@ -186,6 +186,52 @@ public:
   auto const& get_copy_data_fun() const { return copy_data_fun_; }
 };
 
+class MessIputSimcall final : public SimcallObserver {
+  activity::MessageQueueImpl* queue_;
+  void* payload_;
+  activity::MessImpl* mess_ = {};
+
+public:
+  MessIputSimcall(
+      ActorImpl* actor, activity::MessageQueueImpl* queue, void* payload)
+      : SimcallObserver(actor)
+      , queue_(queue)
+      , payload_(payload)
+  {
+  }
+  void serialize(std::stringstream& stream) const override;
+  std::string to_string() const override;
+  activity::MessageQueueImpl* get_queue() const { return queue_; }
+  void* get_payload() const { return payload_; }
+  void set_message(activity::MessImpl* mess) { mess_ = mess; }
+};
+
+class MessIgetSimcall final : public SimcallObserver {
+  activity::MessageQueueImpl* queue_;
+  unsigned char* dst_buff_;
+  size_t* dst_buff_size_;
+  void* payload_;
+  activity::MessImpl* mess_ = {};
+
+public:
+  MessIgetSimcall(ActorImpl* actor, activity::MessageQueueImpl* queue, unsigned char* dst_buff, size_t* dst_buff_size,
+                  void* payload)
+      : SimcallObserver(actor)
+      , queue_(queue)
+      , dst_buff_(dst_buff)
+      , dst_buff_size_(dst_buff_size)
+      , payload_(payload)
+  {
+  }
+  void serialize(std::stringstream& stream) const override;
+  std::string to_string() const override;
+  activity::MessageQueueImpl* get_queue() const { return queue_; }
+  unsigned char* get_dst_buff() const { return dst_buff_; }
+  size_t* get_dst_buff_size() const { return dst_buff_size_; }
+  void* get_payload() const { return payload_; }
+  void set_message(activity::MessImpl* mess) { mess_ = mess; }
+};
+
 } // namespace simgrid::kernel::actor
 
 #endif
index 2d2cf88..3bd6ab9 100644 (file)
@@ -73,6 +73,15 @@ std::string ActorJoinSimcall::to_string() const
 {
   return "ActorJoin(pid:" + std::to_string(other_->get_pid()) + ")";
 }
+void ActorSleepSimcall::serialize(std::stringstream& stream) const
+{
+  stream << (short)mc::Transition::Type::ACTOR_SLEEP;
+}
+
+std::string ActorSleepSimcall::to_string() const
+{
+  return "ActorSleep()";
+}
 
 void ObjectAccessSimcallObserver::serialize(std::stringstream& stream) const
 {
index 4cb7f22..d43ac00 100644 (file)
@@ -127,6 +127,14 @@ public:
   double get_timeout() const { return timeout_; }
 };
 
+class ActorSleepSimcall final : public SimcallObserver {
+
+public:
+  ActorSleepSimcall(ActorImpl* actor) : SimcallObserver(actor) {}
+  void serialize(std::stringstream& stream) const override;
+  std::string to_string() const override;
+};
+
 class ObjectAccessSimcallObserver final : public SimcallObserver {
   ObjectAccessSimcallItem* const object_;
 
index c4f79b4..5736b26 100644 (file)
@@ -54,12 +54,6 @@ void Context::set_current(Context* self)
   current_context_ = self;
 }
 
-void Context::declare_context(std::size_t size)
-{
-  /* Store the address of the stack in heap to compare it apart of heap comparison */
-  MC_ignore_heap(this, size);
-}
-
 Context* ContextFactory::attach(actor::ActorImpl*)
 {
   xbt_die("Cannot attach with this ContextFactory.\n"
index 1961399..16c5e82 100644 (file)
@@ -35,7 +35,6 @@ protected:
   template <class T, class... Args> T* new_context(Args&&... args)
   {
     auto* context = new T(std::forward<Args>(args)...);
-    context->declare_context(sizeof(T));
     return context;
   }
 };
@@ -49,7 +48,6 @@ class XBT_PUBLIC Context {
   std::function<void()> code_;
   actor::ActorImpl* actor_ = nullptr;
   bool is_maestro_;
-  void declare_context(std::size_t size);
 
 public:
   static e_xbt_parmap_mode_t parallel_mode;
index 1c29c66..de72fce 100644 (file)
@@ -190,8 +190,6 @@ RawContext::RawContext(std::function<void()>&& code, actor::ActorImpl* actor, Sw
   XBT_VERB("Creating a context of stack %uMb", actor->get_stacksize() / 1024 / 1024);
   if (has_code()) {
     this->stack_top_ = raw_makecontext(get_stack(), actor->get_stacksize(), smx_ctx_wrapper, this);
-  } else {
-    MC_ignore_heap(&stack_top_, sizeof stack_top_);
   }
 }
 
index 1f3cd31..aff10af 100644 (file)
@@ -82,17 +82,9 @@ SwappedContext::SwappedContext(std::function<void()>&& code, actor::ActorImpl* a
 #endif
 
       size_t size = actor->get_stacksize() + guard_size;
-#if SIMGRID_HAVE_STATEFUL_MC
-      /* Cannot use posix_memalign when SIMGRID_HAVE_STATEFUL_MC. Align stack by hand, and save the
-       * pointer returned by xbt_malloc0. */
-      auto* alloc          = static_cast<unsigned char*>(xbt_malloc0(size + xbt_pagesize));
-      stack_               = alloc - (reinterpret_cast<uintptr_t>(alloc) & (xbt_pagesize - 1)) + xbt_pagesize;
-      reinterpret_cast<unsigned char**>(stack_)[-1] = alloc;
-#else
       void* alloc;
       xbt_assert(posix_memalign(&alloc, xbt_pagesize, size) == 0, "Failed to allocate stack.");
       this->stack_ = static_cast<unsigned char*>(alloc);
-#endif
 
       /* This is fatal. We are going to fail at some point when we try reusing this. */
       xbt_assert(
@@ -146,10 +138,6 @@ SwappedContext::~SwappedContext()
       XBT_WARN("Failed to remove page protection: %s", strerror(errno));
       /* try to pursue anyway */
     }
-#if SIMGRID_HAVE_STATEFUL_MC
-    /* Retrieve the saved pointer.  See the initialization above. */
-    stack_ = reinterpret_cast<unsigned char**>(stack_)[-1];
-#endif
   }
 
   xbt_free(stack_);
index 98e372d..2061a25 100644 (file)
@@ -60,11 +60,6 @@ UContext::UContext(std::function<void()>&& code, actor::ActorImpl* actor, Swappe
     UContext* arg = this;
     memcpy(ctx_addr, &arg, sizeof arg);
     makecontext(&this->uc_, (void (*)())sysv_ctx_wrapper, 2, ctx_addr[0], ctx_addr[1]);
-
-#if SIMGRID_HAVE_STATEFUL_MC
-    if (MC_is_active())
-      simgrid::mc::AppSide::get()->declare_stack(get_stack(), stack_size, &uc_);
-#endif
   }
 }
 
index b4c78c5..da11f9a 100644 (file)
@@ -237,7 +237,7 @@ s4u::Disk* HostImpl::create_disk(const std::string& name, double read_bandwidth,
 
 void HostImpl::add_disk(const s4u::Disk* disk)
 {
-  disks_[disk->get_name()] = kernel::resource::DiskImplPtr(disk->get_impl());
+  disks_.insert({disk->get_name(), kernel::resource::DiskImplPtr(disk->get_impl())});
 }
 
 void HostImpl::remove_disk(const std::string& name)
index b206442..3d4c065 100644 (file)
@@ -119,8 +119,14 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone)
   wifiPhy.Set("Antennas", ns3::UintegerValue(nss_value));
   wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(nss_value));
   wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(nss_value));
-#if NS3_MINOR_VERSION > 33
+#if NS3_MINOR_VERSION < 33
+  // This fails with "The channel width does not uniquely identify an operating channel" on v3.34,
+  // so we specified the ChannelWidth of wifiPhy to 40, above, when creating wifiPhy with v3.34 and higher
+  ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40));
+#elif NS3_MINOR_VERSION < 36
   wifiPhy.Set("ChannelWidth", ns3::UintegerValue(40));
+#else
+  wifiPhy.Set("ChannelSettings", ns3::StringValue("{0, 40, BAND_UNSPECIFIED, 0}"));
 #endif
   wifiMac.SetType("ns3::ApWifiMac", "Ssid", ns3::SsidValue(ssid));
 
@@ -166,12 +172,6 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone)
     ns3::Simulator::Schedule(ns3::Seconds(start_time_value), &resumeWifiDevice, device);
   }
 
-#if NS3_MINOR_VERSION < 33
-  // This fails with "The channel width does not uniquely identify an operating channel" on v3.34,
-  // so we specified the ChannelWidth of wifiPhy to 40, above, when creating wifiPhy with v3.34 and higher
-  ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40));
-#endif
-
   mobility.SetPositionAllocator(positionAllocS);
   mobility.Install(nodes);
   ns3::Ipv4AddressHelper address;
diff --git a/src/mc/AddressSpace.hpp b/src/mc/AddressSpace.hpp
deleted file mode 100644 (file)
index f817bf0..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (c) 2008-2023. 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 SIMGRID_MC_ADDRESS_SPACE_H
-#define SIMGRID_MC_ADDRESS_SPACE_H
-
-#include "src/mc/mc_forward.hpp"
-#include "src/mc/remote/RemotePtr.hpp"
-
-namespace simgrid::mc {
-
-/** Options for read operations
- *
- *  This is a set of flags managed with bitwise operators. Only the
- *  meaningful operations are defined: addition, conversions to/from
- *  integers are not allowed.
- */
-class ReadOptions {
-  std::uint32_t value_ = 0;
-  constexpr explicit ReadOptions(std::uint32_t value) : value_(value) {}
-
-public:
-  constexpr ReadOptions() = default;
-
-  explicit constexpr operator bool() const { return value_ != 0; }
-  constexpr bool operator!() const { return value_ == 0; }
-
-  constexpr ReadOptions operator|(ReadOptions const& that) const
-  {
-    return ReadOptions(value_ | that.value_);
-  }
-  constexpr ReadOptions operator&(ReadOptions const& that) const
-  {
-    return ReadOptions(value_ & that.value_);
-  }
-  constexpr ReadOptions operator^(ReadOptions const& that) const
-  {
-    return ReadOptions(value_ ^ that.value_);
-  }
-  constexpr ReadOptions operator~() const
-  {
-    return ReadOptions(~value_);
-  }
-
-  ReadOptions& operator|=(ReadOptions const& that)
-  {
-    value_ |= that.value_;
-    return *this;
-  }
-  ReadOptions& operator&=(ReadOptions const& that)
-  {
-    value_ &= that.value_;
-    return *this;
-  }
-  ReadOptions& operator^=(ReadOptions const& that)
-  {
-    value_ ^= that.value_;
-    return *this;
-  }
-
-  /** Copy the data to the given buffer */
-  static constexpr ReadOptions none() { return ReadOptions(0); }
-
-  /** Allows to return a pointer to another buffer where the data is
-   *  available instead of copying the data into the buffer
-   */
-  static constexpr ReadOptions lazy() { return ReadOptions(1); }
-};
-
-/** A given state of a given process (abstract base class)
- *
- *  Currently, this might either be:
- *
- *  * the current state of an existing process;
- *
- *  * a snapshot.
- */
-class AddressSpace {
-private:
-  RemoteProcessMemory* remote_process_memory_;
-
-public:
-  explicit AddressSpace(RemoteProcessMemory* process) : remote_process_memory_(process) {}
-  virtual ~AddressSpace() = default;
-
-  /** The process of this address space
-   *
-   *  This is where we can get debug information, memory layout, etc.
-   */
-  simgrid::mc::RemoteProcessMemory* get_remote_process_memory() const { return remote_process_memory_; }
-
-  /** Read data from the address space
-   *
-   *  @param buffer        target buffer for the data
-   *  @param size          number of bytes to read
-   *  @param address       remote source address of the data
-   *  @param options
-   */
-  virtual void* read_bytes(void* buffer, std::size_t size, RemotePtr<void> address,
-                           ReadOptions options = ReadOptions::none()) const = 0;
-
-  /** Read a given data structure from the address space */
-  template <class T> inline void read(T* buffer, RemotePtr<T> ptr) const { this->read_bytes(buffer, sizeof(T), ptr); }
-
-  template <class T> inline void read(Remote<T>& buffer, RemotePtr<T> ptr) const
-  {
-    this->read_bytes(buffer.get_buffer(), sizeof(T), ptr);
-  }
-
-  /** Read a given data structure from the address space
-   *
-   *  This version returns by value.
-   */
-  template <class T> inline Remote<T> read(RemotePtr<T> ptr) const
-  {
-    Remote<T> res;
-    this->read_bytes(&res, sizeof(T), ptr);
-    return res;
-  }
-
-  /** Read a string of known size */
-  std::string read_string(RemotePtr<char> address, std::size_t len) const
-  {
-    std::string res;
-    res.resize(len);
-    this->read_bytes(&res[0], len, address);
-    return res;
-  }
-};
-
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/VisitedState.cpp b/src/mc/VisitedState.cpp
deleted file mode 100644 (file)
index 8e19472..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (c) 2011-2023. 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 "src/mc/VisitedState.hpp"
-#include "src/mc/explo/Exploration.hpp"
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_private.hpp"
-
-#include <unistd.h>
-#include <sys/wait.h>
-#include <memory>
-#include <boost/range/algorithm.hpp>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_VisitedState, mc, "Logging specific to state equality detection mechanisms");
-
-namespace simgrid::mc {
-
-/** @brief Save the current state */
-VisitedState::VisitedState(unsigned long state_number, unsigned int actor_count, RemoteApp& remote_app)
-    : heap_bytes_used_(remote_app.get_remote_process_memory()->get_remote_heap_bytes())
-    , actor_count_(actor_count)
-    , num_(state_number)
-{
-  this->system_state_ = std::make_shared<simgrid::mc::Snapshot>(state_number, remote_app.get_page_store(),
-                                                                *remote_app.get_remote_process_memory());
-}
-
-void VisitedStates::prune()
-{
-  while (states_.size() > (std::size_t)_sg_mc_max_visited_states) {
-    XBT_DEBUG("Try to remove visited state (maximum number of stored states reached)");
-    auto min_element = boost::range::min_element(
-        states_, [](const std::unique_ptr<simgrid::mc::VisitedState>& a,
-                    const std::unique_ptr<simgrid::mc::VisitedState>& b) { return a->num_ < b->num_; });
-    xbt_assert(min_element != states_.end());
-    // and drop it:
-    states_.erase(min_element);
-    XBT_DEBUG("Remove visited state (maximum number of stored states reached)");
-  }
-}
-
-/** @brief Checks whether a given state has already been visited by the algorithm. */
-std::unique_ptr<simgrid::mc::VisitedState>
-VisitedStates::addVisitedState(unsigned long state_number, simgrid::mc::State* graph_state, RemoteApp& remote_app)
-{
-  auto new_state =
-      std::make_unique<simgrid::mc::VisitedState>(state_number, graph_state->get_actor_count(), remote_app);
-
-  graph_state->set_system_state(new_state->system_state_);
-  XBT_DEBUG("Snapshot %p of visited state %ld (exploration stack state %ld)", new_state->system_state_.get(),
-            new_state->num_, graph_state->get_num());
-
-  auto [range_begin, range_end] = boost::range::equal_range(states_, new_state.get(), [](auto const& a, auto const& b) {
-    return std::make_pair(a->actor_count_, a->heap_bytes_used_) < std::make_pair(b->actor_count_, b->heap_bytes_used_);
-  });
-
-  for (auto i = range_begin; i != range_end; ++i) {
-    auto& visited_state = *i;
-    if (visited_state->system_state_->equals_to(*new_state->system_state_.get(),
-                                                *remote_app.get_remote_process_memory())) {
-      // The state has been visited:
-
-      std::unique_ptr<simgrid::mc::VisitedState> old_state = std::move(visited_state);
-
-      if (old_state->original_num_ == -1) // I'm the copy of an original process
-        new_state->original_num_ = old_state->num_;
-      else // I'm the copy of a copy
-        new_state->original_num_ = old_state->original_num_;
-
-      XBT_DEBUG("State %ld already visited ! (equal to state %ld (state %ld in dot_output))", new_state->num_,
-                old_state->num_, new_state->original_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_DEBUG("Replace visited state %ld with the new visited state %ld", old_state->num_, new_state->num_);
-
-      visited_state = std::move(new_state);
-      return old_state;
-    }
-  }
-
-  XBT_DEBUG("Insert new visited state %ld (total : %lu)", new_state->num_, (unsigned long)states_.size());
-  states_.insert(range_begin, std::move(new_state));
-  this->prune();
-  return nullptr;
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/VisitedState.hpp b/src/mc/VisitedState.hpp
deleted file mode 100644 (file)
index b2f2694..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_VISITED_STATE_HPP
-#define SIMGRID_MC_VISITED_STATE_HPP
-
-#include "src/mc/api/State.hpp"
-#include "src/mc/sosp/Snapshot.hpp"
-
-#include <cstddef>
-#include <memory>
-
-namespace simgrid::mc {
-
-class XBT_PRIVATE VisitedState {
-public:
-  std::shared_ptr<simgrid::mc::Snapshot> system_state_ = nullptr;
-  std::size_t heap_bytes_used_                         = 0;
-  int actor_count_;
-  long num_;               // unique id of that state in the storage of all stored IDs
-  long original_num_ = -1; // num field of the VisitedState to which I was declared equal to (used for dot_output)
-
-  explicit VisitedState(unsigned long state_number, unsigned int actor_count, RemoteApp& remote_app);
-};
-
-class XBT_PRIVATE VisitedStates {
-  std::vector<std::unique_ptr<simgrid::mc::VisitedState>> states_;
-public:
-  void clear() { states_.clear(); }
-  std::unique_ptr<simgrid::mc::VisitedState> addVisitedState(unsigned long state_number,
-                                                             simgrid::mc::State* graph_state, RemoteApp& remote_app);
-
-private:
-  void prune();
-};
-
-} // namespace simgrid::mc
-
-#endif
index 49622dd..dc6c7d0 100644 (file)
@@ -32,23 +32,15 @@ namespace simgrid::mc {
 
 static std::string master_socket_name;
 
-RemoteApp::RemoteApp(const std::vector<char*>& args, bool need_memory_introspection) : app_args_(args)
+RemoteApp::RemoteApp(const std::vector<char*>& args) : app_args_(args)
 {
-  if (need_memory_introspection) {
-#if SIMGRID_HAVE_STATEFUL_MC
-    checker_side_     = std::make_unique<simgrid::mc::CheckerSide>(app_args_, need_memory_introspection);
-    initial_snapshot_ = std::make_shared<simgrid::mc::Snapshot>(0, page_store_, *checker_side_->get_remote_memory());
-#else
-    xbt_die("SimGrid MC was compiled without memory introspection support.");
-#endif
-  } else {
-    master_socket_ = socket(AF_UNIX,
+  master_socket_ = socket(AF_UNIX,
 #ifdef __APPLE__
-                            SOCK_STREAM, /* Mac OSX does not have AF_UNIX + SOCK_SEQPACKET, even if that's faster */
+                          SOCK_STREAM, /* Mac OSX does not have AF_UNIX + SOCK_SEQPACKET, even if that's faster */
 #else
-                            SOCK_SEQPACKET,
+                          SOCK_SEQPACKET,
 #endif
-                            0);
+                          0);
     xbt_assert(master_socket_ != -1, "Cannot create the master socket: %s", strerror(errno));
 
     master_socket_name = "/tmp/simgrid-mc-" + std::to_string(getpid());
@@ -75,19 +67,13 @@ RemoteApp::RemoteApp(const std::vector<char*>& args, bool need_memory_introspect
 
     xbt_assert(listen(master_socket_, SOMAXCONN) >= 0, "Cannot listen to the master socket: %s.", strerror(errno));
 
-    application_factory_ = std::make_unique<simgrid::mc::CheckerSide>(app_args_, need_memory_introspection);
+    application_factory_ = std::make_unique<simgrid::mc::CheckerSide>(app_args_);
     checker_side_        = application_factory_->clone(master_socket_, master_socket_name);
-  }
 }
 
 void RemoteApp::restore_initial_state()
 {
-  if (initial_snapshot_ == nullptr) // No memory introspection
     checker_side_ = application_factory_->clone(master_socket_, master_socket_name);
-#if SIMGRID_HAVE_STATEFUL_MC
-  else
-    initial_snapshot_->restore(*checker_side_->get_remote_memory());
-#endif
 }
 
 unsigned long RemoteApp::get_maxpid() const
@@ -158,7 +144,8 @@ void RemoteApp::get_actors_status(std::map<aid_t, ActorState>& whereto) const
       actor_transitions.emplace_back(deserialize_transition(actor.aid, times_considered, stream));
     }
 
-    XBT_DEBUG("Received %zu transitions for actor %ld", actor_transitions.size(), actor.aid);
+    XBT_DEBUG("Received %zu transitions for actor %ld. The first one is %s", actor_transitions.size(), actor.aid,
+              (actor_transitions.size() > 0 ? actor_transitions[0]->to_string().c_str() : "null"));
     whereto.try_emplace(actor.aid, actor.aid, actor.enabled, actor.max_considered, std::move(actor_transitions));
   }
 }
@@ -200,10 +187,6 @@ Transition* RemoteApp::handle_simcall(aid_t aid, int times_considered, bool new_
   m.times_considered_              = times_considered;
   checker_side_->get_channel().send(m);
 
-#if SIMGRID_HAVE_STATEFUL_MC
-  if (auto* memory = get_remote_process_memory(); memory != nullptr)
-    memory->clear_cache();
-#endif
   if (checker_side_->running())
     checker_side_->dispatch_events(); // The app may send messages while processing the transition
 
index dbb5e5d..6954a98 100644 (file)
@@ -10,7 +10,6 @@
 #include "src/mc/api/ActorState.hpp"
 #include "src/mc/remote/CheckerSide.hpp"
 #include "src/mc/remote/RemotePtr.hpp"
-#include "src/mc/sosp/PageStore.hpp"
 
 #include <functional>
 
@@ -26,12 +25,6 @@ namespace simgrid::mc {
  */
 class XBT_PUBLIC RemoteApp {
 private:
-#if SIMGRID_HAVE_STATEFUL_MC
-  PageStore page_store_{500};
-  std::shared_ptr<simgrid::mc::Snapshot> initial_snapshot_;
-#else
-  void* initial_snapshot_ = nullptr; // The code tests it to decide whether to use the refork exec path
-#endif
   std::unique_ptr<CheckerSide> checker_side_;
   std::unique_ptr<CheckerSide> application_factory_; // when no meminfo, create checker_side_ by cloning this one
   int master_socket_ = -1;
@@ -50,7 +43,7 @@ public:
    *
    *  The code is expected to `exec` the model-checked application.
    */
-  explicit RemoteApp(const std::vector<char*>& args, bool need_memory_introspection);
+  explicit RemoteApp(const std::vector<char*>& args);
 
   void restore_initial_state();
   void wait_for_requests();
@@ -69,13 +62,6 @@ public:
 
   /** Take a transition. A new Transition is created iff the last parameter is true */
   Transition* handle_simcall(aid_t aid, int times_considered, bool new_transition);
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  /* Get the memory of the remote process */
-  RemoteProcessMemory* get_remote_process_memory() { return checker_side_->get_remote_memory(); }
-
-  PageStore& get_page_store() { return page_store_; }
-#endif
 };
 } // namespace simgrid::mc
 
index 866a1d0..aff9d5c 100644 (file)
@@ -38,13 +38,6 @@ State::State(RemoteApp& remote_app) : num_(++expended_states_)
     THROW_IMPOSSIBLE;
 
   remote_app.get_actors_status(strategy_->actors_to_run_);
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  /* Stateful model checking */
-  if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
-    system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store(),
-                                                            *remote_app.get_remote_process_memory());
-#endif
 }
 
 State::State(RemoteApp& remote_app, std::shared_ptr<State> parent_state)
@@ -64,12 +57,6 @@ State::State(RemoteApp& remote_app, std::shared_ptr<State> parent_state)
 
   remote_app.get_actors_status(strategy_->actors_to_run_);
 
-#if SIMGRID_HAVE_STATEFUL_MC /* Stateful model checking */
-  if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
-    system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store(),
-                                                            *remote_app.get_remote_process_memory());
-#endif
-
   /* Copy the sleep set and eventually removes things from it: */
   /* For each actor in the previous sleep set, keep it if it is not dependent with current transition.
    * And if we kept it and the actor is enabled in this state, mark the actor as already done, so that
@@ -252,14 +239,18 @@ void State::sprout_tree_from_parent_state()
                                            "parent with an empty wakeup tree. This indicates either that ODPOR "
                                            "actor selection in State.cpp is incorrect, or that the code "
                                            "deciding when to make subtrees in ODPOR is incorrect");
-  xbt_assert((get_transition_in()->aid_ == min_process_node.value()->get_actor()) &&
-                 (get_transition_in()->type_ == min_process_node.value()->get_action()->type_),
-             "We tried to make a subtree from a parent state who claimed to have executed `%s` on actor %ld "
-             "but whose wakeup tree indicates it should have executed `%s` on actor %ld. This indicates "
-             "that exploration is not following ODPOR. Are you sure you're choosing actors "
-             "to schedule from the wakeup tree?",
-             get_transition_in()->to_string(false).c_str(), get_transition_in()->aid_,
-             min_process_node.value()->get_action()->to_string(false).c_str(), min_process_node.value()->get_actor());
+  if (not(get_transition_in()->aid_ == min_process_node.value()->get_actor() &&
+          get_transition_in()->type_ == min_process_node.value()->get_action()->type_)) {
+    XBT_ERROR("We tried to make a subtree from a parent state who claimed to have executed `%s` on actor %ld "
+              "but whose wakeup tree indicates it should have executed `%s` on actor %ld. This indicates "
+              "that exploration is not following ODPOR. Are you sure you're choosing actors "
+              "to schedule from the wakeup tree? Trace so far:",
+              get_transition_in()->to_string(false).c_str(), get_transition_in()->aid_,
+              min_process_node.value()->get_action()->to_string(false).c_str(), min_process_node.value()->get_actor());
+    for (auto elm : Exploration::get_instance()->get_textual_trace())
+      XBT_ERROR("%s", elm.c_str());
+    xbt_abort();
+  }
   this->wakeup_tree_ = odpor::WakeupTree::make_subtree_rooted_at(min_process_node.value());
 }
 
index f10d7bd..de11f78 100644 (file)
 #include "src/mc/explo/odpor/WakeupTree.hpp"
 #include "src/mc/transition/Transition.hpp"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/sosp/Snapshot.hpp"
-#endif
-
 namespace simgrid::mc {
 
 /* A node in the exploration graph (kind-of) */
@@ -32,9 +28,6 @@ class XBT_PRIVATE State : public xbt::Extendable<State> {
   /** Sequential state ID (used for debugging) */
   long num_ = 0;
 
-  /** Snapshot of system state (if needed) */
-  std::shared_ptr<Snapshot> system_state_;
-
   /** Unique parent of this state. Required both for sleep set computation
       and for guided model-checking */
   std::shared_ptr<State> parent_state_ = nullptr;
@@ -98,9 +91,6 @@ public:
   unsigned long get_actor_count() const { return strategy_->actors_to_run_.size(); }
   bool is_actor_enabled(aid_t actor) const { return strategy_->actors_to_run_.at(actor).is_enabled(); }
 
-  Snapshot* get_system_state() const { return system_state_.get(); }
-  void set_system_state(std::shared_ptr<Snapshot> state) { system_state_ = std::move(state); }
-
   /**
    * @brief Computes the backtrack set for this state
    * according to its definition in SimGrid.
index fd28633..de0fe65 100644 (file)
@@ -7,13 +7,17 @@
 #define SIMGRID_MC_BASICSTRATEGY_HPP
 
 #include "Strategy.hpp"
+#include "src/mc/explo/Exploration.hpp"
+
+XBT_LOG_EXTERNAL_CATEGORY(mc_dfs);
 
 namespace simgrid::mc {
 
 /** Basic MC guiding class which corresponds to no guide. When asked for different states
  *  it will follow a depth first search politics to minize the number of opened states. */
 class BasicStrategy : public Strategy {
-    int depth_ = _sg_mc_max_depth; // Arbitrary starting point. next_transition must return a positiv value to work with threshold in DFSExplorer
+  int depth_ = _sg_mc_max_depth; // Arbitrary starting point. next_transition must return a positive value to work with
+                                 // threshold in DFSExplorer
 
 public:
   void copy_from(const Strategy* strategy) override
@@ -21,7 +25,16 @@ public:
     const auto* cast_strategy = dynamic_cast<BasicStrategy const*>(strategy);
     xbt_assert(cast_strategy != nullptr);
     depth_ = cast_strategy->depth_ - 1;
-    xbt_assert(depth_ > 0, "The exploration reached a depth greater than %d. We will stop here to prevent weird interaction with DFSExplorer. If you want to change that behaviour, you should augment the size of the search by using --cfg=model-check/max-depth:", _sg_mc_max_depth.get());
+    if (depth_ <= 0) {
+      XBT_CERROR(mc_dfs,
+                 "The exploration reached a depth greater than %d. Change the depth limit with "
+                 "--cfg=model-check/max-depth. Here are the 100 first trace elements",
+                 _sg_mc_max_depth.get());
+      auto trace = Exploration::get_instance()->get_textual_trace(100);
+      for (auto elm : trace)
+        XBT_CERROR(mc_dfs, "  %s", elm.c_str());
+      xbt_die("Aborting now.");
+    }
   }
   BasicStrategy()                     = default;
   ~BasicStrategy() override           = default;
diff --git a/src/mc/compare.cpp b/src/mc/compare.cpp
deleted file mode 100644 (file)
index 9fe8072..0000000
+++ /dev/null
@@ -1,1300 +0,0 @@
-/* Copyright (c) 2008-2023. 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. */
-
-/** \file compare.cpp Memory snapshotting and comparison                    */
-
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_private.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-#include "src/mc/sosp/Snapshot.hpp"
-#include "xbt/ex.h"
-
-#include <algorithm>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, mc, "Logging specific to mc_compare in mc");
-
-namespace simgrid::mc {
-
-/*********************************** Heap comparison ***********************************/
-/***************************************************************************************/
-
-class HeapLocation {
-public:
-  int block_    = 0;
-  int fragment_ = 0;
-
-  HeapLocation() = default;
-  explicit HeapLocation(int block, int fragment = 0) : block_(block), fragment_(fragment) {}
-
-  bool operator==(HeapLocation const& that) const
-  {
-    return block_ == that.block_ && fragment_ == that.fragment_;
-  }
-  bool operator<(HeapLocation const& that) const
-  {
-    return std::make_pair(block_, fragment_) < std::make_pair(that.block_, that.fragment_);
-  }
-};
-
-using HeapLocationPair  = std::array<HeapLocation, 2>;
-using HeapLocationPairs = std::set<HeapLocationPair>;
-
-class HeapArea : public HeapLocation {
-public:
-  bool valid_ = false;
-  HeapArea() = default;
-  explicit HeapArea(int block) : valid_(true) { block_ = block; }
-  HeapArea(int block, int fragment) : valid_(true)
-  {
-    block_    = block;
-    fragment_ = fragment;
-  }
-};
-
-class ProcessComparisonState {
-public:
-  const std::vector<IgnoredHeapRegion>* to_ignore = nullptr;
-  std::vector<HeapArea> equals_to;
-  std::vector<Type*> types;
-  std::size_t heapsize = 0;
-
-  void initHeapInformation(const s_xbt_mheap_t* heap, const std::vector<IgnoredHeapRegion>& i);
-};
-
-class StateComparator {
-public:
-  s_xbt_mheap_t std_heap_copy;
-  std::size_t heaplimit;
-  std::array<ProcessComparisonState, 2> processStates;
-
-  std::unordered_set<std::pair<const void*, const void*>, simgrid::xbt::hash<std::pair<const void*, const void*>>>
-      compared_pointers;
-
-  void clear()
-  {
-    compared_pointers.clear();
-  }
-
-  int initHeapInformation(RemoteProcessMemory& appli, const s_xbt_mheap_t* heap1, const s_xbt_mheap_t* heap2,
-                          const std::vector<IgnoredHeapRegion>& i1, const std::vector<IgnoredHeapRegion>& i2);
-
-  template <int rank> HeapArea& equals_to_(std::size_t i, std::size_t j)
-  {
-    return processStates[rank - 1].equals_to[MAX_FRAGMENT_PER_BLOCK * i + j];
-  }
-  template <int rank> Type*& types_(std::size_t i, std::size_t j)
-  {
-    return processStates[rank - 1].types[MAX_FRAGMENT_PER_BLOCK * i + j];
-  }
-
-  template <int rank> HeapArea const& equals_to_(std::size_t i, std::size_t j) const
-  {
-    return processStates[rank - 1].equals_to[MAX_FRAGMENT_PER_BLOCK * i + j];
-  }
-  template <int rank> Type* const& types_(std::size_t i, std::size_t j) const
-  {
-    return processStates[rank - 1].types[MAX_FRAGMENT_PER_BLOCK * i + j];
-  }
-
-  /** Check whether two blocks are known to be matching
-   *
-   *  @param b1     Block of state 1
-   *  @param b2     Block of state 2
-   *  @return       if the blocks are known to be matching
-   */
-  bool blocksEqual(int b1, int b2) const
-  {
-    return this->equals_to_<1>(b1, 0).block_ == b2 && this->equals_to_<2>(b2, 0).block_ == b1;
-  }
-
-  /** Check whether two fragments are known to be matching
-   *
-   *  @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
-   */
-  int fragmentsEqual(int b1, int f1, int b2, int f2) const
-  {
-    return this->equals_to_<1>(b1, f1).block_ == b2 && this->equals_to_<1>(b1, f1).fragment_ == f2 &&
-           this->equals_to_<2>(b2, f2).block_ == b1 && this->equals_to_<2>(b2, f2).fragment_ == f1;
-  }
-
-  void match_equals(const HeapLocationPairs* list);
-};
-
-} // namespace simgrid::mc
-
-/************************************************************************************/
-
-static ssize_t heap_comparison_ignore_size(const std::vector<simgrid::mc::IgnoredHeapRegion>* ignore_list,
-                                           const void* address)
-{
-  auto pos = std::lower_bound(ignore_list->begin(), ignore_list->end(), address,
-                              [](auto const& reg, auto const* addr) { return reg.address < addr; });
-  return (pos != ignore_list->end() && pos->address == address) ? pos->size : -1;
-}
-
-static bool is_stack(const simgrid::mc::RemoteProcessMemory& process, const void* address)
-{
-  auto const& stack_areas = process.stack_areas();
-  return std::any_of(stack_areas.begin(), stack_areas.end(),
-                     [address](auto const& stack) { return stack.address == address; });
-}
-
-// TODO, this should depend on the snapshot?
-static bool is_block_stack(const simgrid::mc::RemoteProcessMemory& process, int block)
-{
-  auto const& stack_areas = process.stack_areas();
-  return std::any_of(stack_areas.begin(), stack_areas.end(),
-                     [block](auto const& stack) { return stack.block == block; });
-}
-
-namespace simgrid::mc {
-
-void StateComparator::match_equals(const HeapLocationPairs* list)
-{
-  for (auto const& pair : *list) {
-    if (pair[0].fragment_ != -1) {
-      this->equals_to_<1>(pair[0].block_, pair[0].fragment_) = HeapArea(pair[1].block_, pair[1].fragment_);
-      this->equals_to_<2>(pair[1].block_, pair[1].fragment_) = HeapArea(pair[0].block_, pair[0].fragment_);
-    } else {
-      this->equals_to_<1>(pair[0].block_, 0) = HeapArea(pair[1].block_, pair[1].fragment_);
-      this->equals_to_<2>(pair[1].block_, 0) = HeapArea(pair[0].block_, pair[0].fragment_);
-    }
-  }
-}
-
-void ProcessComparisonState::initHeapInformation(const s_xbt_mheap_t* heap, const std::vector<IgnoredHeapRegion>& i)
-{
-  auto heaplimit  = heap->heaplimit;
-  this->heapsize  = heap->heapsize;
-  this->to_ignore = &i;
-  this->equals_to.assign(heaplimit * MAX_FRAGMENT_PER_BLOCK, HeapArea());
-  this->types.assign(heaplimit * MAX_FRAGMENT_PER_BLOCK, nullptr);
-}
-
-int StateComparator::initHeapInformation(simgrid::mc::RemoteProcessMemory& memory, const s_xbt_mheap_t* heap1,
-                                         const s_xbt_mheap_t* heap2, const std::vector<IgnoredHeapRegion>& i1,
-                                         const std::vector<IgnoredHeapRegion>& i2)
-{
-  if ((heap1->heaplimit != heap2->heaplimit) || (heap1->heapsize != heap2->heapsize))
-    return -1;
-  this->heaplimit     = heap1->heaplimit;
-  this->std_heap_copy = *memory.get_heap();
-  this->processStates[0].initHeapInformation(heap1, i1);
-  this->processStates[1].initHeapInformation(heap2, i2);
-  return 0;
-}
-
-// TODO, have a robust way to find it in O(1)
-static inline Region* MC_get_heap_region(const Snapshot& snapshot)
-{
-  for (auto const& region : snapshot.snapshot_regions_)
-    if (region->region_type() == RegionType::Heap)
-      return region.get();
-  xbt_die("No heap region");
-}
-
-static bool heap_area_differ(const RemoteProcessMemory& process, StateComparator& state, const void* area1,
-                             const void* area2, const Snapshot& snapshot1, const Snapshot& snapshot2,
-                             HeapLocationPairs* previous, Type* type, int pointer_level);
-
-/* Compares the content of each heap fragment between the two states, at the bit level.
- *
- * This operation is costly (about 5 seconds per snapshots' pair to compare on a small program),
- * but hard to optimize because our algorithm is too hackish.
- *
- * Going at bit level can trigger syntaxtic differences on states that are semantically equivalent.
- *
- * Padding bytes constitute the first source of such syntaxtic difference: Any malloced memory contains spaces that
- * are not used to enforce the memory alignment constraints of the CPU. So, cruft of irrelevant changes could get
- * added on these bits. But this case is handled properly, as any memory block is zeroed by mmalloc before being handled
- * back, not only for calloc but also for malloc. So the memory interstices due to padding bytes are properly zeroed.
- *
- * Another source of such change comes from the order of mallocs, that may well change from one execution path to
- * another. This will change the malloc fragment in which the data is stored and the pointer values (syntaxtic
- * difference) while the semantic of the state remains the same.
- *
- * To fix this, this code relies on a hugly hack. When we see a difference during the bit-level comparison,
- * we first check if it could be explained by a pointer-to-block difference. Ie, if when interpreting the memory
- * area containing that difference as a pointer, I get the pointer to a valid fragment in the heap (in both snapshots).
- *
- * This is why we cannot pre-compute a bit-level hash of the heap content: we discover the pointers to other memory
- * fragment when a difference is found during the bit-level exploration. Fixing this would require to save typing
- * information about the memory fragments, which is something that could be done with https://github.com/tudasc/TypeART
- * This would give us all pointers in the mallocated memory, allowing the graph traversal needed to precompute the hash.
- *
- * Using a hash without paying attention to malloc fragment reordering would lead to false negatives:
- * semantically equivalent states would be detected as [syntaxically] different. It's of no importance for the
- * state-equality reduction (we would re-explore semantically equivalent states), but it would endanger the soundness
- * of the liveness model-checker, as state-equality is used to detect the loops that constitute the accepting states of
- * the verified property. So we could miss counter-examples to the verified property. Not good. Not good at all.
- */
-static bool mmalloc_heap_differ(const RemoteProcessMemory& process, StateComparator& state, const Snapshot& snapshot1,
-                                const Snapshot& snapshot2)
-{
-  /* Check busy blocks */
-  size_t i1 = 1;
-
-  malloc_info heapinfo_temp1;
-  malloc_info heapinfo_temp2;
-  malloc_info heapinfo_temp2b;
-
-  const Region* heap_region1 = MC_get_heap_region(snapshot1);
-  const Region* heap_region2 = MC_get_heap_region(snapshot2);
-
-  // This is the address of std_heap->heapinfo in the application process:
-  uint64_t heapinfo_address = process.heap_address.address() + offsetof(s_xbt_mheap_t, heapinfo);
-
-  // This is in snapshot do not use them directly:
-  const malloc_info* heapinfos1 = snapshot1.read(remote<malloc_info*>(heapinfo_address));
-  const malloc_info* heapinfos2 = snapshot2.read(remote<malloc_info*>(heapinfo_address));
-
-  while (i1 < state.heaplimit) {
-    const auto* heapinfo1 =
-        static_cast<malloc_info*>(heap_region1->read(&heapinfo_temp1, &heapinfos1[i1], sizeof(malloc_info)));
-    const auto* heapinfo2 =
-        static_cast<malloc_info*>(heap_region2->read(&heapinfo_temp2, &heapinfos2[i1], sizeof(malloc_info)));
-
-    if (heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type == MMALLOC_TYPE_HEAPINFO) {      /* Free block */
-      i1 ++;
-      continue;
-    }
-
-    xbt_assert(heapinfo1->type >= 0, "Unknown mmalloc block type: %d", heapinfo1->type);
-
-    void* addr_block1 = (ADDR2UINT(i1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase;
-
-    if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) { /* Large block */
-      if (is_stack(process, addr_block1)) {
-        for (size_t k = 0; k < heapinfo1->busy_block.size; k++)
-          state.equals_to_<1>(i1 + k, 0) = HeapArea(i1, -1);
-        for (size_t k = 0; k < heapinfo2->busy_block.size; k++)
-          state.equals_to_<2>(i1 + k, 0) = HeapArea(i1, -1);
-        i1 += heapinfo1->busy_block.size;
-        continue;
-      }
-
-      if (state.equals_to_<1>(i1, 0).valid_) {
-        i1++;
-        continue;
-      }
-
-      size_t i2 = 1;
-      bool equal = false;
-
-      /* Try first to associate to same block in the other heap */
-      if (heapinfo2->type == heapinfo1->type && state.equals_to_<2>(i1, 0).valid_ == 0) {
-        const void* addr_block2 = (ADDR2UINT(i1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase;
-        if (not heap_area_differ(process, state, addr_block1, addr_block2, snapshot1, snapshot2, nullptr, nullptr, 0)) {
-          for (size_t k = 1; k < heapinfo2->busy_block.size; k++)
-            state.equals_to_<2>(i1 + k, 0) = HeapArea(i1, -1);
-          for (size_t k = 1; k < heapinfo1->busy_block.size; k++)
-            state.equals_to_<1>(i1 + k, 0) = HeapArea(i1, -1);
-          equal = true;
-          i1 += heapinfo1->busy_block.size;
-        }
-      }
-
-      while (i2 < state.heaplimit && not equal) {
-        const void* addr_block2 = (ADDR2UINT(i2) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase;
-
-        if (i2 == i1) {
-          i2++;
-          continue;
-        }
-
-        const auto* heapinfo2b =
-            static_cast<malloc_info*>(heap_region2->read(&heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info)));
-
-        if (heapinfo2b->type != MMALLOC_TYPE_UNFRAGMENTED) {
-          i2++;
-          continue;
-        }
-
-        if (state.equals_to_<2>(i2, 0).valid_) {
-          i2++;
-          continue;
-        }
-
-        if (not heap_area_differ(process, state, addr_block1, addr_block2, snapshot1, snapshot2, nullptr, nullptr, 0)) {
-          for (size_t k = 1; k < heapinfo2b->busy_block.size; k++)
-            state.equals_to_<2>(i2 + k, 0) = HeapArea(i1, -1);
-          for (size_t k = 1; k < heapinfo1->busy_block.size; k++)
-            state.equals_to_<1>(i1 + k, 0) = HeapArea(i2, -1);
-          equal = true;
-          i1 += heapinfo1->busy_block.size;
-        }
-        i2++;
-      }
-
-      if (not equal) {
-        XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, heapinfo1->busy_block.busy_size, addr_block1);
-        return true;
-      }
-    } else { /* Fragmented block */
-      for (size_t j1 = 0; j1 < (size_t)(BLOCKSIZE >> heapinfo1->type); j1++) {
-        if (heapinfo1->busy_frag.frag_size[j1] == -1) /* Free fragment_ */
-          continue;
-
-        if (state.equals_to_<1>(i1, j1).valid_)
-          continue;
-
-        void* addr_frag1 = (char*)addr_block1 + (j1 << heapinfo1->type);
-
-        size_t i2 = 1;
-        bool equal = false;
-
-        /* Try first to associate to same fragment_ in the other heap */
-        if (heapinfo2->type == heapinfo1->type && not state.equals_to_<2>(i1, j1).valid_) {
-          const void* addr_block2 = (ADDR2UINT(i1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase;
-          const void* addr_frag2  = (const char*)addr_block2 + (j1 << heapinfo2->type);
-          if (not heap_area_differ(process, state, addr_frag1, addr_frag2, snapshot1, snapshot2, nullptr, nullptr, 0))
-            equal = true;
-        }
-
-        while (i2 < state.heaplimit && not equal) {
-          const auto* heapinfo2b =
-              static_cast<malloc_info*>(heap_region2->read(&heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info)));
-
-          if (heapinfo2b->type == MMALLOC_TYPE_FREE || heapinfo2b->type == MMALLOC_TYPE_HEAPINFO) {
-            i2 ++;
-            continue;
-          }
-
-          // We currently do not match fragments with unfragmented blocks (maybe we should).
-          if (heapinfo2b->type == MMALLOC_TYPE_UNFRAGMENTED) {
-            i2++;
-            continue;
-          }
-
-          xbt_assert(heapinfo2b->type >= 0, "Unknown mmalloc block type: %d", heapinfo2b->type);
-
-          for (size_t j2 = 0; j2 < (size_t)(BLOCKSIZE >> heapinfo2b->type); j2++) {
-            if (i2 == i1 && j2 == j1)
-              continue;
-
-            if (state.equals_to_<2>(i2, j2).valid_)
-              continue;
-
-            const void* addr_block2 = (ADDR2UINT(i2) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase;
-            const void* addr_frag2  = (const char*)addr_block2 + (j2 << heapinfo2b->type);
-
-            if (not heap_area_differ(process, state, addr_frag1, addr_frag2, snapshot1, snapshot2, nullptr, nullptr,
-                                     0)) {
-              equal = true;
-              break;
-            }
-          }
-          i2++;
-        }
-
-        if (not 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);
-          return true;
-        }
-      }
-      i1++;
-    }
-  }
-
-  /* All blocks/fragments are equal to another block/fragment_ ? */
-  for (size_t i = 1; i < state.heaplimit; i++) {
-    const auto* heapinfo1 =
-        static_cast<malloc_info*>(heap_region1->read(&heapinfo_temp1, &heapinfos1[i], sizeof(malloc_info)));
-
-    if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED && i1 == state.heaplimit && heapinfo1->busy_block.busy_size > 0 &&
-        not state.equals_to_<1>(i, 0).valid_) {
-      XBT_DEBUG("Block %zu not found (size used = %zu)", i, heapinfo1->busy_block.busy_size);
-      return true;
-    }
-
-    if (heapinfo1->type <= 0)
-      continue;
-    for (size_t j = 0; j < (size_t)(BLOCKSIZE >> heapinfo1->type); j++)
-      if (i1 == state.heaplimit && heapinfo1->busy_frag.frag_size[j] > 0 && not state.equals_to_<1>(i, j).valid_) {
-        XBT_DEBUG("Block %zu, Fragment %zu not found (size used = %zd)", i, j, heapinfo1->busy_frag.frag_size[j]);
-        return true;
-      }
-  }
-
-  for (size_t i = 1; i < state.heaplimit; i++) {
-    const auto* heapinfo2 =
-        static_cast<malloc_info*>(heap_region2->read(&heapinfo_temp2, &heapinfos2[i], sizeof(malloc_info)));
-    if (heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED && i1 == state.heaplimit && heapinfo2->busy_block.busy_size > 0 &&
-        not state.equals_to_<2>(i, 0).valid_) {
-      XBT_DEBUG("Block %zu not found (size used = %zu)", i,
-                heapinfo2->busy_block.busy_size);
-      return true;
-    }
-
-    if (heapinfo2->type <= 0)
-      continue;
-
-    for (size_t j = 0; j < (size_t)(BLOCKSIZE >> heapinfo2->type); j++)
-      if (i1 == state.heaplimit && heapinfo2->busy_frag.frag_size[j] > 0 && not state.equals_to_<2>(i, j).valid_) {
-        XBT_DEBUG("Block %zu, Fragment %zu not found (size used = %zd)",
-          i, j, heapinfo2->busy_frag.frag_size[j]);
-        return true;
-      }
-  }
-  return false;
-}
-
-/**
- *
- * @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
- * @return true when different, false otherwise (same or unknown)
- */
-static bool heap_area_differ_without_type(const RemoteProcessMemory& process, StateComparator& state,
-                                          const void* real_area1, const void* real_area2, const Snapshot& snapshot1,
-                                          const Snapshot& snapshot2, HeapLocationPairs* previous, int size,
-                                          int check_ignore)
-{
-  const Region* heap_region1  = MC_get_heap_region(snapshot1);
-  const Region* heap_region2  = MC_get_heap_region(snapshot2);
-
-  for (int i = 0; i < size; ) {
-    if (check_ignore > 0) {
-      ssize_t ignore1 = heap_comparison_ignore_size(state.processStates[0].to_ignore, (const char*)real_area1 + i);
-      if (ignore1 != -1) {
-        ssize_t ignore2 = heap_comparison_ignore_size(state.processStates[1].to_ignore, (const char*)real_area2 + i);
-        if (ignore2 == ignore1) {
-          if (ignore1 == 0) {
-            return false;
-          } else {
-            i = i + ignore2;
-            check_ignore--;
-            continue;
-          }
-        }
-      }
-    }
-
-    if (MC_snapshot_region_memcmp((const char*)real_area1 + i, heap_region1, (const char*)real_area2 + i, heap_region2,
-                                  1) != 0) {
-      int pointer_align = (i / sizeof(void *)) * sizeof(void *);
-      const void* addr_pointed1 = snapshot1.read(remote((void* const*)((const char*)real_area1 + pointer_align)));
-      const void* addr_pointed2 = snapshot2.read(remote((void* const*)((const char*)real_area2 + pointer_align)));
-
-      if (process.in_maestro_stack(remote(addr_pointed1)) && process.in_maestro_stack(remote(addr_pointed2))) {
-        i = pointer_align + sizeof(void *);
-        continue;
-      }
-
-      if (snapshot1.on_heap(addr_pointed1) && snapshot2.on_heap(addr_pointed2)) {
-        // Both addresses are in the heap:
-        if (heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, nullptr, 0))
-          return true;
-        i = pointer_align + sizeof(void *);
-        continue;
-      }
-      return true;
-    }
-    i++;
-  }
-  return false;
-}
-
-/**
- *
- * @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
- * @param area_size      either a byte_size or an elements_count (?)
- * @param check_ignore
- * @param pointer_level
- * @return               true when different, false otherwise (same or unknown)
- */
-static bool heap_area_differ_with_type(const simgrid::mc::RemoteProcessMemory& process, StateComparator& state,
-                                       const void* real_area1, const void* real_area2, const Snapshot& snapshot1,
-                                       const Snapshot& snapshot2, HeapLocationPairs* previous, const Type* type,
-                                       int area_size, int check_ignore, int pointer_level)
-{
-  // HACK: This should not happen but in practice, there are some
-  // DW_TAG_typedef without an associated DW_AT_type:
-  //<1><538832>: Abbrev Number: 111 (DW_TAG_typedef)
-  //    <538833>   DW_AT_name        : (indirect string, offset: 0x2292f3): gregset_t
-  //    <538837>   DW_AT_decl_file   : 98
-  //    <538838>   DW_AT_decl_line   : 37
-  if (type == nullptr)
-    return false;
-
-  if (is_stack(process, real_area1) && is_stack(process, real_area2))
-    return false;
-
-  if (check_ignore > 0) {
-    ssize_t ignore1 = heap_comparison_ignore_size(state.processStates[0].to_ignore, real_area1);
-    if (ignore1 > 0 && heap_comparison_ignore_size(state.processStates[1].to_ignore, real_area2) == ignore1)
-      return false;
-  }
-
-  const Type* subtype;
-  const Type* subsubtype;
-  int elm_size;
-  const void* addr_pointed1;
-  const void* addr_pointed2;
-
-  const Region* heap_region1 = MC_get_heap_region(snapshot1);
-  const Region* heap_region2 = MC_get_heap_region(snapshot2);
-
-  switch (type->type) {
-    case DW_TAG_unspecified_type:
-      return true;
-
-    case DW_TAG_base_type:
-      if (not type->name.empty() && type->name == "char") { /* String, hence random (arbitrary ?) size */
-        if (real_area1 == real_area2)
-          return false;
-        else
-          return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0;
-      } else {
-        if (area_size != -1 && type->byte_size != area_size)
-          return false;
-        else
-          return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0;
-      }
-
-    case DW_TAG_enumeration_type:
-      if (area_size != -1 && type->byte_size != area_size)
-        return false;
-      return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0;
-
-    case DW_TAG_typedef:
-    case DW_TAG_const_type:
-    case DW_TAG_volatile_type:
-      return heap_area_differ_with_type(process, state, real_area1, real_area2, snapshot1, snapshot2, previous,
-                                        type->subtype, area_size, check_ignore, pointer_level);
-
-    case DW_TAG_array_type:
-      subtype = type->subtype;
-      switch (subtype->type) {
-        case DW_TAG_unspecified_type:
-          return true;
-
-        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 false;
-      }
-      for (int i = 0; i < type->element_count; i++) {
-        // TODO, add support for variable stride (DW_AT_byte_stride)
-        if (heap_area_differ_with_type(process, state, (const char*)real_area1 + (i * elm_size),
-                                       (const char*)real_area2 + (i * elm_size), snapshot1, snapshot2, previous,
-                                       type->subtype, subtype->byte_size, check_ignore, pointer_level))
-          return true;
-      }
-      return false;
-
-    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 = snapshot1.read(remote((void* const*)real_area1));
-        addr_pointed2 = snapshot2.read(remote((void* const*)real_area2));
-        return (addr_pointed1 != addr_pointed2);
-      }
-      pointer_level++;
-      if (pointer_level <= 1) {
-        addr_pointed1 = snapshot1.read(remote((void* const*)real_area1));
-        addr_pointed2 = snapshot2.read(remote((void* const*)real_area2));
-        if (snapshot1.on_heap(addr_pointed1) && snapshot2.on_heap(addr_pointed2))
-          return heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous,
-                                  type->subtype, pointer_level);
-        else
-          return (addr_pointed1 != addr_pointed2);
-      }
-      for (size_t i = 0; i < (area_size / sizeof(void*)); i++) {
-        addr_pointed1 = snapshot1.read(remote((void* const*)((const char*)real_area1 + i * sizeof(void*))));
-        addr_pointed2 = snapshot2.read(remote((void* const*)((const char*)real_area2 + i * sizeof(void*))));
-        bool differ   = snapshot1.on_heap(addr_pointed1) && snapshot2.on_heap(addr_pointed2)
-                            ? heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2,
-                                             previous, type->subtype, pointer_level)
-                            : addr_pointed1 != addr_pointed2;
-        if (differ)
-          return true;
-      }
-      return false;
-
-    case DW_TAG_structure_type:
-    case DW_TAG_class_type:
-      if (type->full_type)
-        type = type->full_type;
-      if (type->byte_size == 0)
-        return false;
-      if (area_size != -1 && type->byte_size != area_size) {
-        if (area_size <= type->byte_size || area_size % type->byte_size != 0)
-          return false;
-        for (size_t i = 0; i < (size_t)(area_size / type->byte_size); i++) {
-          if (heap_area_differ_with_type(process, state, (const char*)real_area1 + i * type->byte_size,
-                                         (const char*)real_area2 + i * type->byte_size, snapshot1, snapshot2, previous,
-                                         type, -1, check_ignore, 0))
-            return true;
-        }
-        } else {
-          for (const simgrid::mc::Member& member : type->members) {
-            // TODO, optimize this? (for the offset case)
-            const void* real_member1 = dwarf::resolve_member(real_area1, type, &member, &snapshot1);
-            const void* real_member2 = dwarf::resolve_member(real_area2, type, &member, &snapshot2);
-            if (heap_area_differ_with_type(process, state, real_member1, real_member2, snapshot1, snapshot2, previous,
-                                           member.type, -1, check_ignore, 0))
-              return true;
-          }
-        }
-        return false;
-
-    case DW_TAG_union_type:
-      return heap_area_differ_without_type(process, state, real_area1, real_area2, snapshot1, snapshot2, previous,
-                                           type->byte_size, check_ignore);
-
-    default:
-      THROW_IMPOSSIBLE;
-  }
-}
-
-/** 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               DWARF type ID of the root address
- * @param  area_size
- * @return                    DWARF type ID for given offset
- */
-static Type* get_offset_type(void* real_base_address, Type* type, int offset, int area_size, const Snapshot& snapshot)
-{
-  // Beginning of the block, the inferred 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 nullptr;
-    }
-
-    for (const simgrid::mc::Member& member : type->members) {
-      if (member.has_offset_location()) {
-        // We have the offset, use it directly (shortcut):
-        if (member.offset() == offset)
-          return member.type;
-      } else {
-        void* real_member = dwarf::resolve_member(real_base_address, type, &member, &snapshot);
-        if ((char*)real_member - (char*)real_base_address == offset)
-          return member.type;
-      }
-    }
-    return nullptr;
-
-  default:
-    /* FIXME: other cases ? */
-    return nullptr;
-  }
-}
-
-/**
- *
- * @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 nullptr)
- * @param type_id        Type of variable
- * @param pointer_level
- * @return true when different, false otherwise (same or unknown)
- */
-static bool heap_area_differ(const RemoteProcessMemory& process, StateComparator& state, const void* area1,
-                             const void* area2, const Snapshot& snapshot1, const Snapshot& snapshot2,
-                             HeapLocationPairs* previous, Type* type, int pointer_level)
-{
-  ssize_t block1;
-  ssize_t block2;
-  ssize_t size;
-  int check_ignore = 0;
-
-  int type_size = -1;
-  int offset1   = 0;
-  int offset2   = 0;
-  int new_size1 = -1;
-  int new_size2 = -1;
-
-  Type* new_type1 = nullptr;
-
-  bool match_pairs = false;
-
-  // This is the address of std_heap->heapinfo in the application process:
-  uint64_t heapinfo_address = process.heap_address.address() + offsetof(s_xbt_mheap_t, heapinfo);
-
-  const malloc_info* heapinfos1 = snapshot1.read(remote<malloc_info*>(heapinfo_address));
-  const malloc_info* heapinfos2 = snapshot2.read(remote<malloc_info*>(heapinfo_address));
-
-  malloc_info heapinfo_temp1;
-  malloc_info heapinfo_temp2;
-
-  simgrid::mc::HeapLocationPairs current;
-  if (previous == nullptr) {
-    previous = &current;
-    match_pairs = true;
-  }
-
-  // Get block number:
-  block1 = ((const char*)area1 - (const char*)state.std_heap_copy.heapbase) / BLOCKSIZE + 1;
-  block2 = ((const char*)area2 - (const char*)state.std_heap_copy.heapbase) / BLOCKSIZE + 1;
-
-  // If either block is a stack block:
-  if (is_block_stack(process, (int)block1) && is_block_stack(process, (int)block2)) {
-    previous->insert(HeapLocationPair{{HeapLocation(block1, -1), HeapLocation(block2, -1)}});
-    if (match_pairs)
-      state.match_equals(previous);
-    return false;
-  }
-
-  // If either block is not in the expected area of memory:
-  if (((const char*)area1 < (const char*)state.std_heap_copy.heapbase) ||
-      (block1 > (ssize_t)state.processStates[0].heapsize) ||
-      ((const char*)area2 < (const char*)state.std_heap_copy.heapbase) ||
-      (block2 > (ssize_t)state.processStates[1].heapsize)) {
-    return true;
-  }
-
-  // Process address of the block:
-  void* real_addr_block1 = (ADDR2UINT(block1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase;
-  void* real_addr_block2 = (ADDR2UINT(block2) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.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 != nullptr)
-      type = type->subtype;
-
-    // Find type_size:
-    if (type->type == DW_TAG_pointer_type ||
-        (type->type == DW_TAG_base_type && not type->name.empty() && type->name == "char"))
-      type_size = -1;
-    else
-      type_size = type->byte_size;
-  }
-
-  const Region* heap_region1 = MC_get_heap_region(snapshot1);
-  const Region* heap_region2 = MC_get_heap_region(snapshot2);
-
-  const auto* heapinfo1 =
-      static_cast<malloc_info*>(heap_region1->read(&heapinfo_temp1, &heapinfos1[block1], sizeof(malloc_info)));
-  const auto* heapinfo2 =
-      static_cast<malloc_info*>(heap_region2->read(&heapinfo_temp2, &heapinfos2[block2], sizeof(malloc_info)));
-
-  if ((heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type==MMALLOC_TYPE_HEAPINFO)
-    && (heapinfo2->type == MMALLOC_TYPE_FREE || heapinfo2->type ==MMALLOC_TYPE_HEAPINFO)) {
-    /* Free block */
-    if (match_pairs)
-      state.match_equals(previous);
-    return false;
-  }
-
-  if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED && heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) {
-    /* Complete block */
-
-    // TODO, lookup variable type from block type as done for fragmented blocks
-
-    if (state.equals_to_<1>(block1, 0).valid_ && state.equals_to_<2>(block2, 0).valid_ &&
-        state.blocksEqual(block1, block2)) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-
-    if (type_size != -1 && type_size != (ssize_t)heapinfo1->busy_block.busy_size &&
-        type_size != (ssize_t)heapinfo2->busy_block.busy_size && type->name.empty()) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-
-    if (heapinfo1->busy_block.size != heapinfo2->busy_block.size ||
-        heapinfo1->busy_block.busy_size != heapinfo2->busy_block.busy_size)
-      return true;
-
-    if (not previous->insert(HeapLocationPair{{HeapLocation(block1, -1), HeapLocation(block2, -1)}}).second) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-
-    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 != nullptr && area1 == real_addr_block1)
-      state.types_<1>(block1, 0) = type;
-    if (type != nullptr && area2 == real_addr_block2)
-      state.types_<2>(block2, 0) = type;
-
-    if (size <= 0) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-
-    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:
-    ssize_t frag1 = (ADDR2UINT(area1) % BLOCKSIZE) >> heapinfo1->type;
-    ssize_t frag2 = (ADDR2UINT(area2) % BLOCKSIZE) >> heapinfo2->type;
-
-    // Process address of the fragment_:
-    void* real_addr_frag1 = (char*)real_addr_block1 + (frag1 << heapinfo1->type);
-    void* real_addr_frag2 = (char*)real_addr_block2 + (frag2 << heapinfo2->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)
-          state.match_equals(previous);
-        return false;
-      }
-      // ?
-      if (type_size != heapinfo1->busy_frag.frag_size[frag1]
-          || type_size != heapinfo2->busy_frag.frag_size[frag2]) {
-        if (match_pairs)
-          state.match_equals(previous);
-        return false;
-      }
-    }
-
-    // Check if the blocks are already matched together:
-    if (state.equals_to_<1>(block1, frag1).valid_ && state.equals_to_<2>(block2, frag2).valid_ &&
-        state.fragmentsEqual(block1, frag1, block2, frag2)) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-    // 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)
-          state.match_equals(previous);
-        return false;
-      } else
-        return true;
-    }
-
-    // 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 fragment_.
-    if (type != nullptr && area1 == real_addr_frag1)
-      state.types_<1>(block1, frag1) = type;
-    if (type != nullptr && area2 == real_addr_frag2)
-      state.types_<2>(block2, frag2) = type;
-
-    // The type of the variable is already known:
-    if (type) {
-      new_type1 = type;
-    }
-    // Type inference from the block type.
-    else if (state.types_<1>(block1, frag1) != nullptr || state.types_<2>(block2, frag2) != nullptr) {
-      Type* new_type2 = nullptr;
-
-      offset1 = (const char*)area1 - (const char*)real_addr_frag1;
-      offset2 = (const char*)area2 - (const char*)real_addr_frag2;
-
-      if (state.types_<1>(block1, frag1) != nullptr && state.types_<2>(block2, frag2) != nullptr) {
-        new_type1 = get_offset_type(real_addr_frag1, state.types_<1>(block1, frag1), offset1, size, snapshot1);
-        new_type2 = get_offset_type(real_addr_frag2, state.types_<2>(block2, frag2), offset1, size, snapshot2);
-      } else if (state.types_<1>(block1, frag1) != nullptr) {
-        new_type1 = get_offset_type(real_addr_frag1, state.types_<1>(block1, frag1), offset1, size, snapshot1);
-        new_type2 = get_offset_type(real_addr_frag2, state.types_<1>(block1, frag1), offset2, size, snapshot2);
-      } else if (state.types_<2>(block2, frag2) != nullptr) {
-        new_type1 = get_offset_type(real_addr_frag1, state.types_<2>(block2, frag2), offset1, size, snapshot1);
-        new_type2 = get_offset_type(real_addr_frag2, state.types_<2>(block2, frag2), offset2, size, snapshot2);
-      } else {
-        if (match_pairs)
-          state.match_equals(previous);
-        return false;
-      }
-
-      if (new_type1 != nullptr && new_type2 != nullptr && new_type1 != new_type2) {
-        type = new_type1;
-        while (type->byte_size == 0 && type->subtype != nullptr)
-          type = type->subtype;
-        new_size1 = type->byte_size;
-
-        type = new_type2;
-        while (type->byte_size == 0 && type->subtype != nullptr)
-          type = type->subtype;
-        new_size2 = type->byte_size;
-
-      } else {
-        if (match_pairs)
-          state.match_equals(previous);
-        return false;
-      }
-    }
-
-    if (new_size1 > 0 && new_size1 == new_size2) {
-      type = new_type1;
-      size = new_size1;
-    }
-
-    if (offset1 == 0 && offset2 == 0 &&
-        not previous->insert(HeapLocationPair{{HeapLocation(block1, frag1), HeapLocation(block2, frag2)}}).second) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-
-    if (size <= 0) {
-      if (match_pairs)
-        state.match_equals(previous);
-      return false;
-    }
-
-    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
-    return true;
-
-  /* Start comparison */
-  if (type ? heap_area_differ_with_type(process, state, area1, area2, snapshot1, snapshot2, previous, type, size,
-                                        check_ignore, pointer_level)
-           : heap_area_differ_without_type(process, state, area1, area2, snapshot1, snapshot2, previous, size,
-                                           check_ignore))
-    return true;
-
-  if (match_pairs)
-    state.match_equals(previous);
-  return false;
-}
-} // namespace simgrid::mc
-
-/************************** Snapshot comparison *******************************/
-/******************************************************************************/
-
-static bool areas_differ_with_type(const simgrid::mc::RemoteProcessMemory& process, simgrid::mc::StateComparator& state,
-                                   const void* real_area1, const simgrid::mc::Snapshot& snapshot1,
-                                   simgrid::mc::Region* region1, const void* real_area2,
-                                   const simgrid::mc::Snapshot& snapshot2, simgrid::mc::Region* region2,
-                                   const simgrid::mc::Type* type, int pointer_level)
-{
-  const simgrid::mc::Type* subtype;
-  const simgrid::mc::Type* subsubtype;
-  int elm_size;
-
-  xbt_assert(type != nullptr);
-  switch (type->type) {
-    case DW_TAG_unspecified_type:
-      return true;
-
-    case DW_TAG_base_type:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_union_type:
-      return MC_snapshot_region_memcmp(real_area1, region1, real_area2, region2, type->byte_size) != 0;
-    case DW_TAG_typedef:
-    case DW_TAG_volatile_type:
-    case DW_TAG_const_type:
-      return areas_differ_with_type(process, state, real_area1, snapshot1, region1, real_area2, snapshot2, region2,
-                                    type->subtype, pointer_level);
-    case DW_TAG_array_type:
-      subtype = type->subtype;
-      switch (subtype->type) {
-        case DW_TAG_unspecified_type:
-          return true;
-
-        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 false;
-      }
-      for (int i = 0; i < type->element_count; i++) {
-        size_t off = i * elm_size;
-        if (areas_differ_with_type(process, state, (const char*)real_area1 + off, snapshot1, region1,
-                                   (const char*)real_area2 + off, snapshot2, region2, type->subtype, pointer_level))
-          return true;
-      }
-      break;
-    case DW_TAG_pointer_type:
-    case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type: {
-      const void* addr_pointed1 = MC_region_read_pointer(region1, real_area1);
-      const void* addr_pointed2 = MC_region_read_pointer(region2, real_area2);
-
-      if (type->subtype && type->subtype->type == DW_TAG_subroutine_type)
-        return (addr_pointed1 != addr_pointed2);
-      if (addr_pointed1 == nullptr && addr_pointed2 == nullptr)
-        return false;
-      if (addr_pointed1 == nullptr || addr_pointed2 == nullptr)
-        return true;
-      if (not state.compared_pointers.insert(std::make_pair(addr_pointed1, addr_pointed2)).second)
-        return false;
-
-      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 (snapshot1.on_heap(addr_pointed1)) {
-        if (not snapshot2.on_heap(addr_pointed2))
-          return true;
-        // The pointers are both in the heap:
-        return simgrid::mc::heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2,
-                                             nullptr, type->subtype, pointer_level);
-
-      } else if (region1->contain(simgrid::mc::remote(addr_pointed1))) {
-        // The pointers are both in the current object R/W segment:
-        if (not region2->contain(simgrid::mc::remote(addr_pointed2)))
-          return true;
-        if (not type->type_id)
-          return (addr_pointed1 != addr_pointed2);
-        else
-          return areas_differ_with_type(process, state, addr_pointed1, snapshot1, region1, addr_pointed2, snapshot2,
-                                        region2, type->subtype, pointer_level);
-      } else {
-        // TODO, We do not handle very well the case where
-        // it belongs to a different (non-heap) region from the current one.
-
-        return (addr_pointed1 != addr_pointed2);
-      }
-    }
-    case DW_TAG_structure_type:
-    case DW_TAG_class_type:
-      for (const simgrid::mc::Member& member : type->members) {
-        const void* member1             = simgrid::dwarf::resolve_member(real_area1, type, &member, &snapshot1);
-        const void* member2             = simgrid::dwarf::resolve_member(real_area2, type, &member, &snapshot2);
-        simgrid::mc::Region* subregion1 = snapshot1.get_region(member1, region1); // region1 is hinted
-        simgrid::mc::Region* subregion2 = snapshot2.get_region(member2, region2); // region2 is hinted
-        if (areas_differ_with_type(process, state, member1, snapshot1, subregion1, member2, snapshot2, subregion2,
-                                   member.type, pointer_level))
-          return true;
-      }
-      break;
-    case DW_TAG_subroutine_type:
-      return false;
-    default:
-      XBT_VERB("Unknown case: %d", type->type);
-      break;
-  }
-
-  return false;
-}
-
-static bool global_variables_differ(const simgrid::mc::RemoteProcessMemory& process,
-                                    simgrid::mc::StateComparator& state,
-                                    const simgrid::mc::ObjectInformation* object_info, simgrid::mc::Region* r1,
-                                    simgrid::mc::Region* r2, const simgrid::mc::Snapshot& snapshot1,
-                                    const simgrid::mc::Snapshot& snapshot2)
-{
-  xbt_assert(r1 && r2, "Missing region.");
-
-  const std::vector<simgrid::mc::Variable>& variables = object_info->global_variables;
-
-  for (simgrid::mc::Variable const& current_var : variables) {
-    // 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 < object_info->start_rw || (char*)current_var.address > object_info->end_rw)
-      continue;
-
-    const simgrid::mc::Type* bvariable_type = current_var.type;
-    if (areas_differ_with_type(process, state, current_var.address, snapshot1, r1, current_var.address, snapshot2, r2,
-                               bvariable_type, 0)) {
-      XBT_VERB("Global variable %s (%p) is different between snapshots", current_var.name.c_str(), current_var.address);
-      return true;
-    }
-  }
-
-  return false;
-}
-
-static bool local_variables_differ(const simgrid::mc::RemoteProcessMemory& process, simgrid::mc::StateComparator& state,
-                                   const simgrid::mc::Snapshot& snapshot1, const simgrid::mc::Snapshot& snapshot2,
-                                   const_mc_snapshot_stack_t stack1, const_mc_snapshot_stack_t stack2)
-{
-  if (stack1->local_variables.size() != stack2->local_variables.size()) {
-    XBT_VERB("Different number of local variables");
-    return true;
-  }
-
-  for (unsigned int cursor = 0; cursor < stack1->local_variables.size(); cursor++) {
-    const_local_variable_t current_var1 = &stack1->local_variables[cursor];
-    const_local_variable_t current_var2 = &stack2->local_variables[cursor];
-    if (current_var1->name != current_var2->name || current_var1->subprogram != current_var2->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.c_str(),
-               current_var2->name.c_str(), current_var1->subprogram->name.c_str(),
-               current_var2->subprogram->name.c_str(), current_var1->ip, current_var2->ip);
-      return true;
-    }
-
-    if (areas_differ_with_type(process, state, current_var1->address, snapshot1,
-                               snapshot1.get_region(current_var1->address), current_var2->address, snapshot2,
-                               snapshot2.get_region(current_var2->address), current_var1->type, 0)) {
-      XBT_VERB("Local variable %s (%p - %p) in frame %s is different between snapshots", current_var1->name.c_str(),
-               current_var1->address, current_var2->address, current_var1->subprogram->name.c_str());
-      return true;
-    }
-  }
-  return false;
-}
-
-namespace simgrid::mc {
-bool Snapshot::equals_to(const Snapshot& other, RemoteProcessMemory& memory)
-{
-  /* TODO: the memory parameter should be eventually removed. It seems to be there because each snapshot lacks some sort
-    of metadata. That's OK for now (letting appart the fact that we cannot have a nice operator== because we need that
-    extra parameter), but it will fall short when we want to have parallel explorations, with more than one
-    RemoteProcess. At the very least, snapshots will need to know the remote process they are corresponding to, and more
-    probably they will need to embeed all their metadata to let the remoteprocesses die before the end of the
-    exploration. */
-
-  /* TODO: This method should moved to Snapshot.cpp, but it needs the StateComparator that is declared locally to this
-   * file only. */
-
-  static StateComparator state_comparator; // TODO, make this a field of a persistant state object
-
-  if (hash_ != other.hash_) {
-    XBT_VERB("(%ld - %ld) Different hash: 0x%" PRIx64 "--0x%" PRIx64, this->num_state_, other.num_state_, this->hash_,
-             other.hash_);
-    return false;
-  }
-  XBT_VERB("(%ld - %ld) Same hash: 0x%" PRIx64, this->num_state_, other.num_state_, this->hash_);
-
-  /* TODO: re-enable the quick filter of counting enabled processes in each snapshots */
-
-  /* Compare size of stacks */
-  for (unsigned long i = 0; i < this->stacks_.size(); i++) {
-    size_t size_used1 = this->stack_sizes_[i];
-    size_t size_used2 = other.stack_sizes_[i];
-    if (size_used1 != size_used2) {
-      XBT_VERB("(%ld - %ld) Different size used in stacks: %zu - %zu", num_state_, other.num_state_, size_used1,
-               size_used2);
-      return false;
-    }
-  }
-
-  /* Init heap information used in heap comparison algorithm */
-  const s_xbt_mheap_t* heap1 = static_cast<xbt_mheap_t>(
-      this->read_bytes(alloca(sizeof(s_xbt_mheap_t)), sizeof(s_xbt_mheap_t), memory.heap_address, ReadOptions::lazy()));
-  const s_xbt_mheap_t* heap2 = static_cast<xbt_mheap_t>(
-      other.read_bytes(alloca(sizeof(s_xbt_mheap_t)), sizeof(s_xbt_mheap_t), memory.heap_address, ReadOptions::lazy()));
-  if (state_comparator.initHeapInformation(memory, heap1, heap2, this->to_ignore_, other.to_ignore_) == -1) {
-    XBT_VERB("(%ld - %ld) Different heap information", this->num_state_, other.num_state_);
-    return false;
-  }
-
-  /* Stacks comparison */
-  for (unsigned int cursor = 0; cursor < this->stacks_.size(); cursor++) {
-    const_mc_snapshot_stack_t stack1 = &this->stacks_[cursor];
-    const_mc_snapshot_stack_t stack2 = &other.stacks_[cursor];
-
-    if (local_variables_differ(memory, state_comparator, *this, other, stack1, stack2)) {
-      XBT_VERB("(%ld - %ld) Different local variables between stacks %u", this->num_state_, other.num_state_,
-               cursor + 1);
-      return false;
-    }
-  }
-
-  size_t regions_count = this->snapshot_regions_.size();
-  if (regions_count != other.snapshot_regions_.size())
-    return false;
-
-  for (size_t k = 0; k != regions_count; ++k) {
-    Region* region1 = this->snapshot_regions_[k].get();
-    Region* region2 = other.snapshot_regions_[k].get();
-
-    // Preconditions:
-    if (region1->region_type() != RegionType::Data)
-      continue;
-
-    xbt_assert(region1->region_type() == region2->region_type());
-    xbt_assert(region1->object_info() == region2->object_info());
-    xbt_assert(region1->object_info());
-
-    /* Compare global variables */
-    if (global_variables_differ(memory, state_comparator, region1->object_info(), region1, region2, *this, other)) {
-      std::string const& name = region1->object_info()->file_name;
-      XBT_VERB("(%ld - %ld) Different global variables in %s", this->num_state_, other.num_state_, name.c_str());
-      return false;
-    }
-  }
-
-  XBT_VERB("   Compare heap...");
-  /* Compare heap */
-  if (mmalloc_heap_differ(memory, state_comparator, *this, other)) {
-    XBT_VERB("(%ld - %ld) Different heap (mmalloc_heap_differ)", this->num_state_, other.num_state_);
-    return false;
-  }
-
-  XBT_VERB("(%ld - %ld) No difference found", this->num_state_, other.num_state_);
-
-  return true;
-}
-} // namespace simgrid::mc
index 8a70fc7..639b28c 100644 (file)
@@ -14,6 +14,7 @@
 #include "xbt/string.hpp"
 
 #include <cstdint>
+#include <inttypes.h>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_comm_determinism, mc, "Logging specific to MC communication determinism detection");
 
@@ -327,7 +328,7 @@ Exploration* create_communication_determinism_checker(const std::vector<char*>&
 
   XBT_DEBUG("********* Start communication determinism verification *********");
 
-  auto* base      = new DFSExplorer(args, mode, true);
+  auto* base      = new DFSExplorer(args, mode);
   auto* extension = new CommDetExtension(*base);
 
   DFSExplorer::on_exploration_start([extension](RemoteApp const&) {
index b23ce48..f82d8da 100644 (file)
 #include "src/mc/mc_record.hpp"
 #include "src/mc/transition/Transition.hpp"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/VisitedState.hpp"
-#endif
-
-#include "src/xbt/mmalloc/mmprivate.h"
 #include "xbt/log.h"
 #include "xbt/string.hpp"
 #include "xbt/sysdep.h"
@@ -44,30 +39,6 @@ xbt::signal<void(Transition*, RemoteApp&)> DFSExplorer::on_transition_execute_si
 
 xbt::signal<void(RemoteApp&)> DFSExplorer::on_log_state_signal;
 
-void DFSExplorer::check_non_termination(const State* current_state)
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  for (auto const& state : stack_) {
-    if (state->get_system_state()->equals_to(*current_state->get_system_state(),
-                                             *get_remote_app().get_remote_process_memory())) {
-      XBT_INFO("Non-progressive cycle: state %ld -> state %ld", state->get_num(), current_state->get_num());
-      XBT_INFO("******************************************");
-      XBT_INFO("*** NON-PROGRESSIVE CYCLE DETECTED ***");
-      XBT_INFO("******************************************");
-      XBT_INFO("Counter-example execution trace:");
-      for (auto const& s : get_textual_trace())
-        XBT_INFO("  %s", s.c_str());
-      XBT_INFO("You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with "
-               "--cfg=model-check/replay:'%s'",
-               get_record_trace().to_string().c_str());
-      log_state();
-
-      throw McError(ExitStatus::NON_TERMINATION);
-    }
-  }
-#endif
-}
-
 RecordTrace DFSExplorer::get_record_trace() // override
 {
   RecordTrace res;
@@ -152,18 +123,6 @@ void DFSExplorer::run()
       continue;
     }
 
-#if SIMGRID_HAVE_STATEFUL_MC
-    // Backtrack if we are revisiting a state we saw previously while applying state-equality reduction
-    if (visited_state_ != nullptr) {
-      XBT_DEBUG("State already visited (equal to state %ld), exploration stopped on this path.",
-                visited_state_->original_num_ == -1 ? visited_state_->num_ : visited_state_->original_num_);
-
-      visited_state_ = nullptr;
-      this->backtrack();
-      continue;
-    }
-#endif
-
     if (reduction_mode_ == ReductionMode::odpor) {
       // In the case of ODPOR, the wakeup tree for this
       // state may be empty if we're exploring new territory
@@ -253,8 +212,10 @@ void DFSExplorer::run()
           continue;
         } else if (prev_state->get_transition_out()->depends(state->get_transition_out().get())) {
           XBT_VERB("Dependent Transitions:");
-          XBT_VERB("  %s (state=%ld)", prev_state->get_transition_out()->to_string().c_str(), prev_state->get_num());
-          XBT_VERB("  %s (state=%ld)", state->get_transition_out()->to_string().c_str(), state->get_num());
+          XBT_VERB(" #%ld %s (state=%ld)", prev_state->get_transition_out()->aid_,
+                   prev_state->get_transition_out()->to_string().c_str(), prev_state->get_num());
+          XBT_VERB(" #%ld %s (state=%ld)", state->get_transition_out()->aid_,
+                   state->get_transition_out()->to_string().c_str(), state->get_num());
 
           if (prev_state->is_actor_enabled(issuer_id)) {
             if (not prev_state->is_actor_done(issuer_id)) {
@@ -273,8 +234,10 @@ void DFSExplorer::run()
           break;
         } else {
           XBT_VERB("INDEPENDENT Transitions:");
-          XBT_VERB("  %s (state=%ld)", prev_state->get_transition_out()->to_string().c_str(), prev_state->get_num());
-          XBT_VERB("  %s (state=%ld)", state->get_transition_out()->to_string().c_str(), state->get_num());
+          XBT_VERB(" #%ld %s (state=%ld)", prev_state->get_transition_out()->aid_,
+                   prev_state->get_transition_out()->to_string().c_str(), prev_state->get_num());
+          XBT_VERB(" #%ld %s (state=%ld)", state->get_transition_out()->aid_,
+                   state->get_transition_out()->to_string().c_str(), state->get_num());
         }
         tmp_stack.pop_back();
       }
@@ -324,36 +287,18 @@ void DFSExplorer::run()
     if (stack_.back()->count_todo_multiples() > 0)
       opened_states_.emplace_back(stack_.back());
 
-    if (_sg_mc_termination)
-      this->check_non_termination(next_state.get());
-
-#if SIMGRID_HAVE_STATEFUL_MC
-    /* Check whether we already explored next_state in the past (but only if interested in state-equality reduction)
-     */
-    if (_sg_mc_max_visited_states > 0)
-      visited_state_ = visited_states_.addVisitedState(next_state->get_num(), next_state.get(), get_remote_app());
-#endif
-
     stack_.emplace_back(std::move(next_state));
 
     /* If this is a new state (or if we don't care about state-equality reduction) */
-    if (visited_state_ == nullptr) {
-      /* Get an enabled process and insert it in the interleave set of the next state */
-      if (reduction_mode_ == ReductionMode::dpor)
-        stack_.back()->consider_best(); // Take only one transition if DPOR: others may be considered later if required
-      else {
-        stack_.back()->consider_all();
-      }
-
-      dot_output("\"%ld\" -> \"%ld\" [%s];\n", state->get_num(), stack_.back()->get_num(),
-                 state->get_transition_out()->dot_string().c_str());
-#if SIMGRID_HAVE_STATEFUL_MC
-    } else {
-      dot_output("\"%ld\" -> \"%ld\" [%s];\n", state->get_num(),
-                 visited_state_->original_num_ == -1 ? visited_state_->num_ : visited_state_->original_num_,
-                 state->get_transition_out()->dot_string().c_str());
-#endif
+    /* Get an enabled process and insert it in the interleave set of the next state */
+    if (reduction_mode_ == ReductionMode::dpor)
+      stack_.back()->consider_best(); // Take only one transition if DPOR: others may be considered later if required
+    else {
+      stack_.back()->consider_all();
     }
+
+    dot_output("\"%ld\" -> \"%ld\" [%s];\n", state->get_num(), stack_.back()->get_num(),
+               state->get_transition_out()->dot_string().c_str());
   }
   log_state();
 }
@@ -486,41 +431,16 @@ void DFSExplorer::backtrack()
   backtrack_count_++;
   XBT_DEBUG("Backtracking to state#%ld", backtracking_point->get_num());
 
-#if SIMGRID_HAVE_STATEFUL_MC
-  /* If asked to rollback on a state that has a snapshot, restore it */
-  if (const auto* system_state = backtracking_point->get_system_state()) {
-    system_state->restore(*get_remote_app().get_remote_process_memory());
-    on_restore_system_state_signal(backtracking_point.get(), get_remote_app());
-    this->restore_stack(backtracking_point);
-    return;
-  }
-#endif
-
   // Search how to restore the backtracking point
-  State* init_state = nullptr;
   std::deque<Transition*> replay_recipe;
   for (auto* s = backtracking_point.get(); s != nullptr; s = s->get_parent_state().get()) {
-#if SIMGRID_HAVE_STATEFUL_MC
-    if (s->get_system_state() != nullptr) { // Found a state that I can restore
-      init_state = s;
-      break;
-    }
-#endif
     if (s->get_transition_in() != nullptr) // The root has no transition_in
       replay_recipe.push_front(s->get_transition_in().get());
   }
 
-  // Restore the init_state, if any
-  if (init_state != nullptr) {
-#if SIMGRID_HAVE_STATEFUL_MC
-    const auto* system_state = init_state->get_system_state();
-    system_state->restore(*get_remote_app().get_remote_process_memory());
-    on_restore_system_state_signal(init_state, get_remote_app());
-#endif
-  } else { // Restore the initial state if no intermediate state was found
-    get_remote_app().restore_initial_state();
-    on_restore_initial_state_signal(get_remote_app());
-  }
+  // Restore the initial state if no intermediate state was found
+  get_remote_app().restore_initial_state();
+  on_restore_initial_state_signal(get_remote_app());
 
   /* if no snapshot, we need to restore the initial state and replay the transitions */
   /* Traverse the stack from the state at position start and re-execute the transitions */
@@ -532,23 +452,9 @@ void DFSExplorer::backtrack()
   this->restore_stack(backtracking_point);
 }
 
-DFSExplorer::DFSExplorer(const std::vector<char*>& args, ReductionMode mode, bool need_memory_info)
-    : Exploration(args, need_memory_info || _sg_mc_termination
-#if SIMGRID_HAVE_STATEFUL_MC
-                            || _sg_mc_checkpoint > 0
-#endif
-                  )
-    , reduction_mode_(mode)
+DFSExplorer::DFSExplorer(const std::vector<char*>& args, ReductionMode mode) : Exploration(args), reduction_mode_(mode)
 {
-  if (_sg_mc_termination) {
-    if (mode != ReductionMode::none) {
-      XBT_INFO("Check non progressive cycles (turning DPOR off)");
-      reduction_mode_ = ReductionMode::none;
-    } else {
-      XBT_INFO("Check non progressive cycles");
-    }
-  } else
-    XBT_INFO("Start a DFS exploration. Reduction is: %s.", to_c_str(reduction_mode_));
+  XBT_INFO("Start a DFS exploration. Reduction is: %s.", to_c_str(reduction_mode_));
 
   auto initial_state = std::make_shared<State>(get_remote_app());
 
index a0dc478..bb80b08 100644 (file)
 #include "src/mc/explo/odpor/Execution.hpp"
 #include "src/mc/mc_config.hpp"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/VisitedState.hpp"
-#endif
-
 #include <deque>
 #include <list>
 #include <memory>
@@ -47,7 +43,7 @@ private:
   static xbt::signal<void(RemoteApp&)> on_log_state_signal;
 
 public:
-  explicit DFSExplorer(const std::vector<char*>& args, ReductionMode mode, bool need_memory_info = false);
+  explicit DFSExplorer(const std::vector<char*>& args, ReductionMode mode);
   void run() override;
   RecordTrace get_record_trace() override;
   void log_state() override;
@@ -92,7 +88,6 @@ public:
   static void on_log_state(std::function<void(RemoteApp&)> const& f) { on_log_state_signal.connect(f); }
 
 private:
-  void check_non_termination(const State* current_state);
   void backtrack();
 
   /** Stack representing the position in the exploration graph */
@@ -107,13 +102,6 @@ private:
   /** Per-actor clock vectors used to compute the "happens-before" relation */
   std::unordered_map<aid_t, ClockVector> per_actor_clocks_;
 
-#if SIMGRID_HAVE_STATEFUL_MC
-  VisitedStates visited_states_;
-  std::unique_ptr<VisitedState> visited_state_;
-#else
-  void* visited_state_ = nullptr; /* The code uses it to detect whether we are doing stateful MC */
-#endif
-
   /** Opened states are states that still contains todo actors.
    *  When backtracking, we pick a state from it*/
   std::vector<std::shared_ptr<State>> opened_states_;
index 3c8e650..58bc34d 100644 (file)
 #include "src/mc/mc_private.hpp"
 #include "xbt/string.hpp"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-#endif
-
 #include <sys/wait.h>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_explo, mc, "Generic exploration algorithm of the model-checker");
@@ -25,8 +21,7 @@ static simgrid::config::Flag<std::string> cfg_dot_output_file{
 
 Exploration* Exploration::instance_ = nullptr; // singleton instance
 
-Exploration::Exploration(const std::vector<char*>& args, bool need_memory_introspection)
-    : remote_app_(std::make_unique<RemoteApp>(args, need_memory_introspection))
+Exploration::Exploration(const std::vector<char*>& args) : remote_app_(std::make_unique<RemoteApp>(args))
 {
   xbt_assert(instance_ == nullptr, "Cannot have more than one exploration instance");
   instance_ = this;
@@ -83,7 +78,7 @@ static const char* signal_name(int status)
   }
 }
 
-std::vector<std::string> Exploration::get_textual_trace()
+std::vector<std::string> Exploration::get_textual_trace(int max_elements)
 {
   std::vector<std::string> trace;
   for (auto const& transition : get_record_trace()) {
@@ -93,6 +88,9 @@ std::vector<std::string> Exploration::get_textual_trace()
                                          transition->to_string().c_str()));
     else
       trace.push_back(xbt::string_printf("Actor %ld in simcall %s", transition->aid_, transition->to_string().c_str()));
+    max_elements--;
+    if (max_elements == 0)
+      break;
   }
   return trace;
 }
@@ -116,18 +114,6 @@ XBT_ATTRIB_NORETURN void Exploration::report_crash(int status)
            "--cfg=model-check/replay:'%s'",
            get_record_trace().to_string().c_str());
   log_state();
-  if (xbt_log_no_loc) {
-    XBT_INFO("Stack trace not displayed because you passed --log=no_loc");
-  } else {
-#if SIMGRID_HAVE_STATEFUL_MC
-    const auto* memory = get_remote_app().get_remote_process_memory();
-    if (memory) {
-      XBT_INFO("Stack trace:");
-      memory->dump_stack();
-    } else
-#endif
-      XBT_INFO("Stack trace not shown because there is no memory introspection.");
-  }
 
   throw McError(ExitStatus::PROGRAM_CRASH);
 }
index 64114d4..8ef417c 100644 (file)
@@ -36,7 +36,7 @@ class Exploration : public xbt::Extendable<Exploration> {
   FILE* dot_output_ = nullptr;
 
 public:
-  explicit Exploration(const std::vector<char*>& args, bool need_memory_introspection);
+  explicit Exploration(const std::vector<char*>& args);
   virtual ~Exploration();
 
   static Exploration* get_instance() { return instance_; }
@@ -60,7 +60,7 @@ public:
   virtual RecordTrace get_record_trace() = 0;
 
   /** Generate a textual execution trace of the simulated application */
-  std::vector<std::string> get_textual_trace();
+  std::vector<std::string> get_textual_trace(int max_elements = -1);
 
   /** Log additional information about the state of the model-checker */
   virtual void log_state();
@@ -72,7 +72,6 @@ public:
 };
 
 // External constructors so that the types (and the types of their content) remain hidden
-XBT_PUBLIC Exploration* create_liveness_checker(const std::vector<char*>& args);
 XBT_PUBLIC Exploration* create_dfs_exploration(const std::vector<char*>& args, ReductionMode mode);
 XBT_PUBLIC Exploration* create_communication_determinism_checker(const std::vector<char*>& args, ReductionMode mode);
 XBT_PUBLIC Exploration* create_udpor_checker(const std::vector<char*>& args);
diff --git a/src/mc/explo/LivenessChecker.cpp b/src/mc/explo/LivenessChecker.cpp
deleted file mode 100644 (file)
index 3d60ef9..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-/* Copyright (c) 2011-2023. 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 "src/mc/explo/LivenessChecker.hpp"
-#include "src/mc/api/RemoteApp.hpp"
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_exit.hpp"
-#include "src/mc/mc_private.hpp"
-
-#include <boost/range/algorithm.hpp>
-#include <cstring>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc, "Logging specific to algorithms for liveness properties verification");
-
-/********* Static functions *********/
-
-namespace simgrid::mc {
-
-VisitedPair::VisitedPair(int pair_num, xbt_automaton_state_t prop_state,
-                         std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> app_state,
-                         RemoteApp& remote_app)
-    : num(pair_num), prop_state_(prop_state)
-{
-  auto* memory     = remote_app.get_remote_process_memory();
-  this->app_state_ = std::move(app_state);
-  if (not this->app_state_->get_system_state())
-    this->app_state_->set_system_state(std::make_shared<Snapshot>(pair_num, remote_app.get_page_store(), *memory));
-  this->heap_bytes_used     = memory->get_remote_heap_bytes();
-  this->actor_count_        = app_state_->get_actor_count();
-  this->other_num           = -1;
-  this->atomic_propositions = std::move(atomic_propositions);
-}
-
-bool LivenessChecker::evaluate_label(const xbt_automaton_exp_label* l, std::vector<int> const& values)
-{
-  switch (l->type) {
-    case xbt_automaton_exp_label::AUT_OR:
-      return evaluate_label(l->u.or_and.left_exp, values) || evaluate_label(l->u.or_and.right_exp, values);
-    case xbt_automaton_exp_label::AUT_AND:
-      return evaluate_label(l->u.or_and.left_exp, values) && evaluate_label(l->u.or_and.right_exp, values);
-    case xbt_automaton_exp_label::AUT_NOT:
-      return not evaluate_label(l->u.exp_not, values);
-    case xbt_automaton_exp_label::AUT_PREDICAT:
-      return values.at(compare_automaton_exp_label(l)) != 0;
-    case xbt_automaton_exp_label::AUT_ONE:
-      return true;
-    default:
-      xbt_die("Unexpected value for automaton");
-  }
-}
-
-Pair::Pair(unsigned long expanded_pairs) : num(expanded_pairs) {}
-
-std::shared_ptr<const std::vector<int>> LivenessChecker::get_proposition_values() const
-{
-  auto values = automaton_propositional_symbol_evaluate();
-  return std::make_shared<const std::vector<int>>(std::move(values));
-}
-
-std::shared_ptr<VisitedPair> LivenessChecker::insert_acceptance_pair(simgrid::mc::Pair* pair)
-{
-  auto new_pair = std::make_shared<VisitedPair>(pair->num, pair->prop_state_, pair->atomic_propositions,
-                                                pair->app_state_, get_remote_app());
-
-  auto [res_begin,
-        res_end] = boost::range::equal_range(acceptance_pairs_, new_pair.get(), [](auto const& a, auto const& b) {
-    return std::make_pair(a->actor_count_, a->heap_bytes_used) < std::make_pair(b->actor_count_, b->heap_bytes_used);
-  });
-
-  if (pair->search_cycle)
-    for (auto i = res_begin; i != res_end; ++i) {
-      std::shared_ptr<simgrid::mc::VisitedPair> const& pair_test = *i;
-      if (xbt_automaton_state_compare(pair_test->prop_state_, new_pair->prop_state_) != 0 ||
-          *(pair_test->atomic_propositions) != *(new_pair->atomic_propositions) ||
-          (not pair_test->app_state_->get_system_state()->equals_to(*new_pair->app_state_->get_system_state(),
-                                                                    *get_remote_app().get_remote_process_memory())))
-        continue;
-      XBT_INFO("Pair %d already reached (equal to pair %d) !", new_pair->num, pair_test->num);
-      exploration_stack_.pop_back();
-      dot_output("\"%d\" -> \"%d\" [%s];\n", this->previous_pair_, pair_test->num, this->previous_request_.c_str());
-      return nullptr;
-    }
-
-  acceptance_pairs_.insert(res_begin, new_pair);
-  return new_pair;
-}
-
-void LivenessChecker::remove_acceptance_pair(int pair_num)
-{
-  for (auto i = acceptance_pairs_.begin(); i != acceptance_pairs_.end(); ++i)
-    if ((*i)->num == pair_num) {
-      acceptance_pairs_.erase(i);
-      break;
-    }
-}
-
-void LivenessChecker::replay()
-{
-  XBT_DEBUG("**** Begin Replay ****");
-
-  /* Intermediate backtracking */
-  if (_sg_mc_checkpoint > 0) {
-    const Pair* pair = exploration_stack_.back().get();
-    if (const auto* system_state = pair->app_state_->get_system_state()) {
-      system_state->restore(*get_remote_app().get_remote_process_memory());
-      return;
-    }
-  }
-
-  get_remote_app().restore_initial_state();
-
-  /* Traverse the stack from the initial state and re-execute the transitions */
-  int depth = 1;
-  for (std::shared_ptr<Pair> const& pair : exploration_stack_) {
-    if (pair == exploration_stack_.back())
-      break;
-
-    std::shared_ptr<State> state = pair->app_state_;
-
-    if (pair->exploration_started) {
-      state->get_transition_out()->replay(get_remote_app());
-      XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, state->get_transition_out()->to_string().c_str(), state.get());
-    }
-
-    /* Update statistics */
-    visited_pairs_count_++;
-    depth++;
-  }
-  XBT_DEBUG("**** End Replay ****");
-}
-
-/**
- * @brief Checks whether a given pair has already been visited by the algorithm.
- */
-int LivenessChecker::insert_visited_pair(std::shared_ptr<VisitedPair> visited_pair, simgrid::mc::Pair* pair)
-{
-  if (_sg_mc_max_visited_states == 0)
-    return -1;
-
-  if (visited_pair == nullptr)
-    visited_pair = std::make_shared<VisitedPair>(pair->num, pair->prop_state_, pair->atomic_propositions,
-                                                 pair->app_state_, get_remote_app());
-
-  auto [range_begin,
-        range_end] = boost::range::equal_range(visited_pairs_, visited_pair.get(), [](auto const& a, auto const& b) {
-    return std::make_pair(a->actor_count_, a->heap_bytes_used) < std::make_pair(b->actor_count_, b->heap_bytes_used);
-  });
-
-  for (auto i = range_begin; i != range_end; ++i) {
-    const VisitedPair* pair_test = i->get();
-    if (xbt_automaton_state_compare(pair_test->prop_state_, visited_pair->prop_state_) != 0 ||
-        *(pair_test->atomic_propositions) != *(visited_pair->atomic_propositions) ||
-        (not pair_test->app_state_->get_system_state()->equals_to(*visited_pair->app_state_->get_system_state(),
-                                                                  *get_remote_app().get_remote_process_memory())))
-      continue;
-    if (pair_test->other_num == -1)
-      visited_pair->other_num = pair_test->num;
-    else
-      visited_pair->other_num = pair_test->other_num;
-    XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", visited_pair->num, pair_test->num,
-              visited_pair->other_num);
-    (*i) = std::move(visited_pair);
-    return (*i)->other_num;
-  }
-
-  visited_pairs_.insert(range_begin, std::move(visited_pair));
-  this->purge_visited_pairs();
-  return -1;
-}
-
-void LivenessChecker::purge_visited_pairs()
-{
-  if (_sg_mc_max_visited_states != 0 && visited_pairs_.size() > (std::size_t)_sg_mc_max_visited_states) {
-    // Remove the oldest entry with a linear search:
-    visited_pairs_.erase(
-        boost::min_element(visited_pairs_, [](std::shared_ptr<VisitedPair> const a,
-                                              std::shared_ptr<VisitedPair> const& b) { return a->num < b->num; }));
-  }
-}
-
-LivenessChecker::LivenessChecker(const std::vector<char*>& args) : Exploration(args, true) {}
-LivenessChecker::~LivenessChecker()
-{
-  xbt_automaton_free(property_automaton_);
-}
-
-xbt_automaton_t LivenessChecker::property_automaton_ = nullptr;
-
-void LivenessChecker::automaton_load(const char* file) const
-{
-  if (property_automaton_ == nullptr)
-    property_automaton_ = xbt_automaton_new();
-
-  xbt_automaton_load(property_automaton_, file);
-}
-
-std::vector<int> LivenessChecker::automaton_propositional_symbol_evaluate() const
-{
-  unsigned int cursor = 0;
-  std::vector<int> values;
-  xbt_automaton_propositional_symbol_t ps = nullptr;
-  xbt_dynar_foreach (property_automaton_->propositional_symbols, cursor, ps)
-    values.push_back(xbt_automaton_propositional_symbol_evaluate(ps));
-  return values;
-}
-
-std::vector<xbt_automaton_state_t> LivenessChecker::get_automaton_state() const
-{
-  std::vector<xbt_automaton_state_t> automaton_stack;
-  unsigned int cursor = 0;
-  xbt_automaton_state_t automaton_state;
-  xbt_dynar_foreach (property_automaton_->states, cursor, automaton_state)
-    if (automaton_state->type == -1)
-      automaton_stack.push_back(automaton_state);
-  return automaton_stack;
-}
-
-int LivenessChecker::compare_automaton_exp_label(const xbt_automaton_exp_label* l) const
-{
-  unsigned int cursor                    = 0;
-  xbt_automaton_propositional_symbol_t p = nullptr;
-  xbt_dynar_foreach (property_automaton_->propositional_symbols, cursor, p) {
-    if (std::strcmp(xbt_automaton_propositional_symbol_get_name(p), l->u.predicat) == 0)
-      return cursor;
-  }
-  return -1;
-}
-
-void LivenessChecker::set_property_automaton(xbt_automaton_state_t const& automaton_state) const
-{
-  property_automaton_->current_state = automaton_state;
-}
-
-xbt_automaton_exp_label_t LivenessChecker::get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const
-{
-  const xbt_automaton_transition* transition = xbt_dynar_get_as(dynar, index, xbt_automaton_transition_t);
-  return transition->label;
-}
-
-xbt_automaton_state_t LivenessChecker::get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const
-{
-  const xbt_automaton_transition* transition = xbt_dynar_get_as(dynar, index, xbt_automaton_transition_t);
-  return transition->dst;
-}
-void LivenessChecker::automaton_register_symbol(RemoteProcessMemory const& remote_process, const char* name,
-                                                RemotePtr<int> address)
-{
-  if (property_automaton_ == nullptr)
-    property_automaton_ = xbt_automaton_new();
-
-  xbt::add_proposition(property_automaton_, name,
-                       [&remote_process, address]() { return remote_process.read(address); });
-}
-
-RecordTrace LivenessChecker::get_record_trace() // override
-{
-  RecordTrace res;
-  for (std::shared_ptr<Pair> const& pair : exploration_stack_)
-    if (pair->app_state_->get_transition_out() != nullptr)
-      res.push_back(pair->app_state_->get_transition_out().get());
-  return res;
-}
-
-void LivenessChecker::log_state() // override
-{
-  XBT_INFO("Expanded pairs = %lu", expanded_pairs_count_);
-  XBT_INFO("Visited pairs = %lu", visited_pairs_count_);
-  XBT_INFO("Executed transitions = %lu", Transition::get_executed_transitions());
-  Exploration::log_state();
-}
-
-void LivenessChecker::show_acceptance_cycle(std::size_t depth)
-{
-  XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
-  XBT_INFO("|             ACCEPTANCE CYCLE            |");
-  XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
-  XBT_INFO("Counter-example that violates formula:");
-  for (auto const& s : this->get_textual_trace())
-    XBT_INFO("  %s", s.c_str());
-  XBT_INFO("You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with "
-           "--cfg=model-check/replay:'%s'",
-           get_record_trace().to_string().c_str());
-  log_state();
-  XBT_INFO("Counter-example depth: %zu", depth);
-}
-
-std::shared_ptr<Pair> LivenessChecker::create_pair(const Pair* current_pair, xbt_automaton_state_t state,
-                                                   std::shared_ptr<const std::vector<int>> propositions)
-{
-  ++expanded_pairs_count_;
-  auto next_pair                 = std::make_shared<Pair>(expanded_pairs_count_);
-  next_pair->prop_state_         = state;
-  next_pair->app_state_          = std::make_shared<State>(get_remote_app());
-  next_pair->atomic_propositions = std::move(propositions);
-  if (current_pair)
-    next_pair->depth = current_pair->depth + 1;
-  else
-    next_pair->depth = 1;
-  /* Add all enabled actors to the interleave set of the initial state */
-  for (auto const& [aid, _] : next_pair->app_state_->get_actors_list())
-    if (next_pair->app_state_->is_actor_enabled(aid))
-      next_pair->app_state_->consider_one(aid);
-
-  next_pair->requests = next_pair->app_state_->count_todo();
-  /* FIXME : get search_cycle value for each accepting state */
-  if (next_pair->prop_state_->type == 1 || (current_pair && current_pair->search_cycle))
-    next_pair->search_cycle = true;
-  else
-    next_pair->search_cycle = false;
-  return next_pair;
-}
-
-void LivenessChecker::backtrack()
-{
-  /* Traverse the stack backwards until a pair with a non empty interleave
-     set is found, deleting all the pairs that have it empty in the way. */
-  while (not exploration_stack_.empty()) {
-    std::shared_ptr<simgrid::mc::Pair> current_pair = exploration_stack_.back();
-    exploration_stack_.pop_back();
-    if (current_pair->requests > 0) {
-      /* We found a backtracking point */
-      XBT_DEBUG("Backtracking to depth %d", current_pair->depth);
-      exploration_stack_.push_back(std::move(current_pair));
-      this->replay();
-      XBT_DEBUG("Backtracking done");
-      break;
-    } else {
-      XBT_DEBUG("Delete pair %d at depth %d", current_pair->num, current_pair->depth);
-      if (current_pair->prop_state_->type == 1)
-        this->remove_acceptance_pair(current_pair->num);
-    }
-  }
-}
-
-void LivenessChecker::run()
-{
-  XBT_INFO("Check the liveness property %s", _sg_mc_property_file.get().c_str());
-  automaton_load(_sg_mc_property_file.get().c_str());
-
-  XBT_DEBUG("Starting the liveness algorithm");
-
-  /* Initialize */
-  this->previous_pair_ = 0;
-
-  std::shared_ptr<const std::vector<int>> propos = this->get_proposition_values();
-
-  // For each initial state of the property automaton, push a
-  // (application_state, automaton_state) pair to the exploration stack:
-  auto automaton_stack = get_automaton_state();
-  for (auto* automaton_state : automaton_stack) {
-    if (automaton_state->type == -1)
-      exploration_stack_.push_back(this->create_pair(nullptr, automaton_state, propos));
-  }
-
-  /* Actually run the double DFS search for counter-examples */
-  while (not exploration_stack_.empty()) {
-    std::shared_ptr<Pair> current_pair = exploration_stack_.back();
-
-    /* Update current state in buchi automaton */
-    set_property_automaton(current_pair->prop_state_);
-
-    XBT_DEBUG(
-        "********************* ( Depth = %d, search_cycle = %d, interleave size = %zu, pair_num = %d, requests = %d)",
-        current_pair->depth, current_pair->search_cycle, current_pair->app_state_->count_todo(), current_pair->num,
-        current_pair->requests);
-
-    if (current_pair->requests == 0) {
-      this->backtrack();
-      continue;
-    }
-
-    std::shared_ptr<VisitedPair> reached_pair;
-    if (current_pair->prop_state_->type == 1 && not current_pair->exploration_started) {
-      reached_pair = this->insert_acceptance_pair(current_pair.get());
-      if (reached_pair == nullptr) {
-        this->show_acceptance_cycle(current_pair->depth);
-        throw McError(ExitStatus::LIVENESS);
-      }
-    }
-
-    /* Pair already visited ? stop the exploration on the current path */
-    if (not current_pair->exploration_started) {
-      int visited_num = this->insert_visited_pair(reached_pair, current_pair.get());
-      if (visited_num != -1) {
-        dot_output("\"%d\" -> \"%d\" [%s];\n", this->previous_pair_, visited_num, this->previous_request_.c_str());
-
-        XBT_DEBUG("Pair already visited (equal to pair %d), exploration on the current path stopped.", visited_num);
-        current_pair->requests = 0;
-        this->backtrack();
-        continue;
-      }
-    }
-
-    current_pair->app_state_->execute_next(current_pair->app_state_->next_transition(), get_remote_app());
-    XBT_DEBUG("Execute: %s", current_pair->app_state_->get_transition_out()->to_string().c_str());
-
-    /* Update the dot output */
-    if (this->previous_pair_ != 0 && this->previous_pair_ != current_pair->num) {
-      dot_output("\"%d\" -> \"%d\" [%s];\n", this->previous_pair_, current_pair->num, this->previous_request_.c_str());
-      this->previous_request_.clear();
-    }
-    this->previous_pair_    = current_pair->num;
-    this->previous_request_ = current_pair->app_state_->get_transition_out()->dot_string();
-    if (current_pair->search_cycle)
-      dot_output("%d [shape=doublecircle];\n", current_pair->num);
-
-    if (not current_pair->exploration_started)
-      visited_pairs_count_++;
-
-    current_pair->requests--;
-    current_pair->exploration_started = true;
-
-    /* Get values of atomic propositions (variables used in the property formula) */
-    std::shared_ptr<const std::vector<int>> prop_values = this->get_proposition_values();
-
-    // For each enabled transition in the property automaton, push a
-    // (application_state, automaton_state) pair to the exploration stack:
-    for (int i = xbt_dynar_length(current_pair->prop_state_->out) - 1; i >= 0; i--) {
-      const auto* transition_succ_label = get_automaton_transition_label(current_pair->prop_state_->out, i);
-      auto* transition_succ_dst         = get_automaton_transition_dst(current_pair->prop_state_->out, i);
-      if (evaluate_label(transition_succ_label, *prop_values))
-        exploration_stack_.push_back(this->create_pair(current_pair.get(), transition_succ_dst, prop_values));
-    }
-  }
-
-  XBT_INFO("No property violation found.");
-  log_state();
-}
-
-Exploration* create_liveness_checker(const std::vector<char*>& args)
-{
-  return new LivenessChecker(args);
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/explo/LivenessChecker.hpp b/src/mc/explo/LivenessChecker.hpp
deleted file mode 100644 (file)
index baed48e..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_LIVENESS_CHECKER_HPP
-#define SIMGRID_MC_LIVENESS_CHECKER_HPP
-
-#include "src/mc/api/State.hpp"
-#include "src/mc/explo/Exploration.hpp"
-#include "xbt/automaton.hpp"
-
-#include <list>
-#include <memory>
-#include <vector>
-
-namespace simgrid::mc {
-
-class XBT_PRIVATE Pair {
-public:
-  int num                           = 0;
-  bool search_cycle                 = false;
-  std::shared_ptr<State> app_state_ = nullptr; /* State of the application (including system state) */
-  xbt_automaton_state_t prop_state_ = nullptr; /* State of the property automaton */
-  std::shared_ptr<const std::vector<int>> atomic_propositions;
-  int requests             = 0;
-  int depth                = 0;
-  bool exploration_started = false;
-
-  explicit Pair(unsigned long expanded_pairs);
-
-  Pair(Pair const&) = delete;
-  Pair& operator=(Pair const&) = delete;
-};
-
-class XBT_PRIVATE VisitedPair {
-public:
-  int num;
-  int other_num                      = 0;       /* Dot output for */
-  std::shared_ptr<State> app_state_  = nullptr; /* State of the application (including system state) */
-  xbt_automaton_state_t prop_state_;            /* State of the property automaton */
-  std::shared_ptr<const std::vector<int>> atomic_propositions;
-  std::size_t heap_bytes_used = 0;
-  int actor_count_;
-
-  VisitedPair(int pair_num, xbt_automaton_state_t prop_state,
-              std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> app_state,
-              RemoteApp& remote_app);
-};
-
-class XBT_PRIVATE LivenessChecker : public Exploration {
-public:
-  explicit LivenessChecker(const std::vector<char*>& args);
-  ~LivenessChecker() override;
-
-  void run() override;
-  RecordTrace get_record_trace() override;
-  void log_state() override;
-
-private:
-  std::shared_ptr<const std::vector<int>> get_proposition_values() const;
-  std::shared_ptr<VisitedPair> insert_acceptance_pair(Pair* pair);
-  int insert_visited_pair(std::shared_ptr<VisitedPair> visited_pair, Pair* pair);
-  void show_acceptance_cycle(std::size_t depth);
-  void replay();
-  void remove_acceptance_pair(int pair_num);
-  void purge_visited_pairs();
-  void backtrack();
-  std::shared_ptr<Pair> create_pair(const Pair* pair, xbt_automaton_state_t state,
-                                    std::shared_ptr<const std::vector<int>> propositions);
-
-  // A stack of (application_state, automaton_state) pairs for DFS exploration:
-  std::list<std::shared_ptr<Pair>> exploration_stack_;
-  std::list<std::shared_ptr<VisitedPair>> acceptance_pairs_;
-  std::list<std::shared_ptr<VisitedPair>> visited_pairs_;
-  unsigned long visited_pairs_count_  = 0;
-  unsigned long expanded_pairs_count_ = 0;
-  int previous_pair_                  = 0;
-  std::string previous_request_;
-
-  /* The property automaton must be a static because it's sometimes used before the explorer is even created.
-   *
-   * This can happen if some symbols are created during the application's initialization process, before the first
-   * decision point for the model-checker. Since the first snapshot is taken at the first decision point and since the
-   * explorer is created after the first snapshot, this may result in some symbols being registered even before the
-   * model-checker notices that this is a LivenessChecker to create.
-   *
-   * This situation is unfortunate, but I guess that it's the best I can achieve given the state of our initialization
-   * code.
-   */
-  static xbt_automaton_t property_automaton_;
-  bool evaluate_label(const xbt_automaton_exp_label* l, std::vector<int> const& values);
-
-public:
-  void automaton_load(const char* file) const;
-  std::vector<int> automaton_propositional_symbol_evaluate() const;
-  std::vector<xbt_automaton_state_t> get_automaton_state() const;
-  int compare_automaton_exp_label(const xbt_automaton_exp_label* l) const;
-  void set_property_automaton(xbt_automaton_state_t const& automaton_state) const;
-  xbt_automaton_exp_label_t get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const;
-  xbt_automaton_state_t get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const;
-  static void automaton_register_symbol(RemoteProcessMemory const& remote_process, const char* name,
-                                        RemotePtr<int> addr);
-};
-
-} // namespace simgrid::mc
-
-#endif
index c8bac5b..f5c512f 100644 (file)
@@ -19,7 +19,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_udpor, mc, "Logging specific to verification
 
 namespace simgrid::mc::udpor {
 
-UdporChecker::UdporChecker(const std::vector<char*>& args) : Exploration(args, true) {}
+UdporChecker::UdporChecker(const std::vector<char*>& args) : Exploration(args) {}
 
 void UdporChecker::run()
 {
index 283b7c9..88c6839 100644 (file)
@@ -9,7 +9,7 @@
 #include "src/mc/explo/odpor/Execution.hpp"
 #include "src/mc/explo/odpor/odpor_forward.hpp"
 #include "src/mc/transition/Transition.hpp"
-#include "src/mc/transition/TransitionActorJoin.hpp"
+#include "src/mc/transition/TransitionActor.hpp"
 #include "src/mc/transition/TransitionAny.hpp"
 #include "src/mc/transition/TransitionComm.hpp"
 #include "src/mc/transition/TransitionObjectAccess.hpp"
index 513c997..5187135 100644 (file)
@@ -35,16 +35,12 @@ int main(int argc, char** argv)
 
   std::unique_ptr<Exploration> explo;
 
-#if SIMGRID_HAVE_STATEFUL_MC
   if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
     explo = std::unique_ptr<Exploration>(
         create_communication_determinism_checker(argv_copy, get_model_checking_reduction()));
   else if (_sg_mc_unfolding_checker)
     explo = std::unique_ptr<Exploration>(create_udpor_checker(argv_copy));
-  else if (not _sg_mc_property_file.get().empty())
-    explo = std::unique_ptr<Exploration>(create_liveness_checker(argv_copy));
   else
-#endif
     explo = std::unique_ptr<Exploration>(create_dfs_exploration(argv_copy, get_model_checking_reduction()));
 
   ExitStatus status;
index 60a4ac3..cd68c9c 100644 (file)
@@ -9,7 +9,7 @@
 #include "src/mc/explo/udpor/EventSet.hpp"
 #include "src/mc/explo/udpor/udpor_forward.hpp"
 #include "src/mc/transition/Transition.hpp"
-#include "src/mc/transition/TransitionActorJoin.hpp"
+#include "src/mc/transition/TransitionActor.hpp"
 #include "src/mc/transition/TransitionAny.hpp"
 #include "src/mc/transition/TransitionComm.hpp"
 #include "src/mc/transition/TransitionObjectAccess.hpp"
index 92ac709..8651a2a 100644 (file)
@@ -58,7 +58,7 @@ std::string UnfoldingEvent::to_string() const
   }
   dependencies_string += "]";
 
-  return xbt::string_printf("Event %lu, Actor %ld: %s (%zu dependencies: %s)", this->id, associated_transition->aid_,
+  return xbt::string_printf("Event %lu, Actor %ld: %s (%lu dependencies: %s)", this->id, associated_transition->aid_,
                             associated_transition->to_string().c_str(), immediate_causes.size(),
                             dependencies_string.c_str());
 }
index 5486709..98f40ad 100644 (file)
@@ -97,7 +97,7 @@ private:
    * @brief An identifier which is used to sort events
    * deterministically
    */
-  uint64_t id = 0;
+  unsigned long id = 0;
 };
 
 } // namespace simgrid::mc::udpor
index 23c13f3..a279b8f 100644 (file)
 namespace simgrid::mc::udpor {
 
 class Comb;
-class ExtensionSetCalculator;
+struct ExtensionSetCalculator;
 class EventSet;
 class Configuration;
 class History;
 class Unfolding;
 class UnfoldingEvent;
-class maximal_subsets_iterator;
+struct maximal_subsets_iterator;
 
 } // namespace simgrid::mc::udpor
 
diff --git a/src/mc/inspect/DwarfExpression.cpp b/src/mc/inspect/DwarfExpression.cpp
deleted file mode 100644 (file)
index 2e74410..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/* Copyright (c) 2014-2023. 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 <cstddef>
-#include <cstdint>
-#include <unordered_set>
-
-#include "src/mc/AddressSpace.hpp"
-#include "src/mc/inspect/DwarfExpression.hpp"
-#include "src/mc/inspect/Frame.hpp"
-#include "src/mc/inspect/LocationList.hpp"
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/inspect/mc_dwarf.hpp"
-#include "src/mc/mc_private.hpp"
-
-namespace simgrid::dwarf {
-
-void execute(const Dwarf_Op* ops, std::size_t n, const ExpressionContext& context, ExpressionStack& stack)
-{
-  for (size_t i = 0; i != n; ++i) {
-    const Dwarf_Op* op = ops + i;
-    std::uint8_t atom  = op->atom;
-    intptr_t first;
-    intptr_t second;
-
-    switch (atom) {
-        // Push the CFA (Canonical Frame Address):
-      case DW_OP_call_frame_cfa:
-        /* See 6.4 of DWARF4 (http://dwarfstd.org/doc/DWARF4.pdf#page=140):
-         *
-         * > Typically, the CFA is defined to be the value of the stack
-         * > pointer at the call site in the previous frame (which may be
-         * > different from its value on entry to the current frame).
-         *
-         * We need to unwind the frame in order to get the SP of the parent
-         * frame.
-         *
-         * Warning: the CFA returned by libunwind (UNW_X86_64_RSP, etc.)
-         * is the SP of the *current* frame. */
-        if (context.cursor) {
-          // Get frame:
-          unw_cursor_t cursor = *(context.cursor);
-          unw_step(&cursor);
-
-          unw_word_t res;
-          unw_get_reg(&cursor, UNW_REG_SP, &res);
-          stack.push(res);
-          break;
-        }
-        throw evaluation_error("Missing cursor");
-
-        // Frame base:
-      case DW_OP_fbreg:
-        stack.push((std::uintptr_t)context.frame_base + op->number);
-        break;
-
-        // Address from the base address of this ELF object.
-        // Push the address on the stack (base_address + argument).
-      case DW_OP_addr:
-        if (context.object_info) {
-          Dwarf_Off addr = (Dwarf_Off)(std::uintptr_t)context.object_info->base_address() + op->number;
-          stack.push(addr);
-          break;
-        }
-        throw evaluation_error("No base address");
-
-        // ***** Stack manipulation:
-
-        // Push another copy/duplicate the value at the top of the stack:
-      case DW_OP_dup:
-        stack.dup();
-        break;
-
-        // Pop/drop the top of the stack:
-      case DW_OP_drop:
-        (void)stack.pop();
-        break;
-
-      case DW_OP_swap:
-        stack.swap();
-        break;
-
-        // Duplicate the value under the top of the stack:
-      case DW_OP_over:
-        stack.push(stack.top(1));
-        break;
-
-        // ***** Operations:
-        // Those usually take the top of the stack and the next value as argument
-        // and replace the top of the stack with the computed value
-        // (stack.top() += stack.before_top()).
-
-      case DW_OP_plus:
-        first  = stack.pop();
-        second = stack.pop();
-        stack.push(first + second);
-        break;
-
-      case DW_OP_mul:
-        first  = stack.pop();
-        second = stack.pop();
-        stack.push(first * second);
-        break;
-
-      case DW_OP_plus_uconst:
-        stack.top() += op->number;
-        break;
-
-      case DW_OP_not:
-        stack.top() = ~stack.top();
-        break;
-
-      case DW_OP_neg:
-        stack.top() = -(intptr_t)stack.top();
-        break;
-
-      case DW_OP_minus:
-        first  = stack.pop();
-        second = stack.pop();
-        stack.push(second - first);
-        break;
-
-      case DW_OP_and:
-        first  = stack.pop();
-        second = stack.pop();
-        stack.push(first & second);
-        break;
-
-      case DW_OP_or:
-        first  = stack.pop();
-        second = stack.pop();
-        stack.push(first | second);
-        break;
-
-      case DW_OP_xor:
-        first  = stack.pop();
-        second = stack.pop();
-        stack.push(first ^ second);
-        break;
-
-      case DW_OP_nop:
-        break;
-
-        // ***** Deference (memory fetch)
-
-      case DW_OP_deref_size:
-        throw evaluation_error("Unsupported operation");
-
-      case DW_OP_deref:
-        // Computed address:
-        if (not context.address_space)
-          throw evaluation_error("Missing address space");
-        context.address_space->read_bytes(&stack.top(), sizeof(uintptr_t), mc::remote(stack.top()));
-        break;
-
-      default:
-
-        // Registers:
-        if (static const std::unordered_set<uint8_t> registers =
-                {DW_OP_breg0,  DW_OP_breg1,  DW_OP_breg2,  DW_OP_breg3,  DW_OP_breg4,  DW_OP_breg5,  DW_OP_breg6,
-                 DW_OP_breg7,  DW_OP_breg8,  DW_OP_breg9,  DW_OP_breg10, DW_OP_breg11, DW_OP_breg12, DW_OP_breg13,
-                 DW_OP_breg14, DW_OP_breg15, DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20,
-                 DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25, DW_OP_breg26, DW_OP_breg27,
-                 DW_OP_breg28, DW_OP_breg29, DW_OP_breg30, DW_OP_breg31};
-            registers.count(atom) > 0) {
-          // Push register + constant:
-          int register_id = dwarf_register_to_libunwind(op->atom - DW_OP_breg0);
-          unw_word_t res;
-          if (not context.cursor)
-            throw evaluation_error("Missing stack context");
-          unw_get_reg(context.cursor, register_id, &res);
-          stack.push(res + op->number);
-          break;
-        }
-
-        // ***** Constants:
-
-        // Short constant literals:
-        if (static const std::unordered_set<uint8_t> literals = {DW_OP_lit0,  DW_OP_lit1,  DW_OP_lit2,  DW_OP_lit3,
-                                                                 DW_OP_lit4,  DW_OP_lit5,  DW_OP_lit6,  DW_OP_lit7,
-                                                                 DW_OP_lit8,  DW_OP_lit9,  DW_OP_lit10, DW_OP_lit11,
-                                                                 DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15,
-                                                                 DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19,
-                                                                 DW_OP_lit20, DW_OP_lit21, DW_OP_lit22, DW_OP_lit23,
-                                                                 DW_OP_lit24, DW_OP_lit25, DW_OP_lit26, DW_OP_lit27,
-                                                                 DW_OP_lit28, DW_OP_lit29, DW_OP_lit30, DW_OP_lit31};
-            literals.count(atom) > 0) {
-          // Push a literal/constant on the stack:
-          stack.push(atom - DW_OP_lit0);
-          break;
-        }
-
-        // General constants:
-        if (static const std::unordered_set<uint8_t> constants = {DW_OP_const1u, DW_OP_const2u, DW_OP_const4u,
-                                                                  DW_OP_const8u, DW_OP_const1s, DW_OP_const2s,
-                                                                  DW_OP_const4s, DW_OP_const8s, DW_OP_constu,
-                                                                  DW_OP_consts};
-            constants.count(atom) > 0) {
-          // Push the constant argument on the stack.
-          stack.push(op->number);
-          break;
-        }
-
-        // Not handled:
-        throw evaluation_error("Unsupported operation");
-    }
-  }
-}
-
-} // namespace simgrid::dwarf
diff --git a/src/mc/inspect/DwarfExpression.hpp b/src/mc/inspect/DwarfExpression.hpp
deleted file mode 100644 (file)
index 2e8de12..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/* Copyright (c) 2015-2023. 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 SIMGRID_MC_DWARF_EXPRESSION_HPP
-#define SIMGRID_MC_DWARF_EXPRESSION_HPP
-
-#include <cstdint>
-#include <cstdlib>
-
-#include <array>
-#include <stdexcept> // runtime_error
-#include <utility>
-#include <vector>
-
-#include <elfutils/libdw.h>
-#include <libunwind.h>
-
-#include "src/mc/inspect/mc_dwarf.hpp"
-#include "src/mc/mc_forward.hpp"
-
-/** @file DwarfExpression.hpp
- *
- *  Evaluation of DWARF location expressions.
- */
-
-namespace simgrid::dwarf {
-
-/** A DWARF expression
- *
- *  DWARF defines a simple stack-based VM for evaluating expressions
- *  (such as locations of variables, etc.): a DWARF expression is
- *  just a sequence of dwarf instructions. We currently directly use
- *  `Dwarf_Op` from `dwarf.h` for dwarf instructions.
- */
-using DwarfExpression = std::vector<Dwarf_Op>;
-
-/** Context of evaluation of a DWARF expression
- *
- *  Some DWARF instructions need to read the CPU registers,
- *  the process memory, etc. All those information are gathered in
- *  the evaluation context.
- */
-struct ExpressionContext {
-  /** CPU state (registers) */
-  unw_cursor_t* cursor                  = nullptr;
-  void* frame_base                      = nullptr;
-  const mc::AddressSpace* address_space = nullptr; /** Address space used to read memory */
-  mc::ObjectInformation* object_info    = nullptr;
-};
-
-/** When an error happens in the execution of a DWARF expression */
-class evaluation_error : public std::runtime_error {
-public:
-  using std::runtime_error::runtime_error;
-};
-
-/** A stack for evaluating a DWARF expression
- *
- *  DWARF expressions work by manipulating a stack of integer values.
- */
-class ExpressionStack {
-public:
-  using value_type                      = std::uintptr_t;
-  static constexpr std::size_t MAX_SIZE = 64;
-
-private:
-  // Values of the stack (the top is stack_[size_ - 1]):
-  std::array<uintptr_t, MAX_SIZE> stack_{{0}};
-  size_t size_ = 0;
-
-public:
-  // Access:
-  std::size_t size() const { return size_; }
-  bool empty() const { return size_ == 0; }
-  void clear() { size_ = 0; }
-  uintptr_t& operator[](int i) { return stack_[i]; }
-  uintptr_t const& operator[](int i) const { return stack_[i]; }
-
-  /** Top of the stack */
-  value_type& top()
-  {
-    if (size_ == 0)
-      throw evaluation_error("Empty stack");
-    return stack_[size_ - 1];
-  }
-
-  /** Access the i-th element from the top of the stack */
-  value_type& top(unsigned i)
-  {
-    if (size_ < i)
-      throw evaluation_error("Invalid element");
-    return stack_[size_ - 1 - i];
-  }
-
-  /** Push a value on the top of the stack */
-  void push(value_type value)
-  {
-    if (size_ == stack_.size())
-      throw evaluation_error("DWARF stack overflow");
-    stack_[size_] = value;
-    size_++;
-  }
-
-  /* Pop a value from the top of the stack */
-  value_type pop()
-  {
-    if (size_ == 0)
-      throw evaluation_error("DWARF stack underflow");
-    --size_;
-    return stack_[size_];
-  }
-
-  // These are DWARF operations (DW_OP_foo):
-
-  /* Push a copy of the top-value (DW_OP_dup) */
-  void dup() { push(top()); }
-
-  /* Swap the two top-most values */
-  void swap() { std::swap(top(), top(1)); }
-};
-
-/** Executes a DWARF expression
- *
- *  @param ops     DWARF expression instructions
- *  @param n       number of instructions
- *  @param context evaluation context (registers, memory, etc.)
- *  @param stack   DWARf stack where the operations are executed
- */
-void execute(const Dwarf_Op* ops, std::size_t n, ExpressionContext const& context, ExpressionStack& stack);
-
-/** Executes/evaluates a DWARF expression
- *
- *  @param expression DWARF expression to execute
- *  @param context    evaluation context (registers, memory, etc.)
- *  @param stack      DWARf stack where the operations are executed
- */
-inline void execute(simgrid::dwarf::DwarfExpression const& expression, ExpressionContext const& context,
-                    ExpressionStack& stack)
-{
-  execute(expression.data(), expression.size(), context, stack);
-}
-
-} // namespace simgrid::dwarf
-
-#endif
diff --git a/src/mc/inspect/Frame.cpp b/src/mc/inspect/Frame.cpp
deleted file mode 100644 (file)
index 9d80454..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2007-2023. 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 <libunwind.h>
-
-#include "xbt/sysdep.h"
-
-#include "src/mc/inspect/Frame.hpp"
-
-namespace simgrid::mc {
-
-void* Frame::frame_base(unw_cursor_t& unw_cursor) const
-{
-  simgrid::dwarf::Location location =
-      simgrid::dwarf::resolve(frame_base_location, object_info, &unw_cursor, nullptr, nullptr);
-  if (location.in_memory())
-    return location.address();
-  else if (location.in_register()) {
-    // This is a special case.
-    // The register is not the location of the frame base
-    // (a frame base cannot be located in a register).
-    // Instead, DWARF defines this to mean that the register
-    // contains the address of the frame base.
-    unw_word_t word;
-    unw_get_reg(&unw_cursor, location.register_id(), &word);
-    return (void*)word;
-  } else
-    xbt_die("Unexpected location type");
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/inspect/Frame.hpp b/src/mc/inspect/Frame.hpp
deleted file mode 100644 (file)
index d02e25e..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_FRAME_HPP
-#define SIMGRID_MC_FRAME_HPP
-
-#include <cstdint>
-#include <string>
-
-#include "xbt/base.h"
-#include "xbt/range.hpp"
-
-#include "src/mc/inspect/LocationList.hpp"
-#include "src/mc/inspect/Variable.hpp"
-#include "src/mc/mc_forward.hpp"
-
-namespace simgrid::mc {
-
-/** Debug information about a given function or scope within a function */
-class Frame {
-public:
-  /** Kind of scope (DW_TAG_subprogram, DW_TAG_inlined_subroutine, etc.) */
-  int tag = DW_TAG_invalid;
-
-  /** Name of the function (if it is a function) */
-  std::string name;
-
-  /** Range of instruction addresses for which this scope is valid */
-  simgrid::xbt::Range<std::uint64_t> range{0, 0};
-
-  simgrid::dwarf::LocationList frame_base_location;
-
-  /** List of the variables (sorted by name) */
-  std::vector<Variable> variables;
-
-  /* Unique identifier for this scope (in the object_info)
-   *
-   * This is the global DWARF offset of the DIE. */
-  unsigned long int id = 0;
-
-  std::vector<Frame> scopes;
-
-  /** Value of `DW_AT_abstract_origin`
-   *
-   *  For inlined subprograms, this is the ID of the
-   *  parent function.
-   */
-  unsigned long int abstract_origin_id = 0;
-
-  simgrid::mc::ObjectInformation* object_info = nullptr;
-
-  void* frame_base(unw_cursor_t& unw_cursor) const;
-  void remove_variable(char* name);
-};
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/inspect/LocationList.cpp b/src/mc/inspect/LocationList.cpp
deleted file mode 100644 (file)
index 18a585d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright (c) 2004-2023. 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 "src/mc/inspect/LocationList.hpp"
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/inspect/mc_dwarf.hpp"
-
-#include "xbt/asserts.h"
-#include "xbt/log.h"
-#include "xbt/sysdep.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <libunwind.h>
-#include <utility>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(mc_dwarf);
-
-namespace simgrid::dwarf {
-
-/** Resolve a location expression */
-Location resolve(simgrid::dwarf::DwarfExpression const& expression, simgrid::mc::ObjectInformation* object_info,
-                 unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space)
-{
-  simgrid::dwarf::ExpressionContext context;
-  context.frame_base    = frame_pointer_address;
-  context.cursor        = c;
-  context.address_space = address_space;
-  context.object_info   = object_info;
-
-  if (not expression.empty() && expression[0].atom >= DW_OP_reg0 && expression[0].atom <= DW_OP_reg31) {
-    int dwarf_register = expression[0].atom - DW_OP_reg0;
-    xbt_assert(c, "Missing frame context for register operation DW_OP_reg%i", dwarf_register);
-    return Location(dwarf_register_to_libunwind(dwarf_register));
-  }
-
-  simgrid::dwarf::ExpressionStack stack;
-  simgrid::dwarf::execute(expression, context, stack);
-  return Location((void*)stack.top());
-}
-
-// TODO, move this in a method of LocationList
-static simgrid::dwarf::DwarfExpression const* find_expression(simgrid::dwarf::LocationList const& locations,
-                                                              unw_word_t ip)
-{
-  for (simgrid::dwarf::LocationListEntry const& entry : locations)
-    if (entry.valid_for_ip(ip))
-      return &entry.expression();
-  return nullptr;
-}
-
-Location resolve(simgrid::dwarf::LocationList const& locations, simgrid::mc::ObjectInformation* object_info,
-                 unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space)
-{
-  unw_word_t ip = 0;
-  if (c)
-    xbt_assert(unw_get_reg(c, UNW_REG_IP, &ip) == 0, "Could not resolve IP");
-  simgrid::dwarf::DwarfExpression const* expression = find_expression(locations, ip);
-  xbt_assert(expression != nullptr, "Could not resolve location");
-  return simgrid::dwarf::resolve(*expression, object_info, c, frame_pointer_address, address_space);
-}
-
-LocationList location_list(const simgrid::mc::ObjectInformation& info, Dwarf_Attribute& attr)
-{
-  LocationList locations;
-  std::ptrdiff_t offset = 0;
-  while (true) {
-    Dwarf_Addr base;
-    Dwarf_Addr start;
-    Dwarf_Addr end;
-    Dwarf_Op* ops;
-    std::size_t len;
-
-    offset = dwarf_getlocations(&attr, offset, &base, &start, &end, &ops, &len);
-
-    if (offset == -1)
-      XBT_WARN("Error while loading location list: %s", dwarf_errmsg(-1));
-    if (offset <= 0)
-      break;
-
-    auto base_address = reinterpret_cast<std::uint64_t>(info.base_address());
-
-    LocationListEntry::range_type range;
-    if (start == 0)
-      // If start == 0, this is not a location list:
-      range = {0, UINT64_MAX};
-    else
-      range = {base_address + start, base_address + end};
-
-    locations.emplace_back(DwarfExpression(ops, ops + len), range);
-  }
-
-  return locations;
-}
-} // namespace simgrid::dwarf
diff --git a/src/mc/inspect/LocationList.hpp b/src/mc/inspect/LocationList.hpp
deleted file mode 100644 (file)
index 9504a98..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (c) 2004-2023. 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 SIMGRID_MC_OBJECT_LOCATION_H
-#define SIMGRID_MC_OBJECT_LOCATION_H
-
-#include "xbt/base.h"
-#include "xbt/range.hpp"
-
-#include "src/mc/inspect/DwarfExpression.hpp"
-#include "src/mc/mc_base.hpp"
-#include "src/mc/mc_forward.hpp"
-
-#include <cstdint>
-#include <vector>
-
-namespace simgrid::dwarf {
-
-/** A DWARF expression with optional validity constraints */
-class LocationListEntry {
-public:
-  using range_type = simgrid::xbt::Range<std::uint64_t>;
-
-private:
-  DwarfExpression expression_;
-  // By default, the expression is always valid:
-  range_type range_ = {0, UINT64_MAX};
-
-public:
-  LocationListEntry() = default;
-  LocationListEntry(DwarfExpression expression, range_type range) : expression_(std::move(expression)), range_(range) {}
-  explicit LocationListEntry(DwarfExpression expression) : expression_(std::move(expression)) {}
-
-  DwarfExpression& expression() { return expression_; }
-  DwarfExpression const& expression() const { return expression_; }
-  bool valid_for_ip(unw_word_t ip) const { return range_.contain(ip); }
-};
-
-using LocationList = std::vector<LocationListEntry>;
-
-/** Location of some variable in memory
- *
- *  The variable is located either in memory of a register.
- */
-class Location {
-private:
-  void* memory_    = nullptr;
-  int register_id_ = 0;
-
-public:
-  explicit Location(void* x) : memory_(x) {}
-  explicit Location(int register_id) : register_id_(register_id) {}
-  // Type of location:
-  bool in_register() const { return memory_ == nullptr; }
-  bool in_memory() const { return memory_ != nullptr; }
-
-  // Get the location:
-  void* address() const { return memory_; }
-  int register_id() const { return register_id_; }
-};
-
-XBT_PRIVATE
-Location resolve(simgrid::dwarf::DwarfExpression const& expression, simgrid::mc::ObjectInformation* object_info,
-                 unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space);
-
-Location resolve(simgrid::dwarf::LocationList const& locations, simgrid::mc::ObjectInformation* object_info,
-                 unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space);
-
-XBT_PRIVATE
-simgrid::dwarf::LocationList location_list(const simgrid::mc::ObjectInformation& info, Dwarf_Attribute& attr);
-
-} // namespace simgrid::dwarf
-
-#endif
diff --git a/src/mc/inspect/ObjectInformation.cpp b/src/mc/inspect/ObjectInformation.cpp
deleted file mode 100644 (file)
index 479dd7f..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* Copyright (c) 2014-2023. 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 <algorithm>
-#include <cstdint>
-#include <sys/mman.h> // PROT_READ and friends
-#include <vector>
-
-#include "src/mc/inspect/Frame.hpp"
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/inspect/Variable.hpp"
-#include "src/mc/mc_private.hpp"
-#include "xbt/file.hpp"
-
-namespace simgrid::mc {
-
-/* For an executable object, addresses are virtual address (there is no offset) i.e.
- *  \f$\text{virtual address} = \{dwarf address}\f$
- *
- * For a shared object, the addresses are offset from the beginning of the shared object (the base address of the
- * mapped shared object must be used as offset
- * i.e. \f$\text{virtual address} = \text{shared object base address}
- *             + \text{dwarf address}\f$.
- */
-void* ObjectInformation::base_address() const
-{
-  // For an executable (more precisely for an ET_EXEC) the base it 0:
-  if (this->executable())
-    return nullptr;
-
-  // For an a shared-object (ET_DYN, including position-independent executables) the base address is its lowest address:
-  void* result = this->start_exec;
-  if (this->start_rw != nullptr && result > (void*)this->start_rw)
-    result = this->start_rw;
-  if (this->start_ro != nullptr && result > (void*)this->start_ro)
-    result = this->start_ro;
-  return result;
-}
-
-Frame* ObjectInformation::find_function(const void* ip)
-{
-  ensure_dwarf_loaded();
-
-  /* This is implemented by binary search on a sorted array.
-   *
-   * We do quite a lot of those so we want this to be cache efficient.
-   * We pack the only information we need in the index entries in order
-   * to successfully do the binary search. We do not need the high_pc
-   * during the binary search (only at the end) so it is not included
-   * in the index entry. We could use parallel arrays as well.
-   *
-   * Note the usage of reverse iterators to match the correct interval.
-   */
-  auto pos = std::lower_bound(this->functions_index.rbegin(), this->functions_index.rend(), ip,
-                              [](auto const& func, auto const* addr) { return func.low_pc > addr; });
-
-  /* At this point, the search is over.
-   * Either we have found the correct function or we do not know
-   * any function corresponding to this instruction address.
-   * Only at the point do we dereference the function pointer. */
-  return (pos != this->functions_index.rend() && reinterpret_cast<std::uint64_t>(ip) < pos->function->range.end())
-             ? pos->function
-             : nullptr;
-}
-
-const Variable* ObjectInformation::find_variable(const char* var_name)
-{
-  ensure_dwarf_loaded();
-
-  auto pos = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name,
-                              [](auto const& var, const char* name) { return var.name < name; });
-  return (pos != this->global_variables.end() && pos->name == var_name) ? &(*pos) : nullptr;
-}
-
-void ObjectInformation::remove_global_variable(const char* var_name)
-{
-  // Binary search:
-  auto pos1 = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name,
-                               [](auto const& var, const char* name) { return var.name < name; });
-  // Find the whole range:
-  auto pos2 = std::upper_bound(pos1, this->global_variables.end(), var_name,
-                               [](const char* name, auto const& var) { return name < var.name; });
-  // Remove the whole range:
-  this->global_variables.erase(pos1, pos2);
-}
-
-/** 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 to ignore
- *  @param subprogram_name Name of the subprogram to ignore (nullptr for any)
- *  @param subprogram      (possibly inlined) Subprogram of the scope current scope
- *  @param scope           Current scope
- */
-static void remove_local_variable(Frame& scope, const char* var_name, const char* subprogram_name,
-                                  Frame const& subprogram)
-{
-  // If the current subprogram matches the given name:
-  if (subprogram_name == nullptr || (not subprogram.name.empty() && subprogram.name == subprogram_name)) {
-    // Try to find the variable and remove it:
-
-    // Binary search:
-    auto pos = std::lower_bound(scope.variables.begin(), scope.variables.end(), var_name,
-                                [](auto const& var, const char* name) { return var.name < name; });
-    if (pos != scope.variables.end() && pos->name == var_name) {
-      // Variable found, remove it:
-      scope.variables.erase(pos);
-    }
-  }
-
-  // And recursive processing in nested scopes:
-  for (Frame& nested_scope : scope.scopes) {
-    // The new scope may be an inlined subroutine, in this case we want to use its
-    // namespaced name in recursive calls:
-    Frame const& nested_subprogram = nested_scope.tag == DW_TAG_inlined_subroutine ? nested_scope : subprogram;
-    remove_local_variable(nested_scope, var_name, subprogram_name, nested_subprogram);
-  }
-}
-
-void ObjectInformation::remove_local_variable(const char* var_name, const char* subprogram_name)
-{
-  for (auto& [_, entry] : this->subprograms)
-    mc::remove_local_variable(entry, var_name, subprogram_name, entry);
-}
-
-/** @brief Fills the position of the segments (executable, read-only, read/write) */
-// TODO, use the ELF segment information for more robustness
-void find_object_address(std::vector<xbt::VmMap> const& maps, ObjectInformation* result)
-{
-  const int PROT_RW = PROT_READ | PROT_WRITE;
-  const int PROT_RX = PROT_READ | PROT_EXEC;
-
-  std::string name = xbt::Path(result->file_name).get_base_name();
-
-  for (size_t i = 0; i < maps.size(); ++i) {
-    simgrid::xbt::VmMap const& reg = maps[i];
-    if (reg.pathname.empty() || name != simgrid::xbt::Path(reg.pathname).get_base_name())
-      continue;
-
-    // This is the non-GNU_RELRO-part of the data segment:
-    if (reg.prot == PROT_RW) {
-      xbt_assert(not result->start_rw, "Multiple read-write segments for %s, not supported", maps[i].pathname.c_str());
-      result->start_rw = (char*)reg.start_addr;
-      result->end_rw   = (char*)reg.end_addr;
-
-      // The next VMA might be end of the data segment:
-      if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW &&
-          maps[i + 1].start_addr == reg.end_addr)
-        result->end_rw = (char*)maps[i + 1].end_addr;
-    }
-
-    // This is the text segment:
-    else if (reg.prot == PROT_RX) {
-      xbt_assert(not result->start_exec, "Multiple executable segments for %s, not supported",
-                 maps[i].pathname.c_str());
-      result->start_exec = (char*)reg.start_addr;
-      result->end_exec   = (char*)reg.end_addr;
-
-      // The next VMA might be end of the data segment:
-      if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW &&
-          maps[i + 1].start_addr == reg.end_addr) {
-        result->start_rw = (char*)maps[i + 1].start_addr;
-        result->end_rw   = (char*)maps[i + 1].end_addr;
-      }
-    }
-
-    // This is the GNU_RELRO-part of the data segment:
-    else if (reg.prot == PROT_READ) {
-      xbt_assert(not result->start_ro,
-                 "Multiple read-only segments for %s, not supported. Compiling with the following may help: "
-                 "-g -Wl,-znorelro -Wl,-znoseparate-code",
-                 maps[i].pathname.c_str());
-      result->start_ro = (char*)reg.start_addr;
-      result->end_ro   = (char*)reg.end_addr;
-    }
-  }
-
-  result->start = result->start_rw;
-  if ((const void*)result->start_ro < result->start)
-    result->start = result->start_ro;
-  if ((const void*)result->start_exec < result->start)
-    result->start = result->start_exec;
-
-  result->end = result->end_rw;
-  if (result->end_ro && (const void*)result->end_ro > result->end)
-    result->end = result->end_ro;
-  if (result->end_exec && (const void*)result->end_exec > result->end)
-    result->end = result->end_exec;
-
-  xbt_assert(result->start_exec || result->start_rw || result->start_ro);
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/inspect/ObjectInformation.hpp b/src/mc/inspect/ObjectInformation.hpp
deleted file mode 100644 (file)
index 7d1dfa1..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_OBJECT_INFORMATION_HPP
-#define SIMGRID_MC_OBJECT_INFORMATION_HPP
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "src/mc/inspect/Frame.hpp"
-#include "src/mc/inspect/Type.hpp"
-#include "src/mc/mc_forward.hpp"
-#include "src/xbt/memory_map.hpp"
-
-#include "src/smpi/include/private.hpp"
-
-namespace simgrid::mc {
-
-/** An entry in the functions index
- *
- *  See the code of ObjectInformation::find_function.
- */
-struct FunctionIndexEntry {
-  void* low_pc;
-  simgrid::mc::Frame* function;
-};
-
-/** Information about an ELF module (executable or shared object)
- *
- *  This contains all the information we need about an executable or
- *  shared-object in the model-checked process:
- *
- *  - where it is located in the virtual address space;
- *
- *  - where are located its different memory mappings in the the
- *    virtual address space;
- *
- *  - all the debugging (DWARF) information
- *    - types,
- *    - location of the functions and their local variables,
- *    - global variables,
- *
- *  - etc.
- */
-class ObjectInformation {
-  bool dwarf_loaded = false; // Lazily loads the dwarf info
-
-public:
-  void ensure_dwarf_loaded(); // Used by functions that need the dwarf
-  ObjectInformation() = default;
-
-  // Not copiable:
-  ObjectInformation(ObjectInformation const&) = delete;
-  ObjectInformation& operator=(ObjectInformation const&) = delete;
-
-  // Flag:
-  static const int Executable = 1;
-
-  /** Bitfield of flags */
-  int flags = 0;
-  std::string file_name;
-  const void* start = nullptr;
-  const void* end   = nullptr;
-  // Location of its text segment:
-  char* start_exec = nullptr;
-  char* end_exec   = nullptr;
-  // Location of the read-only part of its data segment:
-  char* start_rw = nullptr;
-  char* end_rw   = nullptr;
-  // Location of the read/write part of its data segment:
-  char* start_ro = nullptr;
-  char* end_ro   = nullptr;
-
-  /** All of its subprograms indexed by their address */
-  std::unordered_map<std::uint64_t, simgrid::mc::Frame> subprograms;
-
-  /** Index of functions by instruction address
-   *
-   * We need to efficiently find the function from any given instruction
-   * address inside its range. This index is sorted by low_pc
-   *
-   * The entries are sorted by low_pc and a binary search can be used to look
-   * them up. In order to have a better cache locality, we only keep the
-   * information we need for the lookup in this vector. We could probably
-   * replace subprograms by an ordered vector of Frame and replace this one b
-   * a parallel `std::vector<void*>`.
-   */
-  std::vector<FunctionIndexEntry> functions_index;
-
-  std::vector<simgrid::mc::Variable> global_variables;
-
-  /** Types indexed by DWARF ID */
-  std::unordered_map<std::uint64_t, simgrid::mc::Type> types;
-
-  /** Types indexed by name
-   *
-   *  Different compilation units have their separate type definitions
-   *  (for the same type). When we find an opaque type in one compilation unit,
-   *  we use this in order to try to find its definition in another compilation
-   *  unit.
-   */
-  std::unordered_map<std::string, simgrid::mc::Type*> full_types_by_name;
-
-  /** Whether this module is an executable
-   *
-   *  More precisely we check if this is an ET_EXE ELF. These ELF files
-   *  use fixed addresses instead of base-address relative addresses.
-   *  Position independent executables are in fact ET_DYN.
-   */
-  bool executable() const { return this->flags & simgrid::mc::ObjectInformation::Executable; }
-
-  /** Base address of the module
-   *
-   *  All the location information in ELF and DWARF are expressed as an offsets
-   *  from this base address:
-   *
-   *  - location of the functions and global variables
-   *
-   *  - the DWARF instruction `OP_addr` pushes this on the DWARF stack.
-   **/
-  void* base_address() const;
-
-  /** Find a function by instruction address
-   *
-   *  Loads the dwarf information on need.
-   *
-   *  @param ip instruction address
-   *  @return corresponding function (if any) or nullptr
-   */
-  simgrid::mc::Frame* find_function(const void* ip);
-
-  /** Find a global variable by name
-   *
-   *  Loads the dwarf information on need.
-   *
-   *  This is used to ignore global variables and to find well-known variables
-   *  (`__mmalloc_default_mdp`).
-   *
-   *  @param name scopes name of the global variable (`myproject::Foo::count`)
-   *  @return corresponding variable (if any) or nullptr
-   */
-  const simgrid::mc::Variable* find_variable(const char* name);
-
-  /** Remove a global variable (in order to ignore it)
-   *
-   *  This is used to ignore a global variable for the snapshot comparison.
-   */
-  void remove_global_variable(const char* name);
-
-  /** Remove a local variables (in order to ignore it)
-   *
-   *  @param name Name of the local variable
-   *  @param scope scopes name name of the function (myproject::Foo::count) or null for all functions
-   */
-  void remove_local_variable(const char* name, const char* scope);
-};
-
-XBT_PRIVATE std::shared_ptr<ObjectInformation> createObjectInformation(std::vector<simgrid::xbt::VmMap> const& maps,
-                                                                       const char* name);
-
-/** Augment the current module with information about the other ones */
-XBT_PRIVATE void postProcessObjectInformation(const simgrid::mc::RemoteProcessMemory* process,
-                                              simgrid::mc::ObjectInformation* info);
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/inspect/Type.hpp b/src/mc/inspect/Type.hpp
deleted file mode 100644 (file)
index 3c225a1..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_TYPE_HPP
-#define SIMGRID_MC_TYPE_HPP
-
-#include <cstddef>
-
-#include <string>
-#include <vector>
-
-#include <dwarf.h>
-
-#include "xbt/asserts.h"
-#include "xbt/base.h"
-
-#include "src/mc/inspect/LocationList.hpp"
-#include "src/mc/mc_forward.hpp"
-
-namespace simgrid::mc {
-
-/** A member of a structure, union
- *
- *  Inheritance is seen as a special member as well.
- */
-class Member {
-public:
-  using flags_type                                 = int;
-  static constexpr flags_type INHERITANCE_FLAG     = 1;
-  static constexpr flags_type VIRTUAL_POINTER_FLAG = 2;
-
-  Member() = default;
-
-  /** Whether this member represent some inherited part of the object */
-  flags_type flags = 0;
-
-  /** Name of the member (if any) */
-  std::string name;
-
-  /** DWARF location expression for locating the location of the member */
-  simgrid::dwarf::DwarfExpression location_expression;
-
-  std::size_t byte_size = 0; // Do we really need this?
-
-  unsigned type_id        = 0;
-  simgrid::mc::Type* type = nullptr;
-
-  bool isInheritance() const { return this->flags & INHERITANCE_FLAG; }
-  bool isVirtualPointer() const { return this->flags & VIRTUAL_POINTER_FLAG; }
-
-  /** Whether the member is at a fixed offset from the base address */
-  bool has_offset_location() const
-  {
-    // Recognize the expression `DW_OP_plus_uconst(offset)`:
-    return location_expression.size() == 1 && location_expression[0].atom == DW_OP_plus_uconst;
-  }
-
-  /** Get the offset of the member
-   *
-   *  This is only valid is the member is at a fixed offset from the base.
-   *  This is often the case (for C types, C++ type without virtual
-   *  inheritance).
-   *
-   *  If the location is more complex, the location expression has
-   *  to be evaluated (which might need accessing the memory).
-   */
-  int offset() const
-  {
-    xbt_assert(this->has_offset_location());
-    return this->location_expression[0].number;
-  }
-
-  /** Set the location of the member as a fixed offset */
-  void offset(int new_offset)
-  {
-    // Set the expression to be `DW_OP_plus_uconst(offset)`:
-    Dwarf_Op op;
-    op.atom                   = DW_OP_plus_uconst;
-    op.number                 = new_offset;
-    this->location_expression = {op};
-  }
-};
-
-/** A type in the model-checked program */
-class Type {
-public:
-  Type() = default;
-
-  /** The DWARF TAG of the type (e.g. DW_TAG_array_type) */
-  int type    = 0;
-  unsigned id = 0;             /* Offset in the section (in hexadecimal form) */
-  std::string name;            /* Name of the type */
-  int byte_size     = 0;       /* Size in bytes */
-  int element_count = 0;       /* Number of elements for array type */
-  unsigned type_id  = 0;       /* DW_AT_type id */
-  std::vector<Member> members; /* if DW_TAG_structure_type, DW_TAG_class_type, DW_TAG_union_type*/
-
-  simgrid::mc::Type* subtype   = nullptr; // DW_AT_type
-  simgrid::mc::Type* full_type = nullptr; // The same (but more complete) type
-};
-
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/inspect/Variable.hpp b/src/mc/inspect/Variable.hpp
deleted file mode 100644 (file)
index f2cae32..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_VARIABLE_HPP
-#define SIMGRID_MC_VARIABLE_HPP
-
-#include <cstddef>
-
-#include <string>
-
-#include "src/mc/inspect/LocationList.hpp"
-#include "src/mc/mc_forward.hpp"
-
-namespace simgrid::mc {
-
-/** A variable (global or local) in the model-checked program */
-class Variable {
-public:
-  Variable()       = default;
-  std::uint32_t id = 0;
-  bool global      = false;
-  std::string name;
-  unsigned type_id        = 0;
-  simgrid::mc::Type* type = nullptr;
-
-  /** Address of the variable (if it is fixed) */
-  void* address = nullptr;
-
-  /** Description of the location of the variable (if it's not fixed) */
-  simgrid::dwarf::LocationList location_list;
-
-  /** Offset of validity of the variable (DW_AT_start_scope)
-   *
-   *  This is an offset from the variable scope beginning. This variable
-   *  is only valid starting from this offset.
-   */
-  std::size_t start_scope = 0;
-
-  simgrid::mc::ObjectInformation* object_info = nullptr;
-};
-
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/inspect/mc_dwarf.cpp b/src/mc/inspect/mc_dwarf.cpp
deleted file mode 100644 (file)
index 094635d..0000000
+++ /dev/null
@@ -1,1207 +0,0 @@
-/* Copyright (c) 2008-2023. 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 "src/simgrid/util.hpp"
-#include "xbt/log.h"
-#include "xbt/string.hpp"
-#include "xbt/sysdep.h"
-#include <simgrid/config.h>
-
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/inspect/Variable.hpp"
-#include "src/mc/inspect/mc_dwarf.hpp"
-#include "src/mc/mc_private.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include <algorithm>
-#include <array>
-#include <cerrno>
-#include <cinttypes>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <fcntl.h>
-#include <memory>
-#include <unordered_map>
-#include <utility>
-
-#include <boost/range/algorithm.hpp>
-
-#include <elfutils/libdw.h>
-#include <elfutils/version.h>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing");
-
-/** @brief The default DW_TAG_lower_bound for a given DW_AT_language.
- *
- *  The default for a given language is defined in the DWARF spec.
- *
- *  @param language constant as defined by the DWARf spec
- */
-static uint64_t MC_dwarf_default_lower_bound(int lang);
-
-/** @brief Computes the the element_count of a DW_TAG_enumeration_type DIE
- *
- * This is the number of elements in a given array dimension.
- *
- * A reference of the compilation unit (DW_TAG_compile_unit) is
- * needed because the default lower bound (when there is no DW_AT_lower_bound)
- * depends of the language of the compilation unit (DW_AT_language).
- *
- * @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);
-
-/** @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);
-
-/** @brief Process a DIE
- *
- *  @param info the resulting object for the library/binary file (output)
- *  @param die  the current DIE
- *  @param unit the DIE of the compile unit of the current DIE
- *  @param frame containing frame if any
- */
-static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                simgrid::mc::Frame* frame, const char* ns);
-
-/** @brief Process a type DIE
- */
-static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                     simgrid::mc::Frame* frame, const char* ns);
-
-/** @brief Calls MC_dwarf_handle_die on all children of the given die
- *
- *  @param info the resulting object for the library/binary file (output)
- *  @param die  the current DIE
- *  @param unit the DIE of the compile unit of the current DIE
- *  @param frame containing frame if any
- */
-static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                     simgrid::mc::Frame* frame, const char* ns);
-
-/** @brief Handle a variable (DW_TAG_variable or other)
- *
- *  @param info the resulting object for the library/binary file (output)
- *  @param die  the current DIE
- *  @param unit the DIE of the compile unit of the current DIE
- *  @param frame containing frame if any
- */
-static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, const Dwarf_Die* unit,
-                                         simgrid::mc::Frame* frame, const char* ns);
-
-/** @brief Get the DW_TAG_type of the DIE
- *
- *  @param die DIE
- *  @return DW_TAG_type attribute as a new string (nullptr if none)
- */
-static std::uint64_t MC_dwarf_at_type(Dwarf_Die* die);
-
-namespace simgrid::dwarf {
-
-enum class TagClass { Unknown, Type, Subprogram, Variable, Scope, Namespace };
-
-/*** Class of forms defined in the DWARF standard */
-enum class FormClass {
-  Unknown,
-  Address, // Location in the program's address space
-  Block,   // Arbitrary block of bytes
-  Constant,
-  String,
-  Flag,      // Boolean value
-  Reference, // Reference to another DIE
-  ExprLoc,   // DWARF expression/location description
-  LinePtr,
-  LocListPtr,
-  MacPtr,
-  RangeListPtr
-};
-
-static TagClass classify_tag(int tag)
-{
-  static const std::unordered_map<int, TagClass> map = {
-      {DW_TAG_array_type, TagClass::Type},            {DW_TAG_class_type, TagClass::Type},
-      {DW_TAG_enumeration_type, TagClass::Type},      {DW_TAG_typedef, TagClass::Type},
-      {DW_TAG_pointer_type, TagClass::Type},          {DW_TAG_reference_type, TagClass::Type},
-      {DW_TAG_rvalue_reference_type, TagClass::Type}, {DW_TAG_string_type, TagClass::Type},
-      {DW_TAG_structure_type, TagClass::Type},        {DW_TAG_subroutine_type, TagClass::Type},
-      {DW_TAG_union_type, TagClass::Type},            {DW_TAG_ptr_to_member_type, TagClass::Type},
-      {DW_TAG_set_type, TagClass::Type},              {DW_TAG_subrange_type, TagClass::Type},
-      {DW_TAG_base_type, TagClass::Type},             {DW_TAG_const_type, TagClass::Type},
-      {DW_TAG_file_type, TagClass::Type},             {DW_TAG_packed_type, TagClass::Type},
-      {DW_TAG_volatile_type, TagClass::Type},         {DW_TAG_restrict_type, TagClass::Type},
-      {DW_TAG_interface_type, TagClass::Type},        {DW_TAG_unspecified_type, TagClass::Type},
-      {DW_TAG_shared_type, TagClass::Type},
-
-      {DW_TAG_subprogram, TagClass::Subprogram},
-
-      {DW_TAG_variable, TagClass::Variable},          {DW_TAG_formal_parameter, TagClass::Variable},
-
-      {DW_TAG_lexical_block, TagClass::Scope},        {DW_TAG_try_block, TagClass::Scope},
-      {DW_TAG_catch_block, TagClass::Scope},          {DW_TAG_inlined_subroutine, TagClass::Scope},
-      {DW_TAG_with_stmt, TagClass::Scope},
-
-      {DW_TAG_namespace, TagClass::Namespace}};
-
-  auto res = map.find(tag);
-  return res != map.end() ? res->second : TagClass::Unknown;
-}
-
-/** @brief Find the DWARF data class for a given DWARF data form
- *
- *  This mapping is defined in the DWARF spec.
- *
- *  @param form The form (values taken from the DWARF spec)
- *  @return An internal representation for the corresponding class
- * */
-static FormClass classify_form(int form)
-{
-  static const std::unordered_map<int, FormClass> map = {
-      {DW_FORM_addr, FormClass::Address},
-
-      {DW_FORM_block2, FormClass::Block},           {DW_FORM_block4, FormClass::Block},
-      {DW_FORM_block, FormClass::Block},            {DW_FORM_block1, FormClass::Block},
-
-      {DW_FORM_data1, FormClass::Constant},         {DW_FORM_data2, FormClass::Constant},
-      {DW_FORM_data4, FormClass::Constant},         {DW_FORM_data8, FormClass::Constant},
-      {DW_FORM_udata, FormClass::Constant},         {DW_FORM_sdata, FormClass::Constant},
-#if _ELFUTILS_PREREQ(0, 171)
-      {DW_FORM_implicit_const, FormClass::Constant},
-#endif
-
-      {DW_FORM_string, FormClass::String},          {DW_FORM_strp, FormClass::String},
-
-      {DW_FORM_ref_addr, FormClass::Reference},     {DW_FORM_ref1, FormClass::Reference},
-      {DW_FORM_ref2, FormClass::Reference},         {DW_FORM_ref4, FormClass::Reference},
-      {DW_FORM_ref8, FormClass::Reference},         {DW_FORM_ref_udata, FormClass::Reference},
-
-      {DW_FORM_flag, FormClass::Flag},              {DW_FORM_flag_present, FormClass::Flag},
-
-      {DW_FORM_exprloc, FormClass::ExprLoc}
-
-      // TODO sec offset
-      // TODO indirect
-  };
-
-  auto res = map.find(form);
-  return res != map.end() ? res->second : FormClass::Unknown;
-}
-
-/** @brief Get the name of the tag of a given DIE
- *
- *  @param die DIE
- *  @return name of the tag of this DIE
- */
-inline XBT_PRIVATE const char* tagname(Dwarf_Die* die)
-{
-  return tagname(dwarf_tag(die));
-}
-
-} // namespace simgrid::dwarf
-
-// ***** Attributes
-
-/** @brief Get an attribute of a given DIE as a string
- *
- *  @param die       the 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)
-{
-  Dwarf_Attribute attr;
-  if (not dwarf_attr_integrate(die, attribute, &attr))
-    return nullptr;
-  else
-    return dwarf_formstring(&attr);
-}
-
-static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die* die, int attribute)
-{
-  Dwarf_Attribute attr;
-  if (dwarf_hasattr_integrate(die, attribute) == 0)
-    return 0;
-  dwarf_attr_integrate(die, attribute, &attr);
-  Dwarf_Die subtype_die;
-  xbt_assert(dwarf_formref_die(&attr, &subtype_die) != nullptr, "Could not find DIE");
-  return dwarf_dieoffset(&subtype_die);
-}
-
-/** @brief Find the type/subtype (DW_AT_type) for a DIE
- *
- *  @param die the DIE
- *  @return DW_AT_type reference as a global offset in hexadecimal (or nullptr)
- */
-static std::uint64_t MC_dwarf_at_type(Dwarf_Die* die)
-{
-  return MC_dwarf_attr_integrate_dieoffset(die, DW_AT_type);
-}
-
-static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die* die, int attribute)
-{
-  Dwarf_Attribute attr;
-  if (dwarf_attr_integrate(die, attribute, &attr) == nullptr)
-    return 0;
-  Dwarf_Addr value;
-  if (dwarf_formaddr(&attr, &value) == 0)
-    return (uint64_t)value;
-  else
-    return 0;
-}
-
-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) == nullptr)
-    return default_value;
-  Dwarf_Word 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)
-{
-  Dwarf_Attribute attr;
-  if ((integrate ? dwarf_attr_integrate(die, attribute, &attr) : dwarf_attr(die, attribute, &attr)) == nullptr)
-    return false;
-
-  bool result;
-  xbt_assert(not dwarf_formflag(&attr, &result), "Unexpected form for attribute %s",
-             simgrid::dwarf::attrname(attribute));
-  return result;
-}
-
-/** @brief Find the default lower bound for a given language
- *
- *  The default lower bound of an array (when DW_TAG_lower_bound
- *  is missing) depends on the language of the compilation unit.
- *
- *  @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)
-{
-  const std::unordered_map<int, unsigned> map = {
-      {DW_LANG_C, 0},           {DW_LANG_C89, 0},            {DW_LANG_C99, 0},            {DW_LANG_C11, 0},
-      {DW_LANG_C_plus_plus, 0}, {DW_LANG_C_plus_plus_11, 0}, {DW_LANG_C_plus_plus_14, 0}, {DW_LANG_D, 0},
-      {DW_LANG_Java, 0},        {DW_LANG_ObjC, 0},           {DW_LANG_ObjC_plus_plus, 0}, {DW_LANG_Python, 0},
-      {DW_LANG_UPC, 0},
-
-      {DW_LANG_Ada83, 1},       {DW_LANG_Ada95, 1},          {DW_LANG_Fortran77, 1},      {DW_LANG_Fortran90, 1},
-      {DW_LANG_Fortran95, 1},   {DW_LANG_Fortran03, 1},      {DW_LANG_Fortran08, 1},      {DW_LANG_Modula2, 1},
-      {DW_LANG_Pascal83, 1},    {DW_LANG_PL1, 1},            {DW_LANG_Cobol74, 1},        {DW_LANG_Cobol85, 1}};
-
-  auto res = map.find(lang);
-  xbt_assert(res != map.end(), "No default DW_TAG_lower_bound for language %i and none given", lang);
-  return res->second;
-}
-
-/** @brief Finds the number of elements in a DW_TAG_subrange_type or DW_TAG_enumeration_type DIE
- *
- *  @param die  the DIE
- *  @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", simgrid::dwarf::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 (not dwarf_hasattr_integrate(die, DW_AT_upper_bound))
-    // 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, static_cast<uint64_t>(-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, static_cast<uint64_t>(-1));
-  else
-    lower_bound = MC_dwarf_default_lower_bound(dwarf_srclang(unit));
-  return upper_bound - lower_bound + 1;
-}
-
-/** @brief Finds the number of elements in an array type (DW_TAG_array_type)
- *
- *  The compilation unit might be needed because the default lower
- *  bound depends on the language of the compilation unit.
- *
- *  @param die the DIE of the DW_TAG_array_type
- *  @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",
-             simgrid::dwarf::tagname(die));
-
-  int result = 1;
-  Dwarf_Die child;
-  for (int 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);
-  }
-  return result;
-}
-
-// ***** Variable
-
-/** Sort the variable by name and address.
- *
- *  We could use boost::container::flat_set instead.
- */
-static bool MC_compare_variable(simgrid::mc::Variable const& a, simgrid::mc::Variable const& b)
-{
-  int cmp = a.name.compare(b.name);
-  if (cmp < 0)
-    return true;
-  else if (cmp > 0)
-    return false;
-  else
-    return a.address < b.address;
-}
-
-// ***** simgrid::mc::Type*
-
-/** @brief Initialize the location of a member of a type
- * (DW_AT_data_member_location of a DW_TAG_member).
- *
- *  @param  type   a type (struct, class)
- *  @param  member the member of the type
- *  @param  child  DIE of the member (DW_TAG_member)
- */
-static void MC_dwarf_fill_member_location(const simgrid::mc::Type* type, simgrid::mc::Member* member, Dwarf_Die* child)
-{
-  xbt_assert(not dwarf_hasattr(child, DW_AT_data_bit_offset), "Can't groke DW_AT_data_bit_offset.");
-
-  if (not dwarf_hasattr_integrate(child, DW_AT_data_member_location)) {
-    xbt_assert(type->type == DW_TAG_union_type,
-               "Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%" PRIx64 ">%s",
-               member->name.c_str(), (uint64_t)type->id, type->name.c_str());
-    return;
-  }
-
-  Dwarf_Attribute attr;
-  dwarf_attr_integrate(child, DW_AT_data_member_location, &attr);
-  int form                             = dwarf_whatform(&attr);
-  simgrid::dwarf::FormClass form_class = simgrid::dwarf::classify_form(form);
-  switch (form_class) {
-    case simgrid::dwarf::FormClass::ExprLoc:
-    case simgrid::dwarf::FormClass::Block:
-      // Location expression:
-      {
-        Dwarf_Op* expr;
-        size_t len;
-        xbt_assert(not dwarf_getlocation(&attr, &expr, &len),
-                   "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.c_str());
-        member->location_expression = simgrid::dwarf::DwarfExpression(expr, expr + len);
-        break;
-      }
-    case simgrid::dwarf::FormClass::Constant:
-      // Offset from the base address of the object:
-      {
-        Dwarf_Word offset;
-        xbt_assert(not dwarf_formudata(&attr, &offset), "Cannot get %s location <%" PRIx64 ">%s",
-                   MC_dwarf_attr_integrate_string(child, DW_AT_name), (uint64_t)type->id, type->name.c_str());
-        member->offset(offset);
-        break;
-      }
-
-    default:
-      // includes FormClass::LocListPtr (reference to a location list: TODO) and FormClass::Reference (it's supposed to
-      // be possible in DWARF2 but I couldn't find its semantic in the spec)
-      xbt_die("Can't handle form class (%d) / form 0x%x as DW_AT_member_location", (int)form_class, (unsigned)form);
-  }
-}
-
-/** @brief Populate the list of members of a type
- *
- *  @param info ELF object containing the type DIE
- *  @param die  DIE of the type
- *  @param unit DIE of the compilation unit containing the type DIE
- *  @param type the type
- */
-static void MC_dwarf_add_members(const simgrid::mc::ObjectInformation* /*info*/, Dwarf_Die* die,
-                                 const Dwarf_Die* /*unit*/, simgrid::mc::Type* type)
-{
-  Dwarf_Die child;
-  xbt_assert(type->members.empty());
-  for (int 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) {
-      // 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))
-        continue;
-
-      // TODO, we should use another type (because is is not a type but a member)
-      simgrid::mc::Member member;
-      if (tag == DW_TAG_inheritance)
-        member.flags |= simgrid::mc::Member::INHERITANCE_FLAG;
-
-      const char* name = MC_dwarf_attr_integrate_string(&child, DW_AT_name);
-      if (name)
-        member.name = name;
-      // Those base names are used by GCC and clang for virtual table pointers
-      // respectively ("__vptr$ClassName", "__vptr.ClassName"):
-      if (member.name.rfind("__vptr$", 0) == 0 || member.name.rfind("__vptr.", 0) == 0)
-        member.flags |= simgrid::mc::Member::VIRTUAL_POINTER_FLAG;
-      // A cleaner solution would be to check against the type:
-      // ---
-      // tag: DW_TAG_member
-      // name: "_vptr$Foo"
-      // type:
-      //   # Type for a pointer to a vtable
-      //   tag: DW_TAG_pointer_type
-      //   type:
-      //     # Type for a vtable:
-      //     tag: DW_TAG_pointer_type
-      //     name: "__vtbl_ptr_type"
-      //     type:
-      //       tag: DW_TAG_subroutine_type
-      //       type:
-      //         tag: DW_TAG_base_type
-      //         name: "int"
-      // ---
-
-      member.byte_size = MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0);
-      member.type_id   = MC_dwarf_at_type(&child);
-
-      if (dwarf_hasattr(&child, DW_AT_data_bit_offset)) {
-        XBT_WARN("Can't groke DW_AT_data_bit_offset for %s", name);
-        continue;
-      }
-
-      MC_dwarf_fill_member_location(type, &member, &child);
-
-      xbt_assert(member.type_id, "Missing type for member %s of <%" PRIx64 ">%s", member.name.c_str(),
-                 (uint64_t)type->id, type->name.c_str());
-
-      type->members.push_back(std::move(member));
-    }
-  }
-}
-
-/** @brief Create a MC type object from a DIE
- *
- *  @param info current object info object
- *  @param die DIE (for a given type)
- *  @param unit compilation unit of the current DIE
- *  @return MC representation of the type
- */
-static simgrid::mc::Type MC_dwarf_die_to_type(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                              simgrid::mc::Frame* frame, const char* ns)
-{
-  simgrid::mc::Type type;
-  type.type          = dwarf_tag(die);
-  type.name          = "";
-  type.element_count = -1;
-
-  // Global Offset
-  type.id = dwarf_dieoffset(die);
-
-  const char* prefix;
-  switch (type.type) {
-    case DW_TAG_structure_type:
-      prefix = "struct ";
-      break;
-    case DW_TAG_union_type:
-      prefix = "union ";
-      break;
-    case DW_TAG_class_type:
-      prefix = "class ";
-      break;
-    default:
-      prefix = "";
-  }
-
-  const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-  if (name != nullptr) {
-    if (ns)
-      type.name = simgrid::xbt::string_printf("%s%s::%s", prefix, ns, name);
-    else
-      type.name = simgrid::xbt::string_printf("%s%s", prefix, name);
-  }
-
-  type.type_id = MC_dwarf_at_type(die);
-
-  // Some compilers do not emit DW_AT_byte_size for pointer_type,
-  // so we fill this. We currently assume that the model-checked process is in
-  // the same architecture..
-  if (type.type == DW_TAG_pointer_type)
-    type.byte_size = sizeof(void*);
-
-  // 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) {
-    Dwarf_Word size;
-    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;
-
-    case DW_TAG_pointer_type:
-    case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
-      break;
-
-    case DW_TAG_structure_type:
-    case DW_TAG_union_type:
-    case DW_TAG_class_type:
-      MC_dwarf_add_members(info, die, unit, &type);
-      MC_dwarf_handle_children(info, die, unit, frame,
-                               ns ? simgrid::xbt::string_printf("%s::%s", ns, name).c_str() : type.name.c_str());
-      break;
-
-    default:
-      XBT_DEBUG("Unhandled type: %d (%s)", type.type, simgrid::dwarf::tagname(type.type));
-      break;
-  }
-
-  return type;
-}
-
-static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                     simgrid::mc::Frame* frame, const char* ns)
-{
-  simgrid::mc::Type type = MC_dwarf_die_to_type(info, die, unit, frame, ns);
-  auto& t                = (info->types[type.id] = std::move(type));
-  if (not t.name.empty() && type.byte_size != 0)
-    info->full_types_by_name[t.name] = &t;
-}
-
-static std::unique_ptr<simgrid::mc::Variable> MC_die_to_variable(simgrid::mc::ObjectInformation* info, Dwarf_Die* die,
-                                                                 const Dwarf_Die* /*unit*/,
-                                                                 const simgrid::mc::Frame* frame, const char* ns)
-{
-  // Skip declarations:
-  if (MC_dwarf_attr_flag(die, DW_AT_declaration, false))
-    return nullptr;
-
-  // Skip compile time constants:
-  if (dwarf_hasattr(die, DW_AT_const_value))
-    return nullptr;
-
-  Dwarf_Attribute attr_location;
-  if (dwarf_attr(die, DW_AT_location, &attr_location) == nullptr)
-    // No location: do not add it ?
-    return nullptr;
-
-  auto variable         = std::make_unique<simgrid::mc::Variable>();
-  variable->id          = dwarf_dieoffset(die);
-  variable->global      = frame == nullptr; // Can be override base on DW_AT_location
-  variable->object_info = info;
-
-  const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-  if (name)
-    variable->name = name;
-  variable->type_id = MC_dwarf_at_type(die);
-
-  int form = dwarf_whatform(&attr_location);
-  simgrid::dwarf::FormClass form_class;
-  if (form == DW_FORM_sec_offset)
-    form_class = simgrid::dwarf::FormClass::Constant;
-  else
-    form_class = simgrid::dwarf::classify_form(form);
-  switch (form_class) {
-    case simgrid::dwarf::FormClass::ExprLoc:
-    case simgrid::dwarf::FormClass::Block:
-      // Location expression:
-      {
-        Dwarf_Op* expr;
-        size_t len;
-        xbt_assert(not dwarf_getlocation(&attr_location, &expr, &len),
-                   "Could not read location expression in DW_AT_location "
-                   "of variable <%" PRIx64 ">%s",
-                   (uint64_t)variable->id, variable->name.c_str());
-
-        if (len == 1 && expr[0].atom == DW_OP_addr) {
-          variable->global  = true;
-          auto offset       = static_cast<uintptr_t>(expr[0].number);
-          auto base         = reinterpret_cast<uintptr_t>(info->base_address());
-          variable->address = reinterpret_cast<void*>(base + offset);
-        } else
-          variable->location_list = {
-              simgrid::dwarf::LocationListEntry(simgrid::dwarf::DwarfExpression(expr, expr + len))};
-
-        break;
-      }
-
-    case simgrid::dwarf::FormClass::LocListPtr:
-    case simgrid::dwarf::FormClass::Constant:
-      // Reference to location list:
-      variable->location_list = simgrid::dwarf::location_list(*info, attr_location);
-      break;
-
-    default:
-      xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%" PRIx64 ">%s", (unsigned)form, form,
-              (unsigned)form_class, (int)form_class, (uint64_t)variable->id, variable->name.c_str());
-  }
-
-  // Handle start_scope:
-  if (dwarf_hasattr(die, DW_AT_start_scope)) {
-    Dwarf_Attribute attr;
-    dwarf_attr(die, DW_AT_start_scope, &attr);
-    form       = dwarf_whatform(&attr);
-    form_class = simgrid::dwarf::classify_form(form);
-    if (form_class == simgrid::dwarf::FormClass::Constant) {
-      Dwarf_Word value;
-      variable->start_scope = dwarf_formudata(&attr, &value) == 0 ? (size_t)value : 0;
-    } else {
-      // TODO: FormClass::RangeListPtr
-      xbt_die("Unhandled form 0x%x, class 0x%X for DW_AT_start_scope of variable %s", (unsigned)form,
-              (unsigned)form_class, name == nullptr ? "?" : name);
-    }
-  }
-
-  if (ns && variable->global)
-    variable->name.insert(0, std::string(ns) + "::");
-
-  // The current code needs a variable name,
-  // generate a fake one:
-  static int mc_anonymous_variable_index = 0;
-  if (variable->name.empty()) {
-    variable->name = "@anonymous#" + std::to_string(mc_anonymous_variable_index);
-    mc_anonymous_variable_index++;
-  }
-  return variable;
-}
-
-static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, const Dwarf_Die* unit,
-                                         simgrid::mc::Frame* frame, const char* ns)
-{
-  std::unique_ptr<simgrid::mc::Variable> variable = MC_die_to_variable(info, die, unit, frame, ns);
-  if (not variable)
-    return;
-  // Those arrays are sorted later:
-  if (variable->global)
-    info->global_variables.push_back(std::move(*variable));
-  else if (frame != nullptr)
-    frame->variables.push_back(std::move(*variable));
-  else
-    xbt_die("No frame for this local variable");
-}
-
-static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                      simgrid::mc::Frame* parent_frame, const char* ns)
-{
-  // TODO, handle DW_TAG_type/DW_TAG_location for DW_TAG_with_stmt
-  int tag                        = dwarf_tag(die);
-  simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag);
-
-  // (Template) Subprogram declaration:
-  if (klass == simgrid::dwarf::TagClass::Subprogram && MC_dwarf_attr_flag(die, DW_AT_declaration, false))
-    return;
-
-  if (klass == simgrid::dwarf::TagClass::Scope)
-    xbt_assert(parent_frame, "No parent scope for this scope");
-
-  simgrid::mc::Frame frame;
-  frame.tag         = tag;
-  frame.id          = dwarf_dieoffset(die);
-  frame.object_info = info;
-
-  if (klass == simgrid::dwarf::TagClass::Subprogram) {
-    const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-    if (name && ns)
-      frame.name = std::string(ns) + "::" + name;
-    else if (name)
-      frame.name = name;
-  }
-
-  frame.abstract_origin_id = MC_dwarf_attr_integrate_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
-  auto base = reinterpret_cast<std::uint64_t>(info->base_address());
-
-  // TODO, support DW_AT_ranges
-  uint64_t low_pc     = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc);
-  frame.range.begin() = low_pc ? base + low_pc : 0;
-  if (low_pc) {
-    // DW_AT_high_pc:
-    Dwarf_Attribute attr;
-    xbt_assert(dwarf_attr_integrate(die, DW_AT_high_pc, &attr), "Missing DW_AT_high_pc matching with DW_AT_low_pc");
-
-    Dwarf_Sword offset;
-    Dwarf_Addr high_pc;
-
-    switch (simgrid::dwarf::classify_form(dwarf_whatform(&attr))) {
-      // DW_AT_high_pc if an offset from the low_pc:
-      case simgrid::dwarf::FormClass::Constant:
-
-        xbt_assert(dwarf_formsdata(&attr, &offset) == 0, "Could not read constant");
-        frame.range.end() = frame.range.begin() + offset;
-        break;
-
-        // DW_AT_high_pc is a relocatable address:
-      case simgrid::dwarf::FormClass::Address:
-        xbt_assert(dwarf_formaddr(&attr, &high_pc) == 0, "Could not read address");
-        frame.range.end() = base + high_pc;
-        break;
-
-      default:
-        xbt_die("Unexpected class for DW_AT_high_pc");
-    }
-  }
-
-  if (klass == simgrid::dwarf::TagClass::Subprogram) {
-    Dwarf_Attribute attr_frame_base;
-    if (dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base))
-      frame.frame_base_location = simgrid::dwarf::location_list(*info, attr_frame_base);
-  }
-
-  // Handle children:
-  MC_dwarf_handle_children(info, die, unit, &frame, ns);
-
-  // We sort them in order to have an (somewhat) efficient by name
-  // lookup:
-  boost::range::sort(frame.variables, MC_compare_variable);
-
-  // Register it:
-  if (klass == simgrid::dwarf::TagClass::Subprogram)
-    info->subprograms[frame.id] = std::move(frame);
-  else if (klass == simgrid::dwarf::TagClass::Scope)
-    parent_frame->scopes.push_back(std::move(frame));
-}
-
-static void mc_dwarf_handle_namespace_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                          simgrid::mc::Frame* frame, const char* ns)
-{
-  const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
-  xbt_assert(not frame, "Unexpected namespace in a subprogram");
-  char* new_ns = ns == nullptr ? xbt_strdup(name) : bprintf("%s::%s", ns, name);
-  MC_dwarf_handle_children(info, die, unit, frame, new_ns);
-  xbt_free(new_ns);
-}
-
-static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                     simgrid::mc::Frame* frame, const char* ns)
-{
-  // For each child DIE:
-  Dwarf_Die child;
-  for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child))
-    MC_dwarf_handle_die(info, &child, unit, frame, ns);
-}
-
-static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
-                                simgrid::mc::Frame* frame, const char* ns)
-{
-  int tag                        = dwarf_tag(die);
-  simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag);
-  switch (klass) {
-    // Type:
-    case simgrid::dwarf::TagClass::Type:
-      MC_dwarf_handle_type_die(info, die, unit, frame, ns);
-      break;
-
-      // Subprogram or scope:
-    case simgrid::dwarf::TagClass::Subprogram:
-    case simgrid::dwarf::TagClass::Scope:
-      MC_dwarf_handle_scope_die(info, die, unit, frame, ns);
-      return;
-
-      // Variable:
-    case simgrid::dwarf::TagClass::Variable:
-      MC_dwarf_handle_variable_die(info, die, unit, frame, ns);
-      break;
-
-    case simgrid::dwarf::TagClass::Namespace:
-      mc_dwarf_handle_namespace_die(info, die, unit, frame, ns);
-      break;
-
-    default:
-      break;
-  }
-}
-
-static Elf64_Half get_type(Elf* elf)
-{
-  if (const Elf64_Ehdr* ehdr64 = elf64_getehdr(elf))
-    return ehdr64->e_type;
-  if (const Elf32_Ehdr* ehdr32 = elf32_getehdr(elf))
-    return ehdr32->e_type;
-  xbt_die("Could not get ELF heeader");
-}
-
-static void read_dwarf_info(simgrid::mc::ObjectInformation* info, Dwarf* dwarf)
-{
-  // For each compilation unit:
-  Dwarf_Off offset      = 0;
-  Dwarf_Off next_offset = 0;
-  size_t length;
-
-  while (dwarf_nextcu(dwarf, offset, &next_offset, &length, nullptr, nullptr, nullptr) == 0) {
-    if (Dwarf_Die unit_die; dwarf_offdie(dwarf, offset + length, &unit_die) != nullptr)
-      MC_dwarf_handle_children(info, &unit_die, &unit_die, nullptr, nullptr);
-    offset = next_offset;
-  }
-}
-
-/** Get the build-id (NT_GNU_BUILD_ID) from the ELF file
- *
- *  This build-id may is used to locate an external debug (DWARF) file
- *  for this ELF file.
- *
- *  @param  elf libelf handle for an ELF file
- *  @return build-id for this ELF file (or an empty vector if none is found)
- */
-static std::vector<std::byte> get_build_id(Elf* elf)
-{
-#ifdef __linux
-  // Summary: the GNU build ID is stored in a ("GNU, NT_GNU_BUILD_ID) note
-  // found in a PT_NOTE entry in the program header table.
-
-  size_t phnum;
-  xbt_assert(elf_getphdrnum(elf, &phnum) == 0, "Could not read program headers");
-
-  // Iterate over the program headers and find the PT_NOTE ones:
-  for (size_t i = 0; i < phnum; ++i) {
-    GElf_Phdr phdr_temp;
-    const GElf_Phdr* phdr = gelf_getphdr(elf, i, &phdr_temp);
-    if (phdr->p_type != PT_NOTE)
-      continue;
-
-    Elf_Data* data = elf_getdata_rawchunk(elf, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR);
-
-    // Iterate over the notes and find the NT_GNU_BUILD_ID one:
-    size_t pos = 0;
-    while (pos < data->d_size) {
-      GElf_Nhdr nhdr;
-      // Location of the name within Elf_Data:
-      size_t name_pos;
-      size_t desc_pos;
-      pos = gelf_getnote(data, pos, &nhdr, &name_pos, &desc_pos);
-      // A build ID note is identified by the pair ("GNU", NT_GNU_BUILD_ID)
-      // (a namespace and a type within this namespace):
-      if (nhdr.n_type == NT_GNU_BUILD_ID && nhdr.n_namesz == sizeof("GNU") &&
-          memcmp(static_cast<std::byte*>(data->d_buf) + name_pos, "GNU", sizeof("GNU")) == 0) {
-        XBT_DEBUG("Found GNU/NT_GNU_BUILD_ID note");
-        std::byte* start = static_cast<std::byte*>(data->d_buf) + desc_pos;
-        std::byte* end   = start + nhdr.n_descsz;
-        return std::vector<std::byte>(start, end);
-      }
-    }
-  }
-#endif
-  return std::vector<std::byte>();
-}
-
-/** Binary data to hexadecimal */
-static inline std::array<char, 2> to_hex(std::byte byte)
-{
-  constexpr std::array<char, 16> hexdigits{
-      {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}};
-  return {hexdigits[std::to_integer<unsigned>(byte >> 4)], hexdigits[std::to_integer<unsigned>(byte & std::byte{0xF})]};
-}
-
-/** Binary data to hexadecimal */
-static std::string to_hex(const std::byte* data, std::size_t count)
-{
-  std::string res;
-  res.resize(2 * count);
-  for (std::size_t i = 0; i < count; i++)
-    std::copy_n(cbegin(to_hex(data[i])), 2, &res[2 * i]);
-  return res;
-}
-
-/** Binary data to hexadecimal */
-static std::string to_hex(std::vector<std::byte> const& data)
-{
-  return to_hex(data.data(), data.size());
-}
-
-/** Base directories for external debug files */
-static constexpr auto debug_paths = {
-    "/usr/lib/debug/",
-    "/usr/local/lib/debug/",
-};
-
-/** Locate an external debug file from the NT_GNU_BUILD_ID
- *
- *  This is one of the mechanisms used for
- *  [separate debug files](https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html).
- */
-// Example:
-// /usr/lib/debug/.build-id/0b/dc77f1c29aea2b14ff5acd9a19ab3175ffdeae.debug
-static int find_by_build_id(std::vector<std::byte> id)
-{
-  std::string filename;
-  std::string hex = to_hex(id);
-  for (const char* const& debug_path : debug_paths) {
-    // Example:
-    filename = std::string(debug_path) + ".build-id/" + to_hex(id.data(), 1) + '/' +
-               to_hex(id.data() + 1, id.size() - 1) + ".debug";
-    XBT_DEBUG("Checking debug file: %s", filename.c_str());
-    if (int fd = open(filename.c_str(), O_RDONLY); fd != -1) {
-      XBT_DEBUG("Found debug file: %s\n", hex.c_str());
-      return fd;
-    }
-    xbt_assert(errno != ENOENT, "Could not open file: %s", strerror(errno));
-  }
-  XBT_DEBUG("No debug info found for build ID %s\n", hex.data());
-  return -1;
-}
-
-/** @brief Populate the debugging information of the given ELF object
- *
- *  Read the DWARF information of the ELF object and populate the
- *  lists of types, variables, functions.
- */
-static void MC_load_dwarf(simgrid::mc::ObjectInformation* info)
-{
-  xbt_assert(elf_version(EV_CURRENT) != EV_NONE, "libelf initialization error");
-
-  // Open the ELF file:
-  int fd = open(info->file_name.c_str(), O_RDONLY);
-  xbt_assert(fd >= 0, "Could not open file %s", info->file_name.c_str());
-  Elf* elf = elf_begin(fd, ELF_C_READ, nullptr);
-  xbt_assert(elf != nullptr && elf_kind(elf) == ELF_K_ELF, "%s is not an ELF file", info->file_name.c_str());
-
-  // Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN`:
-  if (get_type(elf) == ET_EXEC)
-    info->flags |= simgrid::mc::ObjectInformation::Executable;
-
-  // Read DWARF debug information in the file:
-  if (Dwarf* dwarf = dwarf_begin_elf(elf, DWARF_C_READ, nullptr)) {
-    read_dwarf_info(info, dwarf);
-    dwarf_end(dwarf);
-    elf_end(elf);
-    close(fd);
-    return;
-  }
-
-  // If there was no DWARF in the file, try to find it in a separate file.
-  // Different methods might be used to store the DWARF information:
-  //  * GNU NT_GNU_BUILD_ID
-  //  * .gnu_debuglink
-  // See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
-  // for reference of what we are doing.
-
-  // Try with NT_GNU_BUILD_ID: we find the build ID in the ELF file and then
-  // use this ID to find the file in some known locations in the filesystem.
-  if (std::vector<std::byte> build_id = get_build_id(elf); not build_id.empty()) {
-    elf_end(elf);
-    close(fd);
-
-    // Find the debug file using the build id:
-    fd = find_by_build_id(build_id);
-    xbt_assert(fd != -1,
-               "Missing debug info for %s with build-id %s\n"
-               "You might want to install the suitable debugging package.\n",
-               info->file_name.c_str(), to_hex(build_id).c_str());
-
-    // Load the DWARF info from this file:
-    XBT_DEBUG("Load DWARF for %s", info->file_name.c_str());
-    Dwarf* dwarf = dwarf_begin(fd, DWARF_C_READ);
-    xbt_assert(dwarf != nullptr, "No DWARF info for %s", info->file_name.c_str());
-    read_dwarf_info(info, dwarf);
-    dwarf_end(dwarf);
-    close(fd);
-    return;
-  }
-
-  // TODO, try to find DWARF info using .gnu_debuglink.
-
-  elf_end(elf);
-  close(fd);
-  xbt_die("Debugging information not found for %s\n"
-          "Try recompiling with -g\n",
-          info->file_name.c_str());
-}
-
-// ***** Functions index
-
-static void MC_make_functions_index(simgrid::mc::ObjectInformation* info)
-{
-  info->functions_index.clear();
-
-  for (auto& [_, e] : info->subprograms) {
-    if (e.range.begin() == 0)
-      continue;
-    simgrid::mc::FunctionIndexEntry entry;
-    entry.low_pc   = (void*)e.range.begin();
-    entry.function = &e;
-    info->functions_index.push_back(entry);
-  }
-
-  info->functions_index.shrink_to_fit();
-
-  // Sort the array by low_pc:
-  boost::range::sort(info->functions_index,
-                     [](simgrid::mc::FunctionIndexEntry const& a, simgrid::mc::FunctionIndexEntry const& b) {
-                       return a.low_pc < b.low_pc;
-                     });
-}
-
-static void MC_post_process_variables(simgrid::mc::ObjectInformation* info)
-{
-  // Someone needs this to be sorted but who?
-  boost::range::sort(info->global_variables, MC_compare_variable);
-
-  for (simgrid::mc::Variable& variable : info->global_variables)
-    if (variable.type_id)
-      variable.type = simgrid::util::find_map_ptr(info->types, variable.type_id);
-}
-
-static void mc_post_process_scope(simgrid::mc::ObjectInformation* info, simgrid::mc::Frame* scope)
-{
-  if (scope->tag == DW_TAG_inlined_subroutine) {
-    // Attach correct namespaced name in inlined subroutine:
-    auto i = info->subprograms.find(scope->abstract_origin_id);
-    xbt_assert(i != info->subprograms.end(), "Could not lookup abstract origin %" PRIx64,
-               (std::uint64_t)scope->abstract_origin_id);
-    scope->name = i->second.name;
-  }
-
-  // Direct:
-  for (simgrid::mc::Variable& variable : scope->variables)
-    if (variable.type_id)
-      variable.type = simgrid::util::find_map_ptr(info->types, variable.type_id);
-
-  // Recursive post-processing of nested-scopes:
-  for (simgrid::mc::Frame& nested_scope : scope->scopes)
-    mc_post_process_scope(info, &nested_scope);
-}
-
-static simgrid::mc::Type* MC_resolve_type(simgrid::mc::ObjectInformation* info, unsigned type_id)
-{
-  if (not type_id)
-    return nullptr;
-  simgrid::mc::Type* type = simgrid::util::find_map_ptr(info->types, type_id);
-  if (type == nullptr)
-    return nullptr;
-
-  // We already have the information on the type:
-  if (type->byte_size != 0)
-    return type;
-
-  // Don't have a name, we can't find a more complete version:
-  if (type->name.empty())
-    return type;
-
-  // Try to find a more complete description of the type:
-  // We need to fix in order to support C++.
-  if (simgrid::mc::Type** subtype = simgrid::util::find_map_ptr(info->full_types_by_name, type->name))
-    type = *subtype;
-  return type;
-}
-
-static void MC_post_process_types(simgrid::mc::ObjectInformation* info)
-{
-  // Lookup "subtype" field:
-  for (auto& [_, i] : info->types) {
-    i.subtype = MC_resolve_type(info, i.type_id);
-    for (simgrid::mc::Member& member : i.members)
-      member.type = MC_resolve_type(info, member.type_id);
-  }
-}
-
-namespace simgrid::mc {
-
-void ObjectInformation::ensure_dwarf_loaded()
-{
-  if (dwarf_loaded)
-    return;
-  dwarf_loaded = true;
-
-  MC_load_dwarf(this);
-  MC_post_process_variables(this);
-  MC_post_process_types(this);
-  for (auto& [_, entry] : this->subprograms)
-    mc_post_process_scope(this, &entry);
-  MC_make_functions_index(this);
-}
-
-/** @brief Finds information about a given shared object/executable */
-std::shared_ptr<ObjectInformation> createObjectInformation(std::vector<xbt::VmMap> const& maps, const char* name)
-{
-  auto result       = std::make_shared<ObjectInformation>();
-  result->file_name = name;
-  simgrid::mc::find_object_address(maps, result.get());
-  return result;
-}
-
-/*************************************************************************/
-
-void postProcessObjectInformation(const RemoteProcessMemory* process, ObjectInformation* info)
-{
-  for (auto& [_, t] : info->types) {
-    Type* type    = &t;
-    Type* subtype = type;
-    while (subtype->type == DW_TAG_typedef || subtype->type == DW_TAG_volatile_type ||
-           subtype->type == DW_TAG_const_type)
-      if (subtype->subtype)
-        subtype = subtype->subtype;
-      else
-        break;
-
-    // Resolve full_type:
-    if (not subtype->name.empty() && subtype->byte_size == 0)
-      for (auto const& object_info : process->object_infos) {
-        auto i = object_info->full_types_by_name.find(subtype->name);
-        if (i != object_info->full_types_by_name.end() && not i->second->name.empty() && i->second->byte_size) {
-          type->full_type = i->second;
-          break;
-        }
-      }
-    else
-      type->full_type = subtype;
-  }
-}
-
-} // namespace simgrid::mc
-
-namespace simgrid::dwarf {
-
-/** Convert a DWARF register into a libunwind register
- *
- *  DWARF and libunwind does not use the same convention for numbering the
- *  registers on some architectures. The function makes the necessary
- *  conversion.
- */
-int dwarf_register_to_libunwind(int dwarf_register)
-{
-#if defined(__x86_64__) || defined(__aarch64__)
-  // It seems for this arch, DWARF and libunwind agree in the numbering:
-  return dwarf_register;
-#elif defined(__i386__)
-  // Couldn't find the authoritative source of information for this.
-  // This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517.
-  constexpr std::array<int, 24> regs{
-      {/*  0 */ UNW_X86_EAX, /*  1 */ UNW_X86_ECX,    /*  2 */ UNW_X86_EDX, /*  3 */ UNW_X86_EBX,
-       /*  4 */ UNW_X86_ESP, /*  5 */ UNW_X86_EBP,    /*  6 */ UNW_X86_ESI, /*  7 */ UNW_X86_EDI,
-       /*  8 */ UNW_X86_EIP, /*  9 */ UNW_X86_EFLAGS, /* 10 */ UNW_X86_CS,  /* 11 */ UNW_X86_SS,
-       /* 12 */ UNW_X86_DS,  /* 13 */ UNW_X86_ES,     /* 14 */ UNW_X86_FS,  /* 15 */ UNW_X86_GS,
-       /* 16 */ UNW_X86_ST0, /* 17 */ UNW_X86_ST1,    /* 18 */ UNW_X86_ST2, /* 19 */ UNW_X86_ST3,
-       /* 20 */ UNW_X86_ST4, /* 21 */ UNW_X86_ST5,    /* 22 */ UNW_X86_ST6, /* 23 */ UNW_X86_ST7}};
-  return regs.at(dwarf_register);
-#else
-#error This architecture is not supported yet for DWARF expression evaluation.
-#endif
-}
-
-} // namespace simgrid::dwarf
diff --git a/src/mc/inspect/mc_dwarf.hpp b/src/mc/inspect/mc_dwarf.hpp
deleted file mode 100644 (file)
index 7575e1d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2008-2023. 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 SIMGRID_MC_DWARF_HPP
-#define SIMGRID_MC_DWARF_HPP
-
-#include "xbt/base.h"
-
-#include "src/mc/mc_forward.hpp"
-
-namespace simgrid::dwarf {
-
-XBT_PRIVATE const char* attrname(int attr);
-XBT_PRIVATE const char* tagname(int tag);
-
-XBT_PRIVATE void* resolve_member(const void* base, const simgrid::mc::Type* type, const simgrid::mc::Member* member,
-                                 const simgrid::mc::AddressSpace* snapshot);
-
-XBT_PRIVATE
-int dwarf_register_to_libunwind(int dwarf_register);
-
-} // namespace simgrid::dwarf
-
-#endif
diff --git a/src/mc/inspect/mc_dwarf_attrnames.cpp b/src/mc/inspect/mc_dwarf_attrnames.cpp
deleted file mode 100644 (file)
index e050f46..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (c) 2014-2023. 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. */
-
-/* Warning: autogenerated, do not edit! */
-
-#include "src/mc/inspect/mc_dwarf.hpp"
-
-#include <string>
-#include <unordered_map>
-
-namespace {
-const std::unordered_map<int, const char*> attrname_map = {
-    {0x01, "DW_AT_sibling"},
-    {0x02, "DW_AT_location"},
-    {0x03, "DW_AT_name"},
-    {0x09, "DW_AT_ordering"},
-    {0x0a, "DW_AT_subscr_data"},
-    {0x0b, "DW_AT_byte_size"},
-    {0x0c, "DW_AT_bit_offset"},
-    {0x0d, "DW_AT_bit_size"},
-    {0x0f, "DW_AT_element_list"},
-    {0x10, "DW_AT_stmt_list"},
-    {0x11, "DW_AT_low_pc"},
-    {0x12, "DW_AT_high_pc"},
-    {0x13, "DW_AT_language"},
-    {0x14, "DW_AT_member"},
-    {0x15, "DW_AT_discr"},
-    {0x16, "DW_AT_discr_value"},
-    {0x17, "DW_AT_visibility"},
-    {0x18, "DW_AT_import"},
-    {0x19, "DW_AT_string_length"},
-    {0x1a, "DW_AT_common_reference"},
-    {0x1b, "DW_AT_comp_dir"},
-    {0x1c, "DW_AT_const_value"},
-    {0x1d, "DW_AT_containing_type"},
-    {0x1e, "DW_AT_default_value"},
-    {0x20, "DW_AT_inline"},
-    {0x21, "DW_AT_is_optional"},
-    {0x22, "DW_AT_lower_bound"},
-    {0x25, "DW_AT_producer"},
-    {0x27, "DW_AT_prototyped"},
-    {0x2a, "DW_AT_return_addr"},
-    {0x2c, "DW_AT_start_scope"},
-    {0x2e, "DW_AT_bit_stride"},
-    {0x2f, "DW_AT_upper_bound"},
-    {0x31, "DW_AT_abstract_origin"},
-    {0x32, "DW_AT_accessibility"},
-    {0x33, "DW_AT_address_class"},
-    {0x34, "DW_AT_artificial"},
-    {0x35, "DW_AT_base_types"},
-    {0x36, "DW_AT_calling_convention"},
-    {0x37, "DW_AT_count"},
-    {0x38, "DW_AT_data_member_location"},
-    {0x39, "DW_AT_decl_column"},
-    {0x3a, "DW_AT_decl_file"},
-    {0x3b, "DW_AT_decl_line"},
-    {0x3c, "DW_AT_declaration"},
-    {0x3d, "DW_AT_discr_list"},
-    {0x3e, "DW_AT_encoding"},
-    {0x3f, "DW_AT_external"},
-    {0x40, "DW_AT_frame_base"},
-    {0x41, "DW_AT_friend"},
-    {0x42, "DW_AT_identifier_case"},
-    {0x43, "DW_AT_macro_info"},
-    {0x44, "DW_AT_namelist_item"},
-    {0x45, "DW_AT_priority"},
-    {0x46, "DW_AT_segment"},
-    {0x47, "DW_AT_specification"},
-    {0x48, "DW_AT_static_link"},
-    {0x49, "DW_AT_type"},
-    {0x4a, "DW_AT_use_location"},
-    {0x4b, "DW_AT_variable_parameter"},
-    {0x4c, "DW_AT_virtuality"},
-    {0x4d, "DW_AT_vtable_elem_location"},
-    {0x4e, "DW_AT_allocated"},
-    {0x4f, "DW_AT_associated"},
-    {0x50, "DW_AT_data_location"},
-    {0x51, "DW_AT_byte_stride"},
-    {0x52, "DW_AT_entry_pc"},
-    {0x53, "DW_AT_use_UTF8"},
-    {0x54, "DW_AT_extension"},
-    {0x55, "DW_AT_ranges"},
-    {0x56, "DW_AT_trampoline"},
-    {0x57, "DW_AT_call_column"},
-    {0x58, "DW_AT_call_file"},
-    {0x59, "DW_AT_call_line"},
-    {0x5a, "DW_AT_description"},
-    {0x5b, "DW_AT_binary_scale"},
-    {0x5c, "DW_AT_decimal_scale"},
-    {0x5d, "DW_AT_small"},
-    {0x5e, "DW_AT_decimal_sign"},
-    {0x5f, "DW_AT_digit_count"},
-    {0x60, "DW_AT_picture_string"},
-    {0x61, "DW_AT_mutable"},
-    {0x62, "DW_AT_threads_scaled"},
-    {0x63, "DW_AT_explicit"},
-    {0x64, "DW_AT_object_pointer"},
-    {0x65, "DW_AT_endianity"},
-    {0x66, "DW_AT_elemental"},
-    {0x67, "DW_AT_pure"},
-    {0x68, "DW_AT_recursive"},
-    {0x69, "DW_AT_signature"},
-    {0x6a, "DW_AT_main_subprogram"},
-    {0x6b, "DW_AT_data_bit_offset"},
-    {0x6c, "DW_AT_const_expr"},
-    {0x6d, "DW_AT_enum_class"},
-    {0x6e, "DW_AT_linkage_name"},
-    {0x87, "DW_AT_noreturn"},
-    {0x2000, "DW_AT_lo_user"},
-    {0x2001, "DW_AT_MIPS_fde"},
-    {0x2002, "DW_AT_MIPS_loop_begin"},
-    {0x2003, "DW_AT_MIPS_tail_loop_begin"},
-    {0x2004, "DW_AT_MIPS_epilog_begin"},
-    {0x2005, "DW_AT_MIPS_loop_unroll_factor"},
-    {0x2006, "DW_AT_MIPS_software_pipeline_depth"},
-    {0x2007, "DW_AT_MIPS_linkage_name"},
-    {0x2008, "DW_AT_MIPS_stride"},
-    {0x2009, "DW_AT_MIPS_abstract_name"},
-    {0x200a, "DW_AT_MIPS_clone_origin"},
-    {0x200b, "DW_AT_MIPS_has_inlines"},
-    {0x200c, "DW_AT_MIPS_stride_byte"},
-    {0x200d, "DW_AT_MIPS_stride_elem"},
-    {0x200e, "DW_AT_MIPS_ptr_dopetype"},
-    {0x200f, "DW_AT_MIPS_allocatable_dopetype"},
-    {0x2010, "DW_AT_MIPS_assumed_shape_dopetype"},
-    {0x2011, "DW_AT_MIPS_assumed_size"},
-    {0x2101, "DW_AT_sf_names"},
-    {0x2102, "DW_AT_src_info"},
-    {0x2103, "DW_AT_mac_info"},
-    {0x2104, "DW_AT_src_coords"},
-    {0x2105, "DW_AT_body_begin"},
-    {0x2106, "DW_AT_body_end"},
-    {0x2107, "DW_AT_GNU_vector"},
-    {0x2108, "DW_AT_GNU_guarded_by"},
-    {0x2109, "DW_AT_GNU_pt_guarded_by"},
-    {0x210a, "DW_AT_GNU_guarded"},
-    {0x210b, "DW_AT_GNU_pt_guarded"},
-    {0x210c, "DW_AT_GNU_locks_excluded"},
-    {0x210d, "DW_AT_GNU_exclusive_locks_required"},
-    {0x210e, "DW_AT_GNU_shared_locks_required"},
-    {0x210f, "DW_AT_GNU_odr_signature"},
-    {0x2110, "DW_AT_GNU_template_name"},
-    {0x2111, "DW_AT_GNU_call_site_value"},
-    {0x2112, "DW_AT_GNU_call_site_data_value"},
-    {0x2113, "DW_AT_GNU_call_site_target"},
-    {0x2114, "DW_AT_GNU_call_site_target_clobbered"},
-    {0x2115, "DW_AT_GNU_tail_call"},
-    {0x2116, "DW_AT_GNU_all_tail_call_sites"},
-    {0x2117, "DW_AT_GNU_all_call_sites"},
-    {0x2118, "DW_AT_GNU_all_source_call_sites"},
-    {0x2119, "DW_AT_GNU_macros"},
-    {0x211a, "DW_AT_GNU_deleted"},
-    {0x3fff, "DW_AT_hi_user"},
-};
-}
-
-namespace simgrid::dwarf {
-
-/** @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
- */
-XBT_PRIVATE
-const char* attrname(int attr)
-{
-  auto name = attrname_map.find(attr);
-  return name == attrname_map.end() ? "DW_AT_unknown" : name->second;
-}
-
-} // namespace simgrid::dwarf
diff --git a/src/mc/inspect/mc_dwarf_tagnames.cpp b/src/mc/inspect/mc_dwarf_tagnames.cpp
deleted file mode 100644 (file)
index 0fcd49f..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Copyright (c) 2014-2023. 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. */
-
-/* Warning: autogenerated, do not edit! */
-
-#include "src/mc/inspect/mc_dwarf.hpp"
-
-#include <string>
-#include <unordered_map>
-
-namespace {
-const std::unordered_map<int, const char*> tagname_map = {
-    {0x00, "DW_TAG_invalid"},
-    {0x01, "DW_TAG_array_type"},
-    {0x02, "DW_TAG_class_type"},
-    {0x03, "DW_TAG_entry_point"},
-    {0x04, "DW_TAG_enumeration_type"},
-    {0x05, "DW_TAG_formal_parameter"},
-    {0x08, "DW_TAG_imported_declaration"},
-    {0x0a, "DW_TAG_label"},
-    {0x0b, "DW_TAG_lexical_block"},
-    {0x0d, "DW_TAG_member"},
-    {0x0f, "DW_TAG_pointer_type"},
-    {0x10, "DW_TAG_reference_type"},
-    {0x11, "DW_TAG_compile_unit"},
-    {0x12, "DW_TAG_string_type"},
-    {0x13, "DW_TAG_structure_type"},
-    {0x15, "DW_TAG_subroutine_type"},
-    {0x16, "DW_TAG_typedef"},
-    {0x17, "DW_TAG_union_type"},
-    {0x18, "DW_TAG_unspecified_parameters"},
-    {0x19, "DW_TAG_variant"},
-    {0x1a, "DW_TAG_common_block"},
-    {0x1b, "DW_TAG_common_inclusion"},
-    {0x1c, "DW_TAG_inheritance"},
-    {0x1d, "DW_TAG_inlined_subroutine"},
-    {0x1e, "DW_TAG_module"},
-    {0x1f, "DW_TAG_ptr_to_member_type"},
-    {0x20, "DW_TAG_set_type"},
-    {0x21, "DW_TAG_subrange_type"},
-    {0x22, "DW_TAG_with_stmt"},
-    {0x23, "DW_TAG_access_declaration"},
-    {0x24, "DW_TAG_base_type"},
-    {0x25, "DW_TAG_catch_block"},
-    {0x26, "DW_TAG_const_type"},
-    {0x27, "DW_TAG_constant"},
-    {0x28, "DW_TAG_enumerator"},
-    {0x29, "DW_TAG_file_type"},
-    {0x2a, "DW_TAG_friend"},
-    {0x2b, "DW_TAG_namelist"},
-    {0x2c, "DW_TAG_namelist_item"},
-    {0x2d, "DW_TAG_packed_type"},
-    {0x2e, "DW_TAG_subprogram"},
-    {0x2f, "DW_TAG_template_type_parameter"},
-    {0x30, "DW_TAG_template_value_parameter"},
-    {0x31, "DW_TAG_thrown_type"},
-    {0x32, "DW_TAG_try_block"},
-    {0x33, "DW_TAG_variant_part"},
-    {0x34, "DW_TAG_variable"},
-    {0x35, "DW_TAG_volatile_type"},
-    {0x36, "DW_TAG_dwarf_procedure"},
-    {0x37, "DW_TAG_restrict_type"},
-    {0x38, "DW_TAG_interface_type"},
-    {0x39, "DW_TAG_namespace"},
-    {0x3a, "DW_TAG_imported_module"},
-    {0x3b, "DW_TAG_unspecified_type"},
-    {0x3c, "DW_TAG_partial_unit"},
-    {0x3d, "DW_TAG_imported_unit"},
-    {0x3f, "DW_TAG_condition"},
-    {0x40, "DW_TAG_shared_type"},
-    {0x41, "DW_TAG_type_unit"},
-    {0x42, "DW_TAG_rvalue_reference_type"},
-    {0x43, "DW_TAG_template_alias"},
-    {0x47, "DW_TAG_atomic_type"},
-    {0x4080, "DW_TAG_lo_user"},
-    {0x4081, "DW_TAG_MIPS_loop"},
-    {0x4101, "DW_TAG_format_label"},
-    {0x4102, "DW_TAG_function_template"},
-    {0x4103, "DW_TAG_class_template"},
-    {0x4104, "DW_TAG_GNU_BINCL"},
-    {0x4105, "DW_TAG_GNU_EINCL"},
-    {0x4106, "DW_TAG_GNU_template_template_param"},
-    {0x4107, "DW_TAG_GNU_template_parameter_pack"},
-    {0x4108, "DW_TAG_GNU_formal_parameter_pack"},
-    {0x4109, "DW_TAG_GNU_call_site"},
-    {0x410a, "DW_TAG_GNU_call_site_parameter"},
-    {0xffff, "DW_TAG_hi_user"},
-};
-}
-
-namespace simgrid::dwarf {
-
-/** @brief Get the name of a dwarf tag (DW_TAG_*) from its code
- *
- *  @param tag tag code (see the DWARF specification)
- *  @return name of the tag
- */
-XBT_PRIVATE
-const char* tagname(int tag)
-{
-  auto name = tagname_map.find(tag);
-  return name == tagname_map.end() ? "DW_TAG_unknown" : name->second;
-}
-
-} // namespace simgrid::dwarf
diff --git a/src/mc/inspect/mc_member.cpp b/src/mc/inspect/mc_member.cpp
deleted file mode 100644 (file)
index 9e9af73..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (c) 2014-2023. 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 "src/mc/inspect/Type.hpp"
-#include "src/mc/inspect/mc_dwarf.hpp"
-#include "src/mc/mc_private.hpp"
-
-namespace simgrid::dwarf {
-
-/** Resolve snapshot in the process address space
- *
- * @param object   Process address of the struct/class
- * @param type     Type of the struct/class
- * @param member   Member description
- * @param snapshot Snapshot (or nullptr)
- * @return Process address of the given member of the 'object' struct/class
- */
-void* resolve_member(const void* base, const simgrid::mc::Type* /*type*/, const simgrid::mc::Member* member,
-                     const simgrid::mc::AddressSpace* address_space)
-{
-  ExpressionContext state;
-  state.address_space = address_space;
-
-  ExpressionStack stack;
-  stack.push((ExpressionStack::value_type)base);
-  simgrid::dwarf::execute(member->location_expression, state, stack);
-  return (void*)stack.top();
-}
-
-} // namespace simgrid::dwarf
diff --git a/src/mc/inspect/mc_unw.cpp b/src/mc/inspect/mc_unw.cpp
deleted file mode 100644 (file)
index c93f195..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* Copyright (c) 2015-2023. 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. */
-
-/** \file Libunwind support for mc_address_space objects. */
-
-// We need this for the register indices:
-// #define _GNU_SOURCE
-
-#include "src/mc/inspect/mc_unw.hpp"
-#include "src/mc/inspect/Frame.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include <cstring>
-
-// On x86_64, libunwind unw_context_t has the same layout as ucontext_t:
-#include <sys/types.h>
-#include <sys/ucontext.h>
-#ifdef __FreeBSD__
-typedef register_t greg_t;
-#endif
-
-#include <libunwind.h>
-
-namespace simgrid::mc {
-
-// ***** Implementation
-
-/** Get frame unwind information (libunwind method)
- *
- *  Delegates to the local/ptrace implementation.
- */
-int UnwindContext::find_proc_info(unw_addr_space_t /*as*/, unw_word_t ip, unw_proc_info_t* pip, int need_unwind_info,
-                                  void* arg) noexcept
-{
-  const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg;
-  return unw_get_accessors(context->process_->unw_underlying_addr_space)
-      ->find_proc_info(context->process_->unw_underlying_addr_space, ip, pip, need_unwind_info,
-                       context->process_->unw_underlying_context);
-}
-
-/** Release frame unwind information (libunwind method)
- *
- *  Delegates to the local/ptrace implementation.
- */
-void UnwindContext::put_unwind_info(unw_addr_space_t /*as*/, unw_proc_info_t* pip, void* arg) noexcept
-{
-  const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg;
-  return unw_get_accessors(context->process_->unw_underlying_addr_space)
-      ->put_unwind_info(context->process_->unw_underlying_addr_space, pip, context->process_->unw_underlying_context);
-}
-
-/** (libunwind method)
- *
- *  Not implemented.
- */
-int UnwindContext::get_dyn_info_list_addr(unw_addr_space_t /*as*/, unw_word_t* dilap, void* arg) noexcept
-{
-  const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg;
-  return unw_get_accessors(context->process_->unw_underlying_addr_space)
-      ->get_dyn_info_list_addr(context->process_->unw_underlying_addr_space, dilap,
-                               context->process_->unw_underlying_context);
-}
-
-/** Read from the target address space memory (libunwind method)
- *
- *  Delegates to the `simgrid::mc::Process*`.
- */
-int UnwindContext::access_mem(unw_addr_space_t /*as*/, unw_word_t addr, unw_word_t* valp, int write, void* arg) noexcept
-{
-  const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg;
-  if (write)
-    return -UNW_EREADONLYREG;
-  context->address_space_->read_bytes(valp, sizeof(unw_word_t), remote(addr));
-  return 0;
-}
-
-void* UnwindContext::get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept
-{
-#ifdef __x86_64
-  mcontext_t* mcontext = &context->uc_mcontext;
-  switch (regnum) {
-#ifdef __linux__
-    case UNW_X86_64_RAX:
-      return &mcontext->gregs[REG_RAX];
-    case UNW_X86_64_RDX:
-      return &mcontext->gregs[REG_RDX];
-    case UNW_X86_64_RCX:
-      return &mcontext->gregs[REG_RCX];
-    case UNW_X86_64_RBX:
-      return &mcontext->gregs[REG_RBX];
-    case UNW_X86_64_RSI:
-      return &mcontext->gregs[REG_RSI];
-    case UNW_X86_64_RDI:
-      return &mcontext->gregs[REG_RDI];
-    case UNW_X86_64_RBP:
-      return &mcontext->gregs[REG_RBP];
-    case UNW_X86_64_RSP:
-      return &mcontext->gregs[REG_RSP];
-    case UNW_X86_64_R8:
-      return &mcontext->gregs[REG_R8];
-    case UNW_X86_64_R9:
-      return &mcontext->gregs[REG_R9];
-    case UNW_X86_64_R10:
-      return &mcontext->gregs[REG_R10];
-    case UNW_X86_64_R11:
-      return &mcontext->gregs[REG_R11];
-    case UNW_X86_64_R12:
-      return &mcontext->gregs[REG_R12];
-    case UNW_X86_64_R13:
-      return &mcontext->gregs[REG_R13];
-    case UNW_X86_64_R14:
-      return &mcontext->gregs[REG_R14];
-    case UNW_X86_64_R15:
-      return &mcontext->gregs[REG_R15];
-    case UNW_X86_64_RIP:
-      return &mcontext->gregs[REG_RIP];
-#elif defined __FreeBSD__
-    case UNW_X86_64_RAX:
-      return &mcontext->mc_rax;
-    case UNW_X86_64_RDX:
-      return &mcontext->mc_rdx;
-    case UNW_X86_64_RCX:
-      return &mcontext->mc_rcx;
-    case UNW_X86_64_RBX:
-      return &mcontext->mc_rbx;
-    case UNW_X86_64_RSI:
-      return &mcontext->mc_rsi;
-    case UNW_X86_64_RDI:
-      return &mcontext->mc_rdi;
-    case UNW_X86_64_RBP:
-      return &mcontext->mc_rbp;
-    case UNW_X86_64_RSP:
-      return &mcontext->mc_rsp;
-    case UNW_X86_64_R8:
-      return &mcontext->mc_r8;
-    case UNW_X86_64_R9:
-      return &mcontext->mc_r9;
-    case UNW_X86_64_R10:
-      return &mcontext->mc_r10;
-    case UNW_X86_64_R11:
-      return &mcontext->mc_r11;
-    case UNW_X86_64_R12:
-      return &mcontext->mc_r12;
-    case UNW_X86_64_R13:
-      return &mcontext->mc_r13;
-    case UNW_X86_64_R14:
-      return &mcontext->mc_r14;
-    case UNW_X86_64_R15:
-      return &mcontext->mc_r15;
-    case UNW_X86_64_RIP:
-      return &mcontext->mc_rip;
-#else
-#error "Unable to get register from ucontext, please add your case"
-#endif
-    default:
-      return nullptr;
-  }
-#else
-  return nullptr;
-#endif
-}
-
-/** Read a standard register (libunwind method)
- */
-int UnwindContext::access_reg(unw_addr_space_t /*as*/, unw_regnum_t regnum, unw_word_t* valp, int write,
-                              void* arg) noexcept
-{
-  auto* as_context       = static_cast<simgrid::mc::UnwindContext*>(arg);
-  unw_context_t* context = &as_context->unwind_context_;
-  if (write)
-    return -UNW_EREADONLYREG;
-  const greg_t* preg = (greg_t*)get_reg(context, regnum);
-  if (not preg)
-    return -UNW_EBADREG;
-  *valp = *preg;
-  return 0;
-}
-
-/** Find information about a function (libunwind method)
- */
-int UnwindContext::get_proc_name(unw_addr_space_t /*as*/, unw_word_t addr, char* bufp, size_t buf_len, unw_word_t* offp,
-                                 void* arg) noexcept
-{
-  const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg;
-  const simgrid::mc::Frame* frame           = context->process_->find_function(remote(addr));
-  if (not frame)
-    return -UNW_ENOINFO;
-  *offp = (unw_word_t)frame->range.begin() - addr;
-
-  strncpy(bufp, frame->name.c_str(), buf_len);
-  if (bufp[buf_len - 1]) {
-    bufp[buf_len - 1] = 0;
-    return -UNW_ENOMEM;
-  }
-
-  return 0;
-}
-
-// ***** Init
-
-unw_addr_space_t UnwindContext::createUnwindAddressSpace()
-{
-  /** Virtual table for our `libunwind` implementation
-   *
-   *  Stack unwinding on a `simgrid::mc::Process*` (for memory, unwinding information)
-   *  and `ucontext_t` (for processor registers).
-   *
-   * It works with the `simgrid::mc::UnwindContext` context.
-   *
-   * Use nullptr as access_fpreg and resume, as we don't need them.
-   */
-  unw_accessors_t accessors        = {};
-  accessors.find_proc_info         = &find_proc_info;
-  accessors.put_unwind_info        = &put_unwind_info;
-  accessors.get_dyn_info_list_addr = &get_dyn_info_list_addr;
-  accessors.access_mem             = &access_mem;
-  accessors.access_reg             = &access_reg;
-  accessors.access_fpreg           = nullptr;
-  accessors.resume                 = nullptr;
-  accessors.get_proc_name          = &get_proc_name;
-  return unw_create_addr_space(&accessors, BYTE_ORDER);
-}
-
-void UnwindContext::initialize(simgrid::mc::RemoteProcessMemory& process_memory, const unw_context_t* c)
-{
-  this->address_space_ = &process_memory;
-  this->process_       = &process_memory;
-
-  // Take a copy of the context for our own purpose:
-  this->unwind_context_ = *c;
-#if SIMGRID_PROCESSOR_x86_64 || SIMGRID_PROCESSOR_i686
-#ifdef __linux__
-  // On x86_64, ucontext_t contains a pointer to itself for FP registers.
-  // We don't really need support for FR registers as they are caller saved
-  // and probably never use those fields as libunwind-x86_64 does not read
-  // FP registers from the unw_context_t
-  // Let's ignore this and see what happens:
-  this->unwind_context_.uc_mcontext.fpregs = nullptr;
-#endif
-#elif SIMGRID_PROCESSOR_arm64
-#ifdef __linux__
-  // On ARM64, ucontext_t doesn't contain `fpregs` and the FP registers
-  // are instead held in the `__reserved` field of the struct. It doesn't
-  // appear anything needs to be done here, although this should be verified
-#endif
-#else
-  // Do we need to do any fixup like this?
-#error Target CPU type is not handled.
-#endif
-}
-
-unw_cursor_t UnwindContext::cursor()
-{
-  unw_cursor_t cursor;
-  xbt_assert(process_ != nullptr && address_space_ != nullptr &&
-                 unw_init_remote(&cursor, process_->unw_addr_space, this) == 0,
-             "UnwindContext not initialized");
-  return cursor;
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/inspect/mc_unw.hpp b/src/mc/inspect/mc_unw.hpp
deleted file mode 100644 (file)
index 6291c1c..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2015-2023. 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 SIMGRID_MC_UNW_HPP
-#define SIMGRID_MC_UNW_HPP
-
-/** @file
- *  Libunwind implementation for the model-checker
- *
- *  Libunwind provides a pluggable stack unwinding API: the way the current
- *  registers and memory is accessed, the way unwinding information is found
- *  is pluggable.
- *
- *  This component implements the libunwind API for he model-checker:
- *
- *    * reading memory from a simgrid::mc::AddressSpace*;
- *
- *    * reading stack registers from a saved snapshot (context).
- *
- *  Parts of the libunwind information fetching is currently handled by the
- *  standard `libunwind` implementations (either the local one or the ptrace one)
- *  because parsing `.eh_frame` section is not fun and `libdw` does not help
- *  much here.
- */
-
-#include "src/mc/mc_forward.hpp"
-#include "xbt/base.h"
-
-#include <cstdio>
-#include <libunwind.h>
-
-namespace simgrid::unw {
-
-XBT_PRIVATE unw_addr_space_t create_addr_space();
-XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid);
-} // namespace simgrid::unw
-
-namespace simgrid::mc {
-
-class UnwindContext {
-  simgrid::mc::AddressSpace* address_space_  = nullptr;
-  simgrid::mc::RemoteProcessMemory* process_ = nullptr;
-  unw_context_t unwind_context_              = {};
-
-public:
-  void initialize(simgrid::mc::RemoteProcessMemory& process, const unw_context_t* c);
-  unw_cursor_t cursor();
-
-private: // Methods and virtual table for libunwind
-  static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t* pip, int need_unwind_info,
-                            void* arg) noexcept;
-  static void put_unwind_info(unw_addr_space_t as, unw_proc_info_t* pip, void* arg) noexcept;
-  static int get_dyn_info_list_addr(unw_addr_space_t as, unw_word_t* dilap, void* arg) noexcept;
-  static int access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t* valp, int write, void* arg) noexcept;
-  static void* get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept;
-  static int access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t* valp, int write, void* arg) noexcept;
-  static int get_proc_name(unw_addr_space_t as, unw_word_t addr, char* bufp, size_t buf_len, unw_word_t* offp,
-                           void* arg) noexcept;
-
-public:
-  // Create a libunwind address space:
-  static unw_addr_space_t createUnwindAddressSpace();
-};
-
-void dumpStack(FILE* file, unw_cursor_t* cursor);
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/inspect/mc_unw_vmread.cpp b/src/mc/inspect/mc_unw_vmread.cpp
deleted file mode 100644 (file)
index 7241da9..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/** \file  Libunwind namespace implementation using process_vm_readv.       */
-
-/* Copyright (c) 2015-2023. 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 "src/mc/inspect/mc_unw.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include <sys/types.h>
-#include <sys/uio.h>
-
-#include <fcntl.h>
-#include <libunwind-ptrace.h>
-#include <libunwind.h>
-
-
-/** Partial structure of libunwind-ptrace context in order to get the PID
- *
- *  HACK, The context type for libunwind-race is an opaque type.
- *  We need to get the PID which is the first field. This is a hack
- *  which might break if the libunwind-ptrace structure changes.
- */
-struct _UPT_info {
-  pid_t pid;
-  // Other things...
-};
-
-/** Read from the memory, avoid using `ptrace` (libunwind method) */
-static int access_mem(const unw_addr_space_t as, const unw_word_t addr, unw_word_t* const valp, const int write,
-                      void* const arg)
-{
-  if (write)
-    return -UNW_EINVAL;
-  pid_t pid   = static_cast<_UPT_info*>(arg)->pid;
-  size_t size = sizeof(unw_word_t);
-
-#if HAVE_PROCESS_VM_READV /* linux but not freebsd */
-  // process_vm_read implementation.
-  // This is only available since Linux 3.2.
-
-  struct iovec local  = {valp, size};
-  struct iovec remote = {(void*)addr, size};
-  if (ssize_t s = process_vm_readv(pid, &local, 1, &remote, 1, 0); s >= 0) {
-    if ((size_t)s != size)
-      return -UNW_EINVAL;
-    else
-      return 0;
-  } else if (errno != ENOSYS) {
-    return -UNW_EINVAL;
-  }
-#endif
-
-  // /proc/${pid}/mem implementation.
-  // On recent kernels, we do not need to ptrace the target process.
-  // On older kernels, it is necessary to ptrace the target process.
-  size_t count = size;
-  auto off     = static_cast<off_t>(addr);
-  auto* buf    = reinterpret_cast<std::byte*>(valp);
-  int fd       = simgrid::mc::open_vm(pid, O_RDONLY);
-  if (fd < 0)
-    return -UNW_EINVAL;
-
-  while (count > 0) {
-    ssize_t nread = pread(fd, buf, count, off);
-    if (nread == 0) {
-      close(fd);
-      return -UNW_EINVAL;
-    }
-    if (nread == -1)
-      // ptrace implementation.
-      // We need to have PTRACE_ATTACH-ed it before.
-      return _UPT_access_mem(as, addr, valp, write, arg);
-
-    count -= nread;
-    buf += nread;
-    off += nread;
-  }
-  close(fd);
-  return 0;
-}
-
-namespace simgrid::unw {
-
-unw_addr_space_t create_addr_space()
-{
-  /** Virtual table for our `libunwind-process_vm_readv` implementation.
-   *
-   *  This implementation reuse most the code of `libunwind-ptrace` but
-   *  does not use ptrace() to read the target process memory by
-   *  `process_vm_readv()` or `/dev/${pid}/mem` if possible.
-   *
-   *  Does not support any MC-specific behavior (privatization, snapshots)
-   *  and `ucontext_t`.
-   *
-   *  It works with `void*` contexts allocated with `_UPT_create(pid)`.
-   */
-  // TODO, we could get rid of this if we properly stop the model-checked
-  // process before reading the memory.
-  unw_accessors_t accessors = _UPT_accessors;
-  accessors.access_mem      = &access_mem;
-  return unw_create_addr_space(&accessors, BYTE_ORDER);
-}
-
-void* create_context(unw_addr_space_t /*as*/, pid_t pid)
-{
-  return _UPT_create(pid);
-}
-
-} // namespace simgrid::unw
index 6e4ecf1..9791f51 100644 (file)
 #include "src/mc/mc_config.hpp"
 #include "src/mc/mc_replay.hpp"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-#endif
-
 XBT_LOG_NEW_DEFAULT_CATEGORY(mc, "All MC categories");
 bool simgrid_mc_replay_show_backtraces = false;
 
index af36677..27e471d 100644 (file)
@@ -53,53 +53,3 @@ int MC_is_active()
   return get_model_checking_mode() == ModelCheckingMode::APP_SIDE ||
          get_model_checking_mode() == ModelCheckingMode::CHECKER_SIDE;
 }
-
-void MC_automaton_new_propositional_symbol_pointer(const char *name, int* value)
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE,
-             "This should be called from the client side");
-  if (MC_is_active())
-    AppSide::get()->declare_symbol(name, value);
-#endif
-}
-
-void MC_ignore(void* addr, size_t size)
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE,
-             "This should be called from the client side");
-  if (MC_is_active())
-    AppSide::get()->ignore_memory(addr, size);
-#endif
-}
-
-void MC_unignore(void* addr, size_t size)
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE,
-             "This should be called from the client side");
-  if (MC_is_active())
-    AppSide::get()->unignore_memory(addr, size);
-#endif
-}
-
-void MC_ignore_heap(void *address, size_t size)
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE,
-             "This should be called from the client side");
-  if (MC_is_active())
-    AppSide::get()->ignore_heap(address, size);
-#endif
-}
-
-void MC_unignore_heap(void* address, size_t size)
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE,
-             "This should be called from the client side");
-  if (MC_is_active())
-    AppSide::get()->unignore_heap(address, size);
-#endif
-}
index 9253c04..25f3090 100644 (file)
@@ -8,10 +8,6 @@
 #include "src/simgrid/sg_config.hpp"
 #include <simgrid/modelchecker.h>
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include <string_view>
-#endif
-
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(xbt_cfg);
 
 static simgrid::mc::ModelCheckingMode model_checking_mode = simgrid::mc::ModelCheckingMode::NONE;
@@ -52,8 +48,6 @@ simgrid::config::Flag<bool> _sg_mc_timeout{
       _mc_cfg_cb_check("value to enable/disable timeout for wait requests", not MC_record_replay_is_active());
     }};
 
-int _sg_mc_max_visited_states = 0;
-
 static simgrid::config::Flag<std::string> cfg_mc_reduction{
     "model-check/reduction", "Specify the kind of exploration reduction (either none or DPOR)", "dpor",
     [](std::string_view value) {
@@ -76,26 +70,11 @@ simgrid::config::Flag<int> _sg_mc_random_seed{"model-check/rand-seed",
                                               "give a specific random seed to initialize the uniform distribution", 0,
                                               [](int) { _mc_cfg_cb_check("Random seed"); }};
 
-#if SIMGRID_HAVE_STATEFUL_MC
-simgrid::config::Flag<int> _sg_mc_checkpoint{
-    "model-check/checkpoint", "Specify the amount of steps between checkpoints during stateful model-checking "
-                              "(default: 0 => stateless verification). If value=1, one checkpoint is saved for each "
-                              "step => faster verification, but huge memory consumption; higher values are good "
-                              "compromises between speed and memory consumption.",
-    0, [](int) { _mc_cfg_cb_check("checkpointing value"); }};
-
-simgrid::config::Flag<std::string> _sg_mc_property_file{
-    "model-check/property", "Name of the file containing the property, as formatted by the ltl2ba program.", "",
-    [](const std::string&) { _mc_cfg_cb_check("property"); }};
-
 simgrid::config::Flag<bool> _sg_mc_comms_determinism{
-    "model-check/communications-determinism",
-    "Whether to enable the detection of communication determinism",
-    false,
+    "model-check/communications-determinism", "Whether to enable the detection of communication determinism", false,
     [](bool) {
       _mc_cfg_cb_check("value to enable/disable the detection of determinism in the communications schemes");
     }};
-
 simgrid::config::Flag<bool> _sg_mc_send_determinism{
     "model-check/send-determinism",
     "Enable/disable the detection of send-determinism in the communications schemes",
@@ -109,7 +88,6 @@ simgrid::config::Flag<bool> _sg_mc_unfolding_checker{
     "Whether to enable the unfolding-based dynamic partial order reduction to MPI programs", false, [](bool) {
       _mc_cfg_cb_check("value to to enable/disable the unfolding-based dynamic partial order reduction to MPI programs");
     }};
-#endif
 
 simgrid::config::Flag<std::string> _sg_mc_buffering{
     "smpi/buffering",
@@ -124,29 +102,8 @@ simgrid::config::Flag<int> _sg_mc_max_depth{"model-check/max-depth",
                                             1000,
                                             [](int) { _mc_cfg_cb_check("max depth value"); }};
 
-static simgrid::config::Flag<int> _sg_mc_max_visited_states__{
-    "model-check/visited",
-    "Specify the number of visited state stored for state comparison reduction: any branch leading to a state that is "
-    "already stored is cut.\n"
-    "If value=5, the last 5 visited states are stored. If value=0 (the default), no state is stored and this reduction "
-    "technique is disabled.",
-    0, [](int value) {
-      _mc_cfg_cb_check("number of stored visited states");
-      _sg_mc_max_visited_states = value;
-    }};
-
-simgrid::config::Flag<bool> _sg_mc_termination{
-    "model-check/termination", "Whether to enable non progressive cycle detection", false,
-    [](bool) { _mc_cfg_cb_check("value to enable/disable the detection of non progressive cycles"); }};
-
 simgrid::mc::ReductionMode simgrid::mc::get_model_checking_reduction()
 {
-  if ((cfg_mc_reduction.get() == "dpor" || cfg_mc_reduction.get() == "sdpor" || cfg_mc_reduction.get() == "odpor") &&
-      _sg_mc_max_visited_states__ > 0) {
-    XBT_INFO("Disabling DPOR since state-equality reduction is activated with 'model-check/visited'");
-    return simgrid::mc::ReductionMode::none;
-  }
-
   if (cfg_mc_reduction.get() == "none") {
     return ReductionMode::none;
   } else if (cfg_mc_reduction.get() == "dpor") {
index b581155..621e06f 100644 (file)
@@ -26,9 +26,7 @@ extern XBT_PUBLIC simgrid::config::Flag<bool> _sg_mc_unfolding_checker;
 extern XBT_PRIVATE simgrid::config::Flag<bool> _sg_mc_timeout;
 extern XBT_PRIVATE simgrid::config::Flag<int> _sg_mc_max_depth;
 extern XBT_PRIVATE simgrid::config::Flag<int> _sg_mc_random_seed;
-extern "C" XBT_PUBLIC int _sg_mc_max_visited_states;
 extern XBT_PRIVATE simgrid::config::Flag<std::string> _sg_mc_dot_output_file;
-extern XBT_PRIVATE simgrid::config::Flag<bool> _sg_mc_termination;
 extern XBT_PUBLIC simgrid::config::Flag<std::string> _sg_mc_strategy;
 
 #endif
index a6e8979..a8ff230 100644 (file)
  */
 #define MC_ENV_SOCKET_FD "SIMGRID_MC_SOCKET_FD"
 
-/** Environment variable name defined when ptrace(2) is used to control the MCed process.
- */
-#define MC_ENV_NEED_PTRACE "SIMGRID_MC_NEED_PTRACE"
-
 /** Environment variable used to request additional system statistics.
  */
 #define MC_ENV_SYSTEM_STATISTICS "SIMGRID_MC_SYSTEM_STATISTICS"
index 262fa72..d7962fa 100644 (file)
@@ -6,22 +6,6 @@
 #include "src/kernel/actor/ActorImpl.hpp"
 #include "src/mc/mc.h"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/api/RemoteApp.hpp"
-#include "src/mc/explo/Exploration.hpp"
-#include "src/mc/inspect/mc_unw.hpp"
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_private.hpp"
-#include "src/mc/remote/AppSide.hpp"
-#include "src/mc/sosp/Snapshot.hpp"
-
-#include <array>
-#include <boost/core/demangle.hpp>
-#include <cerrno>
-#include <cstring>
-#include <libunwind.h>
-#endif
-
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -34,41 +18,6 @@ std::vector<double> processes_time;
 
 }
 
-#if SIMGRID_HAVE_STATEFUL_MC
-
-namespace simgrid::mc {
-
-/*******************************  Core of MC *******************************/
-/**************************************************************************/
-void dumpStack(FILE* file, unw_cursor_t* cursor)
-{
-  int nframe = 0;
-  std::array<char, 100> buffer;
-
-  unw_word_t off;
-  do {
-    const char* name = not unw_get_proc_name(cursor, buffer.data(), buffer.size(), &off) ? buffer.data() : "?";
-    // Unmangle C++ names:
-    std::string realname = boost::core::demangle(name);
-
-#if defined(__x86_64__)
-    unw_word_t rip = 0;
-    unw_word_t rsp = 0;
-    unw_get_reg(cursor, UNW_X86_64_RIP, &rip);
-    unw_get_reg(cursor, UNW_X86_64_RSP, &rsp);
-    fprintf(file, "  %i: %s (RIP=0x%" PRIx64 " RSP=0x%" PRIx64 ")\n", nframe, realname.c_str(), (std::uint64_t)rip,
-            (std::uint64_t)rsp);
-#else
-    fprintf(file, "  %i: %s\n", nframe, realname.c_str());
-#endif
-
-    ++nframe;
-  } while (unw_step(cursor));
-}
-
-} // namespace simgrid::mc
-#endif
-
 double MC_process_clock_get(const simgrid::kernel::actor::ActorImpl* process)
 {
   if (process) {
index facb90d..d4185f0 100644 (file)
@@ -7,7 +7,6 @@
 #define SIMGRID_MC_PRIVATE_HPP
 
 #include "src/mc/mc.h"
-#include "xbt/automaton.h"
 
 #include "src/mc/mc_forward.hpp"
 #include "src/xbt/memory_map.hpp"
index 5d00307..84769a1 100644 (file)
@@ -12,9 +12,6 @@
 #include "src/mc/mc_base.hpp"
 #include "src/mc/mc_config.hpp"
 #include "src/mc/mc_environ.h"
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-#endif
 #if HAVE_SMPI
 #include "src/smpi/include/private.hpp"
 #endif
@@ -51,7 +48,7 @@ AppSide* AppSide::get()
   if (std::getenv(MC_ENV_SOCKET_FD) == nullptr) // We are not in MC mode: don't initialize the MC world
     return nullptr;
 
-  XBT_DEBUG("Initialize the MC world. %s=%s", MC_ENV_NEED_PTRACE, std::getenv(MC_ENV_NEED_PTRACE));
+  XBT_DEBUG("Initialize the MC world.");
 
   simgrid::mc::set_model_checking_mode(ModelCheckingMode::APP_SIDE);
 
@@ -64,21 +61,6 @@ AppSide* AppSide::get()
 
   instance_ = std::make_unique<simgrid::mc::AppSide>(fd);
 
-  // Wait for the model-checker:
-  if (getenv(MC_ENV_NEED_PTRACE) != nullptr) {
-    errno = 0;
-#if defined __linux__
-    ptrace(PTRACE_TRACEME, 0, nullptr, nullptr);
-#elif defined BSD
-    ptrace(PT_TRACE_ME, 0, nullptr, 0);
-#else
-    xbt_die("no ptrace equivalent coded for this platform, please don't use the liveness checker here.");
-#endif
-
-    xbt_assert(errno == 0 && raise(SIGSTOP) == 0, "Could not wait for the model-checker (errno = %d: %s)", errno,
-               strerror(errno));
-  }
-
   instance_->handle_messages();
   return instance_.get();
 }
@@ -206,18 +188,6 @@ void AppSide::handle_wait_child(const s_mc_message_int_t* msg)
   answer.value              = status;
   xbt_assert(channel_.send(answer) == 0, "Could not send response to WAIT_CHILD: %s", strerror(errno));
 }
-void AppSide::handle_need_meminfo()
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  this->need_memory_info_                  = true;
-  s_mc_message_need_meminfo_reply_t answer = {};
-  answer.type                              = MessageType::NEED_MEMINFO_REPLY;
-  answer.mmalloc_default_mdp               = mmalloc_get_current_heap();
-  xbt_assert(channel_.send(answer) == 0, "Could not send response to the request for meminfo: %s", strerror(errno));
-#else
-  xbt_die("SimGrid was compiled without MC suppport, so liveness and similar features are not available.");
-#endif
-}
 void AppSide::handle_actors_status() const
 {
   auto const& actor_list = kernel::EngineImpl::get_instance()->get_actor_list();
@@ -225,6 +195,9 @@ void AppSide::handle_actors_status() const
 
   std::vector<s_mc_message_actors_status_one_t> status;
   for (auto const& [aid, actor] : actor_list) {
+    xbt_assert(actor);
+    xbt_assert(actor->simcall_.observer_, "simcall %s in actor %s has no observer.", actor->simcall_.get_cname(),
+               actor->get_cname());
     s_mc_message_actors_status_one_t one = {};
     one.type                             = MessageType::ACTORS_STATUS_REPLY_TRANSITION;
     one.aid                              = aid;
@@ -336,11 +309,6 @@ void AppSide::handle_messages()
         handle_wait_child((s_mc_message_int_t*)message_buffer.data());
         break;
 
-      case MessageType::NEED_MEMINFO:
-        assert_msg_size("NEED_MEMINFO", s_mc_message_t);
-        handle_need_meminfo();
-        break;
-
       case MessageType::ACTORS_STATUS:
         assert_msg_size("ACTORS_STATUS", s_mc_message_t);
         handle_actors_status();
@@ -361,9 +329,6 @@ void AppSide::handle_messages()
 void AppSide::main_loop()
 {
   simgrid::mc::processes_time.resize(simgrid::kernel::actor::ActorImpl::get_maxpid());
-  MC_ignore_heap(simgrid::mc::processes_time.data(),
-                 simgrid::mc::processes_time.size() * sizeof(simgrid::mc::processes_time[0]));
-  kernel::activity::CommImpl::setup_mc();
 
   sthread_disable();
   coverage_checkpoint();
@@ -383,131 +348,4 @@ void AppSide::report_assertion_failure()
   this->handle_messages();
 }
 
-void AppSide::ignore_memory(void* addr, std::size_t size) const
-{
-  if (not MC_is_active() || not need_memory_info_)
-    return;
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  s_mc_message_ignore_memory_t message = {};
-  message.type = MessageType::IGNORE_MEMORY;
-  message.addr = (std::uintptr_t)addr;
-  message.size = size;
-  xbt_assert(channel_.send(message) == 0, "Could not send IGNORE_MEMORY message to model-checker: %s", strerror(errno));
-#else
-  xbt_die("Cannot really call ignore_memory() in non-SIMGRID_MC mode.");
-#endif
-}
-
-void AppSide::unignore_memory(void* addr, std::size_t size) const
-{
-  if (not MC_is_active() || not need_memory_info_)
-    return;
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  s_mc_message_ignore_memory_t message = {};
-  message.type                         = MessageType::UNIGNORE_MEMORY;
-  message.addr                         = (std::uintptr_t)addr;
-  message.size                         = size;
-  xbt_assert(channel_.send(message) == 0, "Could not send UNIGNORE_MEMORY message to model-checker: %s",
-             strerror(errno));
-#else
-  xbt_die("Cannot really call unignore_memory() in non-SIMGRID_MC mode.");
-#endif
-}
-
-void AppSide::ignore_heap(void* address, std::size_t size) const
-{
-  if (not MC_is_active() || not need_memory_info_)
-    return;
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  const s_xbt_mheap_t* heap = mmalloc_get_current_heap();
-
-  s_mc_message_ignore_heap_t message = {};
-  message.type    = MessageType::IGNORE_HEAP;
-  message.address = address;
-  message.size    = size;
-  message.block   = ((char*)address - (char*)heap->heapbase) / BLOCKSIZE + 1;
-  if (heap->heapinfo[message.block].type == 0) {
-    message.fragment = -1;
-    heap->heapinfo[message.block].busy_block.ignore++;
-  } else {
-    message.fragment = (ADDR2UINT(address) % BLOCKSIZE) >> heap->heapinfo[message.block].type;
-    heap->heapinfo[message.block].busy_frag.ignore[message.fragment]++;
-  }
-
-  xbt_assert(channel_.send(message) == 0, "Could not send ignored region to MCer: %s", strerror(errno));
-#else
-  xbt_die("Cannot really call ignore_heap() in non-SIMGRID_MC mode.");
-#endif
-}
-
-void AppSide::unignore_heap(void* address, std::size_t size) const
-{
-  if (not MC_is_active() || not need_memory_info_)
-    return;
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  s_mc_message_ignore_memory_t message = {};
-  message.type = MessageType::UNIGNORE_HEAP;
-  message.addr = (std::uintptr_t)address;
-  message.size = size;
-  xbt_assert(channel_.send(message) == 0, "Could not send IGNORE_HEAP message to model-checker: %s", strerror(errno));
-#else
-  xbt_die("Cannot really call unignore_heap() in non-SIMGRID_MC mode.");
-#endif
-}
-
-void AppSide::declare_symbol(const char* name, int* value) const
-{
-  if (not MC_is_active() || not need_memory_info_) {
-    XBT_CRITICAL("Ignore AppSide::declare_symbol(%s)", name);
-    return;
-  }
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  s_mc_message_register_symbol_t message = {};
-  message.type = MessageType::REGISTER_SYMBOL;
-  xbt_assert(strlen(name) + 1 <= message.name.size(), "Symbol is too long");
-  strncpy(message.name.data(), name, message.name.size() - 1);
-  message.callback = nullptr;
-  message.data     = value;
-  xbt_assert(channel_.send(message) == 0, "Could send REGISTER_SYMBOL message to model-checker: %s", strerror(errno));
-#else
-  xbt_die("Cannot really call declare_symbol() in non-SIMGRID_MC mode.");
-#endif
-}
-
-/** Register a stack in the model checker
- *
- *  The stacks are allocated in the heap. The MC handle them specifically
- *  when we analyze/compare the content of the heap so it must be told where
- *  they are with this function.
- */
-#if HAVE_UCONTEXT_H /* Apple don't want us to use ucontexts */
-void AppSide::declare_stack(void* stack, size_t size, ucontext_t* context) const
-{
-  if (not MC_is_active() || not need_memory_info_)
-    return;
-
-#if SIMGRID_HAVE_STATEFUL_MC
-  const s_xbt_mheap_t* heap = mmalloc_get_current_heap();
-
-  s_stack_region_t region = {};
-  region.address = stack;
-  region.context = context;
-  region.size    = size;
-  region.block   = ((char*)stack - (char*)heap->heapbase) / BLOCKSIZE + 1;
-
-  s_mc_message_stack_region_t message = {};
-  message.type         = MessageType::STACK_REGION;
-  message.stack_region = region;
-  xbt_assert(channel_.send(message) == 0, "Could not send STACK_REGION to model-checker: %s", strerror(errno));
-#else
-  xbt_die("Cannot really call declare_stack() in non-SIMGRID_MC mode.");
-#endif
-}
-#endif
-
 } // namespace simgrid::mc
index 57189e6..03250e9 100644 (file)
@@ -22,7 +22,6 @@ class XBT_PUBLIC AppSide {
 private:
   Channel channel_;
   static std::unique_ptr<AppSide> instance_;
-  bool need_memory_info_ = false; /* by default we don't send memory info, unless we got a NEED_MEMINFO */
   std::unordered_map<int, int> child_statuses_;
 
 public:
@@ -36,7 +35,6 @@ private:
   void handle_finalize(const s_mc_message_int_t* msg) const;
   void handle_fork(const s_mc_message_fork_t* msg);
   void handle_wait_child(const s_mc_message_int_t* msg);
-  void handle_need_meminfo();
   void handle_actors_status() const;
   void handle_actors_maxpid() const;
 
@@ -45,14 +43,6 @@ public:
   Channel& get_channel() { return channel_; }
   XBT_ATTRIB_NORETURN void main_loop();
   void report_assertion_failure();
-  void ignore_memory(void* addr, std::size_t size) const;
-  void unignore_memory(void* addr, std::size_t size) const;
-  void ignore_heap(void* addr, std::size_t size) const;
-  void unignore_heap(void* addr, std::size_t size) const;
-  void declare_symbol(const char* name, int* value) const;
-#if HAVE_UCONTEXT_H
-  void declare_stack(void* stack, size_t size, ucontext_t* context) const;
-#endif
 
   // TODO, remove the singleton antipattern.
   static AppSide* get();
index f7316ec..2ad4f7e 100644 (file)
@@ -9,11 +9,6 @@
 #include "xbt/config.hpp"
 #include "xbt/system_error.hpp"
 
-#if SIMGRID_HAVE_STATEFUL_MC
-#include "src/mc/explo/LivenessChecker.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-#endif
-
 #ifdef __linux__
 #include <sys/prctl.h>
 #endif
@@ -41,7 +36,7 @@ static simgrid::config::Flag<std::string> _sg_mc_setenv{
 
 namespace simgrid::mc {
 
-XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<char*>& args, bool need_ptrace)
+XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<char*>& args)
 {
   /* On startup, simix_global_init() calls simgrid::mc::Client::initialize(), which checks whether the MC_ENV_SOCKET_FD
    * env variable is set. If so, MC mode is assumed, and the client is setup from its side
@@ -56,8 +51,6 @@ XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<
 #endif
 
   setenv(MC_ENV_SOCKET_FD, std::to_string(socket).c_str(), 1);
-  if (need_ptrace)
-    setenv(MC_ENV_NEED_PTRACE, "1", 1);
 
   /* Setup the tokenizer that parses the cfg:model-check/setenv parameter */
   using Tokenizer = boost::tokenizer<boost::char_separator<char>>;
@@ -175,9 +168,9 @@ void CheckerSide::setup_events(bool socket_only)
 }
 
 /* When this constructor is called, no other checkerside exists */
-CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_info) : running_(true)
+CheckerSide::CheckerSide(const std::vector<char*>& args) : running_(true)
 {
-  XBT_DEBUG("Create a CheckerSide. Needs_meminfo: %s", need_memory_info ? "YES" : "no");
+  XBT_DEBUG("Create a CheckerSide.");
 
   // Create an AF_UNIX socketpair used for exchanging messages between the model-checker process (ancestor)
   // and the application process (child)
@@ -196,7 +189,7 @@ CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_info)
 
   if (pid_ == 0) { // Child
     ::close(sockets[1]);
-    run_child_process(sockets[0], args, need_memory_info); // We need ptrace if we need the mem info
+    run_child_process(sockets[0], args);
     DIE_IMPOSSIBLE;
   }
 
@@ -205,28 +198,6 @@ CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_info)
   channel_.reset_socket(sockets[1]);
 
   setup_events(false); /* we need a signal handler too */
-  if (need_memory_info) {
-#if SIMGRID_HAVE_STATEFUL_MC
-    // setup ptrace and sync with the app
-    wait_application_process(pid_);
-
-    // Request the initial memory on need
-    channel_.send(MessageType::NEED_MEMINFO);
-    s_mc_message_need_meminfo_reply_t answer;
-    ssize_t answer_size = channel_.receive(answer);
-    xbt_assert(answer_size != -1, "Could not receive message");
-    xbt_assert(answer.type == MessageType::NEED_MEMINFO_REPLY,
-               "The received message is not the NEED_MEMINFO_REPLY I was expecting but of type %s",
-               to_c_str(answer.type));
-    xbt_assert(answer_size == sizeof answer, "Broken message (size=%zd; expected %zu)", answer_size, sizeof answer);
-
-    /* We now have enough info to create the memory address space */
-    remote_memory_ = std::make_unique<simgrid::mc::RemoteProcessMemory>(pid_, answer.mmalloc_default_mdp);
-#else
-    xbt_die("Cannot introspect memory without MC support");
-#endif
-  }
-
   wait_for_requests();
 }
 
@@ -306,97 +277,6 @@ bool CheckerSide::handle_message(const char* buffer, ssize_t size)
   memcpy(&base_message, buffer, sizeof(base_message));
 
   switch (base_message.type) {
-    case MessageType::IGNORE_HEAP: {
-      consumed = sizeof(s_mc_message_ignore_heap_t);
-#if SIMGRID_HAVE_STATEFUL_MC
-      if (remote_memory_ != nullptr) {
-        s_mc_message_ignore_heap_t message;
-        xbt_assert(size >= static_cast<ssize_t>(sizeof(message)), "Broken message");
-        memcpy(&message, buffer, sizeof(message));
-
-        IgnoredHeapRegion region;
-        region.block    = message.block;
-        region.fragment = message.fragment;
-        region.address  = message.address;
-        region.size     = message.size;
-        get_remote_memory()->ignore_heap(region);
-      } else
-#endif
-        XBT_INFO("Ignoring a IGNORE_HEAP message because we don't need to introspect memory.");
-      break;
-    }
-
-    case MessageType::UNIGNORE_HEAP: {
-      consumed = sizeof(s_mc_message_ignore_memory_t);
-#if SIMGRID_HAVE_STATEFUL_MC
-      if (remote_memory_ != nullptr) {
-        s_mc_message_ignore_memory_t message;
-        xbt_assert(size == static_cast<ssize_t>(sizeof(message)), "Broken message");
-        memcpy(&message, buffer, sizeof(message));
-        get_remote_memory()->unignore_heap((void*)message.addr, message.size);
-      } else
-#endif
-        XBT_INFO("Ignoring an UNIGNORE_HEAP message because we don't need to introspect memory.");
-      break;
-    }
-
-    case MessageType::IGNORE_MEMORY: {
-      consumed = sizeof(s_mc_message_ignore_memory_t);
-#if SIMGRID_HAVE_STATEFUL_MC
-      if (remote_memory_ != nullptr) {
-        s_mc_message_ignore_memory_t message;
-        xbt_assert(size >= static_cast<ssize_t>(sizeof(message)), "Broken message");
-        memcpy(&message, buffer, sizeof(message));
-        get_remote_memory()->ignore_region(message.addr, message.size);
-      } else
-#endif
-        XBT_INFO("Ignoring an IGNORE_MEMORY message because we don't need to introspect memory.");
-      break;
-    }
-
-    case MessageType::UNIGNORE_MEMORY: {
-      consumed = sizeof(s_mc_message_ignore_memory_t);
-#if SIMGRID_HAVE_STATEFUL_MC
-      if (remote_memory_ != nullptr) {
-        s_mc_message_ignore_memory_t message;
-        xbt_assert(size >= static_cast<ssize_t>(sizeof(message)), "Broken message");
-        memcpy(&message, buffer, sizeof(message));
-        get_remote_memory()->unignore_region(message.addr, message.size);
-      } else
-#endif
-        XBT_INFO("Ignoring an UNIGNORE_MEMORY message because we don't need to introspect memory.");
-      break;
-    }
-
-    case MessageType::STACK_REGION: {
-      consumed = sizeof(s_mc_message_stack_region_t);
-#if SIMGRID_HAVE_STATEFUL_MC
-      if (remote_memory_ != nullptr) {
-        s_mc_message_stack_region_t message;
-        xbt_assert(size >= static_cast<ssize_t>(sizeof(message)), "Broken message");
-        memcpy(&message, buffer, sizeof(message));
-        get_remote_memory()->stack_areas().push_back(message.stack_region);
-      } else
-#endif
-        XBT_INFO("Ignoring an STACK_REGION message because we don't need to introspect memory.");
-      break;
-    }
-
-    case MessageType::REGISTER_SYMBOL: {
-      consumed = sizeof(s_mc_message_register_symbol_t);
-#if SIMGRID_HAVE_STATEFUL_MC
-      s_mc_message_register_symbol_t message;
-      xbt_assert(size >= static_cast<ssize_t>(sizeof(message)), "Broken message");
-      memcpy(&message, buffer, sizeof(message));
-      xbt_assert(not message.callback, "Support for client-side function proposition is not implemented.");
-      XBT_DEBUG("Received symbol: %s", message.name.data());
-
-      LivenessChecker::automaton_register_symbol(*get_remote_memory(), message.name.data(), remote((int*)message.data));
-#else
-      xbt_die("Please don't use liveness properties when MC is compiled out.");
-#endif
-      break;
-    }
 
     case MessageType::WAITING:
       consumed = sizeof(s_mc_message_t);
@@ -430,20 +310,11 @@ void CheckerSide::wait_for_requests()
   XBT_DEBUG("Resume the application");
   if (get_channel().send(MessageType::CONTINUE) != 0)
     throw xbt::errno_error();
-  clear_memory_cache();
 
   if (running())
     dispatch_events();
 }
 
-void CheckerSide::clear_memory_cache()
-{
-#if SIMGRID_HAVE_STATEFUL_MC
-  if (remote_memory_)
-    remote_memory_->clear_cache();
-#endif
-}
-
 void CheckerSide::handle_dead_child(int status)
 {
   // From PTRACE_O_TRACEEXIT:
index d89f712..f4605e4 100644 (file)
@@ -21,9 +21,6 @@ class CheckerSide {
   event* socket_event_;
   event* signal_event_;
   std::unique_ptr<event_base, decltype(&event_base_free)> base_{nullptr, &event_base_free};
-#if SIMGRID_HAVE_STATEFUL_MC
-  std::unique_ptr<RemoteProcessMemory> remote_memory_;
-#endif
 
   Channel channel_;
   bool running_ = false;
@@ -33,13 +30,12 @@ class CheckerSide {
   CheckerSide* child_checker_ = nullptr;
 
   void setup_events(bool socket_only); // Part of the initialization
-  void clear_memory_cache();
   void handle_dead_child(int status); // Launched when the dying child is the PID we follow
   void handle_waitpid();              // Launched when receiving a sigchild
 
 public:
   explicit CheckerSide(int socket, CheckerSide* child_checker);
-  explicit CheckerSide(const std::vector<char*>& args, bool need_memory_introspection);
+  explicit CheckerSide(const std::vector<char*>& args);
   ~CheckerSide();
 
   // No copy:
@@ -66,9 +62,6 @@ public:
   pid_t get_pid() const { return pid_; }
   bool running() const { return running_; }
   void terminate() { running_ = false; }
-#if SIMGRID_HAVE_STATEFUL_MC
-  RemoteProcessMemory* get_remote_memory() { return remote_memory_.get(); }
-#endif
 };
 
 } // namespace simgrid::mc
index dfe103b..0c41b27 100644 (file)
@@ -14,7 +14,6 @@
 
 #include "simgrid/forward.h" // aid_t
 #include "src/mc/datatypes.h"
-#include "src/xbt/mmalloc/mmalloc.h"
 #include <xbt/utility.hpp>
 
 #include <array>
 // ***** Messages
 namespace simgrid::mc {
 
-XBT_DECLARE_ENUM_CLASS(MessageType, NONE, NEED_MEMINFO, NEED_MEMINFO_REPLY, FORK, FORK_REPLY, WAIT_CHILD,
-                       WAIT_CHILD_REPLY, CONTINUE, IGNORE_HEAP, UNIGNORE_HEAP, IGNORE_MEMORY, UNIGNORE_MEMORY,
-                       STACK_REGION, REGISTER_SYMBOL, DEADLOCK_CHECK, DEADLOCK_CHECK_REPLY, WAITING, SIMCALL_EXECUTE,
-                       SIMCALL_EXECUTE_REPLY, ASSERTION_FAILED, ACTORS_STATUS, ACTORS_STATUS_REPLY_COUNT,
-                       ACTORS_STATUS_REPLY_SIMCALL, ACTORS_STATUS_REPLY_TRANSITION, ACTORS_MAXPID, ACTORS_MAXPID_REPLY,
-                       FINALIZE, FINALIZE_REPLY);
+XBT_DECLARE_ENUM_CLASS(MessageType, NONE, FORK, FORK_REPLY, WAIT_CHILD, WAIT_CHILD_REPLY, CONTINUE, DEADLOCK_CHECK,
+                       DEADLOCK_CHECK_REPLY, WAITING, SIMCALL_EXECUTE, SIMCALL_EXECUTE_REPLY, ASSERTION_FAILED,
+                       ACTORS_STATUS, ACTORS_STATUS_REPLY_COUNT, ACTORS_STATUS_REPLY_SIMCALL,
+                       ACTORS_STATUS_REPLY_TRANSITION, ACTORS_MAXPID, ACTORS_MAXPID_REPLY, FINALIZE, FINALIZE_REPLY);
 } // namespace simgrid::mc
 
 constexpr unsigned MC_MESSAGE_LENGTH                 = 512;
@@ -57,38 +54,8 @@ struct s_mc_message_int_t {
 };
 
 /* Client->Server */
-struct s_mc_message_ignore_heap_t {
-  simgrid::mc::MessageType type;
-  int block;
-  int fragment;
-  void* address;
-  size_t size;
-};
-
-struct s_mc_message_ignore_memory_t {
-  simgrid::mc::MessageType type;
-  uint64_t addr;
-  size_t size;
-};
-
-struct s_mc_message_stack_region_t {
-  simgrid::mc::MessageType type;
-  s_stack_region_t stack_region;
-};
-
-struct s_mc_message_register_symbol_t {
-  simgrid::mc::MessageType type;
-  std::array<char, 128> name;
-  int (*callback)(void*);
-  void* data;
-};
 
 /* Server -> client */
-struct s_mc_message_need_meminfo_reply_t {
-  simgrid::mc::MessageType type;
-  xbt_mheap_t mmalloc_default_mdp;
-};
-
 struct s_mc_message_fork_t {
   simgrid::mc::MessageType type;
   std::array<char, MC_SOCKET_NAME_LEN> socket_name;
diff --git a/src/mc/sosp/ChunkedData.cpp b/src/mc/sosp/ChunkedData.cpp
deleted file mode 100644 (file)
index 75c5341..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2007-2023. 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 "src/mc/AddressSpace.hpp"
-#include "src/mc/sosp/ChunkedData.hpp"
-
-namespace simgrid::mc {
-
-/** Take a per-page snapshot of a region
- *
- *  @param addr            The start of the region (must be at the beginning of a page)
- *  @param page_count      Number of pages of the region
- *  @return                Snapshot page numbers of this new snapshot
- */
-ChunkedData::ChunkedData(PageStore& store, const AddressSpace& as, RemotePtr<void> addr, std::size_t page_count)
-    : store_(&store)
-{
-  this->pagenos_.resize(page_count);
-  std::vector<char> buffer(xbt_pagesize);
-
-  for (size_t i = 0; i != page_count; ++i) {
-    RemotePtr<void> page = remote((void*)simgrid::mc::mmu::join(i, addr.address()));
-    xbt_assert(simgrid::mc::mmu::split(page.address()).second == 0, "Not at the beginning of a page");
-
-    /* Adding another copy (and a syscall) will probably slow things a lot.
-       TODO, optimize this somehow (at least by grouping the syscalls)
-       if needed. Either:
-       - reduce the number of syscalls
-       - let the application snapshot itself
-       - move the segments in shared memory (this will break `fork` however)
-    */
-
-    as.read_bytes(buffer.data(), xbt_pagesize, page);
-
-    pagenos_[i] = store_->store_page(buffer.data());
-  }
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/sosp/ChunkedData.hpp b/src/mc/sosp/ChunkedData.hpp
deleted file mode 100644 (file)
index c4a706f..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Copyright (c) 2014-2023. 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 SIMGRID_MC_CHUNKED_DATA_HPP
-#define SIMGRID_MC_CHUNKED_DATA_HPP
-
-#include <vector>
-
-#include "src/mc/mc_forward.hpp"
-#include "src/mc/remote/RemotePtr.hpp"
-#include "src/mc/sosp/PageStore.hpp"
-
-namespace simgrid::mc {
-
-/** A byte-string represented as a sequence of chunks from a PageStore
- *
- *  In order to save memory when taking memory snapshots, a given byte-string
- *  is split in fixed-size chunks. Identical chunks (either from the same
- *  snapshot or more probably from different snapshots) share the same memory
- *  storage.
- *
- *  Thus a chunked is represented as a sequence of indices of each chunk.
- */
-class ChunkedData {
-  /** This is where we store the chunks */
-  PageStore* store_ = nullptr;
-  /** Indices of the chunks in the `PageStore` */
-  std::vector<std::size_t> pagenos_;
-
-public:
-  ChunkedData() = default;
-  void clear()
-  {
-    for (std::size_t const& pageno : pagenos_)
-      store_->unref_page(pageno);
-    pagenos_.clear();
-  }
-  ~ChunkedData() { clear(); }
-
-  // Copy and move
-  ChunkedData(ChunkedData const& that) : store_(that.store_), pagenos_(that.pagenos_)
-  {
-    for (std::size_t const& pageno : pagenos_)
-      store_->ref_page(pageno);
-  }
-  ChunkedData(ChunkedData&& that) noexcept : pagenos_(std::move(that.pagenos_))
-  {
-    std::swap(store_, that.store_);
-    that.pagenos_.clear();
-  }
-  ChunkedData& operator=(ChunkedData const& that)
-  {
-    if (this != &that) {
-      this->clear();
-      store_   = that.store_;
-      pagenos_ = that.pagenos_;
-      for (std::size_t const& pageno : pagenos_)
-        store_->ref_page(pageno);
-    }
-    return *this;
-  }
-  ChunkedData& operator=(ChunkedData&& that) noexcept
-  {
-    if (this != &that) {
-      this->clear();
-      store_      = that.store_;
-      that.store_ = nullptr;
-      pagenos_    = std::move(that.pagenos_);
-      that.pagenos_.clear();
-    }
-    return *this;
-  }
-
-  /** How many pages are used */
-  std::size_t page_count() const { return pagenos_.size(); }
-
-  /** Get a chunk index */
-  std::size_t pageno(std::size_t i) const { return pagenos_[i]; }
-
-  /** Get a view of the chunk indices */
-  const std::size_t* pagenos() const { return pagenos_.data(); }
-
-  /** Get a pointer to a chunk */
-  void* page(std::size_t i) const { return store_->get_page(pagenos_[i]); }
-
-  ChunkedData(PageStore& store, const AddressSpace& as, RemotePtr<void> addr, std::size_t page_count);
-};
-
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/sosp/PageStore.cpp b/src/mc/sosp/PageStore.cpp
deleted file mode 100644 (file)
index e2c46f4..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2015-2023. 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 <sys/mman.h>
-#ifdef __FreeBSD__
-#define MAP_POPULATE MAP_PREFAULT_READ
-#endif
-
-#include "src/internal_config.h"
-#include "xbt/log.h"
-#include "xbt/sysdep.h"
-
-#include "src/3rd-party/xxhash.hpp"
-#include "src/mc/mc_mmu.hpp"
-#include "src/mc/sosp/PageStore.hpp"
-
-#include <cstring> // memcpy, memcmp
-#include <unistd.h>
-
-namespace simgrid::mc {
-
-/** @brief Compute 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 page in the page
- *  store.
- *
- *  @param data Memory page
- *  @return hash off the page
- */
-static XBT_ALWAYS_INLINE PageStore::hash_type mc_hash_page(const void* data)
-{
-  return xxh::xxhash<64>(data, xbt_pagesize);
-}
-
-// ***** snapshot_page_manager
-
-PageStore::PageStore(std::size_t size) : capacity_(size)
-{
-  // Using mmap in order to be able to expand the region by relocating it somewhere else in the virtual memory space:
-  void* memory =
-      ::mmap(nullptr, size << xbt_pagebits, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
-  xbt_assert(memory != MAP_FAILED, "Could not mmap initial snapshot pages.");
-
-  this->top_index_ = 0;
-  this->memory_    = memory;
-  this->page_counts_.resize(size);
-}
-
-PageStore::~PageStore()
-{
-  ::munmap(this->memory_, this->capacity_ << xbt_pagebits);
-}
-
-void PageStore::resize(std::size_t size)
-{
-  size_t old_bytesize = this->capacity_ << xbt_pagebits;
-  size_t new_bytesize = size << xbt_pagebits;
-  void* new_memory;
-
-  // Expand the memory region by moving it into another
-  // virtual memory address if necessary:
-#if HAVE_MREMAP
-  new_memory = mremap(this->memory_, old_bytesize, new_bytesize, MREMAP_MAYMOVE);
-  xbt_assert(new_memory != MAP_FAILED, "Could not mremap snapshot pages.");
-#else
-  if (new_bytesize > old_bytesize) {
-    // Grow: first try to add new space after current map
-    new_memory = mmap((char*)this->memory_ + old_bytesize, new_bytesize - old_bytesize, PROT_READ | PROT_WRITE,
-                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
-    xbt_assert(new_memory != MAP_FAILED, "Could not mremap snapshot pages.");
-    // Check if expanding worked
-    if (new_memory == (char*)this->memory_ + old_bytesize) {
-      new_memory = this->memory_;
-    } else {
-      // New memory segment could not be put at the end of this->memory_,
-      // so cancel this one and try to relocate everything and copy data
-      munmap(new_memory, new_bytesize - old_bytesize);
-      new_memory =
-          mmap(nullptr, new_bytesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
-      xbt_assert(new_memory != MAP_FAILED, "Could not mremap snapshot pages.");
-      memcpy(new_memory, this->memory_, old_bytesize);
-      munmap(this->memory_, old_bytesize);
-    }
-  } else {
-    // We don't have functions to shrink a mapping, so leave memory as
-    // it is for now
-    new_memory = this->memory_;
-  }
-#endif
-
-  this->capacity_ = size;
-  this->memory_   = new_memory;
-  this->page_counts_.resize(size, 0);
-}
-
-/** Allocate a free page
- *
- *  @return index of the free page
- */
-std::size_t PageStore::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 PageStore::remove_page(std::size_t pageno)
-{
-  this->free_pages_.push_back(pageno);
-  const void* page = this->get_page(pageno);
-  hash_type hash   = mc_hash_page(page);
-  this->hash_index_[hash].erase(pageno);
-}
-
-/** Store a page in memory */
-std::size_t PageStore::store_page(const void* 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
-  hash_type hash = mc_hash_page(page);
-
-  // Try to find a duplicate in set of pages with the same hash:
-  page_set_type& page_set = this->hash_index_[hash];
-  for (size_t const& 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's reused and its refcount 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.
-  std::size_t pageno = alloc_page();
-  xbt_assert(this->page_counts_[pageno] == 0, "Allocated page is already used");
-  void* snapshot_page = this->get_page(pageno);
-  memcpy(snapshot_page, page, xbt_pagesize);
-  page_set.insert(pageno);
-  page_counts_[pageno]++;
-  return pageno;
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/sosp/PageStore.hpp b/src/mc/sosp/PageStore.hpp
deleted file mode 100644 (file)
index 034512c..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (c) 2015-2023. 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 SIMGRID_MC_PAGESTORE_HPP
-#define SIMGRID_MC_PAGESTORE_HPP
-
-#include "src/mc/mc_forward.hpp"
-#include "src/mc/mc_mmu.hpp"
-
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#ifndef XBT_ALWAYS_INLINE
-#define XBT_ALWAYS_INLINE inline __attribute__((always_inline))
-#endif
-
-namespace simgrid::mc {
-
-/** @brief Storage for snapshot memory pages
- *
- * The first (lower) layer of the per-page snapshot mechanism is a page store:
- * its responsibility is to store immutable shareable reference-counted memory
- * pages independently of the snapshotting logic. Snapshot management and
- * representation 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 copying 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.
- *
- */
-class PageStore {
-public: // Types
-  using hash_type = std::uint64_t;
-
-private:
-  // Types
-  // We are using a cheap hash to index a page.
-  // We should expect collision and we need to associate multiple page indices
-  // to the same hash.
-  using page_set_type  = std::unordered_set<std::size_t>;
-  using pages_map_type = std::unordered_map<hash_type, page_set_type>;
-
-  // Fields:
-  /** First page */
-  void* memory_;
-  /** Number of available pages in virtual memory */
-  std::size_t capacity_;
-  /** Top of the used pages (index of the next available page) */
-  std::size_t top_index_;
-  /** Page reference count */
-  std::vector<std::uint64_t> page_counts_;
-  /** Index of available pages before the top */
-  std::vector<std::size_t> free_pages_;
-  /** Index from page hash to page index */
-  pages_map_type hash_index_;
-
-  // Methods
-  void resize(std::size_t size);
-  std::size_t alloc_page();
-  void remove_page(std::size_t pageno);
-
-public:
-  // Constructors
-  PageStore(PageStore const&) = delete;
-  PageStore& operator=(PageStore const&) = delete;
-  explicit PageStore(std::size_t size);
-  ~PageStore();
-
-  // 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(std::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 snapshot/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 */
-  std::size_t store_page(const void* page);
-
-  /** @brief Get a page from its page number
-   *
-   *  @param pageno Number of the memory page in the store
-   *  @return Start of the page
-   */
-  void* get_page(std::size_t pageno) const;
-
-  // Debug/test methods
-
-  /** @brief Get the number of references for a page */
-  std::size_t get_ref(std::size_t pageno) const;
-
-  /** @brief Get the number of used pages */
-  std::size_t size() const;
-
-  /** @brief Get the capacity of the page store
-   *
-   *  The capacity is expanded by a system call (mremap).
-   * */
-  std::size_t capacity() const;
-};
-
-XBT_ALWAYS_INLINE void PageStore::unref_page(std::size_t pageno)
-{
-  if ((--this->page_counts_[pageno]) == 0)
-    this->remove_page(pageno);
-}
-
-XBT_ALWAYS_INLINE void PageStore::ref_page(size_t pageno)
-{
-  ++this->page_counts_[pageno];
-}
-
-XBT_ALWAYS_INLINE void* PageStore::get_page(std::size_t pageno) const
-{
-  return (void*)simgrid::mc::mmu::join(pageno, (std::uintptr_t)this->memory_);
-}
-
-XBT_ALWAYS_INLINE std::size_t PageStore::get_ref(std::size_t pageno) const
-{
-  return this->page_counts_[pageno];
-}
-
-XBT_ALWAYS_INLINE std::size_t PageStore::size() const
-{
-  return this->top_index_ - this->free_pages_.size();
-}
-
-XBT_ALWAYS_INLINE std::size_t PageStore::capacity() const
-{
-  return this->capacity_;
-}
-
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/sosp/PageStore_test.cpp b/src/mc/sosp/PageStore_test.cpp
deleted file mode 100644 (file)
index 8de5bc9..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2015-2023. 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 "src/3rd-party/catch.hpp"
-
-#include <array>
-#include <cstdint>
-#include <cstring>
-#include <iostream>
-
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include <memory>
-
-#include "src/mc/sosp/PageStore.hpp"
-
-/***********************************/
-// a class to hold the variable used in the test cases
-class pstore_test_helper {
-  const size_t pagesize = getpagesize();
-  simgrid::mc::PageStore store{50};
-  std::byte* data =
-      static_cast<std::byte*>(mmap(nullptr, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
-  std::array<size_t, 4> pageno = {0, 0, 0, 0};
-  int value                    = 0;
-
-  void new_content(std::byte* buf, size_t size);
-
-public:
-  // member functions used by the test suite(s)
-  void init();
-  void store_page_once();
-  void store_same_page();
-  void store_new_page();
-  void unref_pages();
-  void reallocate_page();
-};
-
-void pstore_test_helper::init()
-{
-  REQUIRE(data != nullptr);
-  REQUIRE(store.size() == 0);
-}
-
-void pstore_test_helper::store_page_once()
-{
-  new_content(data, pagesize);
-  pageno[0] = store.store_page(data);
-  REQUIRE(store.get_ref(pageno[0]) == 1);
-  const auto* copy = store.get_page(pageno[0]);
-  REQUIRE(::memcmp(data, copy, pagesize) == 0); // The page data should be the same
-  REQUIRE(store.size() == 1);
-}
-
-void pstore_test_helper::store_same_page()
-{
-  pageno[1] = store.store_page(data);
-  REQUIRE(pageno[0] == pageno[1]); // Page should be the same
-  REQUIRE(store.get_ref(pageno[0]) == 2);
-  REQUIRE(store.size() == 1);
-}
-
-void pstore_test_helper::store_new_page()
-{
-  new_content(data, pagesize);
-  pageno[2] = store.store_page(data);
-  REQUIRE(pageno[0] != pageno[2]); // The new page should be different
-  REQUIRE(store.size() == 2);
-}
-
-void pstore_test_helper::unref_pages()
-{
-  store.unref_page(pageno[0]);
-  REQUIRE(store.get_ref(pageno[0]) == 1);
-  REQUIRE(store.size() == 2);
-
-  store.unref_page(pageno[1]);
-  REQUIRE(store.size() == 1);
-}
-
-void pstore_test_helper::reallocate_page()
-{
-  new_content(data, pagesize);
-  pageno[3] = store.store_page(data);
-  REQUIRE(pageno[0] == pageno[3]); // The old page should be reused
-  REQUIRE(store.get_ref(pageno[3]) == 1);
-  REQUIRE(store.size() == 2);
-}
-
-void pstore_test_helper::new_content(std::byte* buf, size_t size)
-{
-  value++;
-  std::fill_n(buf, size, static_cast<std::byte>(value));
-}
-
-TEST_CASE("MC page store, used during checkpoint", "MC::PageStore")
-{
-  pstore_test_helper pstore_test;
-  pstore_test.init();
-
-  INFO("Store page once");
-  pstore_test.store_page_once();
-
-  INFO("Store the same page");
-  pstore_test.store_same_page();
-
-  INFO("Store a new page");
-  pstore_test.store_new_page();
-
-  INFO("Unref pages");
-  pstore_test.unref_pages();
-
-  INFO("Reallocate pages");
-  pstore_test.reallocate_page();
-}
diff --git a/src/mc/sosp/Region.cpp b/src/mc/sosp/Region.cpp
deleted file mode 100644 (file)
index 2dca797..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright (c) 2007-2023. 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 "src/mc/sosp/Region.hpp"
-#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_forward.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include <cstdlib>
-#include <sys/mman.h>
-#ifdef __FreeBSD__
-#define MAP_POPULATE MAP_PREFAULT_READ
-#endif
-
-namespace simgrid::mc {
-
-Region::Region(PageStore& store, const RemoteProcessMemory& memory, RegionType region_type, void* start_addr,
-               size_t size)
-    : region_type_(region_type), start_addr_(start_addr), size_(size)
-{
-  xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize - 1)) == 0, "Start address not at the beginning of a page");
-
-  chunks_ = ChunkedData(store, memory, RemotePtr<void>(start_addr), mmu::chunk_count(size));
-}
-
-/** @brief Restore a region from a snapshot
- *
- *  @param region     Target region
- */
-void Region::restore(const RemoteProcessMemory& memory) const
-{
-  xbt_assert(((start().address()) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page");
-  xbt_assert(simgrid::mc::mmu::chunk_count(size()) == get_chunks().page_count());
-
-  for (size_t i = 0; i != get_chunks().page_count(); ++i) {
-    auto* target_page       = (void*)simgrid::mc::mmu::join(i, (std::uintptr_t)(void*)start().address());
-    const void* source_page = get_chunks().page(i);
-    memory.write_bytes(source_page, xbt_pagesize, remote(target_page));
-  }
-}
-
-static XBT_ALWAYS_INLINE void* mc_translate_address_region(uintptr_t addr, const simgrid::mc::Region* region)
-{
-  auto [pageno, offset] = simgrid::mc::mmu::split(addr - region->start().address());
-  void* snapshot_page   = region->get_chunks().page(pageno);
-  return (char*)snapshot_page + offset;
-}
-
-void* Region::read(void* target, const void* addr, std::size_t size) const
-{
-  xbt_assert(contain(simgrid::mc::remote(addr)), "Trying to read out of the region boundary.");
-
-  // Last byte of the region:
-  const void* end_addr = (const char*)addr + size - 1;
-  if (simgrid::mc::mmu::same_chunk((std::uintptr_t)addr, (std::uintptr_t)end_addr)) {
-    // The memory is contained in a single page:
-    return mc_translate_address_region((uintptr_t)addr, this);
-  }
-  // Otherwise, the memory spans several pages. Let's copy it all into the provided buffer
-  xbt_assert(target != nullptr, "Missing destination buffer for fragmented memory access");
-
-  // TODO, we assume the chunks are aligned to natural chunk boundaries.
-  // We should remove this assumption.
-
-  // Page of the last byte of the memory area:
-  size_t page_end = simgrid::mc::mmu::split((std::uintptr_t)end_addr).first;
-
-  void* dest = target; // iterator in the buffer to where we should copy next
-
-  // Read each page:
-  while (simgrid::mc::mmu::split((std::uintptr_t)addr).first != page_end) {
-    const void* snapshot_addr = mc_translate_address_region((uintptr_t)addr, this);
-    auto* next_page     = (void*)simgrid::mc::mmu::join(simgrid::mc::mmu::split((std::uintptr_t)addr).first + 1, 0);
-    size_t readable     = (char*)next_page - (const char*)addr;
-    memcpy(dest, snapshot_addr, readable);
-    addr = (const char*)addr + readable;
-    dest = (char*)dest + readable;
-    size -= readable;
-  }
-
-  // Read the end:
-  const void* snapshot_addr = mc_translate_address_region((uintptr_t)addr, this);
-  memcpy(dest, snapshot_addr, size);
-
-  return target;
-}
-
-} // namespace simgrid::mc
-
-/** Compare memory between snapshots (with known regions)
- *
- * @param addr1 Address in the first snapshot
- * @param region1 Region of the address in the first snapshot
- * @param addr2 Address in the second snapshot
- * @param region2 Region of the address in the second snapshot
- * @return same semantic as memcmp
- */
-int MC_snapshot_region_memcmp(const void* addr1, const simgrid::mc::Region* region1, const void* addr2,
-                              const simgrid::mc::Region* 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* buffer1a      = stack_alloc ? alloca(size) : ::operator new(size);
-  void* buffer2a      = stack_alloc ? alloca(size) : ::operator new(size);
-  const void* buffer1 = region1->read(buffer1a, addr1, size);
-  const void* buffer2 = region2->read(buffer2a, addr2, size);
-  int res;
-  if (buffer1 == buffer2)
-    res = 0;
-  else
-    res = memcmp(buffer1, buffer2, size);
-  if (not stack_alloc) {
-    ::operator delete(buffer1a);
-    ::operator delete(buffer2a);
-  }
-  return res;
-}
diff --git a/src/mc/sosp/Region.hpp b/src/mc/sosp/Region.hpp
deleted file mode 100644 (file)
index 7ab26e2..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_SOSP_REGION_HPP
-#define SIMGRID_MC_SOSP_REGION_HPP
-
-#include "src/mc/remote/RemotePtr.hpp"
-#include "src/mc/sosp/ChunkedData.hpp"
-
-#include <memory>
-#include <vector>
-
-namespace simgrid::mc {
-
-enum class RegionType { Heap = 1, Data = 2 };
-
-/** A copy/snapshot of a given memory region, where identical pages are stored only once */
-class Region {
-public:
-  static const RegionType HeapRegion    = RegionType::Heap;
-  static const RegionType DataRegion    = RegionType::Data;
-
-private:
-  RegionType region_type_;
-  simgrid::mc::ObjectInformation* object_info_ = nullptr;
-
-  /** @brief  Virtual address of the region in the simulated process */
-  void* start_addr_ = nullptr;
-
-  /** @brief Size of the data region in bytes */
-  std::size_t size_ = 0;
-
-  ChunkedData chunks_;
-
-public:
-  Region(PageStore& store, const RemoteProcessMemory& memory, RegionType type, void* start_addr, size_t size);
-  Region(Region const&) = delete;
-  Region& operator=(Region const&) = delete;
-  Region(Region&& that)            = delete;
-  Region& operator=(Region&& that) = delete;
-
-  // Data
-
-  ChunkedData const& get_chunks() const { return chunks_; }
-
-  simgrid::mc::ObjectInformation* object_info() const { return object_info_; }
-  void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; }
-
-  // Other getters
-
-  RemotePtr<void> start() const { return remote(start_addr_); }
-  RemotePtr<void> end() const { return remote((char*)start_addr_ + size_); }
-  std::size_t size() const { return size_; }
-  RegionType region_type() const { return region_type_; }
-
-  bool contain(RemotePtr<void> p) const { return p >= start() && p < end(); }
-
-  /** @brief Restore a region from a snapshot */
-  void restore(const RemoteProcessMemory& memory) const;
-
-  /** @brief Read memory that was snapshotted in this region
-   *
-   *  @param target  Buffer to store contiguously the value if it spans over several pages
-   *  @param addr    Process (non-snapshot) address of the data
-   *  @param size    Size of the data to read in bytes
-   *  @return Pointer where the data is located (either target buffer or original location)
-   */
-  void* read(void* target, const void* addr, std::size_t size) const;
-};
-
-} // namespace simgrid::mc
-
-int MC_snapshot_region_memcmp(const void* addr1, const simgrid::mc::Region* region1, const void* addr2,
-                              const simgrid::mc::Region* region2, std::size_t size);
-
-static XBT_ALWAYS_INLINE void* MC_region_read_pointer(const simgrid::mc::Region* region, const void* addr)
-{
-  void* res;
-  return *(void**)region->read(&res, addr, sizeof(void*));
-}
-
-#endif
diff --git a/src/mc/sosp/RemoteProcessMemory.cpp b/src/mc/sosp/RemoteProcessMemory.cpp
deleted file mode 100644 (file)
index 1d256c1..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/* Copyright (c) 2014-2023. 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. */
-
-#define _FILE_OFFSET_BITS 64 /* needed for pread_whole to work as expected on 32bits */
-
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include "src/mc/explo/Exploration.hpp"
-#include "src/mc/explo/LivenessChecker.hpp"
-#include "src/mc/sosp/Snapshot.hpp"
-#include "xbt/file.hpp"
-#include "xbt/log.h"
-#include "xbt/system_error.hpp"
-
-#include <fcntl.h>
-#include <libunwind-ptrace.h>
-#include <sys/mman.h> // PROT_*
-
-#include <algorithm>
-#include <cerrno>
-#include <cstring>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <string_view>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information");
-
-namespace simgrid::mc {
-
-// ***** Helper stuff
-
-static bool is_filtered_lib(std::string_view libname)
-{
-  return libname != "libsimgrid";
-}
-
-static std::string get_lib_name(const std::string& pathname)
-{
-  std::string map_basename = simgrid::xbt::Path(pathname).get_base_name();
-  std::string libname;
-
-  if (size_t pos = map_basename.rfind(".so"); pos != std::string::npos) {
-    // strip the extension (matching regex "\.so.*$")
-    libname.assign(map_basename, 0, pos);
-
-    // strip the version suffix (matching regex "-[.0-9-]*$")
-    while (true) {
-      pos = libname.rfind('-');
-      if (pos == std::string::npos || libname.find_first_not_of(".0123456789", pos + 1) != std::string::npos)
-        break;
-      libname.erase(pos);
-    }
-  }
-
-  return libname;
-}
-
-static ssize_t pread_whole(int fd, void* buf, size_t count, off_t offset)
-{
-  auto* buffer       = static_cast<char*>(buf);
-  ssize_t real_count = count;
-  while (count) {
-    ssize_t res = pread(fd, buffer, count, offset);
-    if (res > 0) {
-      count -= res;
-      buffer += res;
-      offset += res;
-    } else if (res == 0)
-      return -1;
-    else if (errno != EINTR) {
-      XBT_ERROR("pread_whole: %s", strerror(errno));
-      return -1;
-    }
-  }
-  return real_count;
-}
-
-static ssize_t pwrite_whole(int fd, const void* buf, size_t count, off_t offset)
-{
-  const auto* buffer = static_cast<const char*>(buf);
-  ssize_t real_count = count;
-  while (count) {
-    ssize_t res = pwrite(fd, buffer, count, offset);
-    if (res > 0) {
-      count -= res;
-      buffer += res;
-      offset += res;
-    } else if (res == 0)
-      return -1;
-    else if (errno != EINTR) {
-      XBT_ERROR("pwrite_whole: %s", strerror(errno));
-      return -1;
-    }
-  }
-  return real_count;
-}
-
-int open_vm(pid_t pid, int flags)
-{
-  std::string buffer = "/proc/" + std::to_string(pid) + "/mem";
-  return open(buffer.c_str(), flags);
-}
-
-// ***** RemoteProcessMemory
-
-RemoteProcessMemory::RemoteProcessMemory(pid_t pid, xbt_mheap_t mmalloc_default_mdp) : AddressSpace(this), pid_(pid)
-{
-  this->heap_address = remote(mmalloc_default_mdp);
-
-  this->memory_map_ = simgrid::xbt::get_memory_map(this->pid_);
-  this->init_memory_map_info();
-
-  int fd = open_vm(this->pid_, O_RDWR);
-  xbt_assert(fd >= 0, "Could not open file for process virtual address space");
-  this->memory_file = fd;
-
-  this->unw_addr_space            = simgrid::mc::UnwindContext::createUnwindAddressSpace();
-  this->unw_underlying_addr_space = simgrid::unw::create_addr_space();
-  this->unw_underlying_context    = simgrid::unw::create_context(this->unw_underlying_addr_space, this->pid_);
-
-  auto ignored_local_variables = {
-      std::make_pair("e", "*"),
-      std::make_pair("_log_ev", "*"),
-
-      /* Ignore local variable about time used for tracing */
-      std::make_pair("start_time", "*"),
-  };
-  for (auto const& [var, frame] : ignored_local_variables)
-    ignore_local_variable(var, frame);
-
-  ignore_global_variable("counter"); // Static variable used for tracing
-}
-
-RemoteProcessMemory::~RemoteProcessMemory()
-{
-  if (this->memory_file >= 0)
-    close(this->memory_file);
-
-  if (this->unw_underlying_addr_space != unw_local_addr_space) {
-    if (this->unw_underlying_addr_space)
-      unw_destroy_addr_space(this->unw_underlying_addr_space);
-    if (this->unw_underlying_context)
-      _UPT_destroy(this->unw_underlying_context);
-  }
-
-  unw_destroy_addr_space(this->unw_addr_space);
-}
-
-/** Refresh the information about the process
- *
- *  Do not use directly, this is used by the getters when appropriate
- *  in order to have fresh data.
- */
-void RemoteProcessMemory::refresh_heap()
-{
-  // Read/dereference/refresh the std_heap pointer:
-  this->read(this->heap.get(), this->heap_address);
-  this->cache_flags_ |= RemoteProcessMemory::cache_heap;
-}
-
-/** Refresh the information about the process
- *
- *  Do not use directly, this is used by the getters when appropriate
- *  in order to have fresh data.
- * */
-void RemoteProcessMemory::refresh_malloc_info()
-{
-  // Refresh process->heapinfo:
-  if (this->cache_flags_ & RemoteProcessMemory::cache_malloc)
-    return;
-  size_t count = this->heap->heaplimit + 1;
-  if (this->heap_info.size() < count)
-    this->heap_info.resize(count);
-  this->read_bytes(this->heap_info.data(), count * sizeof(malloc_info), remote(this->heap->heapinfo));
-  this->cache_flags_ |= RemoteProcessMemory::cache_malloc;
-}
-std::size_t RemoteProcessMemory::get_remote_heap_bytes()
-{
-  return mmalloc_get_bytes_used_remote(get_heap()->heaplimit, get_malloc_info());
-}
-
-/** @brief Finds the range of the different memory segments and binary paths */
-void RemoteProcessMemory::init_memory_map_info()
-{
-  XBT_DEBUG("Get debug information ...");
-  this->maestro_stack_start_ = nullptr;
-  this->maestro_stack_end_   = nullptr;
-  this->object_infos.clear();
-  this->binary_info = nullptr;
-
-  std::vector<simgrid::xbt::VmMap> const& maps = this->memory_map_;
-
-  const char* current_name = nullptr;
-
-  for (size_t i = 0; i < maps.size(); i++) {
-    simgrid::xbt::VmMap const& reg = maps[i];
-    const char* pathname           = maps[i].pathname.c_str();
-
-    // Nothing to do
-    if (maps[i].pathname.empty()) {
-      current_name = nullptr;
-      continue;
-    }
-
-    // [stack], [vvar], [vsyscall], [vdso] ...
-    if (pathname[0] == '[') {
-      if ((reg.prot & PROT_WRITE) && not memcmp(pathname, "[stack]", 7)) {
-        this->maestro_stack_start_ = remote(reg.start_addr);
-        this->maestro_stack_end_   = remote(reg.end_addr);
-      }
-      current_name = nullptr;
-      continue;
-    }
-
-    if (current_name && strcmp(current_name, pathname) == 0)
-      continue;
-
-    current_name = pathname;
-    if (not(reg.prot & PROT_READ) && (reg.prot & PROT_EXEC))
-      continue;
-
-    const bool is_executable = not i;
-    std::string libname;
-    if (not is_executable) {
-      libname = get_lib_name(pathname);
-      if (is_filtered_lib(libname)) {
-        continue;
-      }
-    }
-
-    std::shared_ptr<simgrid::mc::ObjectInformation> info =
-        simgrid::mc::createObjectInformation(this->memory_map_, pathname);
-    this->object_infos.push_back(info);
-    if (is_executable)
-      this->binary_info = info;
-  }
-
-  xbt_assert(this->maestro_stack_start_, "Did not find maestro_stack_start");
-  xbt_assert(this->maestro_stack_end_, "Did not find maestro_stack_end");
-
-  XBT_DEBUG("Get debug information done !");
-}
-
-std::shared_ptr<simgrid::mc::ObjectInformation> RemoteProcessMemory::find_object_info(RemotePtr<void> addr) const
-{
-  for (auto const& object_info : this->object_infos)
-    if (addr.address() >= (std::uint64_t)object_info->start && addr.address() <= (std::uint64_t)object_info->end)
-      return object_info;
-  return nullptr;
-}
-
-std::shared_ptr<ObjectInformation> RemoteProcessMemory::find_object_info_exec(RemotePtr<void> addr) const
-{
-  for (std::shared_ptr<ObjectInformation> const& info : this->object_infos)
-    if (addr.address() >= (std::uint64_t)info->start_exec && addr.address() <= (std::uint64_t)info->end_exec)
-      return info;
-  return nullptr;
-}
-
-std::shared_ptr<ObjectInformation> RemoteProcessMemory::find_object_info_rw(RemotePtr<void> addr) const
-{
-  for (std::shared_ptr<ObjectInformation> const& info : this->object_infos)
-    if (addr.address() >= (std::uint64_t)info->start_rw && addr.address() <= (std::uint64_t)info->end_rw)
-      return info;
-  return nullptr;
-}
-
-simgrid::mc::Frame* RemoteProcessMemory::find_function(RemotePtr<void> ip) const
-{
-  std::shared_ptr<simgrid::mc::ObjectInformation> info = this->find_object_info_exec(ip);
-  return info ? info->find_function((void*)ip.address()) : nullptr;
-}
-
-/** Find (one occurrence of) the named variable definition
- */
-const simgrid::mc::Variable* RemoteProcessMemory::find_variable(const char* name) const
-{
-  // First lookup the variable in the executable shared object.
-  // A global variable used directly by the executable code from a library
-  // is reinstantiated in the executable memory .data/.bss.
-  // We need to look up the variable in the executable first.
-  if (this->binary_info) {
-    std::shared_ptr<simgrid::mc::ObjectInformation> const& info = this->binary_info;
-    const simgrid::mc::Variable* var                            = info->find_variable(name);
-    if (var)
-      return var;
-  }
-
-  for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : this->object_infos) {
-    const simgrid::mc::Variable* var = info->find_variable(name);
-    if (var)
-      return var;
-  }
-
-  return nullptr;
-}
-
-void RemoteProcessMemory::read_variable(const char* name, void* target, size_t size) const
-{
-  const simgrid::mc::Variable* var = this->find_variable(name);
-  xbt_assert(var, "Variable %s not found", name);
-  xbt_assert(var->address, "No simple location for this variable");
-
-  if (not var->type->full_type) // Try to resolve this type. The needed ObjectInfo was maybe (lazily) loaded recently
-    for (auto const& object_info : this->object_infos)
-      postProcessObjectInformation(this, object_info.get());
-  xbt_assert(var->type->full_type, "Partial type for %s (even after re-resolving types), cannot retrieve its size.",
-             name);
-  xbt_assert((size_t)var->type->full_type->byte_size == size, "Unexpected size for %s (expected %zu, received %zu).",
-             name, size, (size_t)var->type->full_type->byte_size);
-  this->read_bytes(target, size, remote(var->address));
-}
-
-std::string RemoteProcessMemory::read_string(RemotePtr<char> address) const
-{
-  if (not address)
-    return {};
-
-  std::vector<char> res(128);
-  off_t off = 0;
-
-  while (true) {
-    ssize_t c = pread(this->memory_file, res.data() + off, res.size() - off, (off_t)address.address() + off);
-    if (c == -1 && errno == EINTR)
-      continue;
-    xbt_assert(c > 0, "Could not read string from remote process");
-
-    if (memchr(res.data() + off, '\0', c))
-      return res.data();
-
-    off += c;
-    if (off == (off_t)res.size())
-      res.resize(res.size() * 2);
-  }
-}
-
-void* RemoteProcessMemory::read_bytes(void* buffer, std::size_t size, RemotePtr<void> address,
-                                      ReadOptions /*options*/) const
-{
-  xbt_assert(pread_whole(this->memory_file, buffer, size, (size_t)address.address()) != -1,
-             "Read at %p from process %lli failed", (void*)address.address(), (long long)this->pid_);
-  return buffer;
-}
-
-/** Write data to a process memory
- *
- *  @param buffer   local memory address (source)
- *  @param len      data size
- *  @param address  target process memory address (target)
- */
-void RemoteProcessMemory::write_bytes(const void* buffer, size_t len, RemotePtr<void> address) const
-{
-  xbt_assert(pwrite_whole(this->memory_file, buffer, len, (size_t)address.address()) != -1,
-             "Write to process %lli failed", (long long)this->pid_);
-}
-
-static void zero_buffer_init(const void** zero_buffer, size_t zero_buffer_size)
-{
-  int fd = open("/dev/zero", O_RDONLY);
-  xbt_assert(fd >= 0, "Could not open /dev/zero");
-  *zero_buffer = mmap(nullptr, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0);
-  xbt_assert(*zero_buffer != MAP_FAILED, "Could not map the zero buffer");
-  close(fd);
-}
-
-void RemoteProcessMemory::clear_bytes(RemotePtr<void> address, size_t len) const
-{
-  static constexpr size_t zero_buffer_size = 10 * 4096;
-  static const void* zero_buffer;
-  static std::once_flag zero_buffer_flag;
-
-  std::call_once(zero_buffer_flag, zero_buffer_init, &zero_buffer, zero_buffer_size);
-  while (len) {
-    size_t s = len > zero_buffer_size ? zero_buffer_size : len;
-    this->write_bytes(zero_buffer, s, address);
-    address = remote((char*)address.address() + s);
-    len -= s;
-  }
-}
-
-void RemoteProcessMemory::ignore_region(std::uint64_t addr, std::size_t size)
-{
-  IgnoredRegion region;
-  region.addr = addr;
-  region.size = size;
-
-  auto pos = std::lower_bound(ignored_regions_.begin(), ignored_regions_.end(), region,
-                              [](auto const& reg1, auto const& reg2) {
-                                return reg1.addr < reg2.addr || (reg1.addr == reg2.addr && reg1.size < reg2.size);
-                              });
-  if (pos == ignored_regions_.end() || pos->addr != addr || pos->size != size)
-    ignored_regions_.insert(pos, region);
-}
-
-void RemoteProcessMemory::unignore_region(std::uint64_t addr, std::size_t size)
-{
-  IgnoredRegion region;
-  region.addr = addr;
-  region.size = size;
-
-  auto pos = std::lower_bound(ignored_regions_.begin(), ignored_regions_.end(), region,
-                              [](auto const& reg1, auto const& reg2) {
-                                return reg1.addr < reg2.addr || (reg1.addr == reg2.addr && reg1.size < reg2.size);
-                              });
-  if (pos != ignored_regions_.end())
-    ignored_regions_.erase(pos);
-}
-
-void RemoteProcessMemory::ignore_heap(IgnoredHeapRegion const& region)
-{
-  // Binary search the position of insertion:
-  auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), region.address,
-                              [](auto const& reg, auto const* addr) { return reg.address < addr; });
-  if (pos == ignored_heap_.end() || pos->address != region.address) {
-    // Insert it:
-    ignored_heap_.insert(pos, region);
-  }
-}
-
-void RemoteProcessMemory::unignore_heap(void* address, size_t size)
-{
-  // Binary search:
-  auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), address,
-                              [](auto const& reg, auto const* addr) { return reg.address < addr; });
-  if (pos != ignored_heap_.end() && static_cast<char*>(pos->address) <= static_cast<char*>(address) + size)
-    ignored_heap_.erase(pos);
-}
-
-void RemoteProcessMemory::ignore_local_variable(const char* var_name, const char* frame_name) const
-{
-  if (frame_name != nullptr && strcmp(frame_name, "*") == 0)
-    frame_name = nullptr;
-  for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : this->object_infos)
-    info->remove_local_variable(var_name, frame_name);
-}
-
-void RemoteProcessMemory::dump_stack() const
-{
-  unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, BYTE_ORDER);
-  if (as == nullptr) {
-    XBT_ERROR("Could not initialize ptrace address space");
-    return;
-  }
-
-  void* context = _UPT_create(this->pid_);
-  if (context == nullptr) {
-    unw_destroy_addr_space(as);
-    XBT_ERROR("Could not initialize ptrace context");
-    return;
-  }
-
-  unw_cursor_t cursor;
-  if (unw_init_remote(&cursor, as, context) != 0) {
-    _UPT_destroy(context);
-    unw_destroy_addr_space(as);
-    XBT_ERROR("Could not initialize ptrace cursor");
-    return;
-  }
-
-  simgrid::mc::dumpStack(stderr, &cursor);
-
-  _UPT_destroy(context);
-  unw_destroy_addr_space(as);
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/sosp/RemoteProcessMemory.hpp b/src/mc/sosp/RemoteProcessMemory.hpp
deleted file mode 100644 (file)
index 0643a58..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/* mc::RemoteClient: representative of the Client memory on the MC side */
-
-/* Copyright (c) 2008-2023. 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 SIMGRID_MC_PROCESS_H
-#define SIMGRID_MC_PROCESS_H
-
-#include "src/mc/AddressSpace.hpp"
-#include "src/mc/datatypes.h"
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/remote/RemotePtr.hpp"
-#include "src/xbt/memory_map.hpp"
-#include "src/xbt/mmalloc/mmprivate.h"
-
-#include <libunwind.h>
-#include <vector>
-
-namespace simgrid::mc {
-
-struct IgnoredRegion {
-  std::uint64_t addr;
-  std::size_t size;
-};
-
-struct IgnoredHeapRegion {
-  int block;
-  int fragment;
-  void* address;
-  std::size_t size;
-};
-
-/** The Application's process memory, seen from the Checker perspective. This class is not needed if you don't need to
- * introspect the application process.
- *
- *  Responsabilities:
- *    - reading from the process memory (`AddressSpace`);
- *    - accessing the system state of the process (heap, â€¦);
- *    - stack unwinding;
- *    - etc.
- */
-class RemoteProcessMemory final : public AddressSpace {
-private:
-  // Those flags are used to track down which cached information
-  // is still up to date and which information needs to be updated.
-  static constexpr int cache_none   = 0;
-  static constexpr int cache_heap   = 1;
-  static constexpr int cache_malloc = 2;
-
-public:
-  explicit RemoteProcessMemory(pid_t pid, xbt_mheap_t mmalloc_default_mdp);
-  ~RemoteProcessMemory() override;
-
-  RemoteProcessMemory(RemoteProcessMemory const&)            = delete;
-  RemoteProcessMemory(RemoteProcessMemory&&)                 = delete;
-  RemoteProcessMemory& operator=(RemoteProcessMemory const&) = delete;
-  RemoteProcessMemory& operator=(RemoteProcessMemory&&)      = delete;
-
-  /* ************* */
-  /* Low-level API */
-  /* ************* */
-
-  // Read memory:
-  void* read_bytes(void* buffer, std::size_t size, RemotePtr<void> address,
-                   ReadOptions options = ReadOptions::none()) const override;
-
-  void read_variable(const char* name, void* target, size_t size) const;
-  template <class T> void read_variable(const char* name, T* target) const
-  {
-    read_variable(name, target, sizeof(*target));
-  }
-  template <class T> Remote<T> read_variable(const char* name) const
-  {
-    Remote<T> res;
-    read_variable(name, res.get_buffer(), sizeof(T));
-    return res;
-  }
-
-  std::string read_string(RemotePtr<char> address) const;
-  using AddressSpace::read_string;
-
-  // Write memory:
-  void write_bytes(const void* buffer, size_t len, RemotePtr<void> address) const;
-  void clear_bytes(RemotePtr<void> address, size_t len) const;
-
-  // Debug information:
-  std::shared_ptr<ObjectInformation> find_object_info(RemotePtr<void> addr) const;
-  std::shared_ptr<ObjectInformation> find_object_info_exec(RemotePtr<void> addr) const;
-  std::shared_ptr<ObjectInformation> find_object_info_rw(RemotePtr<void> addr) const;
-  Frame* find_function(RemotePtr<void> ip) const;
-  const Variable* find_variable(const char* name) const;
-
-  // Heap access:
-  xbt_mheap_t get_heap()
-  {
-    if (not(cache_flags_ & RemoteProcessMemory::cache_heap))
-      refresh_heap();
-    return this->heap.get();
-  }
-  const malloc_info* get_malloc_info()
-  {
-    if (not(this->cache_flags_ & RemoteProcessMemory::cache_malloc))
-      this->refresh_malloc_info();
-    return this->heap_info.data();
-  }
-  /* Get the amount of memory mallocated in the remote process (requires mmalloc) */
-  std::size_t get_remote_heap_bytes();
-
-  void clear_cache() { this->cache_flags_ = RemoteProcessMemory::cache_none; }
-
-  std::vector<IgnoredRegion> const& ignored_regions() const { return ignored_regions_; }
-  void ignore_region(std::uint64_t address, std::size_t size);
-  void unignore_region(std::uint64_t address, std::size_t size);
-
-  bool in_maestro_stack(RemotePtr<void> p) const
-  {
-    return p >= this->maestro_stack_start_ && p < this->maestro_stack_end_;
-  }
-
-  void ignore_global_variable(const char* name) const
-  {
-    for (std::shared_ptr<ObjectInformation> const& info : this->object_infos)
-      info->remove_global_variable(name);
-  }
-
-  std::vector<s_stack_region_t>& stack_areas() { return stack_areas_; }
-  std::vector<s_stack_region_t> const& stack_areas() const { return stack_areas_; }
-
-  std::vector<IgnoredHeapRegion> const& ignored_heap() const { return ignored_heap_; }
-  void ignore_heap(IgnoredHeapRegion const& region);
-  void unignore_heap(void* address, size_t size);
-
-  void ignore_local_variable(const char* var_name, const char* frame_name) const;
-
-  void dump_stack() const;
-
-private:
-  void init_memory_map_info();
-  void refresh_heap();
-  void refresh_malloc_info();
-
-  pid_t pid_ = -1;
-  std::vector<xbt::VmMap> memory_map_;
-  RemotePtr<void> maestro_stack_start_;
-  RemotePtr<void> maestro_stack_end_;
-  int memory_file = -1;
-  std::vector<IgnoredRegion> ignored_regions_;
-  std::vector<s_stack_region_t> stack_areas_;
-  std::vector<IgnoredHeapRegion> ignored_heap_;
-
-  /** State of the cache (which variables are up to date) */
-  int cache_flags_ = RemoteProcessMemory::cache_none;
-
-public:
-  // object info
-  // TODO, make private (first, objectify simgrid::mc::ObjectInformation*)
-  std::vector<std::shared_ptr<ObjectInformation>> object_infos;
-  std::shared_ptr<ObjectInformation> binary_info;
-
-  /** Address of the heap structure in the MCed process. */
-  RemotePtr<s_xbt_mheap_t> heap_address;
-
-  /** Copy of the heap structure of the process
-   *
-   *  This is refreshed with the `MC_process_refresh` call.
-   *  This is not used if the process is the current one:
-   *  use `get_heap_info()` in order to use it.
-   */
-  std::unique_ptr<s_xbt_mheap_t> heap = std::make_unique<s_xbt_mheap_t>();
-
-  /** Copy of the allocation info structure
-   *
-   *  This is refreshed with the `MC_process_refresh` call.
-   *  This is not used if the process is the current one:
-   *  use `get_malloc_info()` in order to use it.
-   */
-  std::vector<malloc_info> heap_info;
-
-  // Libunwind-data
-  /** Full-featured MC-aware libunwind address space for the process
-   *
-   *  This address space is using a simgrid::mc::UnwindContext*
-   *  (with simgrid::mc::Process* / simgrid::mc::AddressSpace*
-   *  and unw_context_t).
-   */
-  unw_addr_space_t unw_addr_space = nullptr;
-
-  /** Underlying libunwind address-space
-   *
-   *  The `find_proc_info`, `put_unwind_info`, `get_dyn_info_list_addr`
-   *  operations of the native MC address space is currently delegated
-   *  to this address space (either the local or a ptrace unwinder).
-   */
-  unw_addr_space_t unw_underlying_addr_space = nullptr;
-
-  /** The corresponding context
-   */
-  void* unw_underlying_context = nullptr;
-};
-
-/** Open a FD to a remote process memory (`/dev/$pid/mem`) */
-XBT_PRIVATE int open_vm(pid_t pid, int flags);
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/sosp/Snapshot.cpp b/src/mc/sosp/Snapshot.cpp
deleted file mode 100644 (file)
index ee28945..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* Copyright (c) 2014-2023. 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 "src/mc/sosp/Snapshot.hpp"
-#include "src/mc/mc_config.hpp"
-
-#include <cstddef> /* std::size_t */
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_snapshot, mc, "Taking and restoring snapshots");
-namespace simgrid::mc {
-/************************************* Take Snapshot ************************************/
-/****************************************************************************************/
-
-void Snapshot::snapshot_regions(RemoteProcessMemory& memory)
-{
-  snapshot_regions_.clear();
-
-  for (auto const& object_info : memory.object_infos)
-    add_region(RegionType::Data, memory, object_info.get(), object_info->start_rw,
-               object_info->end_rw - object_info->start_rw);
-
-  const s_xbt_mheap_t* heap = memory.get_heap();
-  void* start_heap = heap->base;
-  void* end_heap   = heap->breakval;
-
-  add_region(RegionType::Heap, memory, nullptr, start_heap, (char*)end_heap - (char*)start_heap);
-  heap_bytes_used_ = mmalloc_get_bytes_used_remote(heap->heaplimit, memory.get_malloc_info());
-}
-
-/** @brief Checks whether the variable is in scope for a given IP.
- *
- *  A variable may be defined only from a given value of IP.
- *
- *  @param var   Variable description
- *  @param scope Scope description
- *  @param ip    Instruction pointer
- *  @return      true if the variable is valid
- * */
-static bool valid_variable(const simgrid::mc::Variable* var, simgrid::mc::Frame* scope, const void* ip)
-{
-  // The variable is not yet valid:
-  if (scope->range.begin() + var->start_scope > (std::uint64_t)ip)
-    return false;
-  else
-    return true;
-}
-
-static void fill_local_variables_values(mc_stack_frame_t stack_frame, Frame* scope,
-                                        std::vector<s_local_variable_t>& result, AddressSpace* memory)
-{
-  if (not scope || not scope->range.contain(stack_frame->ip))
-    return;
-
-  for (const Variable& current_variable : scope->variables) {
-    if (not valid_variable(&current_variable, scope, (void*)stack_frame->ip))
-      continue;
-
-    if (not current_variable.type) {
-      XBT_VERB("Ignore local variable without type: '%s' [%s]", current_variable.name.c_str(),
-               stack_frame->frame->name.c_str());
-      continue;
-    }
-
-    s_local_variable_t new_var;
-    new_var.subprogram = stack_frame->frame;
-    new_var.ip         = stack_frame->ip;
-    new_var.name       = current_variable.name;
-    new_var.type       = current_variable.type;
-    new_var.address    = nullptr;
-
-    if (current_variable.address != nullptr)
-      new_var.address = current_variable.address;
-    else if (not current_variable.location_list.empty()) {
-      dwarf::Location location =
-          simgrid::dwarf::resolve(current_variable.location_list, current_variable.object_info,
-                                  &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, memory);
-
-      xbt_assert(location.in_memory(), "Cannot handle non-address variable");
-      new_var.address = location.address();
-    } else
-      xbt_die("No address");
-
-    result.push_back(std::move(new_var));
-  }
-
-  // Recursive processing of nested scopes:
-  for (Frame& nested_scope : scope->scopes)
-    fill_local_variables_values(stack_frame, &nested_scope, result, memory);
-}
-
-static std::vector<s_local_variable_t> get_local_variables_values(std::vector<s_mc_stack_frame_t>& stack_frames,
-                                                                  AddressSpace* memory)
-{
-  std::vector<s_local_variable_t> variables;
-  for (s_mc_stack_frame_t& stack_frame : stack_frames)
-    fill_local_variables_values(&stack_frame, stack_frame.frame, variables, memory);
-  return variables;
-}
-
-static std::vector<s_mc_stack_frame_t> unwind_stack_frames(UnwindContext* stack_context,
-                                                           const RemoteProcessMemory* process_memory)
-{
-  std::vector<s_mc_stack_frame_t> result;
-
-  unw_cursor_t c = stack_context->cursor();
-
-  // TODO, check condition check (unw_init_local==0 means end of frame)
-
-  while (true) {
-    s_mc_stack_frame_t stack_frame;
-
-    stack_frame.unw_cursor = c;
-
-    unw_word_t ip;
-    unw_word_t 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;
-
-    // TODO, use real addresses in frame_t instead of fixing it here
-
-    Frame* frame              = process_memory->find_function(remote(ip));
-    stack_frame.frame         = frame;
-
-    if (frame) {
-      stack_frame.frame_name = frame->name;
-      stack_frame.frame_base = (unw_word_t)frame->frame_base(c);
-    } else {
-      stack_frame.frame_base = 0;
-      stack_frame.frame_name = "";
-    }
-
-    result.push_back(std::move(stack_frame));
-
-    /* Stop before context switch with maestro */
-    if (frame != nullptr && frame->name == "smx_ctx_wrapper")
-      break;
-
-    int ret = unw_step(&c);
-    xbt_assert(ret >= 0, "Error while unwinding stack");
-    xbt_assert(ret != 0, "Unexpected end of stack.");
-  }
-
-  xbt_assert(not result.empty(), "unw_init_local failed");
-
-  return result;
-}
-
-void Snapshot::snapshot_stacks(RemoteProcessMemory& process_memory)
-{
-  for (auto const& stack : process_memory.stack_areas()) {
-    s_mc_snapshot_stack_t st;
-
-    // Read the context from remote process memory:
-    unw_context_t context;
-    process_memory.read_bytes(&context, sizeof(context), remote(stack.context));
-
-    st.context.initialize(process_memory, &context);
-
-    st.stack_frames    = unwind_stack_frames(&st.context, &process_memory);
-    st.local_variables = get_local_variables_values(st.stack_frames, &process_memory);
-
-    unw_word_t sp = st.stack_frames[0].sp;
-
-    stacks_.push_back(std::move(st));
-
-    size_t stack_size = (char*)stack.address + stack.size - (char*)sp;
-    stack_sizes_.push_back(stack_size);
-  }
-}
-
-void Snapshot::handle_ignore()
-{
-  xbt_assert(get_remote_process_memory());
-
-  // Copy the memory:
-  for (auto const& region : get_remote_process_memory()->ignored_regions()) {
-    s_mc_snapshot_ignored_data_t ignored_data;
-    ignored_data.start = (void*)region.addr;
-    ignored_data.data.resize(region.size);
-    get_remote_process_memory()->read_bytes(ignored_data.data.data(), region.size, remote(region.addr));
-    ignored_data_.push_back(std::move(ignored_data));
-  }
-
-  // Zero the memory:
-  for (auto const& region : get_remote_process_memory()->ignored_regions())
-    get_remote_process_memory()->clear_bytes(remote(region.addr), region.size);
-}
-
-void Snapshot::ignore_restore() const
-{
-  for (auto const& ignored_data : ignored_data_)
-    get_remote_process_memory()->write_bytes(ignored_data.data.data(), ignored_data.data.size(),
-                                             remote(ignored_data.start));
-}
-
-Snapshot::Snapshot(long num_state, PageStore& store, RemoteProcessMemory& memory)
-    : AddressSpace(&memory), page_store_(store), num_state_(num_state)
-{
-  XBT_DEBUG("Taking snapshot %ld", num_state);
-
-  handle_ignore();
-
-  /* Save the std heap and the writable mapped pages of libsimgrid and binary */
-  snapshot_regions(memory);
-
-  to_ignore_ = memory.ignored_heap();
-
-  if (_sg_mc_max_visited_states > 0 || not _sg_mc_property_file.get().empty()) {
-    snapshot_stacks(memory);
-    hash_ = this->do_hash();
-  }
-
-  ignore_restore();
-}
-
-void Snapshot::add_region(RegionType type, const RemoteProcessMemory& memory, ObjectInformation* object_info,
-                          void* start_addr, std::size_t size)
-{
-  if (type == RegionType::Data)
-    xbt_assert(object_info, "Missing object info for object.");
-  else if (type == RegionType::Heap)
-    xbt_assert(not object_info, "Unexpected object info for heap region.");
-
-  auto region = std::make_unique<Region>(page_store_, memory, type, start_addr, size);
-  region->object_info(object_info);
-  snapshot_regions_.push_back(std::move(region));
-}
-
-void* Snapshot::read_bytes(void* buffer, std::size_t size, RemotePtr<void> address, ReadOptions options) const
-{
-  const Region* region = this->get_region((void*)address.address());
-  if (region) {
-    void* res = region->read(buffer, (void*)address.address(), size);
-    if (buffer == res || options & ReadOptions::lazy())
-      return res;
-    else {
-      memcpy(buffer, res, size);
-      return buffer;
-    }
-  } else
-    return this->get_remote_process_memory()->read_bytes(buffer, size, address, options);
-}
-/** @brief Find the snapshotted region from a pointer
- *
- *  @param addr     Pointer
- * */
-Region* Snapshot::get_region(const void* addr) const
-{
-  size_t n = snapshot_regions_.size();
-  for (size_t i = 0; i != n; ++i) {
-    Region* region = snapshot_regions_[i].get();
-    if (not(region && region->contain(simgrid::mc::remote(addr))))
-      continue;
-
-    return region;
-  }
-
-  return nullptr;
-}
-
-/** @brief Find the snapshotted region from a pointer, with a hinted_region */
-Region* Snapshot::get_region(const void* addr, Region* hinted_region) const
-{
-  if (hinted_region->contain(simgrid::mc::remote(addr)))
-    return hinted_region;
-  else
-    return get_region(addr);
-}
-
-void Snapshot::restore(RemoteProcessMemory& memory) const
-{
-  XBT_DEBUG("Restore snapshot %ld", num_state_);
-
-  // Restore regions
-  for (std::unique_ptr<Region> const& region : snapshot_regions_) {
-    region->restore(memory);
-  }
-
-  ignore_restore();
-  memory.clear_cache();
-}
-
-/* ----------- Hashing logic -------------- */
-class djb_hash {
-  hash_type state_ = 5381LL;
-
-public:
-  template <class T> void update(T& x) { state_ = (state_ << 5) + state_ + x; }
-  hash_type value() const { return state_; }
-};
-hash_type Snapshot::do_hash() const
-{
-  XBT_DEBUG("START hash %ld", num_state_);
-  djb_hash hash;
-  // TODO:
-  // * nb_processes
-  // * heap_bytes_used
-  // * root variables
-  // * basic stack frame information
-  // * stack frame local variables
-  XBT_DEBUG("END hash %ld", num_state_);
-  return hash.value();
-}
-
-} // namespace simgrid::mc
diff --git a/src/mc/sosp/Snapshot.hpp b/src/mc/sosp/Snapshot.hpp
deleted file mode 100644 (file)
index 0b9fb57..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (c) 2007-2023. 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 SIMGRID_MC_SNAPSHOT_HPP
-#define SIMGRID_MC_SNAPSHOT_HPP
-
-#include "src/mc/inspect/mc_unw.hpp"
-#include "src/mc/sosp/Region.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-// ***** MC Snapshot
-
-/** Ignored data
- *
- *  Some parts of the snapshot are ignored by zeroing them out: the real values is stored here.
- */
-struct s_mc_snapshot_ignored_data_t {
-  void* start;
-  std::vector<char> data;
-};
-
-/** Information about a given stack frame */
-struct s_mc_stack_frame_t {
-  /** Instruction pointer */
-  unw_word_t ip;
-  /** Stack pointer */
-  unw_word_t sp;
-  unw_word_t frame_base;
-  simgrid::mc::Frame* frame;
-  std::string frame_name;
-  unw_cursor_t unw_cursor;
-};
-using mc_stack_frame_t = s_mc_stack_frame_t*;
-
-struct s_local_variable_t {
-  simgrid::mc::Frame* subprogram;
-  unsigned long ip;
-  std::string name;
-  simgrid::mc::Type* type;
-  void* address;
-};
-using local_variable_t       = s_local_variable_t*;
-using const_local_variable_t = const s_local_variable_t*;
-
-struct XBT_PRIVATE s_mc_snapshot_stack_t {
-  std::vector<s_local_variable_t> local_variables;
-  simgrid::mc::UnwindContext context;
-  std::vector<s_mc_stack_frame_t> stack_frames;
-};
-using mc_snapshot_stack_t       = s_mc_snapshot_stack_t*;
-using const_mc_snapshot_stack_t = const s_mc_snapshot_stack_t*;
-
-namespace simgrid::mc {
-
-using hash_type = std::uint64_t;
-
-class XBT_PRIVATE Snapshot final : public AddressSpace {
-  PageStore& page_store_;
-
-public:
-  /* Initialization */
-  Snapshot(long num_state, PageStore& store, RemoteProcessMemory& memory);
-
-  /* Regular use */
-  bool on_heap(const void* address) const
-  {
-    const s_xbt_mheap_t* heap = get_remote_process_memory()->get_heap();
-    return address >= heap->heapbase && address < heap->breakval;
-  }
-
-  void* read_bytes(void* buffer, std::size_t size, RemotePtr<void> address,
-                   ReadOptions options = ReadOptions::none()) const override;
-  Region* get_region(const void* addr) const;
-  Region* get_region(const void* addr, Region* hinted_region) const;
-  void restore(RemoteProcessMemory& memory) const;
-
-  bool equals_to(const Snapshot& other, RemoteProcessMemory& memory);
-
-  // To be private
-  long num_state_;
-  std::size_t heap_bytes_used_ = 0;
-  std::vector<std::unique_ptr<Region>> snapshot_regions_;
-  std::vector<std::size_t> stack_sizes_;
-  std::vector<s_mc_snapshot_stack_t> stacks_;
-  std::vector<simgrid::mc::IgnoredHeapRegion> to_ignore_;
-  std::uint64_t hash_ = 0;
-  std::vector<s_mc_snapshot_ignored_data_t> ignored_data_;
-
-private:
-  void add_region(RegionType type, const RemoteProcessMemory& memory, ObjectInformation* object_info, void* start_addr,
-                  std::size_t size);
-  void snapshot_regions(RemoteProcessMemory& memory);
-  void snapshot_stacks(RemoteProcessMemory& memory);
-  void handle_ignore();
-  void ignore_restore() const;
-  hash_type do_hash() const;
-};
-} // namespace simgrid::mc
-
-#endif
diff --git a/src/mc/sosp/Snapshot_test.cpp b/src/mc/sosp/Snapshot_test.cpp
deleted file mode 100644 (file)
index abf1dd0..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* Copyright (c) 2014-2023. 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 "src/3rd-party/catch.hpp"
-#include "src/mc/mc_config.hpp"
-#include "src/mc/sosp/Snapshot.hpp"
-
-#include <cstddef>
-#include <memory>
-#include <sys/mman.h>
-#include <xbt/random.hpp>
-
-class snap_test_helper {
-  simgrid::mc::PageStore page_store_{500};
-  simgrid::mc::RemoteProcessMemory memory_{getpid(), nullptr};
-
-  struct prologue_return {
-    size_t size;
-    std::byte* src;
-    std::byte* dstn;
-    std::unique_ptr<simgrid::mc::Region> region0;
-    std::unique_ptr<simgrid::mc::Region> region;
-  };
-  prologue_return prologue(int n); // common to the below 5 fxs
-
-  static void init_memory(std::byte* mem, size_t size);
-
-public:
-  void read_whole_region();
-  void read_region_parts();
-  void compare_whole_region();
-  void compare_region_parts();
-  void read_pointer();
-
-  static void basic_requirements();
-};
-
-void snap_test_helper::init_memory(std::byte* mem, size_t size)
-{
-  std::generate_n(mem, size, []() { return static_cast<std::byte>(simgrid::xbt::random::uniform_int(0, 0xff)); });
-}
-
-void snap_test_helper::basic_requirements()
-{
-  REQUIRE(xbt_pagesize == getpagesize());
-  REQUIRE(1 << xbt_pagebits == xbt_pagesize);
-}
-
-snap_test_helper::prologue_return snap_test_helper::prologue(int n)
-{
-  // Store region page(s):
-  size_t byte_size = n * xbt_pagesize;
-  auto* source =
-      static_cast<std::byte*>(mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
-  INFO("Could not allocate source memory");
-  REQUIRE(source != MAP_FAILED);
-
-  // Init memory and take snapshots:
-  init_memory(source, byte_size);
-  auto region0 =
-      std::make_unique<simgrid::mc::Region>(page_store_, memory_, simgrid::mc::RegionType::Data, source, byte_size);
-  for (int i = 0; i < n; i += 2) {
-    init_memory(source + i * xbt_pagesize, xbt_pagesize);
-  }
-  auto region =
-      std::make_unique<simgrid::mc::Region>(page_store_, memory_, simgrid::mc::RegionType::Data, source, byte_size);
-
-  auto* destination =
-      static_cast<std::byte*>(mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
-  INFO("Could not allocate destination memory");
-  REQUIRE(destination != MAP_FAILED);
-
-  return {.size    = byte_size,
-          .src     = source,
-          .dstn    = destination,
-          .region0 = std::move(region0),
-          .region  = std::move(region)};
-}
-
-void snap_test_helper::read_whole_region()
-{
-  for (int n = 1; n != 32; ++n) {
-    prologue_return ret = prologue(n);
-    const void* read    = ret.region->read(ret.dstn, ret.src, ret.size);
-    INFO("Mismatch in MC_region_read()");
-    REQUIRE(not memcmp(ret.src, read, ret.size));
-
-    munmap(ret.dstn, ret.size);
-    munmap(ret.src, ret.size);
-  }
-}
-
-void snap_test_helper::read_region_parts()
-{
-  for (int n = 1; n != 32; ++n) {
-    prologue_return ret = prologue(n);
-
-    for (int j = 0; j != 100; ++j) {
-      size_t offset    = simgrid::xbt::random::uniform_int(0, ret.size - 1);
-      size_t size      = simgrid::xbt::random::uniform_int(0, ret.size - offset - 1);
-      const void* read = ret.region->read(ret.dstn, (const char*)ret.src + offset, size);
-      INFO("Mismatch in MC_region_read()");
-      REQUIRE(not memcmp((char*)ret.src + offset, read, size));
-    }
-    munmap(ret.dstn, ret.size);
-    munmap(ret.src, ret.size);
-  }
-}
-
-void snap_test_helper::compare_whole_region()
-{
-  for (int n = 1; n != 32; ++n) {
-    prologue_return ret = prologue(n);
-
-    INFO("Unexpected match in MC_snapshot_region_memcmp() with previous snapshot");
-    REQUIRE(MC_snapshot_region_memcmp(ret.src, ret.region0.get(), ret.src, ret.region.get(), ret.size));
-
-    munmap(ret.dstn, ret.size);
-    munmap(ret.src, ret.size);
-  }
-}
-
-void snap_test_helper::compare_region_parts()
-{
-  for (int n = 1; n != 32; ++n) {
-    prologue_return ret = prologue(n);
-
-    for (int j = 0; j != 100; ++j) {
-      size_t offset = simgrid::xbt::random::uniform_int(0, ret.size - 1);
-      size_t size   = simgrid::xbt::random::uniform_int(0, ret.size - offset - 1);
-
-      INFO("Mismatch in MC_snapshot_region_memcmp()");
-      REQUIRE(not MC_snapshot_region_memcmp((char*)ret.src + offset, ret.region.get(), (char*)ret.src + offset,
-                                            ret.region.get(), size));
-    }
-    munmap(ret.dstn, ret.size);
-    munmap(ret.src, ret.size);
-  }
-}
-
-const int some_global_variable  = 42;
-const void* const some_global_pointer = &some_global_variable;
-void snap_test_helper::read_pointer()
-{
-  prologue_return ret = prologue(1);
-  memcpy(ret.src, &some_global_pointer, sizeof(void*));
-  const simgrid::mc::Region region2(page_store_, memory_, simgrid::mc::RegionType::Data, ret.src, ret.size);
-  INFO("Mismtach in MC_region_read_pointer()");
-  REQUIRE(MC_region_read_pointer(&region2, ret.src) == some_global_pointer);
-
-  munmap(ret.dstn, ret.size);
-  munmap(ret.src, ret.size);
-}
-
-/*************** End: class snap_test_helper *****************************/
-
-TEST_CASE("MC::Snapshot: A copy/snapshot of a given memory region", "MC::Snapshot")
-{
-  INFO("Sparse snapshot (using pages)");
-
-  snap_test_helper::basic_requirements();
-
-  snap_test_helper snap_test;
-
-  INFO("Read whole region");
-  snap_test.read_whole_region();
-
-  INFO("Read region parts");
-  snap_test.read_region_parts();
-
-  INFO("Compare whole region");
-  snap_test.compare_whole_region();
-
-  INFO("Compare region parts");
-  snap_test.compare_region_parts();
-
-  INFO("Read pointer");
-  snap_test.read_pointer();
-}
index 84ad991..fc3a5e2 100644 (file)
@@ -11,7 +11,7 @@
 
 #if SIMGRID_HAVE_MC
 #include "src/mc/explo/Exploration.hpp"
-#include "src/mc/transition/TransitionActorJoin.hpp"
+#include "src/mc/transition/TransitionActor.hpp"
 #include "src/mc/transition/TransitionAny.hpp"
 #include "src/mc/transition/TransitionComm.hpp"
 #include "src/mc/transition/TransitionObjectAccess.hpp"
@@ -95,6 +95,8 @@ Transition* deserialize_transition(aid_t issuer, int times_considered, std::stri
 
     case Transition::Type::ACTOR_JOIN:
       return new ActorJoinTransition(issuer, times_considered, stream);
+    case Transition::Type::ACTOR_SLEEP:
+      return new ActorSleepTransition(issuer, times_considered, stream);
 
     case Transition::Type::OBJECT_ACCESS:
       return new ObjectAccessTransition(issuer, times_considered, stream);
index 4bdf7d2..9a84024 100644 (file)
@@ -31,14 +31,23 @@ class Transition {
 
 public:
   /* Ordering is important here. depends() implementations only consider subsequent types in this ordering */
-  XBT_DECLARE_ENUM_CLASS(Type, RANDOM, ACTOR_JOIN, /* First because indep with anybody including themselves */
-                         OBJECT_ACCESS,            /* high priority because indep with almost everybody */
-                         TESTANY, WAITANY,         /* high priority because they can rewrite themselves to *_WAIT */
-                         BARRIER_ASYNC_LOCK, BARRIER_WAIT, /* BARRIER transitions sorted alphabetically */
-                         COMM_ASYNC_RECV, COMM_ASYNC_SEND, COMM_TEST, COMM_WAIT, /* Alphabetical ordering of COMM_* */
-                         MUTEX_ASYNC_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, /* alphabetical */
-                         SEM_ASYNC_LOCK, SEM_UNLOCK, SEM_WAIT, /* alphabetical ordering of SEM transitions */
-                         /* UNKNOWN must be last */ UNKNOWN);
+  XBT_DECLARE_ENUM_CLASS(Type,
+                         /* First because indep with anybody including themselves */
+                         RANDOM, ACTOR_JOIN, ACTOR_SLEEP,
+                         /* high priority because indep with almost everybody */
+                         OBJECT_ACCESS,
+                         /* high priority because they can rewrite themselves to *_WAIT */
+                         TESTANY, WAITANY,
+                         /* BARRIER transitions sorted alphabetically */
+                         BARRIER_ASYNC_LOCK, BARRIER_WAIT,
+                         /* Alphabetical ordering of COMM_* */
+                         COMM_ASYNC_RECV, COMM_ASYNC_SEND, COMM_TEST, COMM_WAIT,
+                         /* alphabetical */
+                         MUTEX_ASYNC_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT,
+                         /* alphabetical ordering of SEM transitions */
+                         SEM_ASYNC_LOCK, SEM_UNLOCK, SEM_WAIT,
+                         /* UNKNOWN must be last */
+                         UNKNOWN);
   Type type_ = Type::UNKNOWN;
 
   aid_t aid_ = 0;
similarity index 68%
rename from src/mc/transition/TransitionActorJoin.cpp
rename to src/mc/transition/TransitionActor.cpp
index 463bfcb..70608f1 100644 (file)
@@ -3,7 +3,7 @@
 /* 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 "src/mc/transition/TransitionActorJoin.hpp"
+#include "src/mc/transition/TransitionActor.hpp"
 #include "simgrid/config.h"
 #include "xbt/asserts.h"
 #include "xbt/string.hpp"
@@ -27,6 +27,10 @@ std::string ActorJoinTransition::to_string(bool verbose) const
 }
 bool ActorJoinTransition::depends(const Transition* other) const
 {
+  // Actions executed by the same actor are always dependent
+  if (other->aid_ == aid_)
+    return true;
+
   // Joining is dependent with any transition whose
   // actor is that of the `other` action. , Join i
   if (other->aid_ == target_) {
@@ -43,4 +47,23 @@ bool ActorJoinTransition::depends(const Transition* other) const
   return false;
 }
 
+ActorSleepTransition::ActorSleepTransition(aid_t issuer, int times_considered, std::stringstream& stream)
+    : Transition(Type::ACTOR_SLEEP, issuer, times_considered)
+{
+  XBT_DEBUG("ActorSleepTransition()");
+}
+std::string ActorSleepTransition::to_string(bool verbose) const
+{
+  return xbt::string_printf("ActorSleep()");
+}
+bool ActorSleepTransition::depends(const Transition* other) const
+{
+  // Actions executed by the same actor are always dependent
+  if (other->aid_ == aid_)
+    return true;
+
+  // Sleeping is indep with any other transitions: always enabled, not impacted by any transition
+  return false;
+}
+
 } // namespace simgrid::mc
similarity index 71%
rename from src/mc/transition/TransitionActorJoin.hpp
rename to src/mc/transition/TransitionActor.hpp
index 78bc765..34df441 100644 (file)
@@ -3,8 +3,8 @@
 /* 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 SIMGRID_MC_TRANSITION_ACTOR_JOIN_HPP
-#define SIMGRID_MC_TRANSITION_ACTOR_JOIN_HPP
+#ifndef SIMGRID_MC_TRANSITION_ACTOR_HPP
+#define SIMGRID_MC_TRANSITION_ACTOR_HPP
 
 #include "src/kernel/actor/SimcallObserver.hpp"
 #include "src/mc/transition/Transition.hpp"
@@ -29,6 +29,14 @@ public:
   aid_t get_target() const { return target_; }
 };
 
+class ActorSleepTransition : public Transition {
+
+public:
+  ActorSleepTransition(aid_t issuer, int times_considered, std::stringstream& stream);
+  std::string to_string(bool verbose) const override;
+  bool depends(const Transition* other) const override;
+};
+
 } // namespace simgrid::mc
 
 #endif
index 21ea4ec..bd57886 100644 (file)
@@ -32,7 +32,7 @@ bool BarrierTransition::depends(const Transition* o) const
   // Actions executed by the same actor are always dependent
   if (o->aid_ == aid_)
     return true;
-  
+
   if (const auto* other = dynamic_cast<const BarrierTransition*>(o)) {
     if (bar_ != other->bar_)
       return false;
@@ -128,7 +128,11 @@ bool SemaphoreTransition::depends(const Transition* o) const
   // Actions executed by the same actor are always dependent
   if (o->aid_ == aid_)
     return true;
+<<<<<<< HEAD
   
+=======
+
+>>>>>>> dfafe652e9ae62c35cd0fc084b117fc987b3e8dc
   if (const auto* other = dynamic_cast<const SemaphoreTransition*>(o)) {
     if (sem_ != other->sem_)
       return false;
index 412b69e..9639bf6 100644 (file)
@@ -6,10 +6,7 @@
 #include <simgrid/plugins/battery.hpp>
 #include <simgrid/plugins/energy.h>
 #include <simgrid/s4u/Engine.hpp>
-#include <simgrid/s4u/Host.hpp>
 #include <simgrid/simix.hpp>
-#include <xbt/asserts.h>
-#include <xbt/log.h>
 
 #include "src/kernel/resource/CpuImpl.hpp"
 #include "src/simgrid/module.hpp"
@@ -84,6 +81,12 @@ You can schedule handlers that will happen at specific SoC of the battery and tr
 Theses handlers may be recurrent, for instance you may want to always set all loads to zero and deactivate all hosts
 connections when the battery reaches 20% SoC.
 
+Connector
+.........
+
+A Battery can act as a connector to connect Solar Panels direcly to loads. Such Battery is created without any
+parameter, cannot store energy and has a transfer efficiency of 100%.
+
   @endrst
  */
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Battery, kernel, "Logging specific to the battery plugin");
@@ -107,6 +110,11 @@ void BatteryModel::update_actions_state(double now, double delta)
 
 double BatteryModel::next_occurring_event(double now)
 {
+  static bool init = false;
+  if (!init) {
+    init = true;
+    return 0;
+  }
   double time_delta = -1;
   for (auto battery : batteries_) {
     double time_delta_battery = battery->next_occurring_handler();
@@ -154,12 +162,15 @@ void Battery::update()
     double consumed_power_w = 0;
     for (auto const& [host, active] : host_loads_)
       provided_power_w += active ? sg_host_get_current_consumption(host) : 0;
-    for (auto const& [name, load] : named_loads_) {
-      if (load > 0)
-        provided_power_w += load;
+    for (auto const& [name, pair] : named_loads_) {
+      if (not pair.first)
+        continue;
+      if (pair.second > 0)
+        provided_power_w += pair.second;
       else
-        consumed_power_w += -load;
+        consumed_power_w += -pair.second;
     }
+
     provided_power_w = std::min(provided_power_w, nominal_discharge_power_w_ * discharge_efficiency_);
     consumed_power_w = std::min(consumed_power_w, -nominal_charge_power_w_);
 
@@ -182,6 +193,14 @@ void Battery::update()
     // Updating battery
     energy_provided_j_ += energy_lost_delta_j * discharge_efficiency_;
     energy_consumed_j_ += energy_gained_delta_j / charge_efficiency_;
+
+    // This battery is a simple connector, we only update energy provided and consumed
+    if (energy_budget_j_ == 0) {
+      energy_consumed_j_ = energy_provided_j_;
+      last_updated_      = now;
+      return;
+    }
+
     capacity_wh_ =
         initial_capacity_wh_ *
         (1 - (energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / energy_budget_j_);
@@ -210,11 +229,13 @@ double Battery::next_occurring_handler()
   double consumed_power_w = 0;
   for (auto const& [host, active] : host_loads_)
     provided_power_w += active ? sg_host_get_current_consumption(host) : 0;
-  for (auto const& [name, load] : named_loads_) {
-    if (load > 0)
-      provided_power_w += load;
+  for (auto const& [name, pair] : named_loads_) {
+    if (not pair.first)
+      continue;
+    if (pair.second > 0)
+      provided_power_w += pair.second;
     else
-      consumed_power_w += -load;
+      consumed_power_w += -pair.second;
   }
 
   provided_power_w = std::min(provided_power_w, nominal_discharge_power_w_ * discharge_efficiency_);
@@ -224,10 +245,11 @@ double Battery::next_occurring_handler()
   for (auto& handler : handlers_) {
     double lost_power_w   = provided_power_w / discharge_efficiency_;
     double gained_power_w = consumed_power_w * charge_efficiency_;
-    // Handler cannot happen
-    if ((lost_power_w == gained_power_w) or (handler->state_of_charge_ == energy_stored_j_ / (3600 * capacity_wh_)) or
-        (lost_power_w > gained_power_w and handler->flow_ == Flow::CHARGE) or
-        (lost_power_w < gained_power_w and handler->flow_ == Flow::DISCHARGE)) {
+    if ((lost_power_w == gained_power_w) or (handler->state_of_charge_ == get_state_of_charge()) or
+        (lost_power_w > gained_power_w and
+         (handler->flow_ == Flow::CHARGE or handler->state_of_charge_ > get_state_of_charge())) or
+        (lost_power_w < gained_power_w and
+         (handler->flow_ == Flow::DISCHARGE or handler->state_of_charge_ < get_state_of_charge()))) {
       continue;
     }
     // Evaluate time until handler happen
@@ -250,6 +272,8 @@ double Battery::next_occurring_handler()
   return time_delta;
 }
 
+Battery::Battery() {}
+
 Battery::Battery(const std::string& name, double state_of_charge, double nominal_charge_power_w,
                  double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency,
                  double initial_capacity_wh, int cycles)
@@ -263,7 +287,7 @@ Battery::Battery(const std::string& name, double state_of_charge, double nominal
     , capacity_wh_(initial_capacity_wh)
     , energy_stored_j_(state_of_charge * 3600 * initial_capacity_wh)
 {
-  xbt_assert(nominal_charge_power_w <= 0, " : nominal charge power must be non-negative (provided: %f)",
+  xbt_assert(nominal_charge_power_w <= 0, " : nominal charge power must be <= 0 (provided: %f)",
              nominal_charge_power_w);
   xbt_assert(nominal_discharge_power_w >= 0, " : nominal discharge power must be non-negative (provided: %f)",
              nominal_discharge_power_w);
@@ -277,11 +301,29 @@ Battery::Battery(const std::string& name, double state_of_charge, double nominal
   xbt_assert(cycles > 0, " : cycles should be > 0 (provided: %d)", cycles);
 }
 
+/** @ingroup plugin_battery
+ *  @brief Init a Battery with this constructor makes it only usable as a connector.
+ *         A connector has no capacity and only delivers as much power as it receives
+           with a transfer efficiency of 100%.
+ *  @return A BatteryPtr pointing to the new Battery.
+ */
+BatteryPtr Battery::init()
+{
+  static bool plugin_inited = false;
+  if (not plugin_inited) {
+    init_plugin();
+    plugin_inited = true;
+  }
+  auto battery = BatteryPtr(new Battery());
+  battery_model_->add_battery(battery);
+  return battery;
+}
+
 /** @ingroup plugin_battery
  *  @param name The name of the Battery.
  *  @param state_of_charge The initial state of charge of the Battery [0,1].
- *  @param nominal_charge_power_w The maximum power delivered by the Battery in W (<= 0).
- *  @param nominal_discharge_power_w The maximum power absorbed by the Battery in W (>= 0).
+ *  @param nominal_charge_power_w The maximum power absorbed by the Battery in W (<= 0).
+ *  @param nominal_discharge_power_w The maximum power delivered by the Battery in W (>= 0).
  *  @param charge_efficiency The charge efficiency of the Battery [0,1].
  *  @param discharge_efficiency The discharge efficiency of the Battery [0,1].
  *  @param initial_capacity_wh The initial capacity of the Battery in Wh (>0).
@@ -309,7 +351,21 @@ BatteryPtr Battery::init(const std::string& name, double state_of_charge, double
  */
 void Battery::set_load(const std::string& name, double power_w)
 {
-  named_loads_[name] = power_w;
+  kernel::actor::simcall_answered([this, &name, &power_w] {
+    if (named_loads_.find(name) == named_loads_.end())
+      named_loads_[name] = std::make_pair(true, power_w);
+    else
+      named_loads_[name].second = power_w;
+  });
+}
+
+/** @ingroup plugin_battery
+ *  @param name The name of the load
+ *  @param active Status of the load. If false then the load is ignored by the Battery.
+ */
+void Battery::set_load(const std::string& name, bool active)
+{
+  kernel::actor::simcall_answered([this, &name, &active] { named_loads_[name].first = active; });
 }
 
 /** @ingroup plugin_battery
@@ -322,7 +378,7 @@ void Battery::set_load(const std::string& name, double power_w)
  */
 void Battery::connect_host(s4u::Host* host, bool active)
 {
-  host_loads_[host] = active;
+  kernel::actor::simcall_answered([this, &host, &active] { host_loads_[host] = active; });
 }
 
 /** @ingroup plugin_battery
index 501f155..3cec29d 100644 (file)
@@ -34,7 +34,7 @@ from the heat of the other devices, such as lighing, accounted using a factor :m
 
   Q_{room} = (1 + \alpha) \times Q_{machines}
 
-This energy heats the input temperature :math:`T_{in}` and gives an output temperature :math:`T_{out}` based on the the
+This energy heats the input temperature :math:`T_{in}` and gives an output temperature :math:`T_{out}` based on the
 mass of air inside the room :math:`m_{air}` and its specific heat :math:`C_{p}`:
 
 .. math::
@@ -75,7 +75,12 @@ void ChillerModel::update_actions_state(double now, double delta)
 
 double ChillerModel::next_occurring_event(double now)
 {
-  return -1;
+  static bool init = false;
+  if (not init) {
+    init = true;
+    return 0;
+  } else
+    return -1;
 }
 
 /* Chiller */
@@ -99,30 +104,20 @@ void Chiller::update()
       return;
 
     double hosts_power_w = 0;
-    for (auto const& host : hosts_)
+    for (auto const& host : hosts_) {
       hosts_power_w += sg_host_get_current_consumption(host);
-    double heat_generated_j = hosts_power_w * (1 + alpha_) * time_delta_s;
-    temp_out_c_             = temp_in_c_ + heat_generated_j / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
-    double delta_temp_c     = temp_out_c_ - goal_temp_c_;
-
-    if (not active_ or delta_temp_c < 0) {
-      temp_in_c_    = temp_out_c_;
-      power_w_      = 0;
-      last_updated_ = now;
-      return;
-    }
-
-    double cooling_demand_w = delta_temp_c * air_mass_kg_ * specific_heat_j_per_kg_per_c_ / time_delta_s;
-    if (cooling_demand_w / cooling_efficiency_ <= max_power_w_) {
-      power_w_   = cooling_demand_w / cooling_efficiency_;
-      temp_in_c_ = temp_out_c_ -
-                   (power_w_ * time_delta_s * cooling_efficiency_) / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
-    } else {
-      power_w_   = max_power_w_;
-      temp_in_c_ = temp_out_c_ -
-                   (power_w_ * time_delta_s * cooling_efficiency_) / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
     }
 
+    double heat_generated_j = hosts_power_w * (1 + alpha_) * time_delta_s;
+    temp_out_c_             = temp_in_c_ + heat_generated_j / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
+    double cooling_demand_w =
+        std::max(temp_out_c_ - goal_temp_c_, 0.0) * air_mass_kg_ * specific_heat_j_per_kg_per_c_ / time_delta_s;
+    if (not active_)
+      power_w_ = 0;
+    else
+      power_w_ = std::min(max_power_w_, cooling_demand_w / cooling_efficiency_);
+    temp_in_c_ =
+        temp_out_c_ - (power_w_ * time_delta_s * cooling_efficiency_) / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
     energy_consumed_j_ += power_w_ * time_delta_s;
     last_updated_ = now;
   });
@@ -284,4 +279,26 @@ ChillerPtr Chiller::remove_host(s4u::Host* host)
   return this;
 }
 
+/** @ingroup plugin_chiller
+ *  @return The time to reach to goal temp, assuming that the system remain in the same state.
+ */
+double Chiller::get_time_to_goal_temp()
+{
+  if (goal_temp_c_ == temp_in_c_)
+    return 0;
+
+  double heat_power_w = 0;
+  for (auto const& host : hosts_)
+    heat_power_w += sg_host_get_current_consumption(host);
+  heat_power_w = heat_power_w * (1 + alpha_);
+
+  if (temp_in_c_ < goal_temp_c_)
+    return air_mass_kg_ * (goal_temp_c_ - temp_in_c_) * specific_heat_j_per_kg_per_c_ / heat_power_w;
+
+  if (not active_)
+    return -1;
+  else
+    return air_mass_kg_ * (temp_in_c_ - goal_temp_c_) * specific_heat_j_per_kg_per_c_ /
+           (power_w_ * cooling_efficiency_ - heat_power_w);
+}
 } // namespace simgrid::plugins
index 8e44734..c6f2581 100644 (file)
@@ -43,50 +43,24 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(SolarPanel, kernel, "Logging specific to the sol
 
 namespace simgrid::plugins {
 
-/* SolarPanelModel */
-
-SolarPanelModel::SolarPanelModel() : Model("SolarPanelModel") {}
-
-void SolarPanelModel::add_solar_panel(SolarPanelPtr b)
-{
-  solar_panels_.push_back(b);
-}
-
-void SolarPanelModel::update_actions_state(double now, double delta)
-{
-  for (auto solar_panel : solar_panels_)
-    solar_panel->update();
-}
-
-double SolarPanelModel::next_occurring_event(double now)
-{
-  return -1;
-}
+xbt::signal<void(SolarPanel*)> SolarPanel::on_power_change;
 
 /* SolarPanel */
 
-std::shared_ptr<SolarPanelModel> SolarPanel::solar_panel_model_;
-
-void SolarPanel::init_plugin()
-{
-  auto model = std::make_shared<SolarPanelModel>();
-  simgrid::s4u::Engine::get_instance()->add_model(model);
-  SolarPanel::solar_panel_model_ = model;
-}
-
 void SolarPanel::update()
 {
   simgrid::kernel::actor::simcall_answered([this] {
-    double now = simgrid::s4u::Engine::get_clock();
-    if (now <= last_updated_)
-      return;
     double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
-    if (power_w_ < min_power_w_)
+    if (power_w < min_power_w_)
       power_w = 0;
-    if (power_w_ > max_power_w_)
+    if (power_w > max_power_w_)
       power_w = max_power_w_;
-    power_w_      = power_w;
-    last_updated_ = now;
+    auto previous_power_w = power_w_;
+    power_w_              = power_w;
+    if (previous_power_w != power_w_) {
+      on_this_power_change(this);
+      on_power_change(this);
+    }
   });
 }
 
@@ -122,14 +96,9 @@ SolarPanel::SolarPanel(std::string name, double area_m2, double conversion_effic
 SolarPanelPtr SolarPanel::init(const std::string& name, double area_m2, double conversion_efficiency,
                                double solar_irradiance_w_per_m2, double min_power_w, double max_power_w)
 {
-  static bool plugin_inited = false;
-  if (not plugin_inited) {
-    init_plugin();
-    plugin_inited = true;
-  }
   auto solar_panel = SolarPanelPtr(
       new SolarPanel(name, area_m2, conversion_efficiency, solar_irradiance_w_per_m2, min_power_w, max_power_w));
-  solar_panel_model_->add_solar_panel(solar_panel);
+  solar_panel->update();
   return solar_panel;
 }
 
@@ -151,6 +120,7 @@ SolarPanelPtr SolarPanel::set_area(double area_m2)
 {
   xbt_assert(area_m2 >= 0, " : area must be > 0 (provided: %f)", area_m2);
   kernel::actor::simcall_answered([this, area_m2] { area_m2_ = area_m2; });
+  update();
   return this;
 }
 
@@ -162,6 +132,7 @@ SolarPanelPtr SolarPanel::set_conversion_efficiency(double e)
 {
   xbt_assert(e >= 0 and e <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", e);
   kernel::actor::simcall_answered([this, e] { conversion_efficiency_ = e; });
+  update();
   return this;
 }
 
@@ -175,6 +146,7 @@ SolarPanelPtr SolarPanel::set_solar_irradiance(double solar_irradiance_w_per_m2)
              solar_irradiance_w_per_m2);
   kernel::actor::simcall_answered(
       [this, solar_irradiance_w_per_m2] { solar_irradiance_w_per_m2_ = solar_irradiance_w_per_m2; });
+  update();
   return this;
 }
 
@@ -188,6 +160,7 @@ SolarPanelPtr SolarPanel::set_min_power(double power_w)
   xbt_assert(max_power_w_ > power_w, " : maximal power must be above minimal power (provided: %f, max: %f)", power_w,
              max_power_w_);
   kernel::actor::simcall_answered([this, power_w] { min_power_w_ = power_w; });
+  update();
   return this;
 }
 
@@ -201,6 +174,7 @@ SolarPanelPtr SolarPanel::set_max_power(double power_w)
   xbt_assert(min_power_w_ < power_w, " : maximal power must be above minimal power (provided: %f, min: %f)", power_w,
              min_power_w_);
   kernel::actor::simcall_answered([this, power_w] { max_power_w_ = power_w; });
+  update();
   return this;
 }
 
index 445364f..091b2a1 100644 (file)
@@ -9,6 +9,7 @@
 #include <simgrid/s4u/Engine.hpp>
 #include <simgrid/s4u/Exec.hpp>
 #include <simgrid/s4u/Io.hpp>
+#include <simgrid/s4u/Mess.hpp>
 #include <xbt/log.h>
 
 #include "src/kernel/activity/ActivityImpl.hpp"
@@ -52,6 +53,8 @@ Activity* Activity::wait_for(double timeout)
   if (state_ == State::FAILED) {
     if (dynamic_cast<Comm*>(this))
       throw NetworkFailureException(XBT_THROW_POINT, "Cannot wait for a failed comm");
+    if (dynamic_cast<Mess*>(this))
+      throw NetworkFailureException(XBT_THROW_POINT, "Cannot wait for a failed mess");
     if (dynamic_cast<Exec*>(this))
       throw HostFailureException(XBT_THROW_POINT, "Cannot wait for a failed exec");
     if (dynamic_cast<Io*>(this))
index e60f73d..573d708 100644 (file)
@@ -328,18 +328,22 @@ void sleep_for(double duration)
   }
 
   kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
+  kernel::actor::ActorSleepSimcall observer(issuer);
+
   Actor::on_sleep(*issuer->get_ciface());
   issuer->get_ciface()->on_this_sleep(*issuer->get_ciface());
 
-  kernel::actor::simcall_blocking([issuer, duration]() {
-    if (MC_is_active() || MC_record_replay_is_active()) {
-      MC_process_clock_add(issuer, duration);
-      issuer->simcall_answer();
-      return;
-    }
-    kernel::activity::ActivityImplPtr sync = issuer->sleep(duration);
-    sync->register_simcall(&issuer->simcall_);
-  });
+  kernel::actor::simcall_blocking(
+      [issuer, duration]() {
+        if (MC_is_active() || MC_record_replay_is_active()) {
+          // MC_process_clock_add(issuer, duration); // BUG: Makes the exploration loop
+          issuer->simcall_answer();
+        } else {
+          kernel::activity::ActivityImplPtr sync = issuer->sleep(duration);
+          sync->register_simcall(&issuer->simcall_);
+        }
+      },
+      &observer);
 
   Actor::on_wake_up(*issuer->get_ciface());
   issuer->get_ciface()->on_this_wake_up(*issuer->get_ciface());
index dc7e77f..094e831 100644 (file)
@@ -400,6 +400,20 @@ Mailbox* Engine::mailbox_by_name_or_create(const std::string& name) const
   return mbox->get_iface();
 }
 
+MessageQueue* Engine::message_queue_by_name_or_create(const std::string& name) const
+{
+  /* two actors may have pushed the same mbox_create simcall at the same time */
+  kernel::activity::MessageQueueImpl* queue = kernel::actor::simcall_answered([&name, this] {
+    auto [m, inserted] = pimpl_->mqueues_.try_emplace(name, nullptr);
+    if (inserted) {
+      m->second = new kernel::activity::MessageQueueImpl(name);
+      XBT_DEBUG("Creating a message queue at %p with name %s", m->second, name.c_str());
+    }
+    return m->second;
+  });
+  return queue->get_iface();
+}
+
 /** @brief Returns the amount of links in the platform */
 size_t Engine::get_link_count() const
 {
index a0482b5..e8aa898 100644 (file)
@@ -99,7 +99,7 @@ ssize_t Io::deprecated_wait_any_for(const std::vector<IoPtr>& ios, double timeou
 {
   ActivitySet set;
   for (const auto& io : ios)
-    set.push(boost::dynamic_pointer_cast<Activity>(io));
+    set.push(io);
 
   auto* ret = set.wait_any_for(timeout).get();
   for (size_t i = 0; i < ios.size(); i++)
diff --git a/src/s4u/s4u_Mess.cpp b/src/s4u/s4u_Mess.cpp
new file mode 100644 (file)
index 0000000..9799ad1
--- /dev/null
@@ -0,0 +1,153 @@
+/* Copyright (c) 2023. 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 <cmath>
+#include <simgrid/Exception.hpp>
+#include <simgrid/s4u/ActivitySet.hpp>
+#include <simgrid/s4u/Mess.hpp>
+#include <simgrid/s4u/Engine.hpp>
+#include <simgrid/s4u/MessageQueue.hpp>
+
+#include "src/kernel/activity/MessImpl.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
+#include "src/kernel/actor/SimcallObserver.hpp"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_mess, s4u_activity, "S4U asynchronous messaging");
+
+namespace simgrid::s4u {
+xbt::signal<void(Mess const&)> Mess::on_send;
+xbt::signal<void(Mess const&)> Mess::on_recv;
+
+MessPtr Mess::set_queue(MessageQueue* queue)
+{
+  queue_ = queue;
+  return this;
+}
+
+MessPtr Mess::set_payload(void* payload)
+{
+  payload_ = payload;
+  return this;
+}
+
+MessPtr Mess::set_dst_data(void** buff, size_t size)
+{
+  xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)",
+             __FUNCTION__);
+
+  dst_buff_      = buff;
+  dst_buff_size_ = size;
+  return this;
+}
+
+Actor* Mess::get_sender() const
+{
+  kernel::actor::ActorImplPtr sender = nullptr;
+  if (pimpl_)
+    sender = boost::static_pointer_cast<kernel::activity::MessImpl>(pimpl_)->src_actor_;
+  return sender ? sender->get_ciface() : nullptr;
+}
+
+Actor* Mess::get_receiver() const
+{
+  kernel::actor::ActorImplPtr receiver = nullptr;
+  if (pimpl_)
+    receiver = boost::static_pointer_cast<kernel::activity::MessImpl>(pimpl_)->dst_actor_;
+  return receiver ? receiver->get_ciface() : nullptr;
+}
+
+Mess* Mess::do_start()
+{
+  xbt_assert(get_state() == State::INITED || get_state() == State::STARTING,
+             "You cannot use %s() once your message exchange has started (not implemented)", __FUNCTION__);
+
+  auto myself = kernel::actor::ActorImpl::self();
+  if (myself == sender_) {
+    on_send(*this);
+    on_this_send(*this);
+    kernel::actor::MessIputSimcall observer{sender_, queue_->get_impl(), get_payload()};
+    pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iput(&observer); },
+                                             &observer);
+  } else if (myself == receiver_) {
+    on_recv(*this);
+    on_this_recv(*this);
+    kernel::actor::MessIgetSimcall observer{receiver_,
+                                            queue_->get_impl(),
+                                            static_cast<unsigned char*>(dst_buff_),
+                                            &dst_buff_size_,
+                                            get_payload()};
+    pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iget(&observer); },
+                                             &observer);
+  } else {
+    xbt_die("Cannot start a message exchange before specifying whether we are the sender or the receiver");
+  }
+
+  pimpl_->set_iface(this);
+  pimpl_->set_actor(sender_);
+  // Only throw the signal when both sides are here and the status is READY
+  if (pimpl_->get_state() != kernel::activity::State::WAITING) {
+    fire_on_start();
+    fire_on_this_start();
+  }
+  state_ = State::STARTED;
+  return this;
+}
+
+Mess* Mess::wait_for(double timeout)
+{
+  XBT_DEBUG("Calling Mess::wait_for with state %s", get_state_str());
+  kernel::actor::ActorImpl* issuer = nullptr;
+  switch (state_) {
+    case State::FINISHED:
+      break;
+    case State::FAILED:
+      throw NetworkFailureException(XBT_THROW_POINT, "Cannot wait for a failed communication");
+    case State::INITED:
+    case State::STARTING:
+      if (get_payload() != nullptr) {
+        on_send(*this);
+        on_this_send(*this);
+        kernel::actor::MessIputSimcall observer{sender_, queue_->get_impl(), get_payload()};
+        pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iput(&observer); },
+                                                 &observer);
+      } else { // Receiver
+        on_recv(*this);
+        on_this_recv(*this);
+        kernel::actor::MessIgetSimcall observer{receiver_,
+                                                queue_->get_impl(),
+                                                static_cast<unsigned char*>(dst_buff_),
+                                                &dst_buff_size_,
+                                                get_payload()};
+        pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iget(&observer); },
+                                                 &observer);
+      }
+      break;
+    case State::STARTED:
+      try {
+        issuer = kernel::actor::ActorImpl::self();
+        kernel::actor::ActivityWaitSimcall observer{issuer, pimpl_.get(), timeout, "Wait"};
+        if (kernel::actor::simcall_blocking(
+                [&observer] { observer.get_activity()->wait_for(observer.get_issuer(), observer.get_timeout()); },
+                &observer)) {
+          throw TimeoutException(XBT_THROW_POINT, "Timeouted");
+        }
+      } catch (const NetworkFailureException& e) {
+        issuer->simcall_.observer_ = nullptr; // Comm failed on network failure, reset the observer to nullptr
+        complete(State::FAILED);
+        e.rethrow_nested(XBT_THROW_POINT, boost::core::demangle(typeid(e).name()) + " raised in kernel mode.");
+      }
+      break;
+
+    case State::CANCELED:
+      throw CancelException(XBT_THROW_POINT, "Message canceled");
+
+    default:
+      THROW_IMPOSSIBLE;
+  }
+  complete(State::FINISHED);
+  return this;
+}
+
+} // namespace simgrid::s4u
diff --git a/src/s4u/s4u_MessageQueue.cpp b/src/s4u/s4u_MessageQueue.cpp
new file mode 100644 (file)
index 0000000..8fe34ac
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (c) 2023. 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 <simgrid/s4u/Engine.hpp>
+#include <simgrid/s4u/Mess.hpp>
+#include <simgrid/s4u/MessageQueue.hpp>
+
+#include "src/kernel/activity/MessageQueueImpl.hpp"
+
+XBT_LOG_EXTERNAL_CATEGORY(s4u);
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_mqueue, s4u, "S4U Message Queues");
+
+namespace simgrid::s4u {
+
+const std::string& MessageQueue::get_name() const
+{
+  return pimpl_->get_name();
+}
+
+const char* MessageQueue::get_cname() const
+{
+  return pimpl_->get_cname();
+}
+
+MessageQueue* MessageQueue::by_name(const std::string& name)
+{
+  return Engine::get_instance()->message_queue_by_name_or_create(name);
+}
+
+bool MessageQueue::empty() const
+{
+  return pimpl_->empty();
+}
+
+size_t MessageQueue::size() const
+{
+  return pimpl_->size();
+}
+
+kernel::activity::MessImplPtr MessageQueue::front() const
+{
+  return pimpl_->empty() ? nullptr : pimpl_->front();
+}
+
+MessPtr MessageQueue::put_init()
+{
+  MessPtr res(new Mess());
+  res->set_queue(this);
+  res->sender_ = kernel::actor::ActorImpl::self();
+  return res;
+}
+
+MessPtr MessageQueue::put_init(void* payload)
+{
+  return put_init()->set_payload(payload);
+}
+
+MessPtr MessageQueue::put_async(void* payload)
+{
+  xbt_assert(payload != nullptr, "You cannot send nullptr");
+  MessPtr res = put_init(payload);
+  res->start();
+  return res;
+}
+
+void MessageQueue::put(void* payload)
+{
+  xbt_assert(payload != nullptr, "You cannot send nullptr");
+
+  put_async(payload)->wait();
+}
+
+/** Blocking send with timeout */
+void MessageQueue::put(void* payload, double timeout)
+{
+  xbt_assert(payload != nullptr, "You cannot send nullptr");
+
+  put_init()->set_payload(payload)->start()->wait_for(timeout);
+}
+
+MessPtr MessageQueue::get_init()
+{
+  MessPtr res(new Mess());
+  res->set_queue(this);
+  res->receiver_ = kernel::actor::ActorImpl::self();
+  return res;
+}
+
+MessPtr MessageQueue::get_async()
+{
+  MessPtr res = get_init()->set_payload(nullptr);
+  res->start();
+  return res;
+}
+
+} // namespace simgrid::s4u
index 051f11c..12fa915 100644 (file)
@@ -55,9 +55,9 @@ bool Mutex::try_lock()
  *
  * See @ref s4u_raii.
  */
-MutexPtr Mutex::create()
+MutexPtr Mutex::create(bool recursive)
 {
-  auto* mutex = new kernel::activity::MutexImpl();
+  auto* mutex = new kernel::activity::MutexImpl(recursive);
   return MutexPtr(&mutex->mutex(), false);
 }
 
index 48377bb..1917f0f 100644 (file)
@@ -96,8 +96,8 @@ void NetZone::add_route(const NetZone* src, const NetZone* dst, const std::vecto
   pimpl_->add_route(src ? src->get_netpoint() : nullptr, dst ? dst->get_netpoint(): nullptr,
                     src ? src->get_gateway() : nullptr, dst ? dst->get_gateway() : nullptr,
                     links_direct, false);
-  pimpl_->add_route(src ? src->get_netpoint() : nullptr, dst ? dst->get_netpoint(): nullptr,
-                    src ? src->get_gateway() : nullptr, dst ? dst->get_gateway() : nullptr,
+  pimpl_->add_route(dst ? dst->get_netpoint(): nullptr, src ? src->get_netpoint() : nullptr,
+                    dst ? dst->get_gateway() : nullptr, src ? src->get_gateway() : nullptr,
                     links_reverse, false);
 }
 
index 98e0648..5902d70 100644 (file)
@@ -20,7 +20,6 @@
 #include "src/simgrid/module.hpp"
 #include "src/simgrid/sg_config.hpp"
 #include "src/smpi/include/smpi_config.hpp"
-#include "src/xbt/mmalloc/mmalloc.h"
 
 #include <string_view>
 
@@ -202,15 +201,8 @@ void sg_config_init(int *argc, char **argv)
       [](int value) { simgrid::kernel::context::Context::guard_size = value * xbt_pagesize; }};
 
   static simgrid::config::Flag<int> cfg_context_nthreads{
-      "contexts/nthreads", "Number of parallel threads used to execute user contexts", 1, [](int nthreads) {
-#if HAVE_MMALLOC
-        xbt_assert(
-            nthreads == 1 || not malloc_use_mmalloc(),
-            "Parallel simulation is forbidden in the verified program, as there is no protection against race "
-            "conditions in mmalloc itself. Please don't be so greedy and show some mercy for our implementation.");
-#endif
-        simgrid::kernel::context::Context::set_nthreads(nthreads);
-      }};
+      "contexts/nthreads", "Number of parallel threads used to execute user contexts", 1,
+      [](int nthreads) { simgrid::kernel::context::Context::set_nthreads(nthreads); }};
 
   /* synchronization mode for parallel user contexts */
 #if HAVE_FUTEX_H
index 10dbe7b..25e4a16 100644 (file)
@@ -10,7 +10,7 @@
 
 /** Config Globals */
 
-XBT_PUBLIC_DATA int _sg_cfg_init_status;
+XBT_PUBLIC_DATA int _sg_cfg_init_status; /* 0: not inited; 1: config module inited; 2: root zone of platform created */
 
 XBT_PUBLIC void sg_config_init(int* argc, char** argv);
 XBT_PUBLIC void sg_config_finalize();
index 1428132..953f6b1 100644 (file)
@@ -50,12 +50,6 @@ void sg_version()
   XBT_HELP("This program was linked against %s (git: %s), found in %s.", SIMGRID_VERSION_STRING, SIMGRID_GIT_VERSION,
            SIMGRID_INSTALL_PREFIX);
 
-#if SIMGRID_HAVE_STATEFUL_MC
-  XBT_HELP("   Stateful model-checking support compiled in.");
-#else
-  XBT_HELP("   Stateful model-checking support disabled at compilation.");
-#endif
-
 #if SIMGRID_HAVE_NS3
   XBT_HELP("   ns-3 support compiled in.");
 #else
index 3bd52c7..7e62ffa 100644 (file)
@@ -501,3 +501,9 @@ UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Unpack_external,(char *datarep, void *in
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Unpublish_name,( char *service_name, MPI_Info info, char *port_name),( service_name, info, port_name))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Win_test,(MPI_Win win, int *flag),(win, flag))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL_NOFAIL(int,MPI_Win_sync,(MPI_Win win),(win))
+UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Parrived, (MPI_Request request, int partition, int *flag), (request, partition, flag))
+UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Pready, (int partitions, MPI_Request request), (partitions, request))
+UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Pready_range, (int partition_low, int partition_high, MPI_Request request),(partition_low, partition_high, request))
+UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Pready_list, (int length, int partition_list[], MPI_Request request), (length, partition_list, request))
+UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Precv_init, (void* buf, int partitions, MPI_Count count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Info info, MPI_Request *request), (buf, partitions, count, datatype, source, tag, comm, info, request))
+UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Psend_init, (const void* buf, int partitions, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Info info, MPI_Request *request), (buf, partitions, count, datatype, dest, tag, comm, info, request))
index 94bb62b..8cf9b41 100644 (file)
@@ -381,6 +381,8 @@ int PMPI_Sendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int
   CHECK_TYPE(8, recvtype)
   CHECK_BUFFER(1, sendbuf, sendcount, sendtype)
   CHECK_BUFFER(6, recvbuf, recvcount, recvtype)
+  CHECK_ARGS(sendbuf == recvbuf && sendcount > 0 && recvcount > 0, MPI_ERR_BUFFER,
+             "%s: Invalid parameters 1 and 6: sendbuf and recvbuf must be disjoint", __func__);
   CHECK_TAG(10, recvtag)
   CHECK_COMM(11)
   const SmpiBenchGuard suspend_bench;
index 2cd94c9..056cecf 100644 (file)
@@ -32,7 +32,6 @@ ActorExt::ActorExt(s4u::Actor* actor) : actor_(actor)
   timer_           = xbt_os_timer_new();
   state_           = SmpiProcessState::UNINITIALIZED;
   info_env_        = MPI_INFO_NULL;
-  MC_ignore_heap(timer_, xbt_os_timer_size());
 
 #if HAVE_PAPI
   if (not smpi_cfg_papi_events_file().empty()) {
index 36a3e39..10203cb 100644 (file)
@@ -59,51 +59,51 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, "Logging specific to SMPI (ke
  * See https://www.akkadia.org/drepper/dsohowto.pdf
  * and https://lists.freebsd.org/pipermail/freebsd-current/2016-March/060284.html
 */
-#if !RTLD_DEEPBIND || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD
+#if !defined(RTLD_DEEPBIND) || !RTLD_DEEPBIND || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD
 #define WANT_RTLD_DEEPBIND 0
 #else
 #define WANT_RTLD_DEEPBIND RTLD_DEEPBIND
 #endif
 
 #if HAVE_PAPI
-std::map</* computation unit name */ std::string, papi_process_data, std::less<>> units2papi_setup;
+  std::map</* computation unit name */ std::string, papi_process_data, std::less<>> units2papi_setup;
 #endif
 
-std::unordered_map<std::string, double> location2speedup;
+  std::unordered_map<std::string, double> location2speedup;
 
-static int smpi_exit_status = 0;
-static xbt_os_timer_t global_timer;
-static std::vector<std::string> privatize_libs_paths;
+  static int smpi_exit_status = 0;
+  static xbt_os_timer_t global_timer;
+  static std::vector<std::string> privatize_libs_paths;
 
-// No instance gets manually created; check also the smpirun.in script as
-// this default name is used there as well (when the <actor> tag is generated).
-static const std::string smpi_default_instance_name("smpirun");
+  // No instance gets manually created; check also the smpirun.in script as
+  // this default name is used there as well (when the <actor> tag is generated).
+  static const std::string smpi_default_instance_name("smpirun");
 
-static simgrid::config::Flag<std::string>
-    smpi_hostfile("smpi/hostfile",
-                  "Classical MPI hostfile containing list of machines to dispatch "
-                  "the processes, one per line",
-                  "");
+  static simgrid::config::Flag<std::string>
+      smpi_hostfile("smpi/hostfile",
+                    "Classical MPI hostfile containing list of machines to dispatch "
+                    "the processes, one per line",
+                    "");
 
-static simgrid::config::Flag<std::string> smpi_replay("smpi/replay",
-                                                      "Replay a trace instead of executing the application", "");
+  static simgrid::config::Flag<std::string> smpi_replay("smpi/replay",
+                                                        "Replay a trace instead of executing the application", "");
 
-static simgrid::config::Flag<int> smpi_np("smpi/np", "Number of processes to be created", 0);
+  static simgrid::config::Flag<int> smpi_np("smpi/np", "Number of processes to be created", 0);
 
-static simgrid::config::Flag<int> smpi_map("smpi/map", "Display the mapping between nodes and processes", 0);
+  static simgrid::config::Flag<int> smpi_map("smpi/map", "Display the mapping between nodes and processes", 0);
 
-std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)> smpi_comm_copy_data_callback =
-    &smpi_comm_copy_buffer_callback;
+  std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)> smpi_comm_copy_data_callback =
+      &smpi_comm_copy_buffer_callback;
 
-simgrid::smpi::ActorExt* smpi_process()
-{
-  simgrid::s4u::ActorPtr me = simgrid::s4u::Actor::self();
+  simgrid::smpi::ActorExt* smpi_process()
+  {
+    simgrid::s4u::ActorPtr me = simgrid::s4u::Actor::self();
 
-  if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
-    return nullptr;
+    if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
+      return nullptr;
 
-  return me->extension<simgrid::smpi::ActorExt>();
-}
+    return me->extension<simgrid::smpi::ActorExt>();
+  }
 
 simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor)
 {
index 642aa24..539e567 100644 (file)
@@ -116,7 +116,6 @@ Datatype::Datatype(int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags) : D
 Datatype::Datatype(int size, MPI_Aint lb, MPI_Aint ub, int flags) : size_(size), lb_(lb), ub_(ub), flags_(flags)
 {
   this->add_f();
-  MC_ignore(&refcount_, sizeof refcount_);
 }
 
 // for predefined types, so refcount_ = 0.
@@ -124,7 +123,6 @@ Datatype::Datatype(const char* name, int ident, int size, MPI_Aint lb, MPI_Aint
     : name_(name), id(std::to_string(ident)), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0)
 {
   id2type_lookup.try_emplace(id, this);
-  MC_ignore(&refcount_, sizeof refcount_);
 }
 
 Datatype::Datatype(Datatype* datatype, int* ret)
@@ -205,14 +203,12 @@ int Datatype::clone(MPI_Datatype* type){
 void Datatype::ref()
 {
   refcount_++;
-  MC_ignore(&refcount_, sizeof refcount_);
 }
 
 void Datatype::unref(MPI_Datatype datatype)
 {
   if (datatype->refcount_ > 0)
     datatype->refcount_--;
-  MC_ignore(&datatype->refcount_, sizeof datatype->refcount_);
 
   if (datatype->refcount_ == 0 && not(datatype->flags_ & DT_FLAG_PREDEFINED))
     delete datatype;
index 6e38668..25e9b52 100644 (file)
@@ -51,6 +51,7 @@ struct ObjectOwner {
   simgrid::kernel::actor::ActorImpl* owner = nullptr;
   const char* file                         = nullptr;
   int line                                 = -1;
+  int recursive_depth                      = 0;
   explicit ObjectOwner(simgrid::kernel::actor::ActorImpl* o) : owner(o) {}
 };
 
@@ -73,7 +74,7 @@ static ObjectOwner* get_owner(void* object)
   return o;
 }
 
-int sthread_access_begin(void* objaddr, const char* objname, const char* file, int line)
+int sthread_access_begin(void* objaddr, const char* objname, const char* file, int line, const char* func)
 {
   sthread_disable();
   auto* self = simgrid::kernel::actor::ActorImpl::self();
@@ -83,10 +84,23 @@ int sthread_access_begin(void* objaddr, const char* objname, const char* file, i
       [self, objaddr, objname, file, line]() -> bool {
         XBT_INFO("%s takes %s", self->get_cname(), objname);
         auto* ownership = get_owner(objaddr);
-        if (ownership->owner != nullptr) {
+        if (ownership->owner == self) {
+          ownership->recursive_depth++;
+          return true;
+        } else if (ownership->owner != nullptr) {
           auto msg = std::string("Unprotected concurent access to ") + objname + ": " + ownership->owner->get_name();
-          if (not xbt_log_no_loc)
+          if (not xbt_log_no_loc) {
             msg += simgrid::xbt::string_printf(" at %s:%d", ownership->file, ownership->line);
+            if (ownership->recursive_depth > 1) {
+              msg += simgrid::xbt::string_printf(" (and %d other locations)", ownership->recursive_depth - 1);
+              if (ownership->recursive_depth != 2)
+                msg += "s";
+            }
+          } else {
+            msg += simgrid::xbt::string_printf(" from %d location", ownership->recursive_depth);
+            if (ownership->recursive_depth != 1)
+              msg += "s";
+          }
           msg += " vs " + self->get_name();
           if (xbt_log_no_loc)
             msg += std::string(" (locations hidden because of --log=no_loc).");
@@ -98,6 +112,7 @@ int sthread_access_begin(void* objaddr, const char* objname, const char* file, i
         ownership->owner = self;
         ownership->file  = file;
         ownership->line  = line;
+        ownership->recursive_depth = 1;
         return true;
       },
       &observer);
@@ -106,7 +121,7 @@ int sthread_access_begin(void* objaddr, const char* objname, const char* file, i
   sthread_enable();
   return true;
 }
-void sthread_access_end(void* objaddr, const char* objname, const char* file, int line)
+void sthread_access_end(void* objaddr, const char* objname, const char* file, int line, const char* func)
 {
   sthread_disable();
   auto* self = simgrid::kernel::actor::ActorImpl::self();
@@ -116,9 +131,12 @@ void sthread_access_end(void* objaddr, const char* objname, const char* file, in
       [self, objaddr, objname]() -> void {
         XBT_INFO("%s releases %s", self->get_cname(), objname);
         auto* ownership = get_owner(objaddr);
-        xbt_assert(ownership->owner == self, "safety check failed: %s is not owner of the object it's releasing.",
-                   self->get_cname());
-        ownership->owner = nullptr;
+        xbt_assert(ownership->owner == self,
+                   "safety check failed: %s is not owner of the object it's releasing. That object owned by %s.",
+                   self->get_cname(), (ownership->owner == nullptr ? "nobody" : ownership->owner->get_cname()));
+        ownership->recursive_depth--;
+        if (ownership->recursive_depth == 0)
+          ownership->owner = nullptr;
       },
       &observer);
   sthread_enable();
index ee9e084..2005f29 100644 (file)
@@ -28,6 +28,12 @@ static int (*raw_mutex_trylock)(pthread_mutex_t*);
 static int (*raw_mutex_unlock)(pthread_mutex_t*);
 static int (*raw_mutex_destroy)(pthread_mutex_t*);
 
+static int (*raw_pthread_mutexattr_init)(pthread_mutexattr_t*);
+static int (*raw_pthread_mutexattr_settype)(pthread_mutexattr_t*, int);
+static int (*raw_pthread_mutexattr_gettype)(const pthread_mutexattr_t* restrict, int* restrict);
+static int (*raw_pthread_mutexattr_getrobust)(const pthread_mutexattr_t*, int*);
+static int (*raw_pthread_mutexattr_setrobust)(pthread_mutexattr_t*, int);
+
 static unsigned int (*raw_sleep)(unsigned int);
 static int (*raw_usleep)(useconds_t);
 static int (*raw_gettimeofday)(struct timeval*, void*);
@@ -50,6 +56,12 @@ static void intercepter_init()
   raw_mutex_unlock   = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
   raw_mutex_destroy  = dlsym(RTLD_NEXT, "pthread_mutex_destroy");
 
+  raw_pthread_mutexattr_init      = dlsym(RTLD_NEXT, "pthread_mutexattr_init");
+  raw_pthread_mutexattr_settype   = dlsym(RTLD_NEXT, "pthread_mutexattr_settype");
+  raw_pthread_mutexattr_gettype   = dlsym(RTLD_NEXT, "pthread_mutexattr_gettype");
+  raw_pthread_mutexattr_getrobust = dlsym(RTLD_NEXT, "pthread_mutexattr_getrobust");
+  raw_pthread_mutexattr_setrobust = dlsym(RTLD_NEXT, "pthread_mutexattr_setrobust");
+
   raw_sleep        = dlsym(RTLD_NEXT, "sleep");
   raw_usleep       = dlsym(RTLD_NEXT, "usleep");
   raw_gettimeofday = dlsym(RTLD_NEXT, "gettimeofday");
@@ -85,6 +97,32 @@ int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_
   sthread_enable();
   return res;
 }
+
+#define _STHREAD_CONCAT(a, b) a##b
+#define intercepted_call(name, raw_params, call_params, sim_params)                                                    \
+  int _STHREAD_CONCAT(pthread_, name) raw_params                                                                       \
+  {                                                                                                                    \
+    if (_STHREAD_CONCAT(raw_pthread_, name) == NULL)                                                                   \
+      intercepter_init();                                                                                              \
+    if (sthread_inside_simgrid)                                                                                        \
+      return _STHREAD_CONCAT(raw_pthread_, name) call_params;                                                          \
+                                                                                                                       \
+    sthread_disable();                                                                                                 \
+    int res = _STHREAD_CONCAT(sthread_, name) sim_params;                                                              \
+    sthread_enable();                                                                                                  \
+    return res;                                                                                                        \
+  }
+
+intercepted_call(mutexattr_init, (pthread_mutexattr_t * attr), (attr), ((sthread_mutexattr_t*)attr));
+intercepted_call(mutexattr_settype, (pthread_mutexattr_t * attr, int type), (attr, type),
+                 ((sthread_mutexattr_t*)attr, type));
+intercepted_call(mutexattr_gettype, (const pthread_mutexattr_t* restrict attr, int* type), (attr, type),
+                 ((sthread_mutexattr_t*)attr, type));
+intercepted_call(mutexattr_setrobust, (pthread_mutexattr_t* restrict attr, int robustness), (attr, robustness),
+                 ((sthread_mutexattr_t*)attr, robustness));
+intercepted_call(mutexattr_getrobust, (const pthread_mutexattr_t* restrict attr, int* restrict robustness),
+                 (attr, robustness), ((sthread_mutexattr_t*)attr, robustness));
+
 int pthread_join(pthread_t thread, void** retval)
 {
   if (raw_pthread_join == NULL)
@@ -107,7 +145,7 @@ int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr)
     return raw_mutex_init(mutex, attr);
 
   sthread_disable();
-  int res = sthread_mutex_init((sthread_mutex_t*)mutex, attr);
+  int res = sthread_mutex_init((sthread_mutex_t*)mutex, (sthread_mutexattr_t*)attr);
   sthread_enable();
   return res;
 }
index 6527968..f0a9117 100644 (file)
@@ -31,10 +31,22 @@ typedef unsigned long int sthread_t;
 int sthread_create(sthread_t* thread, const /*pthread_attr_t*/ void* attr, void* (*start_routine)(void*), void* arg);
 int sthread_join(sthread_t thread, void** retval);
 
+typedef struct {
+  unsigned recursive : 1;
+  unsigned errorcheck : 1;
+  unsigned robust : 1;
+} sthread_mutexattr_t;
+
+int sthread_mutexattr_init(sthread_mutexattr_t* attr);
+int sthread_mutexattr_settype(sthread_mutexattr_t* attr, int type);
+int sthread_mutexattr_gettype(const sthread_mutexattr_t* attr, int* type);
+int sthread_mutexattr_getrobust(const sthread_mutexattr_t* attr, int* robustness);
+int sthread_mutexattr_setrobust(sthread_mutexattr_t* attr, int robustness);
+
 typedef struct {
   void* mutex;
 } sthread_mutex_t;
-int sthread_mutex_init(sthread_mutex_t* mutex, const /*pthread_mutexattr_t*/ void* attr);
+int sthread_mutex_init(sthread_mutex_t* mutex, const sthread_mutexattr_t* attr);
 int sthread_mutex_lock(sthread_mutex_t* mutex);
 int sthread_mutex_trylock(sthread_mutex_t* mutex);
 int sthread_mutex_unlock(sthread_mutex_t* mutex);
@@ -53,8 +65,8 @@ int sthread_sem_timedwait(sthread_sem_t* sem, const struct timespec* abs_timeout
 int sthread_gettimeofday(struct timeval* tv);
 void sthread_sleep(double seconds);
 
-int sthread_access_begin(void* objaddr, const char* objname, const char* file, int line);
-void sthread_access_end(void* objaddr, const char* objname, const char* file, int line);
+int sthread_access_begin(void* objaddr, const char* objname, const char* file, int line, const char* function);
+void sthread_access_end(void* objaddr, const char* objname, const char* file, int line, const char* function);
 
 #if defined(__cplusplus)
 }
index 45ba730..9dbf789 100644 (file)
@@ -6,6 +6,9 @@
 /* SimGrid's pthread interposer. Actual implementation of the symbols (see the comment in sthread.h) */
 
 #include "smpi/smpi.h"
+#include "xbt/asserts.h"
+#include "xbt/ex.h"
+#include "xbt/log.h"
 #include "xbt/string.hpp"
 #include <simgrid/actor.h>
 #include <simgrid/s4u/Actor.hpp>
@@ -38,14 +41,22 @@ int sthread_main(int argc, char** argv, char** envp, int (*raw_main)(int, char**
 {
   /* Do not intercept the main when run from SMPI: it will initialize the simulation properly */
   for (int i = 0; envp[i] != nullptr; i++)
-    if (std::string_view(envp[i]).rfind("SMPI_GLOBAL_SIZE", 0) == 0)
+    if (std::string_view(envp[i]).rfind("SMPI_GLOBAL_SIZE", 0) == 0) {
+      printf("sthread refuses to intercept the SMPI application %s directly, as its interception is done otherwise.\n",
+             argv[0]);
       return raw_main(argc, argv, envp);
+    }
 
-  /* If not in SMPI, the old main becomes an actor in a newly created simulation */
-  std::ostringstream id;
-  id << std::this_thread::get_id();
+  /* Do not intercept valgrind step 1 */
+  if (not strcmp(argv[0], "/usr/bin/valgrind.bin") || not strcmp(argv[0], "/bin/sh")) {
+    printf("sthread refuses to intercept the execution of %s. Running the application unmodified.\n", argv[0]);
+    fflush(stdout);
+    return raw_main(argc, argv, envp);
+  }
 
-  XBT_DEBUG("sthread main() is starting in thread %s", id.str().c_str());
+  /* If not in SMPI, the old main becomes an actor in a newly created simulation */
+  printf("sthread is intercepting the execution of %s\n", argv[0]);
+  fflush(stdout);
 
   sg4::Engine e(&argc, argv);
   auto* zone = sg4::create_full_zone("world");
@@ -56,7 +67,6 @@ int sthread_main(int argc, char** argv, char** envp, int (*raw_main)(int, char**
   sthread_enable();
   sg4::ActorPtr main_actor = sg4::Actor::create("main thread", lilibeth, raw_main, argc, argv, envp);
 
-  XBT_INFO("Starting the simulation.");
   sg4::Engine::get_instance()->run();
   sthread_disable();
   XBT_INFO("All threads exited. Terminating the simulation.");
@@ -108,9 +118,57 @@ int sthread_join(sthread_t thread, void** /*retval*/)
   return 0;
 }
 
-int sthread_mutex_init(sthread_mutex_t* mutex, const void* /*pthread_mutexattr_t* attr*/)
+int sthread_mutexattr_init(sthread_mutexattr_t* attr)
+{
+  memset(attr, 0, sizeof(*attr));
+  return 0;
+}
+int sthread_mutexattr_settype(sthread_mutexattr_t* attr, int type)
 {
-  auto m = sg4::Mutex::create();
+  switch (type) {
+    case PTHREAD_MUTEX_NORMAL:
+      xbt_assert(not attr->recursive, "S4U does not allow to remove the recursivness of a mutex.");
+      attr->recursive = 0;
+      break;
+    case PTHREAD_MUTEX_RECURSIVE:
+      attr->recursive = 1;
+      attr->errorcheck = 0; // reset
+      break;
+    case PTHREAD_MUTEX_ERRORCHECK:
+      attr->errorcheck = 1;
+      THROW_UNIMPLEMENTED;
+      break;
+    default:
+      THROW_IMPOSSIBLE;
+  }
+  return 0;
+}
+int sthread_mutexattr_gettype(const sthread_mutexattr_t* attr, int* type)
+{
+  if (attr->recursive)
+    *type = PTHREAD_MUTEX_RECURSIVE;
+  else if (attr->errorcheck)
+    *type = PTHREAD_MUTEX_ERRORCHECK;
+  else
+    *type = PTHREAD_MUTEX_NORMAL;
+  return 0;
+}
+int sthread_mutexattr_getrobust(const sthread_mutexattr_t* attr, int* robustness)
+{
+  *robustness = attr->robust;
+  return 0;
+}
+int sthread_mutexattr_setrobust(sthread_mutexattr_t* attr, int robustness)
+{
+  attr->robust = robustness;
+  if (robustness)
+    THROW_UNIMPLEMENTED;
+  return 0;
+}
+
+int sthread_mutex_init(sthread_mutex_t* mutex, const sthread_mutexattr_t* attr)
+{
+  auto m = sg4::Mutex::create(attr != nullptr && attr->recursive);
   intrusive_ptr_add_ref(m.get());
 
   mutex->mutex = m.get();
@@ -123,6 +181,7 @@ int sthread_mutex_lock(sthread_mutex_t* mutex)
   if (mutex->mutex == nullptr)
     sthread_mutex_init(mutex, nullptr);
 
+  XBT_DEBUG("%s(%p)", __FUNCTION__, mutex);
   static_cast<sg4::Mutex*>(mutex->mutex)->lock();
   return 0;
 }
@@ -133,7 +192,10 @@ int sthread_mutex_trylock(sthread_mutex_t* mutex)
   if (mutex->mutex == nullptr)
     sthread_mutex_init(mutex, nullptr);
 
-  return static_cast<sg4::Mutex*>(mutex->mutex)->try_lock();
+  XBT_DEBUG("%s(%p)", __FUNCTION__, mutex);
+  if (static_cast<sg4::Mutex*>(mutex->mutex)->try_lock())
+    return 0;
+  return EBUSY;
 }
 
 int sthread_mutex_unlock(sthread_mutex_t* mutex)
@@ -142,6 +204,7 @@ int sthread_mutex_unlock(sthread_mutex_t* mutex)
   if (mutex->mutex == nullptr)
     sthread_mutex_init(mutex, nullptr);
 
+  XBT_DEBUG("%s(%p)", __FUNCTION__, mutex);
   static_cast<sg4::Mutex*>(mutex->mutex)->unlock();
   return 0;
 }
@@ -151,6 +214,7 @@ int sthread_mutex_destroy(sthread_mutex_t* mutex)
   if (mutex->mutex == nullptr)
     sthread_mutex_init(mutex, nullptr);
 
+  XBT_DEBUG("%s(%p)", __FUNCTION__, mutex);
   intrusive_ptr_release(static_cast<sg4::Mutex*>(mutex->mutex));
   return 0;
 }
@@ -211,6 +275,7 @@ int sthread_gettimeofday(struct timeval* tv)
 
 void sthread_sleep(double seconds)
 {
+  XBT_DEBUG("sleep(%lf)", seconds);
   simgrid::s4u::this_actor::sleep_for(seconds);
 }
 
diff --git a/src/xbt/automaton/automaton.c b/src/xbt/automaton/automaton.c
deleted file mode 100644 (file)
index f44bf6d..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/* automaton - representation of büchi automaton */
-
-/* Copyright (c) 2011-2023. 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/automaton.h"
-#include <stdio.h> /* printf */
-#include <xbt/sysdep.h>
-
-struct xbt_automaton_propositional_symbol{
-  char* pred;
-  /** Callback used to evaluate the value of the symbol */
-  int (*callback)(void*);
-  /** Additional data for the callback.
-      Alternatively it can be used as a pointer to the data. */
-  void* data;
-  /** Optional callback used to free the data field */
-  void (*free_function)(void*);
-};
-
-xbt_automaton_t xbt_automaton_new(void){
-  xbt_automaton_t automaton = xbt_new0(struct xbt_automaton, 1);
-  automaton->states = xbt_dynar_new(sizeof(xbt_automaton_state_t), xbt_automaton_state_free_voidp);
-  automaton->transitions = xbt_dynar_new(sizeof(xbt_automaton_transition_t), xbt_automaton_transition_free_voidp);
-  automaton->propositional_symbols = xbt_dynar_new(sizeof(xbt_automaton_propositional_symbol_t), xbt_automaton_propositional_symbol_free_voidp);
-  return automaton;
-}
-
-xbt_automaton_state_t xbt_automaton_state_new(const_xbt_automaton_t a, int type, const char* id)
-{
-  xbt_automaton_state_t state = xbt_new0(struct xbt_automaton_state, 1);
-  state->type = type;
-  state->id = xbt_strdup(id);
-  state->in                   = xbt_dynar_new(sizeof(xbt_automaton_transition_t), NULL);
-  state->out                  = xbt_dynar_new(sizeof(xbt_automaton_transition_t), NULL);
-  xbt_dynar_push(a->states, &state);
-  return state;
-}
-
-xbt_automaton_transition_t xbt_automaton_transition_new(const_xbt_automaton_t a, xbt_automaton_state_t src,
-                                                        xbt_automaton_state_t dst, xbt_automaton_exp_label_t label)
-{
-  xbt_automaton_transition_t transition = xbt_new0(struct xbt_automaton_transition, 1);
-  if(src != NULL){
-    xbt_dynar_push(src->out, &transition);
-    transition->src = src;
-  }
-  if(dst != NULL){
-    xbt_dynar_push(dst->in, &transition);
-    transition->dst = dst;
-  }
-  transition->label = label;
-  xbt_dynar_push(a->transitions, &transition);
-  return transition;
-}
-
-xbt_automaton_exp_label_t xbt_automaton_exp_label_new_or(xbt_automaton_exp_label_t left,
-                                                         xbt_automaton_exp_label_t right)
-{
-  xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1);
-  label->type                     = AUT_OR;
-  label->u.or_and.left_exp        = left;
-  label->u.or_and.right_exp       = right;
-  return label;
-}
-
-xbt_automaton_exp_label_t xbt_automaton_exp_label_new_and(xbt_automaton_exp_label_t left,
-                                                          xbt_automaton_exp_label_t right)
-{
-  xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1);
-  label->type                     = AUT_AND;
-  label->u.or_and.left_exp        = left;
-  label->u.or_and.right_exp       = right;
-  return label;
-}
-
-xbt_automaton_exp_label_t xbt_automaton_exp_label_new_not(xbt_automaton_exp_label_t exp_not)
-{
-  xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1);
-  label->type                     = AUT_NOT;
-  label->u.exp_not                = exp_not;
-  return label;
-}
-
-xbt_automaton_exp_label_t xbt_automaton_exp_label_new_predicat(const char* p)
-{
-  xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1);
-  label->type                     = AUT_PREDICAT;
-  label->u.predicat               = xbt_strdup(p);
-  return label;
-}
-
-xbt_automaton_exp_label_t xbt_automaton_exp_label_new_one(void)
-{
-  xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1);
-  label->type                     = AUT_ONE;
-  return label;
-}
-
-xbt_dynar_t xbt_automaton_get_states(const_xbt_automaton_t a)
-{
-  return a->states;
-}
-
-xbt_dynar_t xbt_automaton_get_transitions(const_xbt_automaton_t a)
-{
-  return a->transitions;
-}
-
-xbt_automaton_transition_t xbt_automaton_get_transition(XBT_ATTRIB_UNUSED const_xbt_automaton_t a,
-                                                        const_xbt_automaton_state_t src,
-                                                        const_xbt_automaton_state_t dst)
-{
-  xbt_automaton_transition_t transition;
-  unsigned int cursor;
-  xbt_dynar_foreach(src->out, cursor, transition){
-    if((transition->src == src) && (transition->dst == dst))
-      return transition;
-  }
-  return NULL;
-}
-
-xbt_automaton_state_t xbt_automaton_transition_get_source(const_xbt_automaton_transition_t t)
-{
-  return t->src;
-}
-
-xbt_automaton_state_t xbt_automaton_transition_get_destination(const_xbt_automaton_transition_t t)
-{
-  return t->dst;
-}
-
-void xbt_automaton_transition_set_source(xbt_automaton_transition_t t, xbt_automaton_state_t src){
-  t->src = src;
-  xbt_dynar_push(src->out,&t);
-}
-
-void xbt_automaton_transition_set_destination(xbt_automaton_transition_t t, xbt_automaton_state_t dst){
-  t->dst = dst;
-  xbt_dynar_push(dst->in,&t);
-}
-
-xbt_dynar_t xbt_automaton_state_get_out_transitions(const_xbt_automaton_state_t s)
-{
-  return s->out;
-}
-
-xbt_dynar_t xbt_automaton_state_get_in_transitions(const_xbt_automaton_state_t s)
-{
-  return s->in;
-}
-
-xbt_automaton_state_t xbt_automaton_state_exists(const_xbt_automaton_t a, const char* id)
-{
-  xbt_automaton_state_t state = NULL;
-  unsigned int cursor = 0;
-  xbt_dynar_foreach(a->states, cursor, state){
-   if(strcmp(state->id, id)==0)
-     return state;
-  }
-  return NULL;
-}
-
-void xbt_automaton_display(const_xbt_automaton_t a)
-{
-  unsigned int cursor;
-  xbt_automaton_state_t state = NULL;
-
-  printf("\n\nCurrent state: %s\n", a->current_state->id);
-
-  printf("\nStates' List: %lu\n\n", xbt_dynar_length(a->states));
-
-  xbt_dynar_foreach(a->states, cursor, state)
-    printf("ID: %s, type: %d\n", state->id, state->type);
-
-  xbt_automaton_transition_t transition;
-  printf("\nTransitions: %lu\n\n", xbt_dynar_length(a->transitions));
-
-  xbt_dynar_foreach(a->transitions, cursor, transition){
-    printf("label:");
-    xbt_automaton_exp_label_display(transition->label);
-    printf(", %s -> %s\n", transition->src->id, transition->dst->id);
-  }
-}
-
-void xbt_automaton_exp_label_display(const_xbt_automaton_exp_label_t label)
-{
-  printf("(");
-  switch(label->type){
-    case 0:
-      xbt_automaton_exp_label_display(label->u.or_and.left_exp);
-      printf(" || ");
-      xbt_automaton_exp_label_display(label->u.or_and.right_exp);
-      break;
-    case 1:
-      xbt_automaton_exp_label_display(label->u.or_and.left_exp);
-      printf(" && ");
-      xbt_automaton_exp_label_display(label->u.or_and.right_exp);
-      break;
-    case 2:
-      printf("!");
-      xbt_automaton_exp_label_display(label->u.exp_not);
-      break;
-    case 3:
-      printf("%s", label->u.predicat);
-      break;
-    case 4:
-      printf("1");
-      break;
-    default:
-      break;
-  }
-  printf(")");
-}
-
-xbt_automaton_state_t xbt_automaton_get_current_state(const_xbt_automaton_t a)
-{
-  return a->current_state;
-}
-
-static int call_simple_function(int function(void) )
-{
-  return function();
-}
-
-xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new(const_xbt_automaton_t a, const char* id,
-                                                                            int (*fct)(void))
-{
-  xbt_automaton_propositional_symbol_t prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1);
-  prop_symb->pred = xbt_strdup(id);
-  prop_symb->callback                            = ((int (*)(void *))&call_simple_function);
-  prop_symb->data = (void*)&fct;
-  prop_symb->free_function = NULL;
-  xbt_dynar_push(a->propositional_symbols, &prop_symb);
-  return prop_symb;
-}
-
-XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_pointer(const_xbt_automaton_t a,
-                                                                                               const char* id,
-                                                                                               int* value)
-{
-  xbt_automaton_propositional_symbol_t prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1);
-  prop_symb->pred = xbt_strdup(id);
-  prop_symb->callback = NULL;
-  prop_symb->data = value;
-  prop_symb->free_function = NULL;
-  xbt_dynar_push(a->propositional_symbols, &prop_symb);
-  return prop_symb;
-}
-
-XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_callback(
-    const_xbt_automaton_t a, const char* id, xbt_automaton_propositional_symbol_callback_type callback, void* data,
-    xbt_automaton_propositional_symbol_free_function_type free_function)
-{
-  xbt_automaton_propositional_symbol_t prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1);
-  prop_symb->pred = xbt_strdup(id);
-  prop_symb->callback = callback;
-  prop_symb->data = data;
-  prop_symb->free_function = free_function;
-  xbt_dynar_push(a->propositional_symbols, &prop_symb);
-  return prop_symb;
-}
-
-XBT_PUBLIC int xbt_automaton_propositional_symbol_evaluate(const_xbt_automaton_propositional_symbol_t symbol)
-{
-  if (symbol->callback)
-    return (symbol->callback)(symbol->data);
-  else
-    return *(int*) symbol->data;
-}
-
-XBT_PUBLIC xbt_automaton_propositional_symbol_callback_type
-xbt_automaton_propositional_symbol_get_callback(const_xbt_automaton_propositional_symbol_t symbol)
-{
-  return symbol->callback;
-}
-
-XBT_PUBLIC void* xbt_automaton_propositional_symbol_get_data(const_xbt_automaton_propositional_symbol_t symbol)
-{
-  return symbol->data;
-}
-
-XBT_PUBLIC const char* xbt_automaton_propositional_symbol_get_name(const_xbt_automaton_propositional_symbol_t symbol)
-{
-  return symbol->pred;
-}
-
-int xbt_automaton_state_compare(const_xbt_automaton_state_t s1, const_xbt_automaton_state_t s2)
-{
-  /* single id for each state, id and type sufficient for comparison*/
-  return (strcmp(s1->id, s2->id) != 0) || (s1->type != s2->type);
-}
-
-int xbt_automaton_transition_compare(const_xbt_automaton_transition_t t1, const_xbt_automaton_transition_t t2)
-{
-  return xbt_automaton_state_compare(t1->src, t2->src) || xbt_automaton_state_compare(t1->dst, t2->dst) ||
-         xbt_automaton_exp_label_compare(t1->label, t2->label);
-}
-
-int xbt_automaton_exp_label_compare(const_xbt_automaton_exp_label_t l1, const_xbt_automaton_exp_label_t l2)
-{
-  if(l1->type != l2->type)
-    return 1;
-
-  int res;
-  switch(l1->type){
-  case 0 : // OR
-  case 1 : // AND
-    res = xbt_automaton_exp_label_compare(l1->u.or_and.left_exp, l2->u.or_and.left_exp) ||
-          xbt_automaton_exp_label_compare(l1->u.or_and.right_exp, l2->u.or_and.right_exp);
-    break;
-  case 2 : // NOT
-    res = xbt_automaton_exp_label_compare(l1->u.exp_not, l2->u.exp_not);
-    break;
-  case 3 : // predicat
-    res = strcmp(l1->u.predicat, l2->u.predicat) != 0;
-    break;
-  case 4 : // 1
-    res = 0;
-    break;
-  default :
-    res = -1;
-    break;
-  }
-  return res;
-}
-
-int xbt_automaton_propositional_symbols_compare_value(const_xbt_dynar_t s1, const_xbt_dynar_t s2)
-{
-  unsigned long nb_elem = xbt_dynar_length(s1);
-
-  for (unsigned long cursor = 0; cursor < nb_elem; cursor++) {
-    const int* iptr1 = xbt_dynar_get_ptr(s1, cursor);
-    const int* iptr2 = xbt_dynar_get_ptr(s2, cursor);
-    if(*iptr1 != *iptr2)
-      return 1;
-  }
-
-  return 0;
-}
-
-static void xbt_automaton_transition_free(xbt_automaton_transition_t t);
-static void xbt_automaton_exp_label_free(xbt_automaton_exp_label_t e);
-static void xbt_automaton_propositional_symbol_free(xbt_automaton_propositional_symbol_t ps);
-
-void xbt_automaton_state_free(xbt_automaton_state_t s){
-  if (s == NULL)
-    return;
-  xbt_free(s->id);
-  xbt_dynar_free(&(s->in));
-  xbt_dynar_free(&(s->out));
-  xbt_free(s);
-}
-
-void xbt_automaton_state_free_voidp(void *s){
-  xbt_automaton_state_free((xbt_automaton_state_t) * (void **) s);
-}
-
-static void xbt_automaton_transition_free(xbt_automaton_transition_t t){
-  if (t == NULL)
-    return;
-  xbt_automaton_exp_label_free(t->label);
-  xbt_free(t);
-}
-
-void xbt_automaton_transition_free_voidp(void *t){
-  xbt_automaton_transition_free((xbt_automaton_transition_t) * (void **) t);
-}
-
-static void xbt_automaton_exp_label_free(xbt_automaton_exp_label_t e){
-  if (e == NULL)
-    return;
-  switch (e->type) {
-    case AUT_OR:
-    case AUT_AND:
-      xbt_automaton_exp_label_free(e->u.or_and.left_exp);
-      xbt_automaton_exp_label_free(e->u.or_and.right_exp);
-      break;
-    case AUT_NOT:
-      xbt_automaton_exp_label_free(e->u.exp_not);
-      break;
-    case AUT_PREDICAT:
-      xbt_free(e->u.predicat);
-      break;
-    default:
-      break;
-  }
-  xbt_free(e);
-}
-
-void xbt_automaton_exp_label_free_voidp(void *e){
-  xbt_automaton_exp_label_free((xbt_automaton_exp_label_t) * (void **) e);
-}
-
-static void xbt_automaton_propositional_symbol_free(xbt_automaton_propositional_symbol_t ps){
-  if (ps == NULL)
-    return;
-  if (ps->free_function)
-    ps->free_function(ps->data);
-  xbt_free(ps->pred);
-  xbt_free(ps);
-}
-
-void xbt_automaton_propositional_symbol_free_voidp(void *ps){
-  xbt_automaton_propositional_symbol_free((xbt_automaton_propositional_symbol_t) * (void**)ps);
-}
-
-void xbt_automaton_free(xbt_automaton_t a){
-  if (a == NULL)
-    return;
-  xbt_dynar_free(&(a->propositional_symbols));
-  xbt_dynar_free(&(a->transitions));
-  xbt_dynar_free(&(a->states));
-  xbt_free(a);
-}
diff --git a/src/xbt/automaton/automaton_lexer.yy.c b/src/xbt/automaton/automaton_lexer.yy.c
deleted file mode 100644 (file)
index 2138ba4..0000000
+++ /dev/null
@@ -1,2184 +0,0 @@
-#line 2 "automaton_lexer.yy.c"
-
-#line 4 "automaton_lexer.yy.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define yy_create_buffer xbt_automaton_parser__create_buffer
-#define yy_delete_buffer xbt_automaton_parser__delete_buffer
-#define yy_scan_buffer xbt_automaton_parser__scan_buffer
-#define yy_scan_string xbt_automaton_parser__scan_string
-#define yy_scan_bytes xbt_automaton_parser__scan_bytes
-#define yy_init_buffer xbt_automaton_parser__init_buffer
-#define yy_flush_buffer xbt_automaton_parser__flush_buffer
-#define yy_load_buffer_state xbt_automaton_parser__load_buffer_state
-#define yy_switch_to_buffer xbt_automaton_parser__switch_to_buffer
-#define yypush_buffer_state xbt_automaton_parser_push_buffer_state
-#define yypop_buffer_state xbt_automaton_parser_pop_buffer_state
-#define yyensure_buffer_stack xbt_automaton_parser_ensure_buffer_stack
-#define yy_flex_debug xbt_automaton_parser__flex_debug
-#define yyin xbt_automaton_parser_in
-#define yyleng xbt_automaton_parser_leng
-#define yylex xbt_automaton_parser_lex
-#define yylineno xbt_automaton_parser_lineno
-#define yyout xbt_automaton_parser_out
-#define yyrestart xbt_automaton_parser_restart
-#define yytext xbt_automaton_parser_text
-#define yywrap xbt_automaton_parser_wrap
-#define yyalloc xbt_automaton_parser_alloc
-#define yyrealloc xbt_automaton_parser_realloc
-#define yyfree xbt_automaton_parser_free
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 4
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-#ifdef yy_create_buffer
-#define xbt_automaton_parser__create_buffer_ALREADY_DEFINED
-#else
-#define yy_create_buffer xbt_automaton_parser__create_buffer
-#endif
-
-#ifdef yy_delete_buffer
-#define xbt_automaton_parser__delete_buffer_ALREADY_DEFINED
-#else
-#define yy_delete_buffer xbt_automaton_parser__delete_buffer
-#endif
-
-#ifdef yy_scan_buffer
-#define xbt_automaton_parser__scan_buffer_ALREADY_DEFINED
-#else
-#define yy_scan_buffer xbt_automaton_parser__scan_buffer
-#endif
-
-#ifdef yy_scan_string
-#define xbt_automaton_parser__scan_string_ALREADY_DEFINED
-#else
-#define yy_scan_string xbt_automaton_parser__scan_string
-#endif
-
-#ifdef yy_scan_bytes
-#define xbt_automaton_parser__scan_bytes_ALREADY_DEFINED
-#else
-#define yy_scan_bytes xbt_automaton_parser__scan_bytes
-#endif
-
-#ifdef yy_init_buffer
-#define xbt_automaton_parser__init_buffer_ALREADY_DEFINED
-#else
-#define yy_init_buffer xbt_automaton_parser__init_buffer
-#endif
-
-#ifdef yy_flush_buffer
-#define xbt_automaton_parser__flush_buffer_ALREADY_DEFINED
-#else
-#define yy_flush_buffer xbt_automaton_parser__flush_buffer
-#endif
-
-#ifdef yy_load_buffer_state
-#define xbt_automaton_parser__load_buffer_state_ALREADY_DEFINED
-#else
-#define yy_load_buffer_state xbt_automaton_parser__load_buffer_state
-#endif
-
-#ifdef yy_switch_to_buffer
-#define xbt_automaton_parser__switch_to_buffer_ALREADY_DEFINED
-#else
-#define yy_switch_to_buffer xbt_automaton_parser__switch_to_buffer
-#endif
-
-#ifdef yypush_buffer_state
-#define xbt_automaton_parser_push_buffer_state_ALREADY_DEFINED
-#else
-#define yypush_buffer_state xbt_automaton_parser_push_buffer_state
-#endif
-
-#ifdef yypop_buffer_state
-#define xbt_automaton_parser_pop_buffer_state_ALREADY_DEFINED
-#else
-#define yypop_buffer_state xbt_automaton_parser_pop_buffer_state
-#endif
-
-#ifdef yyensure_buffer_stack
-#define xbt_automaton_parser_ensure_buffer_stack_ALREADY_DEFINED
-#else
-#define yyensure_buffer_stack xbt_automaton_parser_ensure_buffer_stack
-#endif
-
-#ifdef yylex
-#define xbt_automaton_parser_lex_ALREADY_DEFINED
-#else
-#define yylex xbt_automaton_parser_lex
-#endif
-
-#ifdef yyrestart
-#define xbt_automaton_parser_restart_ALREADY_DEFINED
-#else
-#define yyrestart xbt_automaton_parser_restart
-#endif
-
-#ifdef yylex_init
-#define xbt_automaton_parser_lex_init_ALREADY_DEFINED
-#else
-#define yylex_init xbt_automaton_parser_lex_init
-#endif
-
-#ifdef yylex_init_extra
-#define xbt_automaton_parser_lex_init_extra_ALREADY_DEFINED
-#else
-#define yylex_init_extra xbt_automaton_parser_lex_init_extra
-#endif
-
-#ifdef yylex_destroy
-#define xbt_automaton_parser_lex_destroy_ALREADY_DEFINED
-#else
-#define yylex_destroy xbt_automaton_parser_lex_destroy
-#endif
-
-#ifdef yyget_debug
-#define xbt_automaton_parser_get_debug_ALREADY_DEFINED
-#else
-#define yyget_debug xbt_automaton_parser_get_debug
-#endif
-
-#ifdef yyset_debug
-#define xbt_automaton_parser_set_debug_ALREADY_DEFINED
-#else
-#define yyset_debug xbt_automaton_parser_set_debug
-#endif
-
-#ifdef yyget_extra
-#define xbt_automaton_parser_get_extra_ALREADY_DEFINED
-#else
-#define yyget_extra xbt_automaton_parser_get_extra
-#endif
-
-#ifdef yyset_extra
-#define xbt_automaton_parser_set_extra_ALREADY_DEFINED
-#else
-#define yyset_extra xbt_automaton_parser_set_extra
-#endif
-
-#ifdef yyget_in
-#define xbt_automaton_parser_get_in_ALREADY_DEFINED
-#else
-#define yyget_in xbt_automaton_parser_get_in
-#endif
-
-#ifdef yyset_in
-#define xbt_automaton_parser_set_in_ALREADY_DEFINED
-#else
-#define yyset_in xbt_automaton_parser_set_in
-#endif
-
-#ifdef yyget_out
-#define xbt_automaton_parser_get_out_ALREADY_DEFINED
-#else
-#define yyget_out xbt_automaton_parser_get_out
-#endif
-
-#ifdef yyset_out
-#define xbt_automaton_parser_set_out_ALREADY_DEFINED
-#else
-#define yyset_out xbt_automaton_parser_set_out
-#endif
-
-#ifdef yyget_leng
-#define xbt_automaton_parser_get_leng_ALREADY_DEFINED
-#else
-#define yyget_leng xbt_automaton_parser_get_leng
-#endif
-
-#ifdef yyget_text
-#define xbt_automaton_parser_get_text_ALREADY_DEFINED
-#else
-#define yyget_text xbt_automaton_parser_get_text
-#endif
-
-#ifdef yyget_lineno
-#define xbt_automaton_parser_get_lineno_ALREADY_DEFINED
-#else
-#define yyget_lineno xbt_automaton_parser_get_lineno
-#endif
-
-#ifdef yyset_lineno
-#define xbt_automaton_parser_set_lineno_ALREADY_DEFINED
-#else
-#define yyset_lineno xbt_automaton_parser_set_lineno
-#endif
-
-#ifdef yywrap
-#define xbt_automaton_parser_wrap_ALREADY_DEFINED
-#else
-#define yywrap xbt_automaton_parser_wrap
-#endif
-
-#ifdef yyalloc
-#define xbt_automaton_parser_alloc_ALREADY_DEFINED
-#else
-#define yyalloc xbt_automaton_parser_alloc
-#endif
-
-#ifdef yyrealloc
-#define xbt_automaton_parser_realloc_ALREADY_DEFINED
-#else
-#define yyrealloc xbt_automaton_parser_realloc
-#endif
-
-#ifdef yyfree
-#define xbt_automaton_parser_free_ALREADY_DEFINED
-#else
-#define yyfree xbt_automaton_parser_free
-#endif
-
-#ifdef yytext
-#define xbt_automaton_parser_text_ALREADY_DEFINED
-#else
-#define yytext xbt_automaton_parser_text
-#endif
-
-#ifdef yyleng
-#define xbt_automaton_parser_leng_ALREADY_DEFINED
-#else
-#define yyleng xbt_automaton_parser_leng
-#endif
-
-#ifdef yyin
-#define xbt_automaton_parser_in_ALREADY_DEFINED
-#else
-#define yyin xbt_automaton_parser_in
-#endif
-
-#ifdef yyout
-#define xbt_automaton_parser_out_ALREADY_DEFINED
-#else
-#define yyout xbt_automaton_parser_out
-#endif
-
-#ifdef yy_flex_debug
-#define xbt_automaton_parser__flex_debug_ALREADY_DEFINED
-#else
-#define yy_flex_debug xbt_automaton_parser__flex_debug
-#endif
-
-#ifdef yylineno
-#define xbt_automaton_parser_lineno_ALREADY_DEFINED
-#else
-#define yylineno xbt_automaton_parser_lineno
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#ifndef SIZE_MAX
-#define SIZE_MAX               (~(size_t)0)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-/* begin standard C++ headers. */
-
-/* TODO: this is always defined, so inline it */
-#define yyconst const
-
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define yynoreturn __attribute__((__noreturn__))
-#else
-#define yynoreturn
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an
- *   integer in range [0..255] for use as an array index.
- */
-#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin  )
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-    
-    #define YY_LESS_LINENO(n)
-    #define YY_LINENO_REWIND_TO(ptr)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               *yy_cp = (yy_hold_char); \
-               YY_RESTORE_YY_MORE_OFFSET \
-               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-               } \
-       while ( 0 )
-#define unput(c) yyunput( c, (yytext_ptr)  )
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-       {
-       FILE *yy_input_file;
-
-       char *yy_ch_buf;                /* input buffer */
-       char *yy_buf_pos;               /* current position in input buffer */
-
-       /* Size of input buffer in bytes, not including room for EOB
-        * characters.
-        */
-       int yy_buf_size;
-
-       /* Number of characters read into yy_ch_buf, not including EOB
-        * characters.
-        */
-       int yy_n_chars;
-
-       /* Whether we "own" the buffer - i.e., we know we created it,
-        * and can realloc() it to grow it, and should free() it to
-        * delete it.
-        */
-       int yy_is_our_buffer;
-
-       /* Whether this is an "interactive" input source; if so, and
-        * if we're using stdio for input, then we want to use getc()
-        * instead of fread(), to make sure we stop fetching input after
-        * each newline.
-        */
-       int yy_is_interactive;
-
-       /* Whether we're considered to be at the beginning of a line.
-        * If so, '^' rules will be active on the next match, otherwise
-        * not.
-        */
-       int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-
-       /* Whether to try to fill the input buffer when we reach the
-        * end of it.
-        */
-       int yy_fill_buffer;
-
-       int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-       /* When an EOF's been seen but there's still some text to process
-        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-        * shouldn't try reading from the input source any more.  We might
-        * still have a bunch of tokens to match, though, because of
-        * possible backing-up.
-        *
-        * When we actually see the EOF, we change the status to "new"
-        * (via yyrestart()), so that the user can continue scanning by
-        * just pointing yyin at a new input file.
-        */
-#define YY_BUFFER_EOF_PENDING 2
-
-       };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-static int yy_n_chars;         /* number of characters read into yy_ch_buf */
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = NULL;
-static int yy_init = 0;                /* whether we need to initialize */
-static int yy_start = 0;       /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin.  A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart ( FILE *input_file  );
-void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size  );
-void yy_delete_buffer ( YY_BUFFER_STATE b  );
-void yy_flush_buffer ( YY_BUFFER_STATE b  );
-void yypush_buffer_state ( YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state ( void );
-
-static void yyensure_buffer_stack ( void );
-static void yy_load_buffer_state ( void );
-static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file  );
-#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string ( const char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len  );
-
-void *yyalloc ( yy_size_t  );
-void *yyrealloc ( void *, yy_size_t  );
-void yyfree ( void *  );
-
-#define yy_new_buffer yy_create_buffer
-#define yy_set_interactive(is_interactive) \
-       { \
-       if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer( yyin, YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-       }
-#define yy_set_bol(at_bol) \
-       { \
-       if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer( yyin, YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-       }
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define xbt_automaton_parser_wrap() (/*CONSTCOND*/1)
-#define YY_SKIP_YYWRAP
-typedef flex_uint8_t YY_CHAR;
-
-FILE *yyin = NULL, *yyout = NULL;
-
-typedef int yy_state_type;
-
-extern int yylineno;
-int yylineno = 1;
-
-extern char *yytext;
-#ifdef yytext_ptr
-#undef yytext_ptr
-#endif
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state ( void );
-static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  );
-static int yy_get_next_buffer ( void );
-static void yynoreturn yy_fatal_error ( const char* msg  );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-       (yytext_ptr) = yy_bp; \
-       yyleng = (int) (yy_cp - yy_bp); \
-       (yy_hold_char) = *yy_cp; \
-       *yy_cp = '\0'; \
-       (yy_c_buf_p) = yy_cp;
-#define YY_NUM_RULES 25
-#define YY_END_OF_BUFFER 26
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-       {
-       flex_int32_t yy_verify;
-       flex_int32_t yy_nxt;
-       };
-static const flex_int16_t yy_accept[54] =
-    {   0,
-        0,    0,   26,   24,   18,   23,    8,   24,   24,    9,
-       10,   24,   24,   20,   14,   12,   13,   22,   22,   22,
-       22,   22,   15,   24,   16,   18,    0,    0,   21,    0,
-        6,    4,    0,    0,   20,   11,   22,    3,   22,    2,
-       22,    7,    0,    0,    0,   19,   22,   22,   17,    5,
-       22,    1,    0
-    } ;
-
-static const YY_CHAR yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    4,    5,    6,    1,    1,    1,    7,    1,    8,
-        9,   10,    1,    1,   11,   12,   13,   14,   15,   14,
-       14,   14,   14,   14,   14,   14,   14,   16,   17,    1,
-        1,   18,    1,    1,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
-        1,   20,    1,    1,   21,    1,   19,   19,   19,   19,
-
-       22,   23,   24,   19,   25,   19,   19,   19,   19,   26,
-       27,   19,   19,   28,   19,   29,   19,   30,   19,   19,
-       19,   19,   31,   32,   33,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-static const YY_CHAR yy_meta[34] =
-    {   0,
-        1,    1,    2,    2,    1,    2,    1,    1,    1,    1,
-        1,    1,    3,    4,    4,    1,    1,    1,    4,    2,
-        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
-        1,    1,    1
-    } ;
-
-static const flex_int16_t yy_base[57] =
-    {   0,
-        0,    0,   89,   90,   32,   90,   90,   34,   81,   90,
-       90,   69,   76,   27,   31,   69,   90,    0,   59,   56,
-       58,   55,   90,   42,   90,   45,   47,    0,    0,    0,
-       90,   90,   52,   43,   49,   90,    0,    0,   44,    0,
-       42,   90,   56,   65,   52,   56,   25,   26,   90,    0,
-       16,    0,   90,   74,   31,   78
-    } ;
-
-static const flex_int16_t yy_def[57] =
-    {   0,
-       53,    1,   53,   53,   53,   53,   53,   54,   53,   53,
-       53,   53,   53,   53,   53,   53,   53,   55,   55,   55,
-       55,   55,   53,   53,   53,   53,   54,   27,   27,   27,
-       53,   53,   56,   53,   53,   53,   55,   55,   55,   55,
-       55,   53,   56,   56,   53,   53,   55,   55,   53,   55,
-       55,   55,    0,   53,   53,   53
-    } ;
-
-static const flex_int16_t yy_nxt[124] =
-    {   0,
-        4,    5,    6,    5,    7,    8,    9,   10,   11,    4,
-       12,    4,   13,   14,   15,   16,   17,    4,   18,    4,
-        4,   18,   19,   20,   21,   22,   18,   18,   18,   18,
-       23,   24,   25,   26,   37,   26,   27,   28,   34,   29,
-       35,   35,   34,   52,   35,   35,   26,   51,   26,   27,
-       28,   50,   29,   27,   44,   44,   46,   46,   44,   44,
-       34,   45,   35,   35,   49,   45,   27,   44,   44,   46,
-       46,   48,   47,   42,   45,   30,   41,   30,   43,   43,
-       40,   43,   39,   38,   36,   33,   32,   31,   53,    3,
-       53,   53,   53,   53,   53,   53,   53,   53,   53,   53,
-
-       53,   53,   53,   53,   53,   53,   53,   53,   53,   53,
-       53,   53,   53,   53,   53,   53,   53,   53,   53,   53,
-       53,   53,   53
-    } ;
-
-static const flex_int16_t yy_chk[124] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    5,   55,    5,    8,    8,   14,    8,
-       14,   14,   15,   51,   15,   15,   26,   48,   26,   27,
-       27,   47,   27,    8,   33,   33,   34,   34,   43,   43,
-       35,   33,   35,   35,   45,   43,   27,   44,   44,   46,
-       46,   41,   39,   24,   44,   54,   22,   54,   56,   56,
-       21,   56,   20,   19,   16,   13,   12,    9,    3,   53,
-       53,   53,   53,   53,   53,   53,   53,   53,   53,   53,
-
-       53,   53,   53,   53,   53,   53,   53,   53,   53,   53,
-       53,   53,   53,   53,   53,   53,   53,   53,   53,   53,
-       53,   53,   53
-    } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "parserPromela.lex"
-/* Copyright (c) 2012-2023. 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. */
-#line 10 "parserPromela.lex"
-
-#include "simgrid/config.h"
-#if !HAVE_UNISTD_H
-#define YY_NO_UNISTD_H /* hello Windows */
-#endif
-
-#include <stdio.h>
-#include "parserPromela.tab.hacc"
-
-  extern YYSTYPE yylval;
-
-#line 764 "automaton_lexer.yy.c"
-#line 765 "automaton_lexer.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals ( void );
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy ( void );
-
-int yyget_debug ( void );
-
-void yyset_debug ( int debug_flag  );
-
-YY_EXTRA_TYPE yyget_extra ( void );
-
-void yyset_extra ( YY_EXTRA_TYPE user_defined  );
-
-FILE *yyget_in ( void );
-
-void yyset_in  ( FILE * _in_str  );
-
-FILE *yyget_out ( void );
-
-void yyset_out  ( FILE * _out_str  );
-
-                       int yyget_leng ( void );
-
-char *yyget_text ( void );
-
-int yyget_lineno ( void );
-
-void yyset_lineno ( int _line_number  );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap ( void );
-#else
-extern int yywrap ( void );
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-    
-    static void yyunput ( int c, char *buf_ptr  );
-    
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy ( char *, const char *, int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen ( const char * );
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput ( void );
-#else
-static int input ( void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-               { \
-               int c = '*'; \
-               int n; \
-               for ( n = 0; n < max_size && \
-                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-                       buf[n] = (char) c; \
-               if ( c == '\n' ) \
-                       buf[n++] = (char) c; \
-               if ( c == EOF && ferror( yyin ) ) \
-                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
-               result = n; \
-               } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK /*LINTED*/break;
-#endif
-
-#define YY_RULE_SETUP \
-       YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-       yy_state_type yy_current_state;
-       char *yy_cp, *yy_bp;
-       int yy_act;
-    
-       if ( !(yy_init) )
-               {
-               (yy_init) = 1;
-
-#ifdef YY_USER_INIT
-               YY_USER_INIT;
-#endif
-
-               if ( ! (yy_start) )
-                       (yy_start) = 1; /* first start state */
-
-               if ( ! yyin )
-                       yyin = stdin;
-
-               if ( ! yyout )
-                       yyout = stdout;
-
-               if ( ! YY_CURRENT_BUFFER ) {
-                       yyensure_buffer_stack ();
-                       YY_CURRENT_BUFFER_LVALUE =
-                               yy_create_buffer( yyin, YY_BUF_SIZE );
-               }
-
-               yy_load_buffer_state(  );
-               }
-
-       {
-#line 38 "parserPromela.lex"
-
-
-#line 985 "automaton_lexer.yy.c"
-
-       while ( /*CONSTCOND*/1 )                /* loops until end-of-file is reached */
-               {
-               yy_cp = (yy_c_buf_p);
-
-               /* Support of yytext. */
-               *yy_cp = (yy_hold_char);
-
-               /* yy_bp points to the position in yy_ch_buf of the start of
-                * the current run.
-                */
-               yy_bp = yy_cp;
-
-               yy_current_state = (yy_start);
-yy_match:
-               do
-                       {
-                       YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
-                       if ( yy_accept[yy_current_state] )
-                               {
-                               (yy_last_accepting_state) = yy_current_state;
-                               (yy_last_accepting_cpos) = yy_cp;
-                               }
-                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                               {
-                               yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 54 )
-                                       yy_c = yy_meta[yy_c];
-                               }
-                       yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-                       ++yy_cp;
-                       }
-               while ( yy_base[yy_current_state] != 90 );
-
-yy_find_action:
-               yy_act = yy_accept[yy_current_state];
-               if ( yy_act == 0 )
-                       { /* have to back up */
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
-                       yy_act = yy_accept[yy_current_state];
-                       }
-
-               YY_DO_BEFORE_ACTION;
-
-do_action:     /* This label is used only to access EOF actions. */
-
-               switch ( yy_act )
-       { /* beginning of action switch */
-                       case 0: /* must back up */
-                       /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = (yy_hold_char);
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
-                       goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 40 "parserPromela.lex"
-{ return (NEVER); }
-       YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 41 "parserPromela.lex"
-{ return (IF); }
-       YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 42 "parserPromela.lex"
-{ return (FI); }
-       YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 43 "parserPromela.lex"
-{ return (IMPLIES); }
-       YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 44 "parserPromela.lex"
-{ return (GOTO); }
-       YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 45 "parserPromela.lex"
-{ return (AND); }
-       YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 46 "parserPromela.lex"
-{ return (OR); }
-       YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 47 "parserPromela.lex"
-{ return (NOT); }
-       YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 48 "parserPromela.lex"
-{ return (LEFT_PAR); }
-       YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 49 "parserPromela.lex"
-{ return (RIGHT_PAR); }
-       YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 50 "parserPromela.lex"
-{ return (CASE); }
-       YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 51 "parserPromela.lex"
-{ return (COLON); }
-       YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 52 "parserPromela.lex"
-{ return (SEMI_COLON); }
-       YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 53 "parserPromela.lex"
-{ return (CASE_TRUE); }
-       YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 54 "parserPromela.lex"
-{ return (LEFT_BRACE); }
-       YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 55 "parserPromela.lex"
-{ return (RIGHT_BRACE); }
-       YY_BREAK
-case 17:
-/* rule 17 can match eol */
-YY_RULE_SETUP
-#line 58 "parserPromela.lex"
-{ }
-       YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 60 "parserPromela.lex"
-{ }
-       YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 63 "parserPromela.lex"
-{ sscanf(yytext,"%lf",&yylval.real);
-                            return (LITT_REEL); }
-       YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 66 "parserPromela.lex"
-{ sscanf(yytext,"%d",&yylval.integer);
-                            return (LITT_ENT); }
-       YY_BREAK
-case 21:
-/* rule 21 can match eol */
-YY_RULE_SETUP
-#line 69 "parserPromela.lex"
-{ yylval.string=(char *)malloc(strlen(yytext)+1);
-                            sscanf(yytext,"%s",yylval.string);
-                            return (LITT_CHAINE); }
-       YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 73 "parserPromela.lex"
-{ yylval.string=(char *)malloc(strlen(yytext)+1);
-                            sscanf(yytext,"%s",yylval.string);
-                                             return (ID); }
-       YY_BREAK
-case 23:
-/* rule 23 can match eol */
-YY_RULE_SETUP
-#line 77 "parserPromela.lex"
-{ }
-       YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 79 "parserPromela.lex"
-{ }
-       YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 81 "parserPromela.lex"
-ECHO;
-       YY_BREAK
-#line 1176 "automaton_lexer.yy.c"
-case YY_STATE_EOF(INITIAL):
-       yyterminate();
-
-       case YY_END_OF_BUFFER:
-               {
-               /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-               /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = (yy_hold_char);
-               YY_RESTORE_YY_MORE_OFFSET
-
-               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-                       {
-                       /* We're scanning a new file or input source.  It's
-                        * possible that this happened because the user
-                        * just pointed yyin at a new source and called
-                        * yylex().  If so, then we have to assure
-                        * consistency between YY_CURRENT_BUFFER and our
-                        * globals.  Here is the right place to do so, because
-                        * this is the first action (other than possibly a
-                        * back-up) that will match for the new input source.
-                        */
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-                       }
-
-               /* Note that here we test for yy_c_buf_p "<=" to the position
-                * of the first EOB in the buffer, since yy_c_buf_p will
-                * already have been incremented past the NUL character
-                * (since all states make transitions on EOB to the
-                * end-of-buffer state).  Contrast this with the test
-                * in input().
-                */
-               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-                       { /* This was really a NUL. */
-                       yy_state_type yy_next_state;
-
-                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
-                       yy_current_state = yy_get_previous_state(  );
-
-                       /* Okay, we're now positioned to make the NUL
-                        * transition.  We couldn't have
-                        * yy_get_previous_state() go ahead and do it
-                        * for us because it doesn't know how to deal
-                        * with the possibility of jamming (and we don't
-                        * want to build jamming into it because then it
-                        * will run more slowly).
-                        */
-
-                       yy_next_state = yy_try_NUL_trans( yy_current_state );
-
-                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
-                       if ( yy_next_state )
-                               {
-                               /* Consume the NUL. */
-                               yy_cp = ++(yy_c_buf_p);
-                               yy_current_state = yy_next_state;
-                               goto yy_match;
-                               }
-
-                       else
-                               {
-                               yy_cp = (yy_c_buf_p);
-                               goto yy_find_action;
-                               }
-                       }
-
-               else switch ( yy_get_next_buffer(  ) )
-                       {
-                       case EOB_ACT_END_OF_FILE:
-                               {
-                               (yy_did_buffer_switch_on_eof) = 0;
-
-                               if ( yywrap(  ) )
-                                       {
-                                       /* Note: because we've taken care in
-                                        * yy_get_next_buffer() to have set up
-                                        * yytext, we can now set up
-                                        * yy_c_buf_p so that if some total
-                                        * hoser (like flex itself) wants to
-                                        * call the scanner after we return the
-                                        * YY_NULL, it'll still work - another
-                                        * YY_NULL will get returned.
-                                        */
-                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
-                                       yy_act = YY_STATE_EOF(YY_START);
-                                       goto do_action;
-                                       }
-
-                               else
-                                       {
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
-                                               YY_NEW_FILE;
-                                       }
-                               break;
-                               }
-
-                       case EOB_ACT_CONTINUE_SCAN:
-                               (yy_c_buf_p) =
-                                       (yytext_ptr) + yy_amount_of_matched_text;
-
-                               yy_current_state = yy_get_previous_state(  );
-
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-                               goto yy_match;
-
-                       case EOB_ACT_LAST_MATCH:
-                               (yy_c_buf_p) =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
-                               yy_current_state = yy_get_previous_state(  );
-
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-                               goto yy_find_action;
-                       }
-               break;
-               }
-
-       default:
-               YY_FATAL_ERROR(
-                       "fatal flex scanner internal error--no action found" );
-       } /* end of action switch */
-               } /* end of scanning one token */
-       } /* end of user's declarations */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *     EOB_ACT_LAST_MATCH -
- *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *     EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
-       char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       char *source = (yytext_ptr);
-       int number_to_move, i;
-       int ret_val;
-
-       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
-               YY_FATAL_ERROR(
-               "fatal flex scanner internal error--end of buffer missed" );
-
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-               { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
-                       {
-                       /* We matched a single character, the EOB, so
-                        * treat this as a final EOF.
-                        */
-                       return EOB_ACT_END_OF_FILE;
-                       }
-
-               else
-                       {
-                       /* We matched some text prior to the EOB, first
-                        * process it.
-                        */
-                       return EOB_ACT_LAST_MATCH;
-                       }
-               }
-
-       /* Try to read more data. */
-
-       /* First move last chars to start of buffer. */
-       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
-
-       for ( i = 0; i < number_to_move; ++i )
-               *(dest++) = *(source++);
-
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-               /* don't do the read, it's not guaranteed to return an EOF,
-                * just force an EOF
-                */
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
-       else
-               {
-                       int num_to_read =
-                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-               while ( num_to_read <= 0 )
-                       { /* Not enough room in the buffer - grow it. */
-
-                       /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
-
-                       int yy_c_buf_p_offset =
-                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
-
-                       if ( b->yy_is_our_buffer )
-                               {
-                               int new_size = b->yy_buf_size * 2;
-
-                               if ( new_size <= 0 )
-                                       b->yy_buf_size += b->yy_buf_size / 8;
-                               else
-                                       b->yy_buf_size *= 2;
-
-                               b->yy_ch_buf = (char *)
-                                       /* Include room in for 2 EOB chars. */
-                                       yyrealloc( (void *) b->yy_ch_buf,
-                                                        (yy_size_t) (b->yy_buf_size + 2)  );
-                               }
-                       else
-                               /* Can't grow it, we don't own it. */
-                               b->yy_ch_buf = NULL;
-
-                       if ( ! b->yy_ch_buf )
-                               YY_FATAL_ERROR(
-                               "fatal error - scanner input buffer overflow" );
-
-                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-                                               number_to_move - 1;
-
-                       }
-
-               if ( num_to_read > YY_READ_BUF_SIZE )
-                       num_to_read = YY_READ_BUF_SIZE;
-
-               /* Read in more data. */
-               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), num_to_read );
-
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       if ( (yy_n_chars) == 0 )
-               {
-               if ( number_to_move == YY_MORE_ADJ )
-                       {
-                       ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart( yyin  );
-                       }
-
-               else
-                       {
-                       ret_val = EOB_ACT_LAST_MATCH;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-                               YY_BUFFER_EOF_PENDING;
-                       }
-               }
-
-       else
-               ret_val = EOB_ACT_CONTINUE_SCAN;
-
-       if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-               /* Extend the array by 50%, plus the number we really need. */
-               int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
-                       (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size  );
-               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-               /* "- 2" to take care of EOB's */
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
-       }
-
-       (yy_n_chars) += number_to_move;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
-       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-       return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (void)
-{
-       yy_state_type yy_current_state;
-       char *yy_cp;
-    
-       yy_current_state = (yy_start);
-
-       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
-               {
-               YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-               if ( yy_accept[yy_current_state] )
-                       {
-                       (yy_last_accepting_state) = yy_current_state;
-                       (yy_last_accepting_cpos) = yy_cp;
-                       }
-               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                       {
-                       yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 54 )
-                               yy_c = yy_meta[yy_c];
-                       }
-               yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-               }
-
-       return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *     next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
-       int yy_is_jam;
-       char *yy_cp = (yy_c_buf_p);
-
-       YY_CHAR yy_c = 1;
-       if ( yy_accept[yy_current_state] )
-               {
-               (yy_last_accepting_state) = yy_current_state;
-               (yy_last_accepting_cpos) = yy_cp;
-               }
-       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-               {
-               yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 54 )
-                       yy_c = yy_meta[yy_c];
-               }
-       yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-       yy_is_jam = (yy_current_state == 53);
-
-               return yy_is_jam ? 0 : yy_current_state;
-}
-
-#ifndef YY_NO_UNPUT
-
-    static void yyunput (int c, char * yy_bp )
-{
-       char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
-
-       /* undo effects of setting up yytext */
-       *yy_cp = (yy_hold_char);
-
-       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-               { /* need to shift things up to make room */
-               /* +2 for EOB chars. */
-               int number_to_move = (yy_n_chars) + 2;
-               char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-               char *source =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
-               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-                       *--dest = *--source;
-
-               yy_cp += (int) (dest - source);
-               yy_bp += (int) (dest - source);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                       (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
-               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
-               }
-
-       *--yy_cp = (char) c;
-
-       (yytext_ptr) = yy_bp;
-       (yy_hold_char) = *yy_cp;
-       (yy_c_buf_p) = yy_cp;
-}
-
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (void)
-#else
-    static int input  (void)
-#endif
-
-{
-       int c;
-    
-       *(yy_c_buf_p) = (yy_hold_char);
-
-       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
-               {
-               /* yy_c_buf_p now points to the character we want to return.
-                * If this occurs *before* the EOB characters, then it's a
-                * valid NUL; if not, then we've hit the end of the buffer.
-                */
-               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
-                       /* This was really a NUL. */
-                       *(yy_c_buf_p) = '\0';
-
-               else
-                       { /* need more input */
-                       int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
-                       ++(yy_c_buf_p);
-
-                       switch ( yy_get_next_buffer(  ) )
-                               {
-                               case EOB_ACT_LAST_MATCH:
-                                       /* This happens because yy_g_n_b()
-                                        * sees that we've accumulated a
-                                        * token and flags that we need to
-                                        * try matching the token before
-                                        * proceeding.  But for input(),
-                                        * there's no matching to consider.
-                                        * So convert the EOB_ACT_LAST_MATCH
-                                        * to EOB_ACT_END_OF_FILE.
-                                        */
-
-                                       /* Reset buffer status. */
-                                       yyrestart( yyin );
-
-                                       /*FALLTHROUGH*/
-
-                               case EOB_ACT_END_OF_FILE:
-                                       {
-                                       if ( yywrap(  ) )
-                                               return 0;
-
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
-                                               YY_NEW_FILE;
-#ifdef __cplusplus
-                                       return yyinput();
-#else
-                                       return input();
-#endif
-                                       }
-
-                               case EOB_ACT_CONTINUE_SCAN:
-                                       (yy_c_buf_p) = (yytext_ptr) + offset;
-                                       break;
-                               }
-                       }
-               }
-
-       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
-       *(yy_c_buf_p) = '\0';   /* preserve yytext */
-       (yy_hold_char) = *++(yy_c_buf_p);
-
-       return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-       if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-               YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer( yyin, YY_BUF_SIZE );
-       }
-
-       yy_init_buffer( YY_CURRENT_BUFFER, input_file );
-       yy_load_buffer_state(  );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-       /* TODO. We should be able to replace this entire function body
-        * with
-        *              yypop_buffer_state();
-        *              yypush_buffer_state(new_buffer);
-     */
-       yyensure_buffer_stack ();
-       if ( YY_CURRENT_BUFFER == new_buffer )
-               return;
-
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-       yy_load_buffer_state(  );
-
-       /* We don't actually know whether we did this switch during
-        * EOF (yywrap()) processing, but the only time this flag
-        * is looked at is after yywrap() is called, so it's safe
-        * to go ahead and always set it.
-        */
-       (yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void yy_load_buffer_state  (void)
-{
-       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-       (yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
-       YY_BUFFER_STATE b;
-    
-       b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
-       if ( ! b )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-       b->yy_buf_size = size;
-
-       /* yy_ch_buf has to be 2 characters longer than the size given because
-        * we need to put in 2 end-of-buffer characters.
-        */
-       b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2)  );
-       if ( ! b->yy_ch_buf )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-       b->yy_is_our_buffer = 1;
-
-       yy_init_buffer( b, file );
-
-       return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
-       if ( ! b )
-               return;
-
-       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-       if ( b->yy_is_our_buffer )
-               yyfree( (void *) b->yy_ch_buf  );
-
-       yyfree( (void *) b  );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
-
-{
-       int oerrno = errno;
-    
-       yy_flush_buffer( b );
-
-       b->yy_input_file = file;
-       b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
-       errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-       if ( ! b )
-               return;
-
-       b->yy_n_chars = 0;
-
-       /* We always need two end-of-buffer characters.  The first causes
-        * a transition to the end-of-buffer state.  The second causes
-        * a jam in that state.
-        */
-       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-       b->yy_buf_pos = &b->yy_ch_buf[0];
-
-       b->yy_at_bol = 1;
-       b->yy_buffer_status = YY_BUFFER_NEW;
-
-       if ( b == YY_CURRENT_BUFFER )
-               yy_load_buffer_state(  );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-       if (new_buffer == NULL)
-               return;
-
-       yyensure_buffer_stack();
-
-       /* This block is copied from yy_switch_to_buffer. */
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       /* Only push if top exists. Otherwise, replace top. */
-       if (YY_CURRENT_BUFFER)
-               (yy_buffer_stack_top)++;
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-       /* copied from yy_switch_to_buffer. */
-       yy_load_buffer_state(  );
-       (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-       if (!YY_CURRENT_BUFFER)
-               return;
-
-       yy_delete_buffer(YY_CURRENT_BUFFER );
-       YY_CURRENT_BUFFER_LVALUE = NULL;
-       if ((yy_buffer_stack_top) > 0)
-               --(yy_buffer_stack_top);
-
-       if (YY_CURRENT_BUFFER) {
-               yy_load_buffer_state(  );
-               (yy_did_buffer_switch_on_eof) = 1;
-       }
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-       yy_size_t num_to_alloc;
-    
-       if (!(yy_buffer_stack)) {
-
-               /* First allocation is just for 2 elements, since we don't know if this
-                * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                * immediate realloc on the next call.
-         */
-      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-               if ( ! (yy_buffer_stack) )
-                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
-               (yy_buffer_stack_max) = num_to_alloc;
-               (yy_buffer_stack_top) = 0;
-               return;
-       }
-
-       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-               /* Increase the buffer to prepare for a possible push. */
-               yy_size_t grow_size = 8 /* arbitrary grow size */;
-
-               num_to_alloc = (yy_buffer_stack_max) + grow_size;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-                                                               ((yy_buffer_stack),
-                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-               if ( ! (yy_buffer_stack) )
-                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-               /* zero only the new slots.*/
-               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-               (yy_buffer_stack_max) = num_to_alloc;
-       }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
-       YY_BUFFER_STATE b;
-    
-       if ( size < 2 ||
-            base[size-2] != YY_END_OF_BUFFER_CHAR ||
-            base[size-1] != YY_END_OF_BUFFER_CHAR )
-               /* They forgot to leave room for the EOB's. */
-               return NULL;
-
-       b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
-       if ( ! b )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-       b->yy_buf_size = (int) (size - 2);      /* "- 2" to take care of EOB's */
-       b->yy_buf_pos = b->yy_ch_buf = base;
-       b->yy_is_our_buffer = 0;
-       b->yy_input_file = NULL;
-       b->yy_n_chars = b->yy_buf_size;
-       b->yy_is_interactive = 0;
-       b->yy_at_bol = 1;
-       b->yy_fill_buffer = 0;
-       b->yy_buffer_status = YY_BUFFER_NEW;
-
-       yy_switch_to_buffer( b  );
-
-       return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (const char * yystr )
-{
-    
-       return yy_scan_bytes( yystr, (int) strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len )
-{
-       YY_BUFFER_STATE b;
-       char *buf;
-       yy_size_t n;
-       int i;
-    
-       /* Get memory for full buffer, including space for trailing EOB's. */
-       n = (yy_size_t) (_yybytes_len + 2);
-       buf = (char *) yyalloc( n  );
-       if ( ! buf )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-       for ( i = 0; i < _yybytes_len; ++i )
-               buf[i] = yybytes[i];
-
-       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-       b = yy_scan_buffer( buf, n );
-       if ( ! b )
-               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
-       /* It's okay to grow etc. this buffer, and we should throw it
-        * away when we're done.
-        */
-       b->yy_is_our_buffer = 1;
-
-       return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yynoreturn yy_fatal_error (const char* msg )
-{
-                       fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               yytext[yyleng] = (yy_hold_char); \
-               (yy_c_buf_p) = yytext + yyless_macro_arg; \
-               (yy_hold_char) = *(yy_c_buf_p); \
-               *(yy_c_buf_p) = '\0'; \
-               yyleng = yyless_macro_arg; \
-               } \
-       while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-    
-    return yylineno;
-}
-
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
-
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
-
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
-
-/** Get the current token.
- * 
- */
-
-char *yyget_text  (void)
-{
-        return yytext;
-}
-
-/** Set the current line number.
- * @param _line_number line number
- * 
- */
-void yyset_lineno (int  _line_number )
-{
-    
-    yylineno = _line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param _in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  _in_str )
-{
-        yyin = _in_str ;
-}
-
-void yyset_out (FILE *  _out_str )
-{
-        yyout = _out_str ;
-}
-
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
-
-void yyset_debug (int  _bdebug )
-{
-        yy_flex_debug = _bdebug ;
-}
-
-static int yy_init_globals (void)
-{
-        /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    (yy_buffer_stack) = NULL;
-    (yy_buffer_stack_top) = 0;
-    (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = NULL;
-    (yy_init) = 0;
-    (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
-#else
-    yyin = NULL;
-    yyout = NULL;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-       while(YY_CURRENT_BUFFER){
-               yy_delete_buffer( YY_CURRENT_BUFFER  );
-               YY_CURRENT_BUFFER_LVALUE = NULL;
-               yypop_buffer_state();
-       }
-
-       /* Destroy the stack itself. */
-       yyfree((yy_buffer_stack) );
-       (yy_buffer_stack) = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( );
-
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, const char * s2, int n )
-{
-               
-       int i;
-       for ( i = 0; i < n; ++i )
-               s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (const char * s )
-{
-       int n;
-       for ( n = 0; s[n]; ++n )
-               ;
-
-       return n;
-}
-#endif
-
-void *yyalloc (yy_size_t  size )
-{
-                       return malloc(size);
-}
-
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
-               
-       /* The cast to (char *) in the following accommodates both
-        * implementations that use char* generic pointers, and those
-        * that use void* generic pointers.  It works with the latter
-        * because both ANSI C and C++ allow castless assignment from
-        * any pointer type to void*, and deal with argument conversions
-        * as though doing an assignment.
-        */
-       return realloc(ptr, size);
-}
-
-void yyfree (void * ptr )
-{
-                       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 81 "parserPromela.lex"
-
-
-
-
diff --git a/src/xbt/automaton/automatonparse_promela.c b/src/xbt/automaton/automatonparse_promela.c
deleted file mode 100644 (file)
index 4fad698..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* methods for implementation of automaton from promela description */
-
-/* Copyright (c) 2011-2023. 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 "src/internal_config.h"
-#include "xbt/automaton.h"
-#include <errno.h>
-#include <string.h>   /* strerror */
-#if HAVE_UNISTD_H
-# include <unistd.h>   /* isatty */
-#endif
-#include <xbt/sysdep.h>
-
-#include "parserPromela.tab.cacc"
-
-static xbt_automaton_t parsed_automaton;
-char* state_id_src;
-
-static void new_state(const char* id, int src)
-{
-  char* saveptr = NULL; // for strtok_r()
-  char* id_copy = xbt_strdup(id);
-  const char* first_part = strtok_r(id_copy, "_", &saveptr);
-  int type = 0 ; // -1=initial state; 0=intermediate state; 1=final state
-
-  if(strcmp(first_part,"accept")==0){
-    type = 1;
-  }else{
-    const char* second_part = strtok_r(NULL, "_", &saveptr);
-    if(strcmp(second_part,"init")==0){
-      type = -1;
-    }
-  }
-  xbt_free(id_copy);
-
-  xbt_automaton_state_t state = xbt_automaton_state_exists(parsed_automaton, id);
-  if(state == NULL){
-    state = xbt_automaton_state_new(parsed_automaton, type, id);
-  }
-
-  if(type==-1)
-    parsed_automaton->current_state = state;
-
-  if(src) {
-    xbt_free(state_id_src);
-    state_id_src = xbt_strdup(id);
-  }
-}
-
-static void new_transition(const char* id, xbt_automaton_exp_label_t label)
-{
-  new_state(id, 0);
-  xbt_automaton_state_t state_dst = xbt_automaton_state_exists(parsed_automaton, id);
-  xbt_automaton_state_t state_src = xbt_automaton_state_exists(parsed_automaton, state_id_src);
-
-  xbt_automaton_transition_new(parsed_automaton, state_src, state_dst, label);
-
-}
-
-void xbt_automaton_load(xbt_automaton_t a, const char *file)
-{
-  parsed_automaton = a;
-  xbt_automaton_parser_in = fopen(file, "r");
-  xbt_assert(xbt_automaton_parser_in != NULL, "Failed to open automaton file `%s': %s", file, strerror(errno));
-  xbt_automaton_parser_parse();
-  fclose(xbt_automaton_parser_in);
-}
diff --git a/src/xbt/automaton/parserPromela.lex b/src/xbt/automaton/parserPromela.lex
deleted file mode 100644 (file)
index 461c323..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2012-2023. 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. */
-
-%option noyywrap
-
-%{
-
-#include "simgrid/config.h"
-#if !HAVE_UNISTD_H
-#define YY_NO_UNISTD_H /* hello Windows */
-#endif
-
-#include <stdio.h>
-#include "parserPromela.tab.hacc"
-
-  extern YYSTYPE yylval;
-
-%}
-
-blancs       [ \t]+
-espace       [ ]+
-nouv_ligne   [ \n]
-
-chiffre      [0-9]
-entier       {chiffre}+
-reel         {entier}("."{entier})
-caractere    [a-zA-Z0-9_]
-
-numl         \n
-
-chaine       \"({caractere}*|\n|\\|\"|{espace}*)*\"
-
-commentaire  "/*"([^\*\/]*{nouv_ligne}*[^\*\/]*)*"*/"
-
-%%
-
-"never"      { return (NEVER); }
-"if"         { return (IF); }
-"fi"         { return (FI); }
-"->"         { return (IMPLIES); }
-"goto"       { return (GOTO); }
-"&&"         { return (AND); }
-"||"         { return (OR); }
-"!"          { return (NOT); }
-"("          { return (LEFT_PAR); }
-")"          { return (RIGHT_PAR); }
-"::"         { return (CASE); }
-":"          { return (COLON); }
-";"          { return (SEMI_COLON); }
-"1"          { return (CASE_TRUE); }
-"{"          { return (LEFT_BRACE); }
-"}"          { return (RIGHT_BRACE); }
-
-
-{commentaire}             { }
-
-{blancs}                  { }
-
-
-{reel}                    { sscanf(yytext,"%lf",&yylval.real);
-                            return (LITT_REEL); }
-
-{entier}                  { sscanf(yytext,"%d",&yylval.integer);
-                            return (LITT_ENT); }
-
-{chaine}                  { yylval.string=(char *)malloc(strlen(yytext)+1);
-                            sscanf(yytext,"%s",yylval.string);
-                            return (LITT_CHAINE); }
-
-[a-zA-Z]{caractere}*      { yylval.string=(char *)malloc(strlen(yytext)+1);
-                            sscanf(yytext,"%s",yylval.string);
-                                             return (ID); }
-
-{numl}                    { }
-
-.                         { }
-
-%%
-
-
diff --git a/src/xbt/automaton/parserPromela.tab.cacc b/src/xbt/automaton/parserPromela.tab.cacc
deleted file mode 100644 (file)
index 776faa8..0000000
+++ /dev/null
@@ -1,1364 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.8.2.  */
-
-/* Bison implementation for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
-   Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
-   especially those whose name start with YY_ or yy_.  They are
-   private implementation details that can be changed or removed.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output, and Bison version.  */
-#define YYBISON 30802
-
-/* Bison version string.  */
-#define YYBISON_VERSION "3.8.2"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 0
-
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-
-/* Substitute the variable and function names.  */
-#define yyparse         xbt_automaton_parser_parse
-#define yylex           xbt_automaton_parser_lex
-#define yyerror         xbt_automaton_parser_error
-#define yydebug         xbt_automaton_parser_debug
-#define yynerrs         xbt_automaton_parser_nerrs
-#define yylval          xbt_automaton_parser_lval
-#define yychar          xbt_automaton_parser_char
-
-/* First part of user prologue.  */
-#line 7 "parserPromela.yacc"
-
-#include "simgrid/config.h"
-#if !HAVE_UNISTD_H
-#define YY_NO_UNISTD_H /* hello Windows */
-#endif
-
-#include "automaton_lexer.yy.c"
-#include <xbt/automaton.h>
-
-void yyerror(const char *s);
-
-static void new_state(const char* id, int src);
-static void new_transition(const char* id, xbt_automaton_exp_label_t label);
-
-
-#line 94 "parserPromela.tab.cacc"
-
-# ifndef YY_CAST
-#  ifdef __cplusplus
-#   define YY_CAST(Type, Val) static_cast<Type> (Val)
-#   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
-#  else
-#   define YY_CAST(Type, Val) ((Type) (Val))
-#   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
-#  endif
-# endif
-# ifndef YY_NULLPTR
-#  if defined __cplusplus
-#   if 201103L <= __cplusplus
-#    define YY_NULLPTR nullptr
-#   else
-#    define YY_NULLPTR 0
-#   endif
-#  else
-#   define YY_NULLPTR ((void*)0)
-#  endif
-# endif
-
-#include "parserPromela.tab.hacc"
-/* Symbol kind.  */
-enum yysymbol_kind_t
-{
-  YYSYMBOL_YYEMPTY = -2,
-  YYSYMBOL_YYEOF = 0,                      /* "end of file"  */
-  YYSYMBOL_YYerror = 1,                    /* error  */
-  YYSYMBOL_YYUNDEF = 2,                    /* "invalid token"  */
-  YYSYMBOL_NEVER = 3,                      /* NEVER  */
-  YYSYMBOL_IF = 4,                         /* IF  */
-  YYSYMBOL_FI = 5,                         /* FI  */
-  YYSYMBOL_IMPLIES = 6,                    /* IMPLIES  */
-  YYSYMBOL_GOTO = 7,                       /* GOTO  */
-  YYSYMBOL_AND = 8,                        /* AND  */
-  YYSYMBOL_OR = 9,                         /* OR  */
-  YYSYMBOL_NOT = 10,                       /* NOT  */
-  YYSYMBOL_LEFT_PAR = 11,                  /* LEFT_PAR  */
-  YYSYMBOL_RIGHT_PAR = 12,                 /* RIGHT_PAR  */
-  YYSYMBOL_CASE = 13,                      /* CASE  */
-  YYSYMBOL_COLON = 14,                     /* COLON  */
-  YYSYMBOL_SEMI_COLON = 15,                /* SEMI_COLON  */
-  YYSYMBOL_CASE_TRUE = 16,                 /* CASE_TRUE  */
-  YYSYMBOL_LEFT_BRACE = 17,                /* LEFT_BRACE  */
-  YYSYMBOL_RIGHT_BRACE = 18,               /* RIGHT_BRACE  */
-  YYSYMBOL_LITT_ENT = 19,                  /* LITT_ENT  */
-  YYSYMBOL_LITT_CHAINE = 20,               /* LITT_CHAINE  */
-  YYSYMBOL_LITT_REEL = 21,                 /* LITT_REEL  */
-  YYSYMBOL_ID = 22,                        /* ID  */
-  YYSYMBOL_YYACCEPT = 23,                  /* $accept  */
-  YYSYMBOL_automaton = 24,                 /* automaton  */
-  YYSYMBOL_stateseq = 25,                  /* stateseq  */
-  YYSYMBOL_26_1 = 26,                      /* $@1  */
-  YYSYMBOL_option = 27,                    /* option  */
-  YYSYMBOL_exp = 28                        /* exp  */
-};
-typedef enum yysymbol_kind_t yysymbol_kind_t;
-
-
-
-
-#ifdef short
-# undef short
-#endif
-
-/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
-   <limits.h> and (if available) <stdint.h> are included
-   so that the code can choose integer types of a good width.  */
-
-#ifndef __PTRDIFF_MAX__
-# include <limits.h> /* INFRINGES ON USER NAME SPACE */
-# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
-#  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
-#  define YY_STDINT_H
-# endif
-#endif
-
-/* Narrow types that promote to a signed type and that can represent a
-   signed or unsigned integer of at least N bits.  In tables they can
-   save space and decrease cache pressure.  Promoting to a signed type
-   helps avoid bugs in integer arithmetic.  */
-
-#ifdef __INT_LEAST8_MAX__
-typedef __INT_LEAST8_TYPE__ yytype_int8;
-#elif defined YY_STDINT_H
-typedef int_least8_t yytype_int8;
-#else
-typedef signed char yytype_int8;
-#endif
-
-#ifdef __INT_LEAST16_MAX__
-typedef __INT_LEAST16_TYPE__ yytype_int16;
-#elif defined YY_STDINT_H
-typedef int_least16_t yytype_int16;
-#else
-typedef short yytype_int16;
-#endif
-
-/* Work around bug in HP-UX 11.23, which defines these macros
-   incorrectly for preprocessor constants.  This workaround can likely
-   be removed in 2023, as HPE has promised support for HP-UX 11.23
-   (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
-   <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>.  */
-#ifdef __hpux
-# undef UINT_LEAST8_MAX
-# undef UINT_LEAST16_MAX
-# define UINT_LEAST8_MAX 255
-# define UINT_LEAST16_MAX 65535
-#endif
-
-#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
-typedef __UINT_LEAST8_TYPE__ yytype_uint8;
-#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
-       && UINT_LEAST8_MAX <= INT_MAX)
-typedef uint_least8_t yytype_uint8;
-#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
-typedef unsigned char yytype_uint8;
-#else
-typedef short yytype_uint8;
-#endif
-
-#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
-typedef __UINT_LEAST16_TYPE__ yytype_uint16;
-#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
-       && UINT_LEAST16_MAX <= INT_MAX)
-typedef uint_least16_t yytype_uint16;
-#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
-typedef unsigned short yytype_uint16;
-#else
-typedef int yytype_uint16;
-#endif
-
-#ifndef YYPTRDIFF_T
-# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
-#  define YYPTRDIFF_T __PTRDIFF_TYPE__
-#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
-# elif defined PTRDIFF_MAX
-#  ifndef ptrdiff_t
-#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  endif
-#  define YYPTRDIFF_T ptrdiff_t
-#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
-# else
-#  define YYPTRDIFF_T long
-#  define YYPTRDIFF_MAXIMUM LONG_MAX
-# endif
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM                                  \
-  YY_CAST (YYPTRDIFF_T,                                 \
-           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
-            ? YYPTRDIFF_MAXIMUM                         \
-            : YY_CAST (YYSIZE_T, -1)))
-
-#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
-
-
-/* Stored state numbers (used for stacks). */
-typedef yytype_int8 yy_state_t;
-
-/* State numbers in computations.  */
-typedef int yy_state_fast_t;
-
-#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-
-#ifndef YY_ATTRIBUTE_PURE
-# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
-#  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
-# else
-#  define YY_ATTRIBUTE_PURE
-# endif
-#endif
-
-#ifndef YY_ATTRIBUTE_UNUSED
-# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
-#  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-# else
-#  define YY_ATTRIBUTE_UNUSED
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YY_USE(E) ((void) (E))
-#else
-# define YY_USE(E) /* empty */
-#endif
-
-/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
-# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
-#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
-    _Pragma ("GCC diagnostic push")                                     \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
-# else
-#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
-    _Pragma ("GCC diagnostic push")                                     \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
-    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# endif
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
-    _Pragma ("GCC diagnostic pop")
-#else
-# define YY_INITIAL_VALUE(Value) Value
-#endif
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
-
-#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
-# define YY_IGNORE_USELESS_CAST_BEGIN                          \
-    _Pragma ("GCC diagnostic push")                            \
-    _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
-# define YY_IGNORE_USELESS_CAST_END            \
-    _Pragma ("GCC diagnostic pop")
-#endif
-#ifndef YY_IGNORE_USELESS_CAST_BEGIN
-# define YY_IGNORE_USELESS_CAST_BEGIN
-# define YY_IGNORE_USELESS_CAST_END
-#endif
-
-
-#define YY_ASSERT(E) ((void) (0 && (E)))
-
-#if !defined yyoverflow
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's 'empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
-       && ! ((defined YYMALLOC || defined malloc) \
-             && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* !defined yyoverflow */
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yy_state_t yyss_alloc;
-  YYSTYPE yyvs_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
-      + YYSTACK_GAP_MAXIMUM)
-
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
-    do                                                                  \
-      {                                                                 \
-        YYPTRDIFF_T yynewbytes;                                         \
-        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-        Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
-      }                                                                 \
-    while (0)
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYPTRDIFF_T yyi;                      \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (0)
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  4
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   28
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  23
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  6
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  13
-/* YYNSTATES -- Number of states.  */
-#define YYNSTATES  32
-
-/* YYMAXUTOK -- Last valid token kind.  */
-#define YYMAXUTOK   277
-
-
-/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, with out-of-bounds checking.  */
-#define YYTRANSLATE(YYX)                                \
-  (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
-   ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
-   : YYSYMBOL_YYUNDEF)
-
-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex.  */
-static const yytype_int8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22
-};
-
-#if YYDEBUG
-/* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_int8 yyrline[] =
-{
-       0,    60,    60,    63,    64,    64,    67,    68,    71,    72,
-      73,    74,    75,    76
-};
-#endif
-
-/** Accessing symbol of state STATE.  */
-#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
-
-#if YYDEBUG || 0
-/* The user-facing name of the symbol whose (internal) number is
-   YYSYMBOL.  No bounds checking.  */
-static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
-
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "\"end of file\"", "error", "\"invalid token\"", "NEVER", "IF", "FI",
-  "IMPLIES", "GOTO", "AND", "OR", "NOT", "LEFT_PAR", "RIGHT_PAR", "CASE",
-  "COLON", "SEMI_COLON", "CASE_TRUE", "LEFT_BRACE", "RIGHT_BRACE",
-  "LITT_ENT", "LITT_CHAINE", "LITT_REEL", "ID", "$accept", "automaton",
-  "stateseq", "$@1", "option", "exp", YY_NULLPTR
-};
-
-static const char *
-yysymbol_name (yysymbol_kind_t yysymbol)
-{
-  return yytname[yysymbol];
-}
-#endif
-
-#define YYPACT_NINF (-16)
-
-#define yypact_value_is_default(Yyn) \
-  ((Yyn) == YYPACT_NINF)
-
-#define YYTABLE_NINF (-1)
-
-#define yytable_value_is_error(Yyn) \
-  0
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-static const yytype_int8 yypact[] =
-{
-       0,   -15,    10,   -13,   -16,     2,     1,   -16,   -16,    16,
-       8,   -10,    17,   -10,   -10,   -16,   -16,     9,    11,   -16,
-      -1,    18,   -10,   -10,   -13,   -16,     5,   -16,   -16,   -16,
-       8,   -16
-};
-
-/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE does not specify something else to do.  Zero
-   means the default is an error.  */
-static const yytype_int8 yydefact[] =
-{
-       0,     0,     0,     3,     1,     0,     0,     4,     2,     0,
-       6,     0,     0,     0,     0,    12,    13,     0,     0,    11,
-       0,     0,     0,     0,     3,     8,     0,    10,     9,     5,
-       6,     7
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int8 yypgoto[] =
-{
-     -16,   -16,     4,   -16,    -7,    -9
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int8 yydefgoto[] =
-{
-       0,     2,     6,     9,    12,    17
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
-   positive, shift that token.  If negative, reduce the rule whose
-   number is the opposite.  If YYTABLE_NINF, syntax error.  */
-static const yytype_int8 yytable[] =
-{
-      13,    14,     3,     1,    19,    20,    15,    22,    23,     5,
-       4,    25,    16,    27,    28,    21,     7,    22,    23,     8,
-      10,    11,    18,    31,     0,    26,    24,    30,    29
-};
-
-static const yytype_int8 yycheck[] =
-{
-      10,    11,    17,     3,    13,    14,    16,     8,     9,    22,
-       0,    12,    22,    22,    23,     6,    14,     8,     9,    18,
-       4,    13,     5,    30,    -1,     7,    15,    22,    24
-};
-
-/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
-   state STATE-NUM.  */
-static const yytype_int8 yystos[] =
-{
-       0,     3,    24,    17,     0,    22,    25,    14,    18,    26,
-       4,    13,    27,    10,    11,    16,    22,    28,     5,    28,
-      28,     6,     8,     9,    15,    12,     7,    28,    28,    25,
-      22,    27
-};
-
-/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
-static const yytype_int8 yyr1[] =
-{
-       0,    23,    24,    25,    26,    25,    27,    27,    28,    28,
-      28,    28,    28,    28
-};
-
-/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.  */
-static const yytype_int8 yyr2[] =
-{
-       0,     2,     4,     0,     0,     8,     0,     6,     3,     3,
-       3,     2,     1,     1
-};
-
-
-enum { YYENOMEM = -2 };
-
-#define yyerrok         (yyerrstatus = 0)
-#define yyclearin       (yychar = YYEMPTY)
-
-#define YYACCEPT        goto yyacceptlab
-#define YYABORT         goto yyabortlab
-#define YYERROR         goto yyerrorlab
-#define YYNOMEM         goto yyexhaustedlab
-
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                    \
-  do                                                              \
-    if (yychar == YYEMPTY)                                        \
-      {                                                           \
-        yychar = (Token);                                         \
-        yylval = (Value);                                         \
-        YYPOPSTACK (yylen);                                       \
-        yystate = *yyssp;                                         \
-        goto yybackup;                                            \
-      }                                                           \
-    else                                                          \
-      {                                                           \
-        yyerror (YY_("syntax error: cannot back up")); \
-        YYERROR;                                                  \
-      }                                                           \
-  while (0)
-
-/* Backward compatibility with an undocumented macro.
-   Use YYerror or YYUNDEF. */
-#define YYERRCODE YYUNDEF
-
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                        \
-do {                                            \
-  if (yydebug)                                  \
-    YYFPRINTF Args;                             \
-} while (0)
-
-
-
-
-# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                    \
-do {                                                                      \
-  if (yydebug)                                                            \
-    {                                                                     \
-      YYFPRINTF (stderr, "%s ", Title);                                   \
-      yy_symbol_print (stderr,                                            \
-                  Kind, Value); \
-      YYFPRINTF (stderr, "\n");                                           \
-    }                                                                     \
-} while (0)
-
-
-/*-----------------------------------.
-| Print this symbol's value on YYO.  |
-`-----------------------------------*/
-
-static void
-yy_symbol_value_print (FILE *yyo,
-                       yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
-{
-  FILE *yyoutput = yyo;
-  YY_USE (yyoutput);
-  if (!yyvaluep)
-    return;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  YY_USE (yykind);
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-/*---------------------------.
-| Print this symbol on YYO.  |
-`---------------------------*/
-
-static void
-yy_symbol_print (FILE *yyo,
-                 yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
-{
-  YYFPRINTF (yyo, "%s %s (",
-             yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
-
-  yy_symbol_value_print (yyo, yykind, yyvaluep);
-  YYFPRINTF (yyo, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-static void
-yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)                            \
-do {                                                            \
-  if (yydebug)                                                  \
-    yy_stack_print ((Bottom), (Top));                           \
-} while (0)
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-static void
-yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
-                 int yyrule)
-{
-  int yylno = yyrline[yyrule];
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
-             yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr,
-                       YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
-                       &yyvsp[(yyi + 1) - (yynrhs)]);
-      YYFPRINTF (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)          \
-do {                                    \
-  if (yydebug)                          \
-    yy_reduce_print (yyssp, yyvsp, Rule); \
-} while (0)
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args) ((void) 0)
-# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-
-
-
-
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-static void
-yydestruct (const char *yymsg,
-            yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
-{
-  YY_USE (yyvaluep);
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  YY_USE (yykind);
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-}
-
-
-/* Lookahead token kind.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-/* Number of syntax errors so far.  */
-int yynerrs;
-
-
-
-
-/*----------.
-| yyparse.  |
-`----------*/
-
-int
-yyparse (void)
-{
-    yy_state_fast_t yystate = 0;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus = 0;
-
-    /* Refer to the stacks through separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* Their size.  */
-    YYPTRDIFF_T yystacksize = YYINITDEPTH;
-
-    /* The state stack: array, bottom, top.  */
-    yy_state_t yyssa[YYINITDEPTH];
-    yy_state_t *yyss = yyssa;
-    yy_state_t *yyssp = yyss;
-
-    /* The semantic value stack: array, bottom, top.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs = yyvsa;
-    YYSTYPE *yyvsp = yyvs;
-
-  int yyn;
-  /* The return value of yyparse.  */
-  int yyresult;
-  /* Lookahead symbol kind.  */
-  yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
-
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yychar = YYEMPTY; /* Cause a token to be read.  */
-
-  goto yysetstate;
-
-
-/*------------------------------------------------------------.
-| yynewstate -- push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
-yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
-
-/*--------------------------------------------------------------------.
-| yysetstate -- set current state (the top of the stack) to yystate.  |
-`--------------------------------------------------------------------*/
-yysetstate:
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-  YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
-  YY_IGNORE_USELESS_CAST_BEGIN
-  *yyssp = YY_CAST (yy_state_t, yystate);
-  YY_IGNORE_USELESS_CAST_END
-  YY_STACK_PRINT (yyss, yyssp);
-
-  if (yyss + yystacksize - 1 <= yyssp)
-#if !defined yyoverflow && !defined YYSTACK_RELOCATE
-    YYNOMEM;
-#else
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYPTRDIFF_T yysize = yyssp - yyss + 1;
-
-# if defined yyoverflow
-      {
-        /* Give user a chance to reallocate the stack.  Use copies of
-           these so that the &'s don't force the real ones into
-           memory.  */
-        yy_state_t *yyss1 = yyss;
-        YYSTYPE *yyvs1 = yyvs;
-
-        /* Each stack pointer address is followed by the size of the
-           data in use in that stack, in bytes.  This used to be a
-           conditional around just the two extra args, but that might
-           be undefined if yyoverflow is a macro.  */
-        yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * YYSIZEOF (*yyssp),
-                    &yyvs1, yysize * YYSIZEOF (*yyvsp),
-                    &yystacksize);
-        yyss = yyss1;
-        yyvs = yyvs1;
-      }
-# else /* defined YYSTACK_RELOCATE */
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-        YYNOMEM;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-        yystacksize = YYMAXDEPTH;
-
-      {
-        yy_state_t *yyss1 = yyss;
-        union yyalloc *yyptr =
-          YY_CAST (union yyalloc *,
-                   YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
-        if (! yyptr)
-          YYNOMEM;
-        YYSTACK_RELOCATE (yyss_alloc, yyss);
-        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
-        if (yyss1 != yyssa)
-          YYSTACK_FREE (yyss1);
-      }
-# endif
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-
-      YY_IGNORE_USELESS_CAST_BEGIN
-      YYDPRINTF ((stderr, "Stack size increased to %ld\n",
-                  YY_CAST (long, yystacksize)));
-      YY_IGNORE_USELESS_CAST_END
-
-      if (yyss + yystacksize - 1 <= yyssp)
-        YYABORT;
-    }
-#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
-
-
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
-  goto yybackup;
-
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-  /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-  yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
-    goto yydefault;
-
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* YYCHAR is either empty, or end-of-input, or a valid lookahead.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token\n"));
-      yychar = yylex ();
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = YYEOF;
-      yytoken = YYSYMBOL_YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else if (yychar == YYerror)
-    {
-      /* The scanner already issued an error message, process directly
-         to error recovery.  But do not keep the error token as
-         lookahead, it is too special and may lead us to an endless
-         loop in error recovery. */
-      yychar = YYUNDEF;
-      yytoken = YYSYMBOL_YYerror;
-      goto yyerrlab1;
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-  yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     '$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-  case 4: /* $@1: %empty  */
-#line 64 "parserPromela.yacc"
-                    { new_state((yyvsp[-1].string), 1);}
-#line 1116 "parserPromela.tab.cacc"
-    break;
-
-  case 7: /* option: CASE exp IMPLIES GOTO ID option  */
-#line 68 "parserPromela.yacc"
-                                         { new_transition((yyvsp[-1].string), (yyvsp[-4].label));}
-#line 1122 "parserPromela.tab.cacc"
-    break;
-
-  case 8: /* exp: LEFT_PAR exp RIGHT_PAR  */
-#line 71 "parserPromela.yacc"
-                             { (yyval.label) = (yyvsp[-1].label); }
-#line 1128 "parserPromela.tab.cacc"
-    break;
-
-  case 9: /* exp: exp OR exp  */
-#line 72 "parserPromela.yacc"
-                 { (yyval.label) = xbt_automaton_exp_label_new_or((yyvsp[-2].label), (yyvsp[0].label)); }
-#line 1134 "parserPromela.tab.cacc"
-    break;
-
-  case 10: /* exp: exp AND exp  */
-#line 73 "parserPromela.yacc"
-                  { (yyval.label) = xbt_automaton_exp_label_new_and((yyvsp[-2].label), (yyvsp[0].label)); }
-#line 1140 "parserPromela.tab.cacc"
-    break;
-
-  case 11: /* exp: NOT exp  */
-#line 74 "parserPromela.yacc"
-              { (yyval.label) = xbt_automaton_exp_label_new_not((yyvsp[0].label)); }
-#line 1146 "parserPromela.tab.cacc"
-    break;
-
-  case 12: /* exp: CASE_TRUE  */
-#line 75 "parserPromela.yacc"
-                { (yyval.label) = xbt_automaton_exp_label_new_one(); }
-#line 1152 "parserPromela.tab.cacc"
-    break;
-
-  case 13: /* exp: ID  */
-#line 76 "parserPromela.yacc"
-         { (yyval.label) = xbt_automaton_exp_label_new_predicat((yyvsp[0].string)); }
-#line 1158 "parserPromela.tab.cacc"
-    break;
-
-
-#line 1162 "parserPromela.tab.cacc"
-
-      default: break;
-    }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
-  YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-
-  *++yyvsp = yyval;
-
-  /* Now 'shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-  {
-    const int yylhs = yyr1[yyn] - YYNTOKENS;
-    const int yyi = yypgoto[yylhs] + *yyssp;
-    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
-               ? yytable[yyi]
-               : yydefgoto[yylhs]);
-  }
-
-  goto yynewstate;
-
-
-/*--------------------------------------.
-| yyerrlab -- here on detecting error.  |
-`--------------------------------------*/
-yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-      yyerror (YY_("syntax error"));
-    }
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse lookahead token after an
-         error, discard it.  */
-
-      if (yychar <= YYEOF)
-        {
-          /* Return failure if at end of input.  */
-          if (yychar == YYEOF)
-            YYABORT;
-        }
-      else
-        {
-          yydestruct ("Error: discarding",
-                      yytoken, &yylval);
-          yychar = YYEMPTY;
-        }
-    }
-
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-  /* Pacify compilers when the user code never invokes YYERROR and the
-     label yyerrorlab therefore never appears in user code.  */
-  if (0)
-    YYERROR;
-  ++yynerrs;
-
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
-
-  /* Pop stack until we find a state that shifts the error token.  */
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
-        {
-          yyn += YYSYMBOL_YYerror;
-          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
-            {
-              yyn = yytable[yyn];
-              if (0 < yyn)
-                break;
-            }
-        }
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-        YYABORT;
-
-
-      yydestruct ("Error: popping",
-                  YY_ACCESSING_SYMBOL (yystate), yyvsp);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-  *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
-
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturnlab;
-
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturnlab;
-
-
-/*-----------------------------------------------------------.
-| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here.  |
-`-----------------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (YY_("memory exhausted"));
-  yyresult = 2;
-  goto yyreturnlab;
-
-
-/*----------------------------------------------------------.
-| yyreturnlab -- parsing is finished, clean up and return.  |
-`----------------------------------------------------------*/
-yyreturnlab:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval);
-    }
-  /* Do not reclaim the symbols of the rule whose action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-                  YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-
-  return yyresult;
-}
-
-#line 79 "parserPromela.yacc"
-
-
-
-
-void yyerror(const char *s){
-  fprintf (stderr, "%s\n", s);
-}
-
-
-
diff --git a/src/xbt/automaton/parserPromela.tab.hacc b/src/xbt/automaton/parserPromela.tab.hacc
deleted file mode 100644 (file)
index 9579e0b..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* A Bison parser, made by GNU Bison 3.8.2.  */
-
-/* Bison interface for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
-   Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
-   especially those whose name start with YY_ or yy_.  They are
-   private implementation details that can be changed or removed.  */
-
-#ifndef YY_XBT_AUTOMATON_PARSER_PARSERPROMELA_TAB_HACC_INCLUDED
-# define YY_XBT_AUTOMATON_PARSER_PARSERPROMELA_TAB_HACC_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
-#if YYDEBUG
-extern int xbt_automaton_parser_debug;
-#endif
-
-/* Token kinds.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-  enum yytokentype
-  {
-    YYEMPTY = -2,
-    YYEOF = 0,                     /* "end of file"  */
-    YYerror = 256,                 /* error  */
-    YYUNDEF = 257,                 /* "invalid token"  */
-    NEVER = 258,                   /* NEVER  */
-    IF = 259,                      /* IF  */
-    FI = 260,                      /* FI  */
-    IMPLIES = 261,                 /* IMPLIES  */
-    GOTO = 262,                    /* GOTO  */
-    AND = 263,                     /* AND  */
-    OR = 264,                      /* OR  */
-    NOT = 265,                     /* NOT  */
-    LEFT_PAR = 266,                /* LEFT_PAR  */
-    RIGHT_PAR = 267,               /* RIGHT_PAR  */
-    CASE = 268,                    /* CASE  */
-    COLON = 269,                   /* COLON  */
-    SEMI_COLON = 270,              /* SEMI_COLON  */
-    CASE_TRUE = 271,               /* CASE_TRUE  */
-    LEFT_BRACE = 272,              /* LEFT_BRACE  */
-    RIGHT_BRACE = 273,             /* RIGHT_BRACE  */
-    LITT_ENT = 274,                /* LITT_ENT  */
-    LITT_CHAINE = 275,             /* LITT_CHAINE  */
-    LITT_REEL = 276,               /* LITT_REEL  */
-    ID = 277                       /* ID  */
-  };
-  typedef enum yytokentype yytoken_kind_t;
-#endif
-
-/* Value type.  */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-union YYSTYPE
-{
-#line 23 "parserPromela.yacc"
-
-  double real;
-  int integer;
-  char* string;
-  xbt_automaton_exp_label_t label;
-
-#line 93 "parserPromela.tab.hacc"
-
-};
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-
-extern YYSTYPE xbt_automaton_parser_lval;
-
-
-int xbt_automaton_parser_parse (void);
-
-
-#endif /* !YY_XBT_AUTOMATON_PARSER_PARSERPROMELA_TAB_HACC_INCLUDED  */
diff --git a/src/xbt/automaton/parserPromela.yacc b/src/xbt/automaton/parserPromela.yacc
deleted file mode 100644 (file)
index 05bb382..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (c) 2012-2023. 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 "simgrid/config.h"
-#if !HAVE_UNISTD_H
-#define YY_NO_UNISTD_H /* hello Windows */
-#endif
-
-#include "automaton_lexer.yy.c"
-#include <xbt/automaton.h>
-
-void yyerror(const char *s);
-
-static void new_state(const char* id, int src);
-static void new_transition(const char* id, xbt_automaton_exp_label_t label);
-
-%}
-
-%union{
-  double real;
-  int integer;
-  char* string;
-  xbt_automaton_exp_label_t label;
-}
-
-%token NEVER
-%token IF
-%token FI
-%token IMPLIES
-%token GOTO
-%token AND
-%token OR
-%token NOT
-%token LEFT_PAR
-%token RIGHT_PAR
-%token CASE
-%token COLON
-%token SEMI_COLON
-%token CASE_TRUE
-%token LEFT_BRACE
-%token RIGHT_BRACE
-%token <integer> LITT_ENT
-%token <string> LITT_CHAINE
-%token <real> LITT_REEL
-%token <string> ID
-
-%type <label> exp;
-
-%start automaton
-
-%left AND OR
-%nonassoc NOT
-
-%%
-
-automaton : NEVER LEFT_BRACE stateseq RIGHT_BRACE
-          ;
-
-stateseq :
-         | ID COLON { new_state($1, 1);} IF option FI SEMI_COLON stateseq
-         ;
-
-option :
-       | CASE exp IMPLIES GOTO ID option { new_transition($5, $2);}
-       ;
-
-exp : LEFT_PAR exp RIGHT_PAR { $$ = $2; }
-    | exp OR exp { $$ = xbt_automaton_exp_label_new_or($1, $3); }
-    | exp AND exp { $$ = xbt_automaton_exp_label_new_and($1, $3); }
-    | NOT exp { $$ = xbt_automaton_exp_label_new_not($2); }
-    | CASE_TRUE { $$ = xbt_automaton_exp_label_new_one(); }
-    | ID { $$ = xbt_automaton_exp_label_new_predicat($1); }
-    ;
-
-%%
-
-
-
-void yyerror(const char *s){
-  fprintf (stderr, "%s\n", s);
-}
-
-
-
diff --git a/src/xbt/mmalloc/mfree.c b/src/xbt/mmalloc/mfree.c
deleted file mode 100644 (file)
index 8572826..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/* Free a block of memory allocated by `mmalloc'. */
-
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright 1990, 1991, 1992 Free Software Foundation
-
-   Written May 1989 by Mike Haertel.
-   Heavily modified Mar 1992 by Fred Fish.  (fnf@cygnus.com) */
-
-#include "mmprivate.h"
-#include "src/mc/mc.h"
-
-/* Return memory to the heap.
-   Like `mfree' but don't call a mfree_hook if there is one.  */
-
-/* Return memory to the heap.  */
-void mfree(struct mdesc *mdp, void *ptr)
-{
-  size_t frag_nb;
-  size_t i;
-  size_t it;
-
-  if (ptr == NULL)
-    return;
-
-  size_t block = BLOCK(ptr);
-
-  if ((char *) ptr < (char *) mdp->heapbase || block > mdp->heapsize) {
-    if ((char*)ptr <= (char*)mmalloc_preinit_buffer + mmalloc_preinit_buffer_size &&
-        (char*)ptr >= (char*)mmalloc_preinit_buffer)
-      /* This points to the static buffer for fake mallocs done by dlsym before mmalloc initialization, ignore it */
-      return;
-
-    fprintf(stderr,"Ouch, this pointer is not mine, I refuse to free it. Give me valid pointers, or give me death!!\n");
-    abort();
-  }
-
-  int type = mdp->heapinfo[block].type;
-
-  switch (type) {
-  case MMALLOC_TYPE_HEAPINFO:
-    fprintf(stderr, "Asked to free a fragment in a heapinfo block. I'm confused.\n");
-    abort();
-    break;
-
-  case MMALLOC_TYPE_FREE: /* Already free */
-    fprintf(stderr, "Asked to free a fragment in a block that is already free. I'm puzzled.\n");
-    abort();
-    break;
-
-  case MMALLOC_TYPE_UNFRAGMENTED:
-    /* Get as many statistics as early as we can.  */
-    mdp -> heapstats.chunks_used--;
-    mdp -> heapstats.bytes_used -=
-      mdp -> heapinfo[block].busy_block.size * BLOCKSIZE;
-    mdp -> heapstats.bytes_free +=
-      mdp -> heapinfo[block].busy_block.size * BLOCKSIZE;
-
-    if (MC_is_active() && mdp->heapinfo[block].busy_block.ignore > 0)
-      MC_unignore_heap(ptr, mdp->heapinfo[block].busy_block.busy_size);
-
-    /* Find the free cluster previous to this one in the free list.
-       Start searching at the last block referenced; this may benefit
-       programs with locality of allocation.  */
-    i = mdp->heapindex;
-    if (i > block) {
-      while (i > block) {
-        i = mdp->heapinfo[i].free_block.prev;
-      }
-    } else {
-      do {
-        i = mdp->heapinfo[i].free_block.next;
-      }
-      while ((i != 0) && (i < block));
-      i = mdp->heapinfo[i].free_block.prev;
-    }
-
-    /* Determine how to link this block into the free list.  */
-    if (block == i + mdp->heapinfo[i].free_block.size) {
-
-      /* Coalesce this block with its predecessor.  */
-      mdp->heapinfo[i].free_block.size += mdp->heapinfo[block].busy_block.size;
-      /* Mark all my ex-blocks as free */
-      for (it=0; it<mdp->heapinfo[block].busy_block.size; it++) {
-        if (mdp->heapinfo[block+it].type < 0) {
-          fprintf(stderr,
-                  "Internal Error: Asked to free a block already marked as free (block=%zu it=%zu type=%d). "
-                  "Please report this bug.\n",
-                  block, it, mdp->heapinfo[block].type);
-          abort();
-        }
-        mdp->heapinfo[block+it].type = MMALLOC_TYPE_FREE;
-      }
-
-      block = i;
-    } else {
-      /* Really link this block back into the free list.  */
-      mdp->heapinfo[block].free_block.size = mdp->heapinfo[block].busy_block.size;
-      mdp->heapinfo[block].free_block.next = mdp->heapinfo[i].free_block.next;
-      mdp->heapinfo[block].free_block.prev = i;
-      mdp->heapinfo[i].free_block.next = block;
-      mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = block;
-      mdp -> heapstats.chunks_free++;
-      /* Mark all my ex-blocks as free */
-      for (it=0; it<mdp->heapinfo[block].free_block.size; it++) {
-        if (mdp->heapinfo[block+it].type <0) {
-          fprintf(stderr,
-                  "Internal error: Asked to free a block already marked as free (block=%zu it=%zu/%zu type=%d). "
-                  "Please report this bug.\n",
-                  block, it, mdp->heapinfo[block].free_block.size, mdp->heapinfo[block].type);
-          abort();
-        }
-        mdp->heapinfo[block+it].type = MMALLOC_TYPE_FREE;
-      }
-    }
-
-    /* Now that the block is linked in, see if we can coalesce it
-       with its successor (by deleting its successor from the list
-       and adding in its size).  */
-    if (block + mdp->heapinfo[block].free_block.size ==
-        mdp->heapinfo[block].free_block.next) {
-      mdp->heapinfo[block].free_block.size
-        += mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.size;
-      mdp->heapinfo[block].free_block.next
-        = mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.next;
-      mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev = block;
-      mdp -> heapstats.chunks_free--;
-    }
-
-    /* Now see if we can return stuff to the system.  */
-#if 0
-          blocks = mdp -> heapinfo[block].free.size;
-          if (blocks >= FINAL_FREE_BLOCKS && block + blocks == mdp -> heaplimit
-          && mdp -> morecore (mdp, 0) == ADDRESS (block + blocks))
-          {
-          register size_t bytes = blocks * BLOCKSIZE;
-          mdp -> heaplimit -= blocks;
-          mdp -> morecore (mdp, -bytes);
-          mdp -> heapinfo[mdp -> heapinfo[block].free.prev].free.next
-          = mdp -> heapinfo[block].free.next;
-          mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev
-          = mdp -> heapinfo[block].free.prev;
-          block = mdp -> heapinfo[block].free.prev;
-          mdp -> heapstats.chunks_free--;
-          mdp -> heapstats.bytes_free -= bytes;
-          }
-#endif
-
-    /* Set the next search to begin at this block.
-       This is probably important to the trick where realloc returns the block to
-       the system before reasking for the same block with a bigger size.  */
-    mdp->heapindex = block;
-    break;
-
-  default:
-    if (type < 0) {
-      fprintf(stderr, "Unknown mmalloc block type.\n");
-      abort();
-    }
-
-    /* Do some of the statistics.  */
-    mdp -> heapstats.chunks_used--;
-    mdp -> heapstats.bytes_used -= 1 << type;
-    mdp -> heapstats.chunks_free++;
-    mdp -> heapstats.bytes_free += 1 << type;
-
-    frag_nb = RESIDUAL(ptr, BLOCKSIZE) >> type;
-
-    if( mdp->heapinfo[block].busy_frag.frag_size[frag_nb] == -1){
-      fprintf(stderr, "Asked to free a fragment that is already free. I'm puzzled\n");
-      abort();
-    }
-
-    if (MC_is_active() && mdp->heapinfo[block].busy_frag.ignore[frag_nb] > 0)
-      MC_unignore_heap(ptr, mdp->heapinfo[block].busy_frag.frag_size[frag_nb]);
-
-    /* Set size used in the fragment to -1 */
-    mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = -1;
-    mdp->heapinfo[block].busy_frag.ignore[frag_nb] = 0;
-
-    if (mdp->heapinfo[block].busy_frag.nfree ==
-        (BLOCKSIZE >> type) - 1) {
-      /* If all fragments of this block are free, remove this block from its swag and free the whole block.  */
-      xbt_swag_remove(&mdp->heapinfo[block],&mdp->fraghead[type]);
-
-      /* pretend that this block is used and free it so that it gets properly coalesced with adjacent free blocks */
-      mdp->heapinfo[block].type = MMALLOC_TYPE_UNFRAGMENTED;
-      mdp->heapinfo[block].busy_block.size = 1;
-      mdp->heapinfo[block].busy_block.busy_size = 0;
-
-      /* Keep the statistics accurate.  */
-      mdp -> heapstats.chunks_used++;
-      mdp -> heapstats.bytes_used += BLOCKSIZE;
-      mdp -> heapstats.chunks_free -= BLOCKSIZE >> type;
-      mdp -> heapstats.bytes_free -= BLOCKSIZE;
-
-      mfree(mdp, ADDRESS(block));
-    } else if (mdp->heapinfo[block].busy_frag.nfree != 0) {
-      /* If some fragments of this block are free, you know what? I'm already happy. */
-      ++mdp->heapinfo[block].busy_frag.nfree;
-    } else {
-      /* No fragments of this block were free before the one we just released,
-       * so add this block to the swag and announce that
-       it is the first free fragment of this block. */
-      mdp->heapinfo[block].busy_frag.nfree = 1;
-      mdp->heapinfo[block].freehook.prev = NULL;
-      mdp->heapinfo[block].freehook.next = NULL;
-
-      xbt_swag_insert(&mdp->heapinfo[block],&mdp->fraghead[type]);
-    }
-    break;
-  }
-}
diff --git a/src/xbt/mmalloc/mm.c b/src/xbt/mmalloc/mm.c
deleted file mode 100644 (file)
index 9945155..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Build the entire mmalloc library as a single object module. This
-   avoids having clients pick up part of their allocation routines
-   from mmalloc and part from libc, which results in undefined
-   behavior.  It should also still be possible to build the library
-   as a standard library with multiple objects. */
-
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright 1996, 2000 Free Software Foundation  */
-
-#define _GNU_SOURCE
-#include "src/internal_config.h"
-#if HAVE_UNISTD_H
-#include <unistd.h>             /* Prototypes for lseek, sbrk (maybe) */
-#endif
-
-#include "swag.c"
-#include "mfree.c"
-#include "mmalloc.c"
-#include "mrealloc.c"
-#include "mmorecore.c"
-#include "mm_legacy.c"
-#include "mm_module.c"
diff --git a/src/xbt/mmalloc/mm_interface.c b/src/xbt/mmalloc/mm_interface.c
deleted file mode 100644 (file)
index 967bf2f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* External interface to a mmap'd malloc managed region. */
-
-/* Copyright (c) 2012-2023. 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. */
-
-/* Copyright 1992, 2000 Free Software Foundation, Inc.
-
-   Contributed by Fred Fish at Cygnus Support.   fnf@cygnus.com
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <fcntl.h> /* After sys/types.h, at least for dpx/2.  */
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "mmprivate.h"
-
-// This is the underlying implementation of mmalloc_get_bytes_used_remote.
-// Is it used directly to evaluate the bytes used from a different process.
-size_t mmalloc_get_bytes_used_remote(size_t heaplimit, const malloc_info* heapinfo)
-{
-  int bytes = 0;
-  for (size_t i = 0; i < heaplimit; ++i) {
-    if (heapinfo[i].type == MMALLOC_TYPE_UNFRAGMENTED) {
-      if (heapinfo[i].busy_block.busy_size > 0)
-        bytes += heapinfo[i].busy_block.busy_size;
-    } else if (heapinfo[i].type > 0) {
-      for (size_t j = 0; j < (size_t)(BLOCKSIZE >> heapinfo[i].type); j++) {
-        if (heapinfo[i].busy_frag.frag_size[j] > 0)
-          bytes += heapinfo[i].busy_frag.frag_size[j];
-      }
-    }
-  }
-  return bytes;
-}
diff --git a/src/xbt/mmalloc/mm_legacy.c b/src/xbt/mmalloc/mm_legacy.c
deleted file mode 100644 (file)
index fb22a59..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Copyright (c) 2010-2023. 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. */
-
-/* Redefine the classical malloc/free/realloc functions so that they fit well in the mmalloc framework */
-#define _GNU_SOURCE
-
-#include "mmprivate.h"
-#include "src/mc/mc_environ.h" // MC_ENV_SOCKET_FD
-#include <dlfcn.h>
-#include <math.h>
-#include <stdlib.h>
-
-/* ***** Whether to use `mmalloc` of the underlying malloc ***** */
-
-static int __malloc_use_mmalloc;
-
-int malloc_use_mmalloc(void)
-{
-  return __malloc_use_mmalloc;
-}
-
-/* ***** Current heap ***** */
-
-/* The mmalloc() package can use a single implicit malloc descriptor
-   for mmalloc/mrealloc/mfree operations which do not supply an explicit
-   descriptor.  This allows mmalloc() to provide
-   backwards compatibility with the non-mmap'd version. */
-xbt_mheap_t __mmalloc_default_mdp = NULL;
-
-/* The heap we are currently using. */
-static xbt_mheap_t __mmalloc_current_heap = NULL;
-
-xbt_mheap_t mmalloc_get_current_heap(void)
-{
-  return __mmalloc_current_heap;
-}
-
-/* Override the malloc-like functions if MC is activated at compile time */
-/* ***** Temporary allocator
- *
- * This is used before we have found the real malloc implementation with dlsym.
- */
-
-static size_t fake_alloc_index;
-static uint64_t buffer[mmalloc_preinit_buffer_size];
-uint64_t* mmalloc_preinit_buffer = buffer;
-
-/* Fake implementations, they are used to fool dlsym:
- * dlsym used calloc and falls back to some other mechanism
- * if this fails.
- */
-static void* mm_fake_malloc(size_t n)
-{
-  mmalloc_preinit_buffer = buffer;
-
-  // How many uint64_t do w need?
-  size_t count = n / sizeof(uint64_t);
-  if (n % sizeof(uint64_t))
-    count++;
-  // Check that we have enough available memory:
-  if (fake_alloc_index + count >= mmalloc_preinit_buffer_size) {
-    puts("mmalloc is not initialized yet, but the static buffer used as malloc replacement is already exhausted. "
-         "Please increase `mmalloc_preinit_buffer_size` in mm_legacy.c\n");
-    exit(127);
-  }
-  // Allocate it:
-  uint64_t* res = buffer + fake_alloc_index;
-  fake_alloc_index += count;
-  return res;
-}
-
-static void* mm_fake_calloc(size_t nmemb, size_t size)
-{
-  // This is fresh .bss data, we don't need to clear it:
-  size_t n = nmemb * size;
-  return mm_fake_malloc(n);
-}
-
-static void* mm_fake_realloc(XBT_ATTRIB_UNUSED void* p, size_t s)
-{
-  return mm_fake_malloc(s);
-}
-
-static void mm_fake_free(XBT_ATTRIB_UNUSED void* p)
-{
-  // Nothing to do
-}
-
-/* Function signatures for the main malloc functions: */
-typedef void* (*mm_malloc_t)(size_t size);
-typedef void  (*mm_free_t)(void*);
-typedef void* (*mm_calloc_t)(size_t nmemb, size_t size);
-typedef void* (*mm_realloc_t)(void *ptr, size_t size);
-
-/* Function pointers to the real/next implementations: */
-static mm_malloc_t mm_real_malloc;
-static mm_free_t mm_real_free;
-static mm_calloc_t mm_real_calloc;
-static mm_realloc_t mm_real_realloc;
-
-static int mm_initializing;
-static int mm_initialized;
-
-/** Constructor functions used to initialize the malloc implementation
- */
-XBT_ATTRIB_CONSTRUCTOR(101) static void mm_legacy_constructor()
-{
-  if (mm_initialized)
-    return;
-  mm_initializing = 1;
-  __malloc_use_mmalloc = getenv(MC_ENV_SOCKET_FD) != NULL;
-  if (__malloc_use_mmalloc) {
-    __mmalloc_current_heap = mmalloc_preinit();
-  } else {
-#if HAVE_DLFUNC
-    mm_real_realloc  = (void *(*)(void *, size_t))dlfunc(RTLD_NEXT, "realloc");
-    mm_real_malloc   = (void *(*)(size_t))dlfunc(RTLD_NEXT, "malloc");
-    mm_real_free     = (void (*)(void *))dlfunc(RTLD_NEXT, "free");
-    mm_real_calloc   = (void *(*)(size_t, size_t))dlfunc(RTLD_NEXT, "calloc");
-#else
-    mm_real_realloc  = dlsym(RTLD_NEXT, "realloc");
-    mm_real_malloc   = dlsym(RTLD_NEXT, "malloc");
-    mm_real_free     = dlsym(RTLD_NEXT, "free");
-    mm_real_calloc   = dlsym(RTLD_NEXT, "calloc");
-#endif
-  }
-
-  mm_initializing = 0;
-  mm_initialized = 1;
-}
-
-/* ***** malloc/free implementation
- *
- * They call either the underlying/native/RTLD_NEXT implementation (non MC mode)
- * or the mm implementation (MC mode).
- *
- * If we are initializing the malloc subsystem, we call the fake/dummy `malloc`
- * implementation. This is necessary because `dlsym` calls `malloc` and friends.
- */
-
-#define GET_HEAP() __mmalloc_current_heap
-
-void *malloc(size_t n)
-{
-  if (!mm_initialized) {
-    if (mm_initializing)
-      return mm_fake_malloc(n);
-    mm_legacy_constructor();
-  }
-
-  if (!__malloc_use_mmalloc) {
-    return mm_real_malloc(n);
-  }
-
-  xbt_mheap_t mdp = GET_HEAP();
-  if (!mdp)
-    return NULL;
-
-  return mmalloc(mdp, n);
-}
-
-void *calloc(size_t nmemb, size_t size)
-{
-  if (!mm_initialized) {
-    if (mm_initializing)
-      return mm_fake_calloc(nmemb, size);
-    mm_legacy_constructor();
-  }
-
-  if (!__malloc_use_mmalloc) {
-    return mm_real_calloc(nmemb, size);
-  }
-
-  xbt_mheap_t mdp = GET_HEAP();
-  if (!mdp)
-    return NULL;
-
-  void *ret = mmalloc(mdp, nmemb*size);
-  // This was already done in the callee:
-  if(!(mdp->options & XBT_MHEAP_OPTION_MEMSET)) {
-    memset(ret, 0, nmemb * size);
-  }
-  return ret;
-}
-
-void *realloc(void *p, size_t s)
-{
-  if (!mm_initialized) {
-    if (mm_initializing)
-      return mm_fake_realloc(p, s);
-    mm_legacy_constructor();
-  }
-
-  if (!__malloc_use_mmalloc) {
-    return mm_real_realloc(p, s);
-  }
-
-  xbt_mheap_t mdp = GET_HEAP();
-  if (!mdp)
-    return NULL;
-
-  return mrealloc(mdp, p, s);
-}
-
-void free(void *p)
-{
-  if (!mm_initialized) {
-    if (mm_initializing)
-      return mm_fake_free(p);
-    mm_legacy_constructor();
-  }
-
-  if (!__malloc_use_mmalloc) {
-    mm_real_free(p);
-    return;
-  }
-
-  if (!p)
-    return;
-
-  xbt_mheap_t mdp = GET_HEAP();
-  mfree(mdp, p);
-}
diff --git a/src/xbt/mmalloc/mm_module.c b/src/xbt/mmalloc/mm_module.c
deleted file mode 100644 (file)
index f4bd97a..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Initialization for access to a mmap'd malloc managed region. */
-
-/* Copyright (c) 2012-2023. 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. */
-
-/* Copyright 1992, 2000 Free Software Foundation, Inc.
-
-   Contributed by Fred Fish at Cygnus Support.   fnf@cygnus.com
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <sys/types.h>
-#include <fcntl.h>              /* After sys/types.h, at least for dpx/2.  */
-#include <sys/stat.h>
-#include <string.h>
-#include "mmprivate.h"
-
-/* Initialize access to a mmalloc managed region.
-
-   The mapping is established starting at the specified address BASEADDR
-   in the process address space.
-
-   The provided BASEADDR should be chosen carefully in order to avoid
-   bumping into existing mapped regions or future mapped regions.
-
-   On success, returns a "malloc descriptor" which is used in subsequent
-   calls to other mmalloc package functions.  It is explicitly "void *"
-   so that users of the package don't have to worry about the actual
-   implementation details.
-
-   On failure, returns NULL. */
-
-xbt_mheap_t xbt_mheap_new(void* baseaddr, int options)
-{
-  /* NULL is not a valid baseaddr as we cannot map anything there. C'mon, user. Think! */
-  if (baseaddr == NULL)
-    return NULL;
-
-  /* We start off with the malloc descriptor allocated on the stack, until we build it up enough to
-   * call _mmalloc_mmap_morecore() to allocate the first page of the region and copy it there.  Ensure that it is
-   * zero'd and then initialize the fields that we know values for. */
-
-  struct mdesc mtemp;
-  xbt_mheap_t mdp = &mtemp;
-  memset((char *) mdp, 0, sizeof(mtemp));
-  strncpy(mdp->magic, MMALLOC_MAGIC, MMALLOC_MAGIC_SIZE);
-  mdp->headersize = sizeof(mtemp);
-  mdp->version = MMALLOC_VERSION;
-  mdp->base = mdp->breakval = mdp->top = baseaddr;
-  mdp->next_mdesc = NULL;
-  mdp->options = options;
-
-  /* If we have not been passed a valid open file descriptor for the file
-     to map to, then open /dev/zero and use that to map to. */
-
-  /* Now try to map in the first page, copy the malloc descriptor structure there, and arrange to return a pointer to
-   * this new copy.  If the mapping fails, then close the file descriptor if it was opened by us, and arrange to return
-   * a NULL. */
-
-  void* mbase = mmorecore(mdp, sizeof(mtemp));
-  if (mbase == NULL) {
-    fprintf(stderr, "morecore failed to get some more memory!\n");
-    abort();
-  }
-  memcpy(mbase, mdp, sizeof(mtemp));
-
-  /* Add the new heap to the linked list of heaps attached by mmalloc */
-  if(__mmalloc_default_mdp){
-    mdp = __mmalloc_default_mdp;
-    while(mdp->next_mdesc)
-      mdp = mdp->next_mdesc;
-
-    mdp->next_mdesc = (struct mdesc *)mbase;
-  }
-
-  return mbase;
-}
-
-/** Terminate access to a mmalloc managed region by unmapping all memory pages associated with the region, and closing
- *  the file descriptor if it is one that we opened.
-
-    Returns NULL on success.
-
-    Returns the malloc descriptor on failure, which can subsequently be used for further action, such as obtaining more
-    information about the nature of the failure.
-
-    Note that the malloc descriptor that we are using is currently located in region we are about to unmap, so we first
-    make a local copy of it on the stack and use the copy. */
-
-void *xbt_mheap_destroy(xbt_mheap_t mdp)
-{
-  if (mdp != NULL) {
-    /* Remove the heap from the linked list of heaps attached by mmalloc */
-    struct mdesc* mdptemp = __mmalloc_default_mdp;
-    while(mdptemp->next_mdesc != mdp )
-      mdptemp = mdptemp->next_mdesc;
-
-    mdptemp->next_mdesc = mdp->next_mdesc;
-
-    struct mdesc mtemp = *mdp;
-
-    /* Now unmap all the pages associated with this region by asking for a
-       negative increment equal to the current size of the region. */
-
-    if (mmorecore(&mtemp, (char *)mtemp.base - (char *)mtemp.breakval) == NULL) {
-      /* Deallocating failed.  Update the original malloc descriptor with any changes */
-      *mdp = mtemp;
-    } else {
-      mdp = NULL;
-    }
-  }
-
-  return mdp;
-}
-
-/* Safety gap from the heap's break address.
- * Try to increase this first if you experience strange errors under valgrind. */
-#define HEAP_OFFSET   (128UL<<20)
-
-/* Initialize the default malloc descriptor.
- *
- * There is no malloc_postexit() destroying the default mdp, because it would break ldl trying to free its memory
- */
-xbt_mheap_t mmalloc_preinit(void)
-{
-  if (__mmalloc_default_mdp == NULL) {
-    unsigned long mmalloc_pagesize = (unsigned long)sysconf(_SC_PAGESIZE);
-    unsigned long mask             = ~(mmalloc_pagesize - 1);
-    void* addr            = (void*)(((unsigned long)sbrk(0) + HEAP_OFFSET) & mask);
-    __mmalloc_default_mdp = xbt_mheap_new(addr, XBT_MHEAP_OPTION_MEMSET);
-  }
-  mmalloc_assert(__mmalloc_default_mdp != NULL, "__mmalloc_default_mdp cannot be NULL");
-
-  return __mmalloc_default_mdp;
-}
diff --git a/src/xbt/mmalloc/mmalloc.c b/src/xbt/mmalloc/mmalloc.c
deleted file mode 100644 (file)
index ea99da9..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/* Memory allocator `malloc'. */
-
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright 1990, 1991, 1992 Free Software Foundation
-
-   Written May 1989 by Mike Haertel.
-   Heavily modified Mar 1992 by Fred Fish for mmap'd version. */
-
-#include <string.h>             /* Prototypes for memcpy, memmove, memset, etc */
-#include <stdio.h>
-#include "mmprivate.h"
-
-/* Prototypes for local functions */
-
-static void initialize(xbt_mheap_t mdp);
-static void *register_morecore(xbt_mheap_t mdp, size_t size);
-static void* mmalloc_aligned(xbt_mheap_t mdp, size_t size);
-
-/* Allocation aligned on block boundary.
- *
- * It never returns NULL, but dies verbosely on error.
- */
-static void* mmalloc_aligned(struct mdesc* mdp, size_t size)
-{
-  void *result;
-  unsigned long int adj;
-
-  result = mmorecore(mdp, size);
-
-  /* if this reservation does not fill up the last block of our resa,
-   * complete the reservation by also asking for the full latest block.
-   *
-   * Also, the returned block is aligned to the end of block (but I've
-   * no fucking idea of why, actually -- http://abstrusegoose.com/432 --
-   * but not doing so seems to lead to issues).
-   */
-  adj = RESIDUAL(result, BLOCKSIZE);
-  if (adj != 0) {
-    adj = BLOCKSIZE - adj;
-    mmorecore(mdp, adj);
-    result = (char *) result + adj;
-  }
-  return result;
-}
-
-/** Initialize heapinfo about the heapinfo pages :) */
-static void initialize_heapinfo_heapinfo(const s_xbt_mheap_t* mdp)
-{
-  // Update heapinfo about the heapinfo pages (!):
-  mmalloc_assert((uintptr_t)mdp->heapinfo % BLOCKSIZE == 0, "Failed assert in initialize_heapinfo_heapinfo()");
-  size_t block   = BLOCK(mdp->heapinfo);
-  size_t nblocks = mdp->heapsize * sizeof(malloc_info) / BLOCKSIZE;
-  // Mark them as free:
-  for (size_t j=0; j!=nblocks; ++j) {
-    mdp->heapinfo[block+j].type = MMALLOC_TYPE_FREE;
-    mdp->heapinfo[block+j].free_block.size = 0;
-    mdp->heapinfo[block+j].free_block.next = 0;
-    mdp->heapinfo[block+j].free_block.prev = 0;
-  }
-  mdp->heapinfo[block].free_block.size = nblocks;
-}
-
-/* Finish the initialization of the mheap. If we want to inline it
- * properly, we need to make the mmalloc_aligned function publicly visible, too  */
-static void initialize(xbt_mheap_t mdp)
-{
-  // Update mdp meta-data:
-  mdp->heapsize = HEAP / BLOCKSIZE;
-  mdp->heapinfo = (malloc_info*)mmalloc_aligned(mdp, mdp->heapsize * sizeof(malloc_info));
-  mdp->heapbase = (void *) mdp->heapinfo;
-  mdp->flags |= MMALLOC_INITIALIZED;
-
-  // Update root heapinfo:
-  memset((void *) mdp->heapinfo, 0, mdp->heapsize * sizeof(malloc_info));
-  mdp->heapinfo[0].type = MMALLOC_TYPE_FREE;
-  mdp->heapinfo[0].free_block.size = 0;
-  mdp->heapinfo[0].free_block.next = mdp->heapinfo[0].free_block.prev = 0;
-  mdp->heapindex = 0;
-
-  initialize_heapinfo_heapinfo(mdp);
-
-  for (int i = 0; i < BLOCKLOG; i++) {
-    malloc_info mi; /* to compute the offset of the swag hook */
-    xbt_swag_init(&(mdp->fraghead[i]), xbt_swag_offset(mi, freehook));
-  }
-}
-
-static inline void update_hook(void **a, size_t offset)
-{
-  if (*a)
-    *a = (char*)*a + offset;
-}
-
-/* Get neatly aligned memory from the low level layers, and register it
- * into the heap info table as necessary. */
-static void *register_morecore(struct mdesc *mdp, size_t size)
-{
-  void* result = mmalloc_aligned(mdp, size); // Never returns NULL
-
-  /* Check if we need to grow the info table (in a multiplicative manner)  */
-  if (BLOCK((char*)result + size) > mdp->heapsize) {
-    size_t newsize = mdp->heapsize;
-    while (BLOCK((char*)result + size) > newsize)
-      newsize *= 2;
-
-    /* Copy old info into new location */
-    malloc_info* oldinfo = mdp->heapinfo;
-    malloc_info* newinfo = (malloc_info*)mmalloc_aligned(mdp, newsize * sizeof(malloc_info));
-    memcpy(newinfo, oldinfo, mdp->heapsize * sizeof(malloc_info));
-
-    /* Initialize the new blockinfo : */
-    memset((char*) newinfo + mdp->heapsize * sizeof(malloc_info), 0,
-      (newsize - mdp->heapsize)* sizeof(malloc_info));
-
-    /* Update the swag of busy blocks containing free fragments by applying the offset to all swag_hooks. Yeah. My hand is right in the fan and I still type */
-    size_t offset=((char*)newinfo)-((char*)oldinfo);
-
-    for (size_t i = 1 /*first element of heapinfo describes the mdesc area*/; i < mdp->heaplimit; i++) {
-      update_hook(&newinfo[i].freehook.next, offset);
-      update_hook(&newinfo[i].freehook.prev, offset);
-    }
-    // also update the starting points of the swag
-    for (int i = 0; i < BLOCKLOG; i++) {
-      update_hook(&mdp->fraghead[i].head, offset);
-      update_hook(&mdp->fraghead[i].tail, offset);
-    }
-    mdp->heapinfo = newinfo;
-
-    /* mark the space previously occupied by the block info as free by first marking it
-     * as occupied in the regular way, and then freing it */
-    for (size_t it = 0; it < BLOCKIFY(mdp->heapsize * sizeof(malloc_info)); it++) {
-      newinfo[BLOCK(oldinfo)+it].type = MMALLOC_TYPE_UNFRAGMENTED;
-      newinfo[BLOCK(oldinfo)+it].busy_block.ignore = 0;
-    }
-
-    newinfo[BLOCK(oldinfo)].busy_block.size = BLOCKIFY(mdp->heapsize * sizeof(malloc_info));
-    newinfo[BLOCK(oldinfo)].busy_block.busy_size = size;
-    mfree(mdp, (void *) oldinfo);
-    mdp->heapsize = newsize;
-
-    initialize_heapinfo_heapinfo(mdp);
-  }
-
-  mdp->heaplimit = BLOCK((char *) result + size);
-  return result;
-}
-
-/* Allocate memory from the heap.  */
-void *mmalloc(xbt_mheap_t mdp, size_t size) {
-  void *res= mmalloc_no_memset(mdp,size);
-  if (mdp->options & XBT_MHEAP_OPTION_MEMSET) {
-    memset(res,0,size);
-  }
-  return res;
-}
-
-static void mmalloc_mark_used(xbt_mheap_t mdp, size_t block, size_t nblocks, size_t requested_size)
-{
-  for (size_t it = 0; it < nblocks; it++) {
-    mdp->heapinfo[block + it].type                 = MMALLOC_TYPE_UNFRAGMENTED;
-    mdp->heapinfo[block + it].busy_block.busy_size = 0;
-    mdp->heapinfo[block + it].busy_block.ignore    = 0;
-    mdp->heapinfo[block + it].busy_block.size      = 0;
-  }
-  mdp->heapinfo[block].busy_block.size      = nblocks;
-  mdp->heapinfo[block].busy_block.busy_size = requested_size;
-  mdp->heapstats.chunks_used++;
-  mdp->heapstats.bytes_used += nblocks * BLOCKSIZE;
-}
-
-/* Splitting mmalloc this way is mandated by a trick in mrealloc, that gives
-   back the memory of big blocks to the system before reallocating them: we don't
-   want to loose the beginning of the area when this happens */
-void *mmalloc_no_memset(xbt_mheap_t mdp, size_t size)
-{
-  void *result;
-  size_t block;
-
-  size_t requested_size = size; // The amount of memory requested by user, for real
-
-  /* Work even if the user was stupid enough to ask a ridiculously small block (even 0-length),
-   *    ie return a valid block that can be realloced and freed.
-   * glibc malloc does not use this trick but return a constant pointer, but we need to enlist the free fragments later on.
-   */
-  if (size < SMALLEST_POSSIBLE_MALLOC)
-    size = SMALLEST_POSSIBLE_MALLOC;
-
-  if (!(mdp->flags & MMALLOC_INITIALIZED))
-    initialize(mdp);
-
-  /* Determine the allocation policy based on the request size.  */
-  if (size <= BLOCKSIZE / 2) {
-    /* Small allocation to receive a fragment of a block.
-       Determine the logarithm to base two of the fragment size. */
-    size_t log = 1;
-    --size;
-    while ((size /= 2) != 0) {
-      ++log;
-    }
-
-    /* Look in the fragment lists for a free fragment of the desired size. */
-    if (xbt_swag_size(&mdp->fraghead[log])>0) {
-      /* There are free fragments of this size; Get one of them and prepare to return it.
-         Update the block's nfree and if no other free fragment, get out of the swag. */
-
-      /* search a fragment that I could return as a result */
-      malloc_info *candidate_info = xbt_swag_getFirst(&mdp->fraghead[log]);
-      size_t candidate_block = (candidate_info - &(mdp->heapinfo[0]));
-      size_t candidate_frag;
-      for (candidate_frag=0;candidate_frag<(size_t) (BLOCKSIZE >> log);candidate_frag++)
-        if (candidate_info->busy_frag.frag_size[candidate_frag] == -1)
-          break;
-      mmalloc_assert(candidate_frag < (size_t)(BLOCKSIZE >> log),
-                     "Block %zu was registered as containing free fragments of type %zu, but I can't find any",
-                     candidate_block, log);
-
-      result = (void*) (((char*)ADDRESS(candidate_block)) + (candidate_frag << log));
-
-      /* Remove this fragment from the list of free guys */
-      candidate_info->busy_frag.nfree--;
-      if (candidate_info->busy_frag.nfree == 0) {
-        xbt_swag_remove(candidate_info,&mdp->fraghead[log]);
-      }
-
-      /* Update our metadata about this fragment */
-      candidate_info->busy_frag.frag_size[candidate_frag] = requested_size;
-      candidate_info->busy_frag.ignore[candidate_frag] = 0;
-
-      /* Update the statistics.  */
-      mdp -> heapstats.chunks_used++;
-      mdp -> heapstats.bytes_used += 1 << log;
-      mdp -> heapstats.chunks_free--;
-      mdp -> heapstats.bytes_free -= 1 << log;
-
-    } else {
-      /* No free fragments of the desired size, so get a new block
-         and break it into fragments, returning the first.  */
-
-      result = mmalloc(mdp, BLOCKSIZE); // does not return NULL
-      block = BLOCK(result);
-
-      mdp->heapinfo[block].type = (int)log;
-      /* Link all fragments but the first as free, and add the block to the swag of blocks containing free frags  */
-      size_t i;
-      for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i) {
-        mdp->heapinfo[block].busy_frag.frag_size[i] = -1;
-        mdp->heapinfo[block].busy_frag.ignore[i] = 0;
-      }
-      mdp->heapinfo[block].busy_frag.nfree = i - 1;
-      mdp->heapinfo[block].freehook.prev = NULL;
-      mdp->heapinfo[block].freehook.next = NULL;
-
-      xbt_swag_insert(&mdp->heapinfo[block], &(mdp->fraghead[log]));
-
-      /* mark the fragment returned as busy */
-      mdp->heapinfo[block].busy_frag.frag_size[0] = requested_size;
-      mdp->heapinfo[block].busy_frag.ignore[0] = 0;
-
-      /* update stats */
-      mdp -> heapstats.chunks_free += (BLOCKSIZE >> log) - 1;
-      mdp -> heapstats.bytes_free += BLOCKSIZE - (1 << log);
-      mdp -> heapstats.bytes_used -= BLOCKSIZE - (1 << log);
-    }
-  } else {
-    /* Large allocation to receive one or more blocks.
-       Search the free list in a circle starting at the last place visited.
-       If we loop completely around without finding a large enough
-       space we will have to get more memory from the system.  */
-    size_t blocks = BLOCKIFY(size);
-    size_t start  = MALLOC_SEARCH_START;
-    block         = MALLOC_SEARCH_START;
-    while (mdp->heapinfo[block].free_block.size < blocks) {
-      if (mdp->heapinfo[block].type >=0) { // Don't trust xbt_die and friends in malloc-level library, you fool!
-        fprintf(stderr,
-                "Internal error: found a free block not marked as such (block=%zu type=%d). Please report this bug.\n",
-                block, mdp->heapinfo[block].type);
-        abort();
-      }
-
-      block = mdp->heapinfo[block].free_block.next;
-      if (block == start) {
-        /* Need to get more from the system.  Check to see if
-           the new core will be contiguous with the final free
-           block; if so we don't need to get as much.  */
-        block = mdp->heapinfo[0].free_block.prev;
-        size_t lastblocks = mdp->heapinfo[block].free_block.size;
-        if (mdp->heaplimit != 0 &&
-            block + lastblocks == mdp->heaplimit &&
-            mmorecore(mdp, 0) == ADDRESS(block + lastblocks) &&
-            (register_morecore(mdp, (blocks - lastblocks) * BLOCKSIZE)) != NULL) {
-          /* Which block we are extending (the `final free
-             block' referred to above) might have changed, if
-             it got combined with a freed info table.  */
-          block = mdp->heapinfo[0].free_block.prev;
-
-          mdp->heapinfo[block].free_block.size += (blocks - lastblocks);
-          continue;
-        }
-        result = register_morecore(mdp, blocks * BLOCKSIZE);
-
-        block = BLOCK(result);
-        mmalloc_mark_used(mdp, block, blocks, requested_size);
-
-        return result;
-      }
-      /* Need large block(s), but found some in the existing heap */
-    }
-
-    /* At this point we have found a suitable free list entry.
-       Figure out how to remove what we need from the list. */
-    result = ADDRESS(block);
-    if (mdp->heapinfo[block].free_block.size > blocks) {
-      /* The block we found has a bit left over,
-         so relink the tail end back into the free list. */
-      mdp->heapinfo[block + blocks].free_block.size
-        = mdp->heapinfo[block].free_block.size - blocks;
-      mdp->heapinfo[block + blocks].free_block.next
-        = mdp->heapinfo[block].free_block.next;
-      mdp->heapinfo[block + blocks].free_block.prev
-        = mdp->heapinfo[block].free_block.prev;
-      mdp->heapinfo[mdp->heapinfo[block].free_block.prev].free_block.next
-        = mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev
-        = mdp->heapindex = block + blocks;
-    } else {
-      /* The block exactly matches our requirements,
-         so just remove it from the list. */
-      mdp->heapinfo[mdp->heapinfo[block].free_block.next].free_block.prev
-        = mdp->heapinfo[block].free_block.prev;
-      mdp->heapinfo[mdp->heapinfo[block].free_block.prev].free_block.next
-        = mdp->heapindex = mdp->heapinfo[block].free_block.next;
-    }
-
-    mmalloc_mark_used(mdp, block, blocks, requested_size);
-    mdp -> heapstats.bytes_free -= blocks * BLOCKSIZE;
-
-  }
-
-  return result;
-}
diff --git a/src/xbt/mmalloc/mmalloc.h b/src/xbt/mmalloc/mmalloc.h
deleted file mode 100644 (file)
index 7dff4e7..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-   This file was then part of the GNU C Library. */
-
-#ifndef SIMGRID_MMALLOC_H
-#define SIMGRID_MMALLOC_H
-
-#include "src/internal_config.h"
-
-#include <stdio.h>     /* for NULL */
-#include <sys/types.h> /* for size_t */
-
-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
- * extra first argument: the heap in which the memory is to be taken.
- *
- * The heap structure itself is an opaque object that shouldn't be messed with.
- */
-typedef struct mdesc s_xbt_mheap_t;
-typedef s_xbt_mheap_t* xbt_mheap_t;
-
-#if HAVE_MMALLOC
-/* Allocate SIZE bytes of memory (and memset it to 0).  */
-XBT_PUBLIC void* mmalloc(xbt_mheap_t md, size_t size);
-
-/* Allocate SIZE bytes of memory (and don't mess with it) */
-void* mmalloc_no_memset(xbt_mheap_t mdp, size_t size);
-
-/* Re-allocate the previously allocated block in void*, making the new block SIZE bytes long.  */
-XBT_PUBLIC void* mrealloc(xbt_mheap_t md, void* ptr, size_t size);
-
-/* Free a block allocated by `mmalloc', `mrealloc' or `mcalloc'.  */
-XBT_PUBLIC void mfree(xbt_mheap_t md, void* ptr);
-
-#define XBT_MHEAP_OPTION_MEMSET 1
-
-XBT_PUBLIC xbt_mheap_t xbt_mheap_new(void* baseaddr, int options);
-
-XBT_PUBLIC void* xbt_mheap_destroy(xbt_mheap_t md);
-
-/* To get the heap used when using the legacy version malloc/free/realloc and such */
-xbt_mheap_t mmalloc_get_current_heap(void);
-
-/* Returns true if we are using the internal mmalloc, and false if we are using the libc's malloc */
-XBT_PUBLIC int malloc_use_mmalloc(void);
-
-#endif
-SG_END_DECL
-
-#endif /* SIMGRID_MMALLOC_H */
diff --git a/src/xbt/mmalloc/mmalloc.info b/src/xbt/mmalloc/mmalloc.info
deleted file mode 100644 (file)
index 50fb1ba..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-This is ./mmalloc.info, produced by makeinfo version 4.6 from
-mmalloc.texi.
-
-START-INFO-DIR-ENTRY
-* Mmalloc: (mmalloc).          The GNU mapped-malloc package.
-END-INFO-DIR-ENTRY
-
-   This file documents the GNU mmalloc (mapped-malloc) package, written
-by fnf@cygnus.com, based on GNU malloc written by mike@ai.mit.edu.
-
-   Copyright (C) 1992 Free Software Foundation, Inc.
-
-   Permission is granted to make and distribute verbatim copies of this
-manual provided the copyright notice and this permission notice are
-preserved on all copies.
-
-   Permission is granted to copy and distribute modified versions of
-this manual under the conditions for verbatim copying, provided also
-that the entire resulting derived work is distributed under the terms
-of a permission notice identical to this one.
-
-   Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions.
-
-\1f
-File: mmalloc.info,  Node: Top,  Next: Overview,  Prev: (dir),  Up: (dir)
-
-mmalloc
-*******
-
-This file documents the GNU memory-mapped malloc package mmalloc.
-
-* Menu:
-
-* Overview::                    Overall Description
-* Implementation::              Implementation
-
- --- The Detailed Node Listing ---
-
-Implementation
-
-* Compatibility::               Backwards Compatibility
-* Functions::                   Function Descriptions
-
-\1f
-File: mmalloc.info,  Node: Overview,  Next: Implementation,  Prev: Top,  Up: Top
-
-Overall Description
-*******************
-
-This is a heavily modified version of GNU `malloc'.  It uses `mmap' as
-the basic mechanism for obtaining memory from the system, rather than
-`sbrk'.  This gives it several advantages over the more traditional
-malloc:
-
-   * Several different heaps can be used, each of them growing or
-     shinking under control of `mmap', with the `mmalloc' functions
-     using a specific heap on a call by call basis.
-
-   * By using `mmap', it is easy to create heaps which are intended to
-     be persistent and exist as a filesystem object after the creating
-     process has gone away.
-
-   * Because multiple heaps can be managed, data used for a specific
-     purpose can be allocated into its own heap, making it easier to
-     allow applications to "dump" and "restore" initialized
-     malloc-managed memory regions.  For example, the "unexec" hack
-     popularized by GNU Emacs could potentially go away.
-
-\1f
-File: mmalloc.info,  Node: Implementation,  Prev: Overview,  Up: Top
-
-Implementation
-**************
-
-The `mmalloc' functions contain no internal static state.  All
-`mmalloc' internal data is allocated in the mapped in region, along
-with the user data that it manages.  This allows it to manage multiple
-such regions and to "pick up where it left off" when such regions are
-later dynamically mapped back in.
-
-   In some sense, malloc has been "purified" to contain no internal
-state information and generalized to use multiple memory regions rather
-than a single region managed by `sbrk'.  However the new routines now
-need an extra parameter which informs `mmalloc' which memory region it
-is dealing with (along with other information).  This parameter is
-called the "malloc descriptor".
-
-   The functions initially provided by `mmalloc' are:
-
-     void *mmalloc_attach (int fd, void *baseaddr);
-     void *mmalloc_detach (void *md);
-     int mmalloc_errno (void *md);
-     int mmalloc_setkey (void *md, int keynum, void *key);
-     void *mmalloc_getkey (void *md, int keynum);
-
-     void *mmalloc (void *md, size_t size);
-     void *mrealloc (void *md, void *ptr, size_t size);
-     void *mvalloc (void *md, size_t size);
-     void mfree (void *md, void *ptr);
-
-* Menu:
-
-* Compatibility::               Backwards Compatibility
-* Functions::                   Function Descriptions
-
-\1f
-File: mmalloc.info,  Node: Compatibility,  Next: Functions,  Prev: Implementation,  Up: Implementation
-
-Backwards Compatibility
-=======================
-
-To allow a single malloc package to be used in a given application,
-provision is made for the traditional `malloc', `realloc', and `free'
-functions to be implemented as special cases of the `mmalloc'
-functions.  In particular, if any of the functions that expect malloc
-descriptors are called with a `NULL' pointer rather than a valid malloc
-descriptor, then they default to using an `sbrk' managed region.  The
-`mmalloc' package provides compatible `malloc', `realloc', and `free'
-functions using this mechanism internally.  Applications can avoid this
-extra interface layer by simply including the following defines:
-
-     #define malloc(size)              mmalloc ((void *)0, (size))
-     #define realloc(ptr,size) mrealloc ((void *)0, (ptr), (size));
-     #define free(ptr)         mfree ((void *)0, (ptr))
-
-or replace the existing `malloc', `realloc', and `free' calls with the
-above patterns if using `#define' causes problems.
-
-\1f
-File: mmalloc.info,  Node: Functions,  Prev: Compatibility,  Up: Implementation
-
-Function Descriptions
-=====================
-
-These are the details on the functions that make up the `mmalloc'
-package.
-
-`void *mmalloc_attach (int FD, void *BASEADDR);'
-     Initialize access to a `mmalloc' managed region.
-
-     If FD is a valid file descriptor for an open file, then data for
-     the `mmalloc' managed region is mapped to that file.   Otherwise
-     `/dev/zero' is used and the data will not exist in any filesystem
-     object.
-
-     If the open file corresponding to FD is from a previous use of
-     `mmalloc' and passes some basic sanity checks to ensure that it is
-     compatible with the current `mmalloc' package, then its data is
-     mapped in and is immediately accessible at the same addresses in
-     the current process as the process that created the file.
-
-     If BASEADDR is not `NULL', the mapping is established starting at
-     the specified address in the process address space.  If BASEADDR
-     is `NULL', the `mmalloc' package chooses a suitable address at
-     which to start the mapped region, which will be the value of the
-     previous mapping if opening an existing file which was previously
-     built by `mmalloc', or for new files will be a value chosen by
-     `mmap'.
-
-     Specifying BASEADDR provides more control over where the regions
-     start and how big they can be before bumping into existing mapped
-     regions or future mapped regions.
-
-     On success, returns a malloc descriptor which is used in subsequent
-     calls to other `mmalloc' package functions.  It is explicitly
-     `void *' (`char *' for systems that don't fully support `void') so
-     that users of the package don't have to worry about the actual
-     implementation details.
-
-     On failure returns `NULL'.
-
-`void *mmalloc_detach (void *MD);'
-     Terminate access to a `mmalloc' managed region identified by the
-     descriptor MD, by closing the base file and unmapping all memory
-     pages associated with the region.
-
-     Returns `NULL' on success.
-
-     Returns the malloc descriptor on failure, which can subsequently
-     be used for further action (such as obtaining more information
-     about the nature of the failure).
-
-`void *mmalloc (void *MD, size_t SIZE);'
-     Given an `mmalloc' descriptor MD, allocate additional memory of
-     SIZE bytes in the associated mapped region.
-
-`*mrealloc (void *MD, void *PTR, size_t SIZE);'
-     Given an `mmalloc' descriptor MD and a pointer to memory
-     previously allocated by `mmalloc' in PTR, reallocate the memory to
-     be SIZE bytes long, possibly moving the existing contents of
-     memory if necessary.
-
-`void *mvalloc (void *MD, size_t SIZE);'
-     Like `mmalloc' but the resulting memory is aligned on a page
-     boundary.
-
-`void mfree (void *MD, void *PTR);'
-     Given an `mmalloc' descriptor MD and a pointer to memory previously
-     allocated by `mmalloc' in PTR, free the previously allocated
-     memory.
-
-`int mmalloc_errno (void *MD);'
-     Given a `mmalloc' descriptor, if the last `mmalloc' operation
-     failed for some reason due to a system call failure, then returns
-     the associated `errno'.  Returns 0 otherwise.  (This function is
-     not yet implemented).
-
-
-\1f
-Tag Table:
-Node: Top\7f937
-Node: Overview\7f1370
-Node: Implementation\7f2395
-Node: Compatibility\7f3785
-Node: Functions\7f4856
-\1f
-End Tag Table
diff --git a/src/xbt/mmalloc/mmalloc.texi b/src/xbt/mmalloc/mmalloc.texi
deleted file mode 100644 (file)
index 0669995..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-\input texinfo  @c                                  -*- Texinfo -*-
-@setfilename mmalloc.info
-
-@ifinfo
-@format
-START-INFO-DIR-ENTRY
-* Mmalloc: (mmalloc).          The GNU mapped-malloc package.
-END-INFO-DIR-ENTRY
-@end format
-
-This file documents the GNU mmalloc (mapped-malloc) package, written by
-fnf@@cygnus.com, based on GNU malloc written by mike@@ai.mit.edu.
-
-Copyright (C) 1992 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@ignore
-Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-
-@end ignore
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions.
-@end ifinfo
-@iftex
-@c @finalout
-@setchapternewpage odd
-@settitle MMALLOC, the GNU memory-mapped malloc package
-@titlepage
-@title mmalloc
-@subtitle The GNU memory-mapped malloc package
-@author Fred Fish
-@author Cygnus Support
-@author Mike Haertel
-@author Free Software Foundation
-@page
-
-@tex
-\def\$#1${{#1}}  % Kluge: collect RCS revision info without $...$
-\xdef\manvers{\$Revision: 1.4 $}  % For use in headers, footers too
-{\parskip=0pt
-\hfill Cygnus Support\par
-\hfill fnf\@cygnus.com\par
-\hfill {\it MMALLOC, the GNU memory-mapped malloc package}, \manvers\par
-\hfill \TeX{}info \texinfoversion\par
-}
-@end tex
-
-@vskip 0pt plus 1filll
-Copyright @copyright{} 1992 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that
-the entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions.
-@end titlepage
-@end iftex
-
-@ifinfo
-@node Top, Overview, (dir), (dir)
-@top mmalloc
-This file documents the GNU memory-mapped malloc package mmalloc.
-
-@menu
-* Overview::                    Overall Description
-* Implementation::              Implementation
-
- --- The Detailed Node Listing ---
-
-Implementation
-
-* Compatibility::               Backwards Compatibility
-* Functions::                   Function Descriptions
-@end menu
-
-@end ifinfo
-
-@node Overview, Implementation, Top, Top
-@chapter Overall Description
-
-This is a heavily modified version of GNU @code{malloc}.  It uses
-@code{mmap} as the basic mechanism for obtaining memory from the
-system, rather than @code{sbrk}.  This gives it several advantages over the
-more traditional malloc:
-
-@itemize @bullet
-@item
-Several different heaps can be used, each of them growing
-or shinking under control of @code{mmap}, with the @code{mmalloc} functions
-using a specific heap on a call by call basis.
-
-@item
-By using @code{mmap}, it is easy to create heaps which are intended to
-be persistent and exist as a filesystem object after the creating
-process has gone away.
-
-@item
-Because multiple heaps can be managed, data used for a
-specific purpose can be allocated into its own heap, making
-it easier to allow applications to ``dump'' and ``restore'' initialized
-malloc-managed memory regions.  For example, the ``unexec'' hack popularized
-by GNU Emacs could potentially go away.
-@end itemize
-
-@node Implementation,  , Overview, Top
-@chapter Implementation
-
-The @code{mmalloc} functions contain no internal static state.  All
-@code{mmalloc} internal data is allocated in the mapped in region, along
-with the user data that it manages.  This allows it to manage multiple
-such regions and to ``pick up where it left off'' when such regions are
-later dynamically mapped back in.
-
-In some sense, malloc has been ``purified'' to contain no internal state
-information and generalized to use multiple memory regions rather than a
-single region managed by @code{sbrk}.  However the new routines now need an
-extra parameter which informs @code{mmalloc} which memory region it is dealing
-with (along with other information).  This parameter is called the
-@dfn{malloc descriptor}.
-
-The functions initially provided by @code{mmalloc} are:
-
-@example
-void *mmalloc_attach (int fd, void *baseaddr);
-void *mmalloc_detach (void *md);
-int mmalloc_errno (void *md);
-int mmalloc_setkey (void *md, int keynum, void *key);
-void *mmalloc_getkey (void *md, int keynum);
-
-void *mmalloc (void *md, size_t size);
-void *mrealloc (void *md, void *ptr, size_t size);
-void *mvalloc (void *md, size_t size);
-void mfree (void *md, void *ptr);
-@end example
-
-@menu
-* Compatibility::               Backwards Compatibility
-* Functions::                   Function Descriptions
-@end menu
-
-@node Compatibility, Functions, Implementation, Implementation
-@section Backwards Compatibility
-
-To allow a single malloc package to be used in a given application,
-provision is made for the traditional @code{malloc}, @code{realloc}, and
-@code{free} functions to be implemented as special cases of the
-@code{mmalloc} functions.  In particular, if any of the functions that
-expect malloc descriptors are called with a @code{NULL} pointer rather than a
-valid malloc descriptor, then they default to using an @code{sbrk} managed
-region.
-The @code{mmalloc} package provides compatible @code{malloc}, @code{realloc},
-and @code{free} functions using this mechanism internally.
-Applications can avoid this extra interface layer by simply including the
-following defines:
-
-@example
-#define malloc(size)           mmalloc ((void *)0, (size))
-#define realloc(ptr,size)      mrealloc ((void *)0, (ptr), (size));
-#define free(ptr)              mfree ((void *)0, (ptr))
-@end example
-
-@noindent
-or replace the existing @code{malloc}, @code{realloc}, and @code{free}
-calls with the above patterns if using @code{#define} causes problems.
-
-@node Functions,  , Compatibility, Implementation
-@section Function Descriptions
-
-These are the details on the functions that make up the @code{mmalloc}
-package.
-
-@table @code
-@item void *mmalloc_attach (int @var{fd}, void *@var{baseaddr});
-Initialize access to a @code{mmalloc} managed region.
-
-If @var{fd} is a valid file descriptor for an open file, then data for the
-@code{mmalloc} managed region is mapped to that file.   Otherwise
-@file{/dev/zero} is used and the data will not exist in any filesystem object.
-
-If the open file corresponding to @var{fd} is from a previous use of
-@code{mmalloc} and passes some basic sanity checks to ensure that it is
-compatible with the current @code{mmalloc} package, then its data is
-mapped in and is immediately accessible at the same addresses in
-the current process as the process that created the file.
-
-If @var{baseaddr} is not @code{NULL}, the mapping is established
-starting at the specified address in the process address space.  If
-@var{baseaddr} is @code{NULL}, the @code{mmalloc} package chooses a
-suitable address at which to start the mapped region, which will be the
-value of the previous mapping if opening an existing file which was
-previously built by @code{mmalloc}, or for new files will be a value
-chosen by @code{mmap}.
-
-Specifying @var{baseaddr} provides more control over where the regions
-start and how big they can be before bumping into existing mapped
-regions or future mapped regions.
-
-On success, returns a malloc descriptor which is used in subsequent
-calls to other @code{mmalloc} package functions.  It is explicitly
-@samp{void *} (@samp{char *} for systems that don't fully support
-@code{void}) so that users of the package don't have to worry about the
-actual implementation details.
-
-On failure returns @code{NULL}.
-
-@item void *mmalloc_detach (void *@var{md});
-Terminate access to a @code{mmalloc} managed region identified by the
-descriptor @var{md}, by closing the base file and unmapping all memory
-pages associated with the region.
-
-Returns @code{NULL} on success.
-
-Returns the malloc descriptor on failure, which can subsequently
-be used for further action (such as obtaining more information about
-the nature of the failure).
-
-@item void *mmalloc (void *@var{md}, size_t @var{size});
-Given an @code{mmalloc} descriptor @var{md}, allocate additional memory of
-@var{size} bytes in the associated mapped region.
-
-@item *mrealloc (void *@var{md}, void *@var{ptr}, size_t @var{size});
-Given an @code{mmalloc} descriptor @var{md} and a pointer to memory
-previously allocated by @code{mmalloc} in @var{ptr}, reallocate the
-memory to be @var{size} bytes long, possibly moving the existing
-contents of memory if necessary.
-
-@item void *mvalloc (void *@var{md}, size_t @var{size});
-Like @code{mmalloc} but the resulting memory is aligned on a page boundary.
-
-@item void mfree (void *@var{md}, void *@var{ptr});
-Given an @code{mmalloc} descriptor @var{md} and a pointer to memory previously
-allocated by @code{mmalloc} in @var{ptr}, free the previously allocated memory.
-
-@item int mmalloc_errno (void *@var{md});
-Given a @code{mmalloc} descriptor, if the last @code{mmalloc} operation
-failed for some reason due to a system call failure, then
-returns the associated @code{errno}.  Returns 0 otherwise.
-(This function is not yet implemented).
-@end table
-
-@bye
diff --git a/src/xbt/mmalloc/mmorecore.c b/src/xbt/mmalloc/mmorecore.c
deleted file mode 100644 (file)
index a5f9ff5..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Support for an sbrk-like function that uses mmap. */
-
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright 1992, 2000 Free Software Foundation, Inc.
-
-   Contributed by Fred Fish at Cygnus Support.   fnf@cygnus.com */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <errno.h>
-
-#include "mmprivate.h"
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#define PAGE_ALIGN(addr) (void*)(((unsigned long)(addr) + mmalloc_pagesize - 1) & ~(mmalloc_pagesize - 1))
-
-/** @brief Add memory to this heap
- *
- *  Get core for the memory region specified by MDP, using SIZE as the
- *  amount to either add to or subtract from the existing region.  Works
- *  like sbrk(), but using mmap().
- *
- *  It never returns NULL. Instead, it dies verbosely on errors.
- *
- *  @param mdp  The heap
- *  @param size Bytes to allocate for this heap (or <0 to free memory from this heap)
- */
-void *mmorecore(struct mdesc *mdp, ssize_t size)
-{
-  void* result;                 // please keep it uninitialized to track issues
-  size_t mapbytes;              /* Number of bytes to map */
-  void* moveto;                 /* Address where we wish to move "break value" to */
-  void* mapto;                  /* Address we actually mapped to */
-
-  if (size == 0) {
-    /* Just return the current "break" value. */
-    return mdp->breakval;
-  }
-
-  static unsigned long mmalloc_pagesize = 0;
-  if (!mmalloc_pagesize)
-    mmalloc_pagesize = (unsigned long)sysconf(_SC_PAGESIZE);
-
-  if (size < 0) {
-    /* We are deallocating memory.  If the amount requested would cause us to try to deallocate back past the base of
-     * the mmap'd region then die verbosely.  Otherwise, deallocate the memory and return the old break value. */
-    if (((char*)mdp->breakval) + size >= (char*)mdp->base) {
-      result        = mdp->breakval;
-      mdp->breakval = (char*)mdp->breakval + size;
-      moveto = PAGE_ALIGN(mdp->breakval);
-      munmap(moveto, (size_t)(((char*)mdp->top) - ((char*)moveto)) - 1);
-      mdp->top = moveto;
-    } else {
-      fprintf(stderr,"Internal error: mmap was asked to deallocate more memory than it previously allocated. Bailling out now!\n");
-      abort();
-    }
-  } else if ((char*)mdp->breakval + size > (char*)mdp->top) {
-    /* The request would move us past the end of the currently mapped memory, so map in enough more memory to satisfy
-       the request.  This means we also have to grow the mapped-to file by an appropriate amount, since mmap cannot
-       be used to extend a file. */
-    moveto   = PAGE_ALIGN((char*)mdp->breakval + size);
-    mapbytes = (char*)moveto - (char*)mdp->top;
-
-    /* Let's call mmap. Note that it is possible that mdp->top is 0. In this case mmap will choose the address for us.
-       This call might very well overwrite an already existing memory mapping (leading to weird bugs).
-    */
-    mapto = mmap(mdp->top, mapbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
-
-    if (mapto == MAP_FAILED) {
-      char buff[1024];
-      fprintf(stderr, "Internal error: mmap returned MAP_FAILED! pagesize:%lu error: %s\n", mmalloc_pagesize,
-              strerror(errno));
-      snprintf(buff, 1024, "cat /proc/%d/maps", getpid());
-      int status = system(buff);
-      if (status == -1 || !(WIFEXITED(status) && WEXITSTATUS(status) == 0))
-        fprintf(stderr, "Something went wrong when trying to %s\n", buff);
-      sleep(1);
-      abort();
-    }
-
-    if (mdp->top == 0)
-      mdp->base = mdp->breakval = mapto;
-
-    mdp->top      = PAGE_ALIGN((char*)mdp->breakval + size);
-    result        = mdp->breakval;
-    mdp->breakval = (char*)mdp->breakval + size;
-  } else {
-    /* Memory is already mapped, we only need to increase the breakval: */
-    result        = mdp->breakval;
-    mdp->breakval = (char*)mdp->breakval + size;
-  }
-  return result;
-}
diff --git a/src/xbt/mmalloc/mmprivate.h b/src/xbt/mmalloc/mmprivate.h
deleted file mode 100644 (file)
index e7ae79a..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Declarations for `mmalloc' and friends. */
-
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright 1990, 1991, 1992 Free Software Foundation
-
-   Written May 1989 by Mike Haertel.
-   Heavily modified Mar 1992 by Fred Fish. (fnf@cygnus.com) */
-
-#ifndef XBT_MMPRIVATE_H
-#define XBT_MMPRIVATE_H 1
-
-#include "src/internal_config.h"
-#include "src/xbt/mmalloc/mmalloc.h"
-#include "swag.h"
-
-#include <limits.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-// This macro is veery similar to xbt_assert, but with no dependency on XBT
-#define mmalloc_assert(cond, ...)                                                                                      \
-  do {                                                                                                                 \
-    if (!(cond)) {                                                                                                     \
-      fprintf(stderr, __VA_ARGS__);                                                                                    \
-      abort();                                                                                                         \
-    }                                                                                                                  \
-  } while (0)
-
-XBT_PRIVATE xbt_mheap_t mmalloc_preinit(void);
-
-#define MMALLOC_MAGIC    "mmalloc"       /* Mapped file magic number */
-#define MMALLOC_MAGIC_SIZE  8       /* Size of magic number buf */
-#define MMALLOC_VERSION    2       /* Current mmalloc version */
-
-/* The allocator divides the heap into blocks of fixed size; large
-   requests receive one or more whole blocks, and small requests
-   receive a fragment of a block.  Fragment sizes are powers of two,
-   and all fragments of a block are the same size.  When all the
-   fragments in a block have been freed, the block itself is freed.
-
-   FIXME: we are not targeting 16bits machines anymore; update values */
-
-#define INT_BIT    (CHAR_BIT * sizeof(int))
-#define BLOCKLOG  (INT_BIT > 16 ? 12 : 9)
-#define BLOCKSIZE  ((unsigned int) 1 << BLOCKLOG)
-#define BLOCKIFY(SIZE)  (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
-
-/* We keep fragment-specific meta-data for introspection purposes, and these
- * information are kept in fixed length arrays. Here is the computation of
- * that size.
- *
- * Never make SMALLEST_POSSIBLE_MALLOC too small because we need to enlist
- * the free fragments.
- *
- * FIXME: what's the correct size, actually? The used one is a guess.
- */
-
-#define SMALLEST_POSSIBLE_MALLOC (32 * sizeof(void*))
-#define MAX_FRAGMENT_PER_BLOCK (BLOCKSIZE / SMALLEST_POSSIBLE_MALLOC)
-
-/* The difference between two pointers is a signed int.  On machines where
-   the data addresses have the high bit set, we need to ensure that the
-   difference becomes an unsigned int when we are using the address as an
-   integral value.  In addition, when using with the '%' operator, the
-   sign of the result is machine dependent for negative values, so force
-   it to be treated as an unsigned int. */
-
-#define ADDR2UINT(addr)  ((uintptr_t) (addr))
-#define RESIDUAL(addr,bsize) ((uintptr_t) (ADDR2UINT (addr) % (bsize)))
-
-/* Determine the amount of memory spanned by the initial heap table
-   (not an absolute limit).  */
-
-#define HEAP    (INT_BIT > 16 ? 4194304 : 65536)
-
-/* Number of contiguous free blocks allowed to build up at the end of
-   memory before they will be returned to the system.
-   FIXME: this is not used anymore: we never return memory to the system. */
-#define FINAL_FREE_BLOCKS  8
-
-/* Where to start searching the free list when looking for new memory.
-   The two possible values are 0 and heapindex.  Starting at 0 seems
-   to reduce total memory usage, while starting at heapindex seems to
-   run faster.  */
-
-#define MALLOC_SEARCH_START  mdp -> heapindex
-
-/* Address to block number and vice versa.  */
-
-#define BLOCK(A) ((size_t)(((char*)(A) - (char*)mdp->heapbase) / BLOCKSIZE + 1))
-
-#define ADDRESS(B) ((void*) (((ADDR2UINT(B)) - 1) * BLOCKSIZE + (char*) mdp -> heapbase))
-
-SG_BEGIN_DECL
-
-/* Statistics available to the user. */
-struct mstats
-{
-  size_t bytes_total;    /* Total size of the heap. */
-  size_t chunks_used;    /* Chunks allocated by the user. */
-  size_t bytes_used;    /* Byte total of user-allocated chunks. */
-  size_t chunks_free;    /* Chunks in the free list. */
-  size_t bytes_free;    /* Byte total of chunks in the free list. */
-};
-
-#define MMALLOC_TYPE_HEAPINFO (-2)
-#define MMALLOC_TYPE_FREE (-1)
-#define MMALLOC_TYPE_UNFRAGMENTED 0
-/* >0 values are fragmented blocks */
-
-/* Data structure giving per-block information.
- *
- * There is one such structure in the mdp->heapinfo array per block used in that heap,
- *    the array index is the block number.
- *
- * There is several types of blocks in memory:
- *  - full busy blocks: used when we are asked to malloc a block which size is > BLOCKSIZE/2
- *    In this situation, the full block is given to the malloc.
- *
- *  - fragmented busy blocks: when asked for smaller amount of memory.
- *    Fragment sizes are only power of 2. When looking for such a free fragment,
- *    we get one from mdp->fraghead (that contains a linked list of blocks fragmented at that
- *    size and containing a free fragment), or we get a fresh block that we fragment.
- *
- *  - free blocks are grouped by clusters, that are chained together.
- *    When looking for free blocks, we traverse the mdp->heapinfo looking
- *    for a cluster of free blocks that would be large enough.
- *
- *    The size of the cluster is only to be trusted in the first block of the cluster, not in the middle blocks.
- *
- * The type field is consistently updated for every blocks, even within clusters of blocks.
- * You can crawl the array and rely on that value.
- *
- */
-typedef struct {
-  s_xbt_swag_hookup_t freehook; /* to register this block as having empty frags when needed */
-  int type; /*  0: busy large block
-                >0: busy fragmented (fragments of size 2^type bytes)
-                <0: free block */
-
-  union {
-    /* Heap information for a busy block.  */
-    struct {
-      size_t nfree;               /* Free fragments in a fragmented block.  */
-      ssize_t frag_size[MAX_FRAGMENT_PER_BLOCK];
-      int ignore[MAX_FRAGMENT_PER_BLOCK];
-    } busy_frag;
-    struct {
-      size_t size; /* Size (in blocks) of a large cluster.  */
-      size_t busy_size; /* Actually used space, in bytes */
-      int ignore;
-    } busy_block;
-    /* Heap information for a free block (that may be the first of a free cluster).  */
-    struct {
-      size_t size;                /* Size (in blocks) of a free cluster.  */
-      size_t next;                /* Index of next free cluster.  */
-      size_t prev;                /* Index of previous free cluster.  */
-    } free_block;
-  };
-} malloc_info;
-
-/** @brief Descriptor of a mmalloc area
- *
- * Internal structure that defines the format of the malloc-descriptor.
- * This gets written to the base address of the region that mmalloc is
- * managing, and thus also becomes the file header for the mapped file,
- * if such a file exists.
- * */
-struct mdesc {
-  /** @brief Chained lists of mdescs */
-  struct mdesc *next_mdesc;
-
-  /** @brief The "magic number" for an mmalloc file. */
-  char magic[MMALLOC_MAGIC_SIZE];
-
-  /** @brief The size in bytes of this structure
-   *
-   * Used as a sanity check when reusing a previously created mapped file.
-   * */
-  unsigned int headersize;
-
-  /** @brief Version number of the mmalloc package that created this file. */
-  unsigned char version;
-
-  unsigned int options;
-
-  /** @brief Some flag bits to keep track of various internal things. */
-  unsigned int flags;
-
-  /** @brief Number of info entries.  */
-  size_t heapsize;
-
-  /** @brief Pointer to first block of the heap (base of the first block).  */
-  void *heapbase;
-
-  /** @brief Current search index for the heap table.
-   *
-   *  Search index in the info table.
-   */
-  size_t heapindex;
-
-  /** @brief Limit of valid info table indices.  */
-  size_t heaplimit;
-
-  /** @brief Block information table.
-   *
-   * Table indexed by block number giving per-block information.
-   */
-  malloc_info *heapinfo;
-
-  /* @brief List of all blocks containing free fragments of a given size.
-   *
-   * The array index is the log2 of requested size.
-   * Actually only the sizes 8->11 seem to be used, but who cares? */
-  s_xbt_swag_t fraghead[BLOCKLOG];
-
-  /* @brief Base address of the memory region for this malloc heap
-   *
-   * This is the location where the bookkeeping data for mmap and
-   * for malloc begins.
-   */
-  void *base;
-
-  /** @brief End of memory in use
-   *
-   *  Some memory might be already mapped by the OS but not used
-   *  by the heap.
-   * */
-  void *breakval;
-
-  /** @brief End of the current memory region for this malloc heap.
-   *
-   *  This is the first location past the end of mapped memory.
-   *
-   *  Compared to breakval, this value is rounded to the next memory page.
-   */
-  void *top;
-
-  /* @brief Instrumentation */
-  struct mstats heapstats;
-};
-
-/* Bits to look at in the malloc descriptor flags word */
-
-#define MMALLOC_DEVZERO    (1 << 0)        /* Have mapped to /dev/zero */
-#define MMALLOC_INITIALIZED (1 << 1)      /* Initialized mmalloc */
-
-/* A default malloc descriptor for the single sbrk() managed region. */
-
-XBT_PUBLIC_DATA struct mdesc* __mmalloc_default_mdp;
-
-XBT_PUBLIC void* mmorecore(struct mdesc* mdp, ssize_t size);
-
-XBT_PRIVATE size_t mmalloc_get_bytes_used_remote(size_t heaplimit, const malloc_info* heapinfo);
-
-/* We call dlsym during mmalloc initialization, but dlsym uses malloc.
- * So during mmalloc initialization, any call to malloc is diverted to a private static buffer.
- */
-extern uint64_t* mmalloc_preinit_buffer;
-#ifdef __FreeBSD__ /* FreeBSD require more memory, other might */
-#define mmalloc_preinit_buffer_size 256
-#else /* Valid on: Linux */
-#define mmalloc_preinit_buffer_size 32
-#endif
-
-SG_END_DECL
-
-#endif
diff --git a/src/xbt/mmalloc/mrealloc.c b/src/xbt/mmalloc/mrealloc.c
deleted file mode 100644 (file)
index 662cc0a..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Change the size of a block allocated by `mmalloc'. */
-
-/* Copyright (c) 2010-2023. 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. */
-
-/* Copyright 1990, 1991 Free Software Foundation
-   Written May 1989 by Mike Haertel. */
-
-#include <string.h>             /* Prototypes for memcpy, memmove, memset, etc */
-#include <stdlib.h> /* abort */
-
-#include "mmprivate.h"
-
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-/* Resize the given region to the new size, returning a pointer to the (possibly moved) region. This is optimized for
- * speed; some benchmarks seem to indicate that greater compactness is achieved by unconditionally allocating and
- * copying to a new region.  This module has incestuous knowledge of the internals of both mfree and mmalloc. */
-
-void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size)
-{
-  void *result;
-  size_t blocks;
-
-  /* Only keep real realloc, and reroute hidden malloc and free to the relevant functions */
-  if (size == 0) {
-    mfree(mdp, ptr);
-    return mmalloc(mdp, 0);
-  } else if (ptr == NULL) {
-    return mmalloc(mdp, size);
-  }
-
-  if ((char *) ptr < (char *) mdp->heapbase || BLOCK(ptr) > mdp->heapsize) {
-    // Don't trust xbt_assert and friends in malloc-level library, you fool!
-    fprintf(stderr, "This pointer is not mine, refusing to realloc it (maybe you wanted to malloc it instead?)\n");
-    abort();
-  }
-
-  size_t requested_size = size; // The amount of memory requested by user, for real
-
-  /* Work even if the user was stupid enough to ask a ridiculously small block (even 0-length),
-   *    ie return a valid block that can be realloced and freed.
-   * glibc malloc does not use this trick but return a constant pointer, but we need to enlist the free fragments later on.
-   */
-  if (size < SMALLEST_POSSIBLE_MALLOC)
-    size = SMALLEST_POSSIBLE_MALLOC;
-
-  size_t block = BLOCK(ptr);
-
-  int type = mdp->heapinfo[block].type;
-
-  switch (type) {
-  case MMALLOC_TYPE_HEAPINFO:
-    fprintf(stderr, "Asked realloc a fragment coming from a heapinfo block. I'm confused.\n");
-    abort();
-    break;
-
-  case MMALLOC_TYPE_FREE:
-    fprintf(stderr, "Asked realloc a fragment coming from a *free* block. I'm puzzled.\n");
-    abort();
-    break;
-
-  case MMALLOC_TYPE_UNFRAGMENTED:
-    /* Maybe reallocate a large block to a small fragment.  */
-
-    if (size <= BLOCKSIZE / 2) { // Full block -> Fragment; no need to optimize for time
-
-      result = mmalloc(mdp, size);
-      memcpy(result, ptr, requested_size);
-      mfree(mdp, ptr);
-      return result;
-    }
-
-    /* Full blocks -> Full blocks; see if we can hold it in place. */
-    blocks = BLOCKIFY(size);
-    if (blocks < mdp->heapinfo[block].busy_block.size) {
-      /* The new size is smaller; return excess memory to the free list. */
-      for (size_t it = block + blocks; it < mdp->heapinfo[block].busy_block.size; it++) {
-        mdp->heapinfo[it].type = MMALLOC_TYPE_UNFRAGMENTED; // FIXME that should be useless, type should already be 0 here
-        mdp->heapinfo[it].busy_block.ignore = 0;
-        mdp->heapinfo[it].busy_block.size = 0;
-        mdp->heapinfo[it].busy_block.busy_size = 0;
-      }
-
-      mdp->heapinfo[block + blocks].busy_block.size = mdp->heapinfo[block].busy_block.size - blocks;
-      mfree(mdp, ADDRESS(block + blocks));
-
-      mdp->heapinfo[block].busy_block.size = blocks;
-      mdp->heapinfo[block].busy_block.busy_size = requested_size;
-      mdp->heapinfo[block].busy_block.ignore = 0;
-
-      result = ptr;
-    } else if (blocks == mdp->heapinfo[block].busy_block.size) {
-
-      /* No block size change necessary; only update the requested size  */
-      result = ptr;
-      mdp->heapinfo[block].busy_block.busy_size = requested_size;
-      mdp->heapinfo[block].busy_block.ignore = 0;
-
-    } else {
-      /* Won't fit, so allocate a new region that will.
-         Free the old region first in case there is sufficient adjacent free space to grow without moving.
-         This trick mandates using a specific version of mmalloc that does not memset the memory to 0 after
-           action for obvious reasons. */
-      blocks = mdp->heapinfo[block].busy_block.size;
-      /* Prevent free from actually returning memory to the system.  */
-      size_t oldlimit = mdp->heaplimit;
-      mdp->heaplimit = 0;
-      mfree(mdp, ptr);
-      mdp->heaplimit = oldlimit;
-
-      result = mmalloc_no_memset(mdp, requested_size);
-
-      if (ptr != result)
-        memmove(result, ptr, blocks * BLOCKSIZE);
-      /* FIXME: we should memset the end of the recently area */
-    }
-    break;
-
-  default: /* Fragment -> ??; type=logarithm to base two of the fragment size.  */
-
-    if (type <= 0) {
-      fprintf(stderr, "Unknown mmalloc block type.\n");
-      abort();
-    }
-
-    if (size > ((size_t)1 << (type - 1)) && size <= ((size_t)1 << type)) {
-      /* The new size is the same kind of fragment.  */
-
-      result = ptr;
-      uintptr_t frag_nb                                 = RESIDUAL(result, BLOCKSIZE) >> type;
-      mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = requested_size;
-      mdp->heapinfo[block].busy_frag.ignore[frag_nb] = 0;
-
-    } else { /* fragment -> Either other fragment, or block */
-      /* The new size is different; allocate a new space,
-         and copy the lesser of the new size and the old. */
-
-      result = mmalloc(mdp, requested_size);
-
-      memcpy(result, ptr, MIN(requested_size, (size_t) 1 << type));
-      mfree(mdp, ptr);
-    }
-    break;
-  }
-  return result;
-}
diff --git a/src/xbt/mmalloc/swag.c b/src/xbt/mmalloc/swag.c
deleted file mode 100644 (file)
index eff8368..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2004-2023. 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. */
-
-/* Warning, this module is done to be efficient and performs tons of
-   cast and dirty things. So avoid using it unless you really know
-   what you are doing. */
-
-/* This type should be added to a type that is to be used in such a swag */
-
-#include "swag.h"
-#include "mmprivate.h" // mmalloc_assert
-
-typedef s_xbt_swag_hookup_t *xbt_swag_hookup_t;
-typedef struct xbt_swag* xbt_swag_t;
-typedef const struct xbt_swag* const_xbt_swag_t;
-
-#define xbt_swag_getPrev(obj, offset) (((xbt_swag_hookup_t)(((char*)(obj)) + (offset)))->prev)
-#define xbt_swag_getNext(obj, offset) (((xbt_swag_hookup_t)(((char*)(obj)) + (offset)))->next)
-#define xbt_swag_belongs(obj, swag) (xbt_swag_getNext((obj), (swag)->offset) || (swag)->tail == (obj))
-
-static inline void *xbt_swag_getFirst(const_xbt_swag_t swag)
-{
-  return swag->head;
-}
-
-/*
- * @brief Offset computation
- * @arg var a variable of type <tt>struct</tt> something
- * @arg field a field of <tt>struct</tt> something
- * @return the offset of @a field in <tt>struct</tt> something.
- * @hideinitializer
- *
- * It is very similar to offsetof except that is done at runtime and that you have to declare a variable. Why defining
- * such a macro then ? Because it is portable...
- */
-#define xbt_swag_offset(var, field) ((char*)&((var).field) - (char*)&(var))
-/* @} */
-
-/* Creates a new swag.
- * @param swag the swag to initialize
- * @param offset where the hookup is located in the structure
- * @see xbt_swag_offset
- *
- * Usage : xbt_swag_init(swag,&obj.setA-&obj);
- */
-static inline void xbt_swag_init(xbt_swag_t swag, size_t offset)
-{
-  swag->tail   = NULL;
-  swag->head   = NULL;
-  swag->offset = offset;
-  swag->count  = 0;
-}
-
-/*
- * @param obj the object to insert in the swag
- * @param swag a swag
- *
- * insert (at the tail... you probably had a very good reason to do that, I hope you know what you're doing) @a obj in
- * @a swag
- */
-static inline void xbt_swag_insert(void *obj, xbt_swag_t swag)
-{
-
-  mmalloc_assert(!xbt_swag_belongs(obj, swag) || swag->tail,
-                 "This object belongs to an empty swag! Did you correctly initialize the object's hookup?");
-
-  if (!swag->head) {
-    mmalloc_assert(!(swag->tail), "Inconsistent swag.");
-    swag->head = obj;
-    swag->tail = obj;
-    swag->count++;
-  } else if (obj != swag->tail && !xbt_swag_getNext(obj, swag->offset)) {
-    xbt_swag_getPrev(obj, swag->offset)        = swag->tail;
-    xbt_swag_getNext(swag->tail, swag->offset) = obj;
-    swag->tail = obj;
-    swag->count++;
-  }
-}
-
-/*
- * @param obj the object to remove from the swag
- * @param swag a swag
- * @return @a obj if it was in the @a swag and NULL otherwise
- *
- * removes @a obj from @a swag
- */
-static inline void *xbt_swag_remove(void *obj, xbt_swag_t swag)
-{
-  if (!obj)
-    return NULL;
-
-  size_t offset = swag->offset;
-  void* prev    = xbt_swag_getPrev(obj, offset);
-  void* next    = xbt_swag_getNext(obj, offset);
-
-  if (prev) {
-    xbt_swag_getNext(prev, offset) = next;
-    xbt_swag_getPrev(obj, offset)  = NULL;
-    if (next) {
-      xbt_swag_getPrev(next, offset) = prev;
-      xbt_swag_getNext(obj, offset)  = NULL;
-    } else {
-      swag->tail = prev;
-    }
-    swag->count--;
-  } else if (next) {
-    xbt_swag_getPrev(next, offset) = NULL;
-    xbt_swag_getNext(obj, offset)  = NULL;
-    swag->head = next;
-    swag->count--;
-  } else if (obj == swag->head) {
-    swag->head = swag->tail = NULL;
-    swag->count--;
-  }
-
-  return obj;
-}
-
-/*
- * @param swag a swag
- * @return the number of objects in @a swag
- */
-static inline int xbt_swag_size(const_xbt_swag_t swag)
-{
-  return swag->count;
-}
diff --git a/src/xbt/mmalloc/swag.h b/src/xbt/mmalloc/swag.h
deleted file mode 100644 (file)
index 7997da2..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2004-2023. 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. */
-
-/* Warning, this module is done to be efficient and performs tons of cast and dirty things. So avoid using it unless
- * you really know what you are doing. */
-
-#ifndef XBT_SWAG_H
-#define XBT_SWAG_H
-
-/*
- * XBT_swag: a O(1) set based on linked lists
- *
- *  Warning, this module is done to be efficient and performs tons of cast and dirty things. So make sure you know what
- *  you are doing while using it.
- *  It is basically a fifo but with restrictions so that it can be used as a set. Any operation (add, remove, belongs)
- *  is O(1) and no call to malloc/free is done.
- *
- *  @deprecated If you are using C++, you might want to use `boost::intrusive::set` instead.
- */
-
-/* Swag types
- *
- *  Specific set.
- *
- *  These typedefs are public so that the compiler can do his job but believe me, you don't want to try to play with
- *  those structs directly. Use them as an abstract datatype.
- */
-
-typedef struct xbt_swag_hookup {
-  void *next;
-  void *prev;
-} s_xbt_swag_hookup_t;
-
-/* This type should be added to a type that is to be used in a swag.
- *
- *  Whenever a new object with this struct is created, all fields have to be set to NULL
- *
- * Here is an example like that :
-
-\code
-typedef struct foo {
-  s_xbt_swag_hookup_t set1_hookup;
-  s_xbt_swag_hookup_t set2_hookup;
-
-  double value;
-} s_foo_t, *foo_t;
-...
-{
-  s_foo_t elem;
-  xbt_swag_t set1=NULL;
-  xbt_swag_t set2=NULL;
-
-  set1 = xbt_swag_new(xbt_swag_offset(elem, set1_hookup));
-  set2 = xbt_swag_new(xbt_swag_offset(elem, set2_hookup));
-
-}
-\endcode
-*/
-
-struct xbt_swag {
-  void *head;
-  void *tail;
-  size_t offset;
-  int count;
-};
-typedef struct xbt_swag s_xbt_swag_t;
-
-#endif /* XBT_SWAG_H */
index b6a16ad..f0d5401 100644 (file)
@@ -40,11 +40,11 @@ double xbt_os_time(void)
 #if HAVE_GETTIMEOFDAY
   struct timeval tv;
   gettimeofday(&tv, NULL);
+
+  return (double)tv.tv_sec + (double)tv.tv_usec / 1e6;
 #else                           /* no gettimeofday => poor resolution */
   return (double) (time(NULL));
 #endif                          /* HAVE_GETTIMEOFDAY? */
-
-  return (double)tv.tv_sec + (double)tv.tv_usec / 1e6;
 }
 
 void xbt_os_sleep(double sec)
@@ -59,7 +59,7 @@ void xbt_os_sleep(double sec)
   struct timeval timeout;
 
   timeout.tv_sec  = (long)sec;
-  timeout.tv_usec = (long)(sec - floor(sec)) * 1e6);
+  timeout.tv_usec = (long)(sec - floor(sec)) * 1e6;
 
   select(0, NULL, NULL, NULL, &timeout);
 #endif
index 7addb33..dba795f 100644 (file)
@@ -1,10 +1,5 @@
-if (NOT SIMGRID_HAVE_STATEFUL_MC)
-  set(dwarf_disable 1)
-  set(dwarf-expression_disable 1)
-endif()
-
 
-foreach(x dwarf dwarf-expression random-bug mutex-handling)
+foreach(x random-bug mutex-handling)
 
   if(NOT DEFINED ${x}_sources)
     set(${x}_sources ${x}/${x}.cpp)
@@ -36,10 +31,6 @@ set_target_properties(without-mutex-handling PROPERTIES COMPILE_FLAGS -DDISABLE_
 set_target_properties(without-mutex-handling PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mutex-handling)
 add_dependencies(tests-mc without-mutex-handling)
 
-set(teshsuite_src  ${teshsuite_src}                                                                        PARENT_SCOPE)
-set(tesh_files     ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/random-bug/random-bug-replay.tesh
-                                    ${CMAKE_CURRENT_SOURCE_DIR}/mutex-handling/without-mutex-handling.tesh PARENT_SCOPE)
-
 ADD_TESH(mc-random-bug-replay                --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/random-bug --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/random-bug random-bug-replay.tesh)
 IF(SIMGRID_HAVE_MC)
   ADD_TESH(tesh-mc-mutex-handling              --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/mutex-handling --setenv srcdir=${CMAKE_HOME_DIRECTORY} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/mutex-handling mutex-handling.tesh --cfg=model-check/reduction:none)
@@ -48,11 +39,53 @@ IF(SIMGRID_HAVE_MC)
   ADD_TESH(tesh-mc-without-mutex-handling-dpor --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/mutex-handling --setenv srcdir=${CMAKE_HOME_DIRECTORY} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/mutex-handling without-mutex-handling.tesh --cfg=model-check/reduction:dpor)
   ADD_TESH(mc-random-bug                       --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/random-bug --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/random-bug random-bug.tesh)
 ENDIF()
-IF(SIMGRID_HAVE_STATEFUL_MC)
-  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)
-ENDIF()
 
 if(enable_coverage)
   ADD_TEST(cover-mc-mutex-handling ${CMAKE_CURRENT_BINARY_DIR}/mutex-handling/mutex-handling ${CMAKE_HOME_DIRECTORY}/examples/platforms/small_platform.xml)
 endif()
+
+
+foreach(x
+#              
+#             simple_cond_broadcast_deadlock  simple_semaphore_deadlock  simple_barrier_deadlock  simple_cond_deadlock
+#                   simple_semaphores_deadlock
+#                   
+#                   
+#                   philosophers_spurious_deadlock
+#                   simple_barrier_with_threads_deadlock
+#                   simple_semaphores_with_threads_deadlock
+#                   simple_cond_broadcast_with_semaphore_deadlock1  simple_cond_broadcast_with_semaphore_deadlock2
+#                   simple_mutex_deadlock
+#                   simple_mutex_with_threads_deadlock
+            
+             barber_shop_ok             barber_shop_deadlock
+             philosophers_semaphores_ok philosophers_semaphores_deadlock
+             philosophers_mutex_ok      philosophers_mutex_deadlock
+             producer_consumer_ok       producer_consumer_deadlock    
+             
+             
+             # producer_consumer_spurious_nok # infinite no-op loop
+             
+#               
+#              
+#             simple_barrier_ok simple_barrier_with_threads_ok simple_cond_broadcast_ok
+#             simple_cond_broadcast_with_semaphore_ok simple_cond_ok simple_mutex_ok
+#             simple_mutex_with_threads_ok simple_semaphores_ok simple_semaphores_with_threads_ok simple_threads_ok
+             )
+
+  set(teshsuite_src  ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/mcmini/${x}.c)
+  set(tesh_files     ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/mcmini/${x}.tesh)
+
+  if("${CMAKE_SYSTEM}" MATCHES "Linux" AND ${enable_testsuite_McMini})
+    add_executable       (mcmini-${x}  EXCLUDE_FROM_ALL mcmini/${x}.c)         
+    set_target_properties(mcmini-${x}  PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mcmini)
+    target_link_libraries(mcmini-${x}  PRIVATE Threads::Threads)
+    add_dependencies(tests-mc mcmini-${x})
+
+    ADD_TESH(mc-mini-${x} --setenv libdir=${CMAKE_BINARY_DIR}/lib --setenv bindir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/mcmini/${x}.tesh)
+  endif()
+endforeach()
+
+set(teshsuite_src  ${teshsuite_src}                                                                        PARENT_SCOPE)
+set(tesh_files     ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/random-bug/random-bug-replay.tesh
+                                    ${CMAKE_CURRENT_SOURCE_DIR}/mutex-handling/without-mutex-handling.tesh PARENT_SCOPE)
diff --git a/teshsuite/mc/dwarf-expression/dwarf-expression.cpp b/teshsuite/mc/dwarf-expression/dwarf-expression.cpp
deleted file mode 100644 (file)
index cccdce3..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* Copyright (c) 2014-2023. 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. */
-
-#ifdef NDEBUG
-#undef NDEBUG
-#endif
-
-#include "src/mc/mc_private.hpp"
-
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/inspect/Type.hpp"
-#include "src/mc/inspect/Variable.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include <array>
-#include <cassert>
-#include <cstdlib>
-#include <limits>
-#include <xbt/random.hpp>
-
-static uintptr_t rnd_engine()
-{
-  return simgrid::xbt::random::uniform_int(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
-}
-
-static uintptr_t eval_binary_operation(simgrid::dwarf::ExpressionContext const& state, uint8_t op, uintptr_t a,
-                                       uintptr_t b)
-{
-  std::array<Dwarf_Op, 15> ops;
-  ops[0].atom = DW_OP_const8u;
-  ops[0].number = a;
-  ops[1].atom = DW_OP_const8u;
-  ops[1].number = b;
-  ops[2].atom = op;
-
-  simgrid::dwarf::ExpressionStack stack;
-  try {
-    simgrid::dwarf::execute(ops.data(), 3, state, stack);
-  } catch (const simgrid::dwarf::evaluation_error&) {
-    fprintf(stderr,"Expression evaluation error");
-  }
-
-  assert(stack.size() == 1);
-  return stack.top();
-}
-
-static void basic_test(simgrid::dwarf::ExpressionContext const& state)
-{
-  std::array<Dwarf_Op, 60> ops;
-
-  uintptr_t a = rnd_engine();
-  uintptr_t b = rnd_engine();
-
-  simgrid::dwarf::ExpressionStack stack;
-
-  bool caught_ex = false;
-  try {
-    ops[0].atom = DW_OP_drop;
-    simgrid::dwarf::execute(ops.data(), 1, state, stack);
-  } catch (const simgrid::dwarf::evaluation_error&) {
-    caught_ex = true;
-  }
-  if (not caught_ex)
-    fprintf(stderr, "Exception expected");
-
-  try {
-    ops[0].atom = DW_OP_lit21;
-    simgrid::dwarf::execute(ops.data(), 1, state, stack);
-    assert(stack.size() == 1);
-    assert(stack.top() == 21);
-
-    ops[0].atom   = DW_OP_const8u;
-    ops[0].number = a;
-    simgrid::dwarf::execute(ops.data(), 1, state, stack);
-    assert(stack.size() == 2);
-    assert(stack.top() == a);
-
-    ops[0].atom = DW_OP_drop;
-    ops[1].atom = DW_OP_drop;
-    simgrid::dwarf::execute(ops.data(), 2, state, stack);
-    assert(stack.empty());
-
-    stack.clear();
-    ops[0].atom   = DW_OP_lit21;
-    ops[1].atom   = DW_OP_plus_uconst;
-    ops[1].number = a;
-    simgrid::dwarf::execute(ops.data(), 2, state, stack);
-    assert(stack.size() == 1);
-    assert(stack.top() == a + 21);
-
-    stack.clear();
-    ops[0].atom   = DW_OP_const8u;
-    ops[0].number = a;
-    ops[1].atom   = DW_OP_dup;
-    ops[2].atom   = DW_OP_plus;
-    simgrid::dwarf::execute(ops.data(), 3, state, stack);
-    assert(stack.size() == 1);
-    assert(stack.top() == a + a);
-
-    stack.clear();
-    ops[0].atom   = DW_OP_const8u;
-    ops[0].number = a;
-    ops[1].atom   = DW_OP_const8u;
-    ops[1].number = b;
-    ops[2].atom   = DW_OP_over;
-    simgrid::dwarf::execute(ops.data(), 3, state, stack);
-    assert(stack.size() == 3);
-    assert(stack.top() == a);
-    assert(stack.top(1) == b);
-    assert(stack.top(2) == a);
-
-    stack.clear();
-    ops[0].atom   = DW_OP_const8u;
-    ops[0].number = a;
-    ops[1].atom   = DW_OP_const8u;
-    ops[1].number = b;
-    ops[2].atom   = DW_OP_swap;
-    simgrid::dwarf::execute(ops.data(), 3, state, stack);
-    assert(stack.size() == 2);
-    assert(stack.top() == a);
-    assert(stack.top(1) == b);
-  } catch (const simgrid::dwarf::evaluation_error&) {
-    fprintf(stderr,"Expression evaluation error");
-  }
-}
-
-static void test_deref(simgrid::dwarf::ExpressionContext const& state)
-{
-  try {
-    uintptr_t foo = 42;
-
-    std::array<Dwarf_Op, 60> ops;
-    ops[0].atom   = DW_OP_const8u;
-    ops[0].number = (uintptr_t)&foo;
-    ops[1].atom   = DW_OP_deref;
-
-    simgrid::dwarf::ExpressionStack stack;
-
-    simgrid::dwarf::execute(ops.data(), 2, state, stack);
-    assert(stack.size() == 1);
-    assert(stack.top() == foo);
-  } catch (const simgrid::dwarf::evaluation_error&) {
-    fprintf(stderr,"Expression evaluation error");
-  }
-}
-
-int main()
-{
-  auto* process = new simgrid::mc::RemoteProcessMemory(getpid(), nullptr);
-
-  simgrid::dwarf::ExpressionContext state;
-  state.address_space = (simgrid::mc::AddressSpace*) process;
-
-  basic_test(state);
-
-  for(int i=0; i!=100; ++i) {
-    uintptr_t a = rnd_engine();
-    uintptr_t b = rnd_engine();
-    assert(eval_binary_operation(state, DW_OP_plus, a, b) == (a + b));
-  }
-
-  for(int i=0; i!=100; ++i) {
-    uintptr_t a = rnd_engine();
-    uintptr_t b = rnd_engine();
-    assert(eval_binary_operation(state, DW_OP_or, a, b) == (a | b));
-  }
-
-  for(int i=0; i!=100; ++i) {
-    uintptr_t a = rnd_engine();
-    uintptr_t b = rnd_engine();
-    assert(eval_binary_operation(state, DW_OP_and, a, b) == (a & b));
-  }
-
-  for(int i=0; i!=100; ++i) {
-    uintptr_t a = rnd_engine();
-    uintptr_t b = rnd_engine();
-    assert(eval_binary_operation(state, DW_OP_xor, a, b) == (a ^ b));
-  }
-
-  test_deref(state);
-
-  return 0;
-}
diff --git a/teshsuite/mc/dwarf-expression/dwarf-expression.tesh b/teshsuite/mc/dwarf-expression/dwarf-expression.tesh
deleted file mode 100644 (file)
index 787f2bc..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env tesh
-
-$ ${bindir:=.}/dwarf-expression
diff --git a/teshsuite/mc/dwarf/dwarf.cpp b/teshsuite/mc/dwarf/dwarf.cpp
deleted file mode 100644 (file)
index d4d513e..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (c) 2014-2023. 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. */
-
-#ifdef NDEBUG
-#undef NDEBUG
-#endif
-
-#include <simgrid/s4u/Engine.hpp>
-
-#include "src/mc/datatypes.h"
-#include "src/mc/mc.h"
-#include "src/mc/mc_private.hpp"
-
-#include "src/mc/inspect/ObjectInformation.hpp"
-#include "src/mc/inspect/Type.hpp"
-#include "src/mc/inspect/Variable.hpp"
-#include "src/mc/sosp/RemoteProcessMemory.hpp"
-
-#include <cassert>
-#include <cstring>
-
-#include <elfutils/version.h>
-#if _ELFUTILS_VERSION < 171
-// Elder elfutils/libdw broken with multi-dimensional arrays. See https://sourceware.org/bugzilla/show_bug.cgi?id=22546
-int test_some_array[4 * 5 * 6];
-#else
-int test_some_array[4][5][6];
-#endif
-
-struct some_struct {
-  int first;
-  int second[4][5];
-};
-some_struct test_some_struct;
-
-static simgrid::mc::Frame* find_function_by_name(
-    simgrid::mc::ObjectInformation* info, const char* name)
-{
-  for (auto& [_, entry] : info->subprograms)
-    if (entry.name == name)
-      return &entry;
-  return nullptr;
-}
-
-static simgrid::mc::Variable* find_local_variable(
-    simgrid::mc::Frame* frame, const char* argument_name)
-{
-  for (simgrid::mc::Variable& variable : frame->variables)
-    if(argument_name == variable.name)
-      return &variable;
-
-  for (simgrid::mc::Frame& scope : frame->scopes) {
-    simgrid::mc::Variable* variable = find_local_variable(
-      &scope, argument_name);
-    if(variable)
-      return variable;
-  }
-
-  return nullptr;
-}
-
-static void test_local_variable(simgrid::mc::ObjectInformation* info, const char* function, const char* variable,
-                                const void* address, unw_cursor_t* cursor)
-{
-  simgrid::mc::Frame* subprogram = find_function_by_name(info, function);
-  assert(subprogram);
-  // TODO, Lookup frame by IP and test against name instead
-
-  const simgrid::mc::Variable* var = find_local_variable(subprogram, variable);
-  assert(var);
-
-  void* frame_base = subprogram->frame_base(*cursor);
-  simgrid::dwarf::Location location = simgrid::dwarf::resolve(var->location_list, info, cursor, frame_base, nullptr);
-
-  xbt_assert(location.in_memory(), "Expected the variable %s of function %s to be in memory", variable, function);
-  xbt_assert(location.address() == address, "Bad resolution of local variable %s of %s", variable, function);
-}
-
-static const simgrid::mc::Variable* test_global_variable(const simgrid::mc::RemoteProcessMemory& process,
-                                                         simgrid::mc::ObjectInformation* info, const char* name,
-                                                         void* address, long byte_size)
-{
-  const simgrid::mc::Variable* variable = info->find_variable(name);
-  xbt_assert(variable, "Global variable %s was not found", name);
-  xbt_assert(variable->name == name, "Name mismatch for %s", name);
-  xbt_assert(variable->global, "Variable %s is not global", name);
-  xbt_assert(variable->address == address, "Address mismatch for %s : %p expected but %p found", name, address,
-             variable->address);
-
-  auto i = process.binary_info->types.find(variable->type_id);
-  xbt_assert(i != process.binary_info->types.end(), "Missing type for %s", name);
-  const simgrid::mc::Type* type = &i->second;
-  xbt_assert(type->byte_size == byte_size, "Byte size mismatch for %s", name);
-  return variable;
-}
-
-static const simgrid::mc::Member* find_member(const simgrid::mc::Type& type, const char* name)
-{
-  for (const simgrid::mc::Member& member : type.members)
-    if(member.name == name)
-      return &member;
-  return nullptr;
-}
-
-int some_local_variable = 0;
-
-struct s_foo {
-  int i;
-};
-
-static void test_type_by_name(const simgrid::mc::RemoteProcessMemory& process, s_foo /*my_foo*/)
-{
-  assert(process.binary_info->full_types_by_name.find("struct s_foo") != process.binary_info->full_types_by_name.end());
-}
-
-int main(int argc, char** argv)
-{
-  simgrid::s4u::Engine::get_instance(&argc, argv);
-
-  const simgrid::mc::Variable* var;
-  const simgrid::mc::Type* type;
-
-  simgrid::mc::RemoteProcessMemory process(getpid(), nullptr);
-
-  test_global_variable(process, process.binary_info.get(), "some_local_variable", &some_local_variable, sizeof(int));
-
-  var = test_global_variable(process, process.binary_info.get(), "test_some_array", &test_some_array,
-                             sizeof(test_some_array));
-  auto i = process.binary_info->types.find(var->type_id);
-  xbt_assert(i != process.binary_info->types.end(), "Missing type");
-  type = &i->second;
-  xbt_assert(type->element_count == 6 * 5 * 4, "element_count mismatch in test_some_array : %i / %i",
-             type->element_count, 6 * 5 * 4);
-
-  var = test_global_variable(process, process.binary_info.get(), "test_some_struct", &test_some_struct,
-                             sizeof(test_some_struct));
-  i = process.binary_info->types.find(var->type_id);
-  xbt_assert(i != process.binary_info->types.end(), "Missing type");
-  type = &i->second;
-
-  assert(type);
-  assert(find_member(*type, "first")->offset() == 0);
-  assert(find_member(*type, "second")->offset() ==
-         ((const char*)&test_some_struct.second) - (const char*)&test_some_struct);
-
-  unw_context_t context;
-  unw_cursor_t cursor;
-  unw_getcontext(&context);
-  unw_init_local(&cursor, &context);
-
-  test_local_variable(process.binary_info.get(), "main", "argc", &argc, &cursor);
-
-  int lexical_block_variable = 50;
-  test_local_variable(process.binary_info.get(), "main", "lexical_block_variable", &lexical_block_variable, &cursor);
-
-  s_foo my_foo = {0};
-  test_type_by_name(process, my_foo);
-
-  return 0;
-}
diff --git a/teshsuite/mc/dwarf/dwarf.tesh b/teshsuite/mc/dwarf/dwarf.tesh
deleted file mode 100644 (file)
index f6c817b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env tesh
-
-$ ${bindir:=.}/dwarf
diff --git a/teshsuite/mc/mcmini/barber_shop_deadlock.c b/teshsuite/mc/mcmini/barber_shop_deadlock.c
new file mode 100644 (file)
index 0000000..c10c970
--- /dev/null
@@ -0,0 +1,107 @@
+#define _REENTRANT
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+// The maximum number of customer threads.
+#define MAX_CUSTOMERS 10
+
+// Define the semaphores.
+sem_t waitingRoom;
+sem_t barberChair;
+sem_t barberPillow;
+sem_t seatBelt;
+
+// Flag to stop the barber thread when all customers have been serviced.
+int allDone = 0;
+int DEBUG = 0;
+
+static void *customer(void *number) {
+    int num = *(int *)number;
+
+    if(DEBUG) printf("Customer %d leaving for barber shop.\n", num);
+    if(DEBUG) printf("Customer %d arrived at barber shop.\n", num);
+
+    sem_wait(&waitingRoom);
+
+    if(DEBUG) printf("Customer %d entering waiting room.\n", num);
+
+    sem_wait(&barberChair);
+
+    if(DEBUG) printf("Customer %d waking the barber.\n", num);
+    sem_post(&barberPillow);
+
+    sem_wait(&seatBelt);
+
+    sem_post(&barberChair);
+    if(DEBUG) printf("Customer %d leaving barber shop.\n", num);
+    return NULL;
+}
+
+static void *barber(void *junk) {
+    while (!allDone) {
+        if(DEBUG) printf("The barber is sleeping\n");
+        sem_wait(&barberPillow);
+
+        if (!allDone) {
+            if(DEBUG) printf("The barber is cutting hair\n");
+            if(DEBUG) printf("The barber has finished cutting hair.\n");
+            sem_post(&seatBelt);
+        }
+        else {
+            if(DEBUG) printf("The barber is going home for the day.\n");
+        }
+    }
+    return NULL;
+}
+
+int main(int argc, char *argv[]) {
+    if(argc != 5){
+        printf("Usage: %s numCustomers numChairs RandSeed DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    pthread_t btid;
+    pthread_t tid[MAX_CUSTOMERS];
+    int i, numCustomers, numChairs;
+    long RandSeed;
+    int Number[MAX_CUSTOMERS];
+
+    numCustomers = atoi(argv[1]);
+    numChairs = atoi(argv[2]);
+    RandSeed = atol(argv[3]);
+    DEBUG = atoi(argv[4]);
+
+    if (numCustomers > MAX_CUSTOMERS) {
+        printf("The maximum number of Customers is %d.\n", MAX_CUSTOMERS);
+        exit(-1);
+    }
+
+    srand48(RandSeed);
+
+    for (i=0; i<MAX_CUSTOMERS; i++) {
+        Number[i] = i;
+    }
+
+    sem_init(&waitingRoom, 0, numChairs);
+    sem_init(&barberChair, 0, 1);
+    sem_init(&barberPillow, 0, 0);
+    sem_init(&seatBelt, 0, 0);
+
+    pthread_create(&btid, NULL, barber, NULL);
+
+    for (i=0; i<numCustomers; i++) {
+        pthread_create(&tid[i], NULL, customer, (void *)&Number[i]);
+    }
+
+    for (i=0; i<numCustomers; i++) {
+        pthread_join(tid[i],NULL);
+    }
+
+    allDone = 1;
+    sem_post(&barberPillow);
+    pthread_join(btid,NULL);
+}
diff --git a/teshsuite/mc/mcmini/barber_shop_deadlock.tesh b/teshsuite/mc/mcmini/barber_shop_deadlock.tesh
new file mode 100644 (file)
index 0000000..e3420c9
--- /dev/null
@@ -0,0 +1,58 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+! expect return 3
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-barber_shop_deadlock 5 3 0 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED ***
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [ker_engine/INFO] 4 actors are still running, waiting for something.
+> [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor <pid> (<name>@<host>): <status>"
+> [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:6)
+> [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall SEM_WAIT(sem_id:2 not granted)
+> [0.000000] [ker_engine/INFO] Actor 6 (thread 5@Lilibeth) simcall SEM_WAIT(sem_id:0 not granted)
+> [0.000000] [ker_engine/INFO] Actor 7 (thread 6@Lilibeth) simcall SEM_WAIT(sem_id:0 not granted)
+> [0.000000] [mc_global/INFO] Counter-example execution trace:
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_ASYNC_LOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_WAIT(semaphore: 1, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_UNLOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 2, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_UNLOCK(semaphore: 3)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_ASYNC_LOCK(semaphore: 3)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_WAIT(semaphore: 3, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_UNLOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 1 in simcall ActorJoin(target 3, no timeout)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_ASYNC_LOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_WAIT(semaphore: 1, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_UNLOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 2, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_UNLOCK(semaphore: 3)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_ASYNC_LOCK(semaphore: 3)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_WAIT(semaphore: 3, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_UNLOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 1 in simcall ActorJoin(target 4, no timeout)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_ASYNC_LOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_WAIT(semaphore: 1, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_UNLOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 2, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_UNLOCK(semaphore: 3)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 2)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_ASYNC_LOCK(semaphore: 3)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_WAIT(semaphore: 3, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall SEM_UNLOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 1 in simcall ActorJoin(target 5, no timeout)
+> [0.000000] [mc_global/INFO]   Actor 6 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 7 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_Session/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'2;3;3;3;3;3;2;2;2;3;3;3;1;4;4;4;4;4;2;2;2;4;4;4;1;5;5;5;5;5;2;2;2;5;5;5;1;6;7'
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 40 unique states visited; 0 backtracks (0 transition replays, 40 states visited overall)
\ No newline at end of file
diff --git a/teshsuite/mc/mcmini/barber_shop_ok.c b/teshsuite/mc/mcmini/barber_shop_ok.c
new file mode 100644 (file)
index 0000000..827b8db
--- /dev/null
@@ -0,0 +1,185 @@
+#ifdef _REENTRANT
+#undef _REENTRANT
+#endif
+#define _REENTRANT
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+// The maximum number of customer threads.
+#define MAX_CUSTOMERS 25
+
+// Define the semaphores.
+
+// waitingRoom Limits the # of customers allowed
+// to enter the waiting room at one time.
+sem_t waitingRoom;
+
+// barberChair ensures mutually exclusive access to
+// the barber chair.
+sem_t barberChair;
+
+// barberPillow is used to allow the barber to sleep
+// until a customer arrives.
+sem_t barberPillow;
+
+// seatBelt is used to make the customer to wait until
+// the barber is done cutting his/her hair.
+sem_t seatBelt;
+
+// Flag to stop the barber thread when all customers
+// have been serviced.
+int allDone = 0;
+int DEBUG   = 0;
+
+static void randwait(int secs)
+{
+  int len;
+
+  // Generate a random number...
+  len = (int)((drand48() * secs) + 1);
+  sleep(len);
+}
+
+static void* customer(void* number)
+{
+  int num = *(int*)number;
+
+  // Leave for the shop and take some random amount of
+  // time to arrive.
+  if (DEBUG)
+    printf("Customer %d leaving for barber shop.\n", num);
+  randwait(5);
+  if (DEBUG)
+    printf("Customer %d arrived at barber shop.\n", num);
+
+  // Wait for space to open up in the waiting room...
+  sem_wait(&waitingRoom);
+  if (DEBUG)
+    printf("Customer %d entering waiting room.\n", num);
+
+  // Wait for the barber chair to become free.
+  sem_wait(&barberChair);
+
+  // The chair is free so give up your spot in the
+  // waiting room.
+  sem_post(&waitingRoom);
+
+  // Wake up the barber...
+  if (DEBUG)
+    printf("Customer %d waking the barber.\n", num);
+  sem_post(&barberPillow);
+
+  // Wait for the barber to finish cutting your hair.
+  sem_wait(&seatBelt);
+
+  // Give up the chair.
+  sem_post(&barberChair);
+  if (DEBUG)
+    printf("Customer %d leaving barber shop.\n", num);
+  return NULL;
+}
+
+static void* barber(void* junk)
+{
+  // While there are still customers to be serviced...
+  // Our barber is omnicient and can tell if there are
+  // customers still on the way to his shop.
+  while (!allDone) {
+
+    // Sleep until someone arrives and wakes you..
+    if (DEBUG)
+      printf("The barber is sleeping\n");
+    sem_wait(&barberPillow);
+
+    // Skip this stuff at the end...
+    if (!allDone) {
+
+      // Take a random amount of time to cut the
+      // customer's hair.
+      if (DEBUG)
+        printf("The barber is cutting hair\n");
+      randwait(3);
+      if (DEBUG)
+        printf("The barber has finished cutting hair.\n");
+
+      // Release the customer when done cutting...
+      sem_post(&seatBelt);
+    } else {
+      if (DEBUG)
+        printf("The barber is going home for the day.\n");
+    }
+  }
+  return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+  pthread_t btid;
+  pthread_t tid[MAX_CUSTOMERS];
+  long RandSeed;
+  int i, numCustomers, numChairs;
+  int Number[MAX_CUSTOMERS];
+
+  // Check to make sure there are the right number of
+  // command line arguments.
+  if (argc != 5) {
+    printf("Use: SleepBarber <Num Customers> <Num Chairs> <rand seed> <DEBUG>\n");
+    exit(-1);
+  }
+
+  // Get the command line arguments and convert them
+  // into integers.
+  numCustomers = atoi(argv[1]);
+  numChairs    = atoi(argv[2]);
+  RandSeed     = atol(argv[3]);
+  DEBUG        = atoi(argv[4]);
+
+  // Make sure the number of threads is less than the number of
+  // customers we can support.
+  if (numCustomers > MAX_CUSTOMERS) {
+    printf("The maximum number of Customers is %d.\n", MAX_CUSTOMERS);
+    exit(-1);
+  }
+
+  if (DEBUG) {
+    printf("\nSleepBarber.c\n\n");
+    printf("A solution to the sleeping barber problem using semaphores.\n");
+  }
+
+  // Initialize the random number generator with a new seed.
+  srand48(RandSeed);
+
+  // Initialize the numbers array.
+  for (i = 0; i < MAX_CUSTOMERS; i++) {
+    Number[i] = i;
+  }
+
+  // Initialize the semaphores with initial values...
+  sem_init(&waitingRoom, 0, numChairs);
+  sem_init(&barberChair, 0, 1);
+  sem_init(&barberPillow, 0, 0);
+  sem_init(&seatBelt, 0, 0);
+
+  // Create the barber.
+  pthread_create(&btid, NULL, barber, NULL);
+
+  // Create the customers.
+  for (i = 0; i < numCustomers; i++) {
+    pthread_create(&tid[i], NULL, customer, (void*)&Number[i]);
+  }
+
+  // Join each of the threads to wait for them to finish.
+  for (i = 0; i < numCustomers; i++) {
+    pthread_join(tid[i], NULL);
+  }
+
+  // When all of the customers are finished, kill the
+  // barber thread.
+  allDone = 1;
+  sem_post(&barberPillow); // Wake the barber so he will exit.
+  pthread_join(btid, NULL);
+}
diff --git a/teshsuite/mc/mcmini/barber_shop_ok.tesh b/teshsuite/mc/mcmini/barber_shop_ok.tesh
new file mode 100644 (file)
index 0000000..8745d38
--- /dev/null
@@ -0,0 +1,7 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-barber_shop_ok 4 2 0 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 1266 unique states visited; 23 backtracks (271 transition replays, 1560 states visited overall)
diff --git a/teshsuite/mc/mcmini/philosophers_mutex_deadlock.c b/teshsuite/mc/mcmini/philosophers_mutex_deadlock.c
new file mode 100644 (file)
index 0000000..4497df7
--- /dev/null
@@ -0,0 +1,59 @@
+// Naive dining philosophers solution, which leads to deadlock.
+
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+int DEBUG = 0;
+
+struct forks {
+    int philosopher;
+    pthread_mutex_t *left_fork;
+    pthread_mutex_t *right_fork;
+} *forks;
+
+static void * philosopher_doit(void *forks_arg) {
+    struct forks *forks = forks_arg;
+    pthread_mutex_lock(forks->left_fork);
+    pthread_mutex_lock(forks->right_fork);
+
+    if(DEBUG) printf("Philosopher %d just ate.\n", forks->philosopher);
+    
+    pthread_mutex_unlock(forks->left_fork);
+    pthread_mutex_unlock(forks->right_fork);
+    return NULL;
+}
+
+int main(int argc, char* argv[]) {
+    if(argc != 3){
+        printf("Usage: %s NUM_PHILOSOPHERS DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    int NUM_THREADS = atoi(argv[1]);
+    DEBUG = atoi(argv[2]);
+
+    pthread_t thread[NUM_THREADS];
+    pthread_mutex_t mutex_resource[NUM_THREADS];
+
+    forks = malloc(NUM_THREADS * sizeof(struct forks));
+
+    int i;
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_mutex_init(&mutex_resource[i], NULL);
+        forks[i] = (struct forks){i,
+                                  &mutex_resource[i], &mutex_resource[(i+1) % NUM_THREADS]};
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_create(&thread[i], NULL, &philosopher_doit, &forks[i]);
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_join(thread[i], NULL);
+    }
+
+    free(forks);
+    return 0;
+}
diff --git a/teshsuite/mc/mcmini/philosophers_mutex_deadlock.tesh b/teshsuite/mc/mcmini/philosophers_mutex_deadlock.tesh
new file mode 100644 (file)
index 0000000..9092bf9
--- /dev/null
@@ -0,0 +1,36 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+! expect return 3
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-philosophers_mutex_deadlock 5 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED ***
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [ker_engine/INFO] 6 actors are still running, waiting for something.
+> [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor <pid> (<name>@<host>): <status>"
+> [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2)
+> [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall MUTEX_WAIT(mutex_id:1 owner:3)
+> [0.000000] [ker_engine/INFO] Actor 3 (thread 2@Lilibeth) simcall MUTEX_WAIT(mutex_id:2 owner:4)
+> [0.000000] [ker_engine/INFO] Actor 4 (thread 3@Lilibeth) simcall MUTEX_WAIT(mutex_id:3 owner:5)
+> [0.000000] [ker_engine/INFO] Actor 5 (thread 4@Lilibeth) simcall MUTEX_WAIT(mutex_id:4 owner:6)
+> [0.000000] [ker_engine/INFO] Actor 6 (thread 5@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [mc_global/INFO] Counter-example execution trace:
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 1, owner: 3)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 1, owner: 3)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_WAIT(mutex: 1, owner: 3)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_ASYNC_LOCK(mutex: 2, owner: 4)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 2, owner: 4)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_WAIT(mutex: 2, owner: 4)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall MUTEX_ASYNC_LOCK(mutex: 3, owner: 5)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_ASYNC_LOCK(mutex: 3, owner: 5)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall MUTEX_WAIT(mutex: 3, owner: 5)
+> [0.000000] [mc_global/INFO]   Actor 6 in simcall MUTEX_ASYNC_LOCK(mutex: 4, owner: 6)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall MUTEX_ASYNC_LOCK(mutex: 4, owner: 6)
+> [0.000000] [mc_global/INFO]   Actor 6 in simcall MUTEX_WAIT(mutex: 4, owner: 6)
+> [0.000000] [mc_global/INFO]   Actor 6 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_Session/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'2;2;3;2;3;4;3;4;5;4;5;6;5;6;6'
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 317 unique states visited; 15 backtracks (224 transition replays, 556 states visited overall)
\ No newline at end of file
diff --git a/teshsuite/mc/mcmini/philosophers_mutex_ok.c b/teshsuite/mc/mcmini/philosophers_mutex_ok.c
new file mode 100644 (file)
index 0000000..8c30821
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+int DEBUG = 0;
+
+struct forks {
+    int philosopher;
+    pthread_mutex_t *left_fork;
+    pthread_mutex_t *right_fork;
+    pthread_mutex_t *dining_fork;
+};
+
+static void * philosopher_doit(void *forks_arg) {
+    struct forks *forks = forks_arg;
+    pthread_mutex_lock(forks->dining_fork);
+    pthread_mutex_lock(forks->left_fork);
+    pthread_mutex_lock(forks->right_fork);
+    pthread_mutex_unlock(forks->dining_fork);
+
+    if(DEBUG)
+        printf("Philosopher %d is eating.\n", forks->philosopher);
+        
+    pthread_mutex_unlock(forks->left_fork);
+    pthread_mutex_unlock(forks->right_fork);
+    return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+    if(argc != 3){
+        printf("Usage: %s NUM_THREADS DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    int NUM_THREADS = atoi(argv[1]);
+    DEBUG = atoi(argv[2]);
+
+    pthread_t thread[NUM_THREADS];
+    pthread_mutex_t mutex_resource[NUM_THREADS];
+    struct forks forks[NUM_THREADS];
+
+    pthread_mutex_t dining_fork;
+    pthread_mutex_init(&dining_fork, NULL);
+
+    int i;
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_mutex_init(&mutex_resource[i], NULL);
+        forks[i] = (struct forks){i,
+                                  &mutex_resource[i],
+                                  &mutex_resource[(i+1) % NUM_THREADS],
+                                  &dining_fork};
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_create(&thread[i], NULL, &philosopher_doit, &forks[i]);
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_join(thread[i], NULL);
+    }
+
+    return 0;
+}
diff --git a/teshsuite/mc/mcmini/philosophers_mutex_ok.tesh b/teshsuite/mc/mcmini/philosophers_mutex_ok.tesh
new file mode 100644 (file)
index 0000000..6a93b85
--- /dev/null
@@ -0,0 +1,7 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-philosophers_mutex_ok 5 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 4190 unique states visited; 119 backtracks (1811 transition replays, 6120 states visited overall)
\ No newline at end of file
diff --git a/teshsuite/mc/mcmini/philosophers_semaphores_deadlock.c b/teshsuite/mc/mcmini/philosophers_semaphores_deadlock.c
new file mode 100644 (file)
index 0000000..92e58b1
--- /dev/null
@@ -0,0 +1,67 @@
+// Dining philosophers solution with semaphores
+
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdlib.h>
+
+struct forks {
+    int philosopher;
+    pthread_mutex_t *left_fork;
+    pthread_mutex_t *right_fork;
+    sem_t* sem_dining;
+    int DEBUG;
+} *forks;
+
+static void * philosopher_doit(void *forks_arg) {
+    struct forks *forks = forks_arg;
+    sem_wait(forks->sem_dining);
+    pthread_mutex_lock(forks->left_fork);
+    pthread_mutex_lock(forks->right_fork);
+
+    if(forks->DEBUG) printf("Philosopher %d just ate.\n", forks->philosopher);
+    
+    pthread_mutex_unlock(forks->left_fork);
+    pthread_mutex_unlock(forks->right_fork);
+    sem_post(forks->sem_dining);
+    return NULL;
+}
+
+int main(int argc, char* argv[]) {
+    if(argc != 3){
+        printf("Usage: %s NUM_PHILOSOPHERS DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    int NUM_THREADS = atoi(argv[1]);
+    int DEBUG = atoi(argv[2]);
+
+    pthread_t thread[NUM_THREADS];
+    pthread_mutex_t mutex_resource[NUM_THREADS];
+    sem_t sem_dining;
+    sem_init(&sem_dining, 0, NUM_THREADS);
+
+    forks = malloc(NUM_THREADS * sizeof(struct forks));
+
+    int i;
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_mutex_init(&mutex_resource[i], NULL);
+        forks[i] = (struct forks){i,
+                                  &mutex_resource[i],
+                                  &mutex_resource[(i+1) % NUM_THREADS],
+                                  &sem_dining,
+                                  DEBUG};
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_create(&thread[i], NULL, &philosopher_doit, &forks[i]);
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_join(thread[i], NULL);
+    }
+
+    free(forks);
+    return 0;
+}
diff --git a/teshsuite/mc/mcmini/philosophers_semaphores_deadlock.tesh b/teshsuite/mc/mcmini/philosophers_semaphores_deadlock.tesh
new file mode 100644 (file)
index 0000000..e7a6750
--- /dev/null
@@ -0,0 +1,33 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+! expect return 3
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-philosophers_semaphores_deadlock 3 0
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED ***
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [ker_engine/INFO] 4 actors are still running, waiting for something.
+> [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor <pid> (<name>@<host>): <status>"
+> [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2)
+> [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall MUTEX_WAIT(mutex_id:1 owner:3)
+> [0.000000] [ker_engine/INFO] Actor 3 (thread 2@Lilibeth) simcall MUTEX_WAIT(mutex_id:2 owner:4)
+> [0.000000] [ker_engine/INFO] Actor 4 (thread 3@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [mc_global/INFO] Counter-example execution trace:
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 1, owner: 3)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 1, owner: 3)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_WAIT(mutex: 1, owner: 3)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_ASYNC_LOCK(mutex: 2, owner: 4)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 2, owner: 4)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_WAIT(mutex: 2, owner: 4)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_Session/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'2;2;2;2;3;3;3;2;3;4;4;4;3;4;4'
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 890 unique states visited; 90 backtracks (1415 transition replays, 2395 states visited overall)
diff --git a/teshsuite/mc/mcmini/philosophers_semaphores_ok.c b/teshsuite/mc/mcmini/philosophers_semaphores_ok.c
new file mode 100644 (file)
index 0000000..b11e49f
--- /dev/null
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdlib.h>
+
+int DEBUG = 0;
+
+struct forks {
+    int philosopher;
+    pthread_mutex_t *left_fork;
+    pthread_mutex_t *right_fork;
+    sem_t* sem_dining;
+};
+
+static void * philosopher_doit(void *forks_arg) {
+    struct forks *forks = forks_arg;
+    sem_wait(forks->sem_dining);
+    pthread_mutex_lock(forks->left_fork);
+    pthread_mutex_lock(forks->right_fork);
+
+    if(DEBUG)
+        printf("Philosopher %d is eating.\n", forks->philosopher);
+        
+    pthread_mutex_unlock(forks->left_fork);
+    pthread_mutex_unlock(forks->right_fork);
+    sem_post(forks->sem_dining);
+    return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+    if(argc != 3){
+        printf("Usage: %s NUM_THREADS DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    int NUM_THREADS = atoi(argv[1]);
+    DEBUG = atoi(argv[2]);
+
+    pthread_t thread[NUM_THREADS];
+    pthread_mutex_t mutex_resource[NUM_THREADS];
+    struct forks forks[NUM_THREADS];
+
+    sem_t sem_dining;
+    sem_init(&sem_dining, 0, NUM_THREADS - 1);
+
+    int i;
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_mutex_init(&mutex_resource[i], NULL);
+        forks[i] = (struct forks){i,
+                                  &mutex_resource[i],
+                                  &mutex_resource[(i+1) % NUM_THREADS],
+                                  &sem_dining};
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_create(&thread[i], NULL, &philosopher_doit, &forks[i]);
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_join(thread[i], NULL);
+    }
+
+    return 0;
+}
diff --git a/teshsuite/mc/mcmini/philosophers_semaphores_ok.tesh b/teshsuite/mc/mcmini/philosophers_semaphores_ok.tesh
new file mode 100644 (file)
index 0000000..84b5876
--- /dev/null
@@ -0,0 +1,7 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-philosophers_semaphores_ok 5 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 4979 unique states visited; 119 backtracks (1022 transition replays, 6120 states visited overall)
\ No newline at end of file
diff --git a/teshsuite/mc/mcmini/producer_consumer_deadlock.c b/teshsuite/mc/mcmini/producer_consumer_deadlock.c
new file mode 100644 (file)
index 0000000..2cf1ee6
--- /dev/null
@@ -0,0 +1,83 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+int MaxItems; // Maximum items a producer can produce or a consumer can consume
+int BufferSize; // Size of the buffer
+
+sem_t empty;
+sem_t full;
+int in = 0;
+int out = 0;
+int *buffer;
+pthread_mutex_t mutex;
+
+int DEBUG = 0; // Debug flag
+
+static void *producer(void *pno)
+{
+    int item;
+    for(int i = 0; i < MaxItems; i++) {
+        item = rand(); // Produce a random item
+        pthread_mutex_lock(&mutex);
+        sem_wait(&empty);
+        buffer[in] = item;
+        if(DEBUG) printf("Producer %d: Insert Item %d at %d\n", *((int *)pno),buffer[in],in);
+        in = (in+1)%BufferSize;
+        pthread_mutex_unlock(&mutex);
+        sem_post(&full);
+    }
+    return NULL;
+}
+
+static void *consumer(void *cno)
+{
+    for(int i = 0; i < MaxItems; i++) {
+        pthread_mutex_lock(&mutex);
+        sem_wait(&full);
+        int item = buffer[out];
+        if(DEBUG) printf("Consumer %d: Remove Item %d from %d\n",*((int *)cno),item, out);
+        out = (out+1)%BufferSize;
+        pthread_mutex_unlock(&mutex);
+        sem_post(&empty);
+    }
+    return NULL;
+}
+
+int main(int argc, char* argv[]) {
+    if(argc != 4){
+        printf("Usage: %s MAX_ITEMS BUFFER_SIZE DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    MaxItems = atoi(argv[1]);
+    BufferSize = atoi(argv[2]);
+    DEBUG = atoi(argv[3]);
+
+    buffer = (int*) malloc(BufferSize * sizeof(int));
+
+    pthread_t pro[5],con[5];
+    pthread_mutex_init(&mutex, NULL);
+    sem_init(&empty,0,BufferSize);
+    sem_init(&full,0,0);
+
+    int a[5] = {1,2,3,4,5}; //Just used for numbering the producer and consumer
+
+    for(int i = 0; i < 5; i++) {
+        pthread_create(&pro[i], NULL, producer, (void *)&a[i]);
+    }
+    for(int i = 0; i < 5; i++) {
+        pthread_create(&con[i], NULL, consumer, (void *)&a[i]);
+    }
+
+    for(int i = 0; i < 5; i++) {
+        pthread_join(pro[i], NULL);
+    }
+    for(int i = 0; i < 5; i++) {
+        pthread_join(con[i], NULL);
+    }
+
+    free(buffer);
+    return 0;
+}
diff --git a/teshsuite/mc/mcmini/producer_consumer_deadlock.tesh b/teshsuite/mc/mcmini/producer_consumer_deadlock.tesh
new file mode 100644 (file)
index 0000000..0db5bb8
--- /dev/null
@@ -0,0 +1,56 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+! expect return 3
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-producer_consumer_deadlock 5 3 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED ***
+> [0.000000] [mc_global/INFO] **************************
+> [0.000000] [ker_engine/INFO] 11 actors are still running, waiting for something.
+> [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor <pid> (<name>@<host>): <status>"
+> [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2)
+> [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall SEM_WAIT(sem_id:0 not granted)
+> [0.000000] [ker_engine/INFO] Actor 3 (thread 2@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 4 (thread 3@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 5 (thread 4@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 6 (thread 5@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 7 (thread 6@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 8 (thread 7@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 9 (thread 8@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 10 (thread 9@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [ker_engine/INFO] Actor 11 (thread 10@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2)
+> [0.000000] [mc_global/INFO] Counter-example execution trace:
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_UNLOCK(mutex: 0, owner: -1)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_UNLOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_UNLOCK(mutex: 0, owner: -1)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_UNLOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_WAIT(semaphore: 0, granted: yes)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_UNLOCK(mutex: 0, owner: -1)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_UNLOCK(semaphore: 1)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 2 in simcall SEM_ASYNC_LOCK(semaphore: 0)
+> [0.000000] [mc_global/INFO]   Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 4 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 5 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 6 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 7 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 8 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 9 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 10 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_global/INFO]   Actor 11 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2)
+> [0.000000] [mc_Session/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;3;4;5;6;7;8;9;10;11'
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 31 unique states visited; 0 backtracks (0 transition replays, 31 states visited overall)
diff --git a/teshsuite/mc/mcmini/producer_consumer_ok.c b/teshsuite/mc/mcmini/producer_consumer_ok.c
new file mode 100644 (file)
index 0000000..9fc1583
--- /dev/null
@@ -0,0 +1,93 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#define MaxBufferSize 5
+
+sem_t empty;
+sem_t full;
+int in = 0;
+int out = 0;
+int buffer[MaxBufferSize];
+pthread_mutex_t mutex;
+int BufferSize;
+int ItemCount;
+int DEBUG;
+
+static void *producer(void *pno)
+{
+    int item;
+    for(int i = 0; i < ItemCount; i++) {
+        item = rand(); // Produce an random item
+        sem_wait(&empty);
+        pthread_mutex_lock(&mutex);
+        buffer[in] = item;
+        if (DEBUG) {
+          printf("Producer %d: Insert Item %d at %d\n",
+                 *((int *)pno),buffer[in],in);
+        }
+        in = (in+1)%BufferSize;
+        pthread_mutex_unlock(&mutex);
+        sem_post(&full);
+    }
+    return NULL;
+}
+
+static void *consumer(void *cno)
+{
+    for(int i = 0; i < ItemCount; i++) {
+        sem_wait(&full);
+        pthread_mutex_lock(&mutex);
+        int item = buffer[out];
+        if (DEBUG) {
+          printf("Consumer %d: Remove Item %d from %d\n",
+                 *((int *)cno),item, out);
+        }
+        out = (out+1)%BufferSize;
+        pthread_mutex_unlock(&mutex);
+        sem_post(&empty);
+    }
+    return NULL;
+}
+
+int main(int argc, char* argv[]) 
+{
+    if (argc < 6) {
+      printf("Usage: %s <NUM_PRODUCERS> <NUM_CONSUMERS> <ITEM_COUNT> <BUFFER_SIZE> <DEBUG>\n", argv[0]);
+      return 1;
+    }
+  
+    int NUM_PRODUCERS = atoi(argv[1]);
+    int NUM_CONSUMERS = atoi(argv[2]);
+    ItemCount = atoi(argv[3]);
+    BufferSize = atoi(argv[4]);
+    DEBUG = atoi(argv[5]);
+
+    pthread_t pro[NUM_PRODUCERS],con[NUM_CONSUMERS];
+
+    pthread_mutex_init(&mutex, NULL);
+    sem_init(&empty,0,BufferSize);
+    sem_init(&full,0,0);
+
+    int a[NUM_PRODUCERS > NUM_CONSUMERS ? NUM_PRODUCERS : NUM_CONSUMERS];
+
+    for(int i = 0; i < NUM_PRODUCERS; i++) {
+        a[i] = i+1;
+        pthread_create(&pro[i], NULL, producer, (void *)&a[i]);
+    }
+    for(int i = 0; i < NUM_CONSUMERS; i++) {
+        a[i] = i+1;
+        pthread_create(&con[i], NULL, consumer, (void *)&a[i]);
+    }
+
+    for(int i = 0; i < NUM_PRODUCERS; i++) {
+        pthread_join(pro[i], NULL);
+    }
+    for(int i = 0; i < NUM_CONSUMERS; i++) {
+        pthread_join(con[i], NULL);
+    }
+
+    return 0;
+}
diff --git a/teshsuite/mc/mcmini/producer_consumer_ok.tesh b/teshsuite/mc/mcmini/producer_consumer_ok.tesh
new file mode 100644 (file)
index 0000000..4cac945
--- /dev/null
@@ -0,0 +1,7 @@
+# We ignore the LD_PRELOAD lines from the expected output because they contain the build path
+! ignore .*LD_PRELOAD.*
+
+$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/mcmini/mcmini-producer_consumer_ok 2 2 2 1 0
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor'
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor.
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 1388 unique states visited; 35 backtracks (485 transition replays, 1908 states visited overall)
\ No newline at end of file
index 109c9ff..9300200 100644 (file)
@@ -26,7 +26,6 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/
 > [  0.000000] (0:maestro@)   Actor 1 in simcall Random([0;5] ~> 4)
 > [  0.000000] (0:maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1/3;1/4'
 > [  0.000000] (0:maestro@) DFS exploration ended. 27 unique states visited; 22 backtracks (19 transition replays, 68 states visited overall)
-> [  0.000000] (0:maestro@) Stack trace not displayed because you passed --log=no_loc
 
 $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/random-bug printf ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning
 > [  0.000000] (0:maestro@) Behavior: printf
@@ -49,4 +48,3 @@ $ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/
 > [  0.000000] (0:maestro@)   Actor 1 in simcall Random([0;5] ~> 4)
 > [  0.000000] (0:maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1/3;1/4'
 > [  0.000000] (0:maestro@) DFS exploration ended. 27 unique states visited; 22 backtracks (19 transition replays, 68 states visited overall)
-> [  0.000000] (0:maestro@) Stack trace not displayed because you passed --log=no_loc
index d4f9eb8..9ea75ba 100644 (file)
@@ -7,7 +7,7 @@
 
 file(GLOB generator_scripts *Generator.py)
 
-if (enable_smpi_MBI_testsuite)
+if (enable_testsuite_smpi_MBI)
   if (NOT enable_smpi)
     message(FATAL_ERROR "The MBI test suite cannot be enabled without SMPI. Please change either setting.")
   endif()
@@ -64,6 +64,7 @@ if (enable_smpi_MBI_testsuite)
     add_executable(mbi_${basefile} EXCLUDE_FROM_ALL ${CMAKE_BINARY_DIR}/MBI/${cfile})
     target_link_libraries(mbi_${basefile} simgrid)
     target_compile_options(mbi_${basefile} PRIVATE "-Wno-unused-variable")
+    target_compile_options(mbi_${basefile} PRIVATE "-Wno-unused-but-set-variable")
     set_target_properties(mbi_${basefile} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/MBI)
     add_dependencies(tests-mbi mbi_${basefile})
 
index 899e810..d9f8a51 100755 (executable)
@@ -26,11 +26,11 @@ END_MPI_FEATURES
 
 BEGIN_MBI_TESTS
   $ mpirun -np 2 ${EXE} 1
-  | @{outcome}@
-  | @{errormsg}@
+  | @{outcome1}@
+  | @{errormsg1}@
   $ mpirun -np 2 ${EXE} 2
-  | @{outcome}@
-  | @{errormsg}@
+  | @{outcome2}@
+  | @{errormsg2}@
 END_MBI_TESTS
 //////////////////////       End of MBI headers        /////////////////// */
 
@@ -127,16 +127,20 @@ for s in gen.send + gen.isend:
         replace = patterns.copy()
         replace['shortdesc'] = 'Correct call ordering.'
         replace['longdesc'] = 'Correct call ordering.'
-        replace['outcome'] = 'OK'
-        replace['errormsg'] = 'OK'
+        replace['outcome1'] = 'OK'
+        replace['errormsg1'] = 'OK'
+        replace['outcome2'] = 'OK'
+        replace['errormsg2'] = 'OK'
         gen.make_file(template, f'InputHazardCallOrdering_{r}_{s}_ok.c', replace)
 
         # Generate the incorrect matching
         replace = patterns.copy()
         replace['shortdesc'] = 'Missing Send function.'
         replace['longdesc'] = 'Missing Send function call for a path depending to input, a deadlock is created.'
-        replace['outcome'] = 'ERROR: IHCallMatching'
-        replace['errormsg'] = 'P2P mistmatch. Missing @{r}@ at @{filename}@:@{line:MBIERROR}@.'
+        replace['outcome1'] = 'OK'
+        replace['errormsg1'] = 'OK'
+        replace['outcome2'] = 'ERROR: IHCallMatching'
+        replace['errormsg2'] = 'P2P mistmatch. Missing @{r}@ at @{filename}@:@{line:MBIERROR}@.'
         replace['errorcond'] = '/* MBIERROR */'
         replace['operation1b'] = ''
         replace['fini1b'] = ''
@@ -172,16 +176,20 @@ for c in gen.coll:
     replace = patterns.copy()
     replace['shortdesc'] = 'Correct call ordering.'
     replace['longdesc'] = 'Correct call ordering.'
-    replace['outcome'] = 'OK'
-    replace['errormsg'] = 'OK'
+    replace['outcome1'] = 'OK'
+    replace['errormsg1'] = 'OK'
+    replace['outcome2'] = 'OK'
+    replace['errormsg2'] = 'OK'
     gen.make_file(template, f'InputHazardCallOrdering_{c}_ok.c', replace)
 
     # Generate the incorrect matching
     replace = patterns.copy()
     replace['shortdesc'] = 'Missing collective function call.'
     replace['longdesc'] = 'Missing collective function call for a path depending to input, a deadlock is created.'
-    replace['outcome'] = 'ERROR: IHCallMatching'
-    replace['errormsg'] = 'P2P mistmatch. Missing @{c}@ at @{filename}@:@{line:MBIERROR}@.'
+    replace['outcome1'] = 'OK'
+    replace['errormsg1'] = 'OK'
+    replace['outcome2'] = 'ERROR: IHCallMatching'
+    replace['errormsg2'] = 'P2P mistmatch. Missing @{c}@ at @{filename}@:@{line:MBIERROR}@.'
     replace['errorcond'] = '/* MBIERROR */'
     replace['operation1b'] = ''
     replace['fini1b'] = ''
index c422cca..9a7d837 100644 (file)
@@ -67,6 +67,9 @@ possible_details = {
     'GlobalConcurrency':'DGlobalConcurrency',
     # larger scope
     'BufferingHazard':'EBufferingHazard',
+    # Input Hazard
+    'IHCallMatching':'InputHazard',
+    
     'OK':'FOK'}
 
 error_scope = {
index 05253b8..663a548 100755 (executable)
@@ -25,11 +25,11 @@ END_MPI_FEATURES
 
 BEGIN_MBI_TESTS
   $ mpirun -np 4 $zero_buffer ${EXE}
-  | @{outcome1}@
-  | @{errormsg1}@
+  | @{outcome_zerob}@
+  | @{errormsg_zerob}@
   $ mpirun -np 4 $infty_buffer ${EXE}
-  | @{outcome1}@
-  | @{errormsg1}@
+  | @{outcome_infty}@
+  | @{errormsg_infty}@
 END_MBI_TESTS
 //////////////////////       End of MBI headers        /////////////////// */
 
@@ -123,8 +123,10 @@ for s in gen.send + gen.isend:
         replace = patterns.copy()
         replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ may not be matched'
         replace['longdesc'] = 'Processes 0 and 1 both call @{s}@ and @{r}@. This results in a deadlock depending on the buffering mode'
-        replace['outcome1'] = 'ERROR: BufferingHazard'
-        replace['errormsg1'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause by two processes call {s} before {r}.'
+        replace['outcome_zerob'] = 'ERROR: BufferingHazard'
+        replace['errormsg_zerob'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause by two processes call {s} before {r}.'
+        replace['outcome_infty'] = 'OK'
+        replace['errormsg_infty'] = 'OK'
         gen.make_file(template, f'P2PBuffering_{s}_{r}_{s}_{r}_nok.c', replace)
 
         # Generate the incorrect matching with send message to the same process depending on the buffering mode (send + recv)
@@ -136,8 +138,10 @@ for s in gen.send + gen.isend:
         replace['dest2'] = '1'
         replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ may not be matched'
         replace['longdesc'] = 'Processes 0 and 1 both call @{s}@ and @{r}@. This results in a deadlock depending on the buffering mode'
-        replace['outcome1'] = 'ERROR: BufferingHazard'
-        replace['errormsg1'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause Send message to the same process.'
+        replace['outcome_zerob'] = 'ERROR: BufferingHazard'
+        replace['errormsg_zerob'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause Send message to the same process.'
+        replace['outcome_infty'] = 'OK'
+        replace['errormsg_infty'] = 'OK'
         gen.make_file(template, f'P2PBuffering_SameProcess_{s}_{r}_nok.c', replace)
 
         # Generate the incorrect matching with circular send message depending on the buffering mode (send + recv)
@@ -155,16 +159,20 @@ for s in gen.send + gen.isend:
         replace['operation2c'] = gen.operation[r]("2")
         replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ may not be matched'
         replace['longdesc'] = 'Processes 0 and 1 both call @{s}@ and @{r}@. This results in a deadlock depending on the buffering mode'
-        replace['outcome1'] = 'ERROR: BufferingHazard'
-        replace['errormsg1'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause circular send message.'
+        replace['outcome_zerob'] = 'ERROR: BufferingHazard'
+        replace['errormsg_zerob'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause circular send message.'
+        replace['outcome_infty'] = 'OK'
+        replace['errormsg_infty'] = 'OK'
         gen.make_file(template, f'P2PBuffering_Circular_{s}_{r}_nok.c', replace)
 
         # Generate the incorrect matching depending on the buffering mode (recv + send)
         replace = patterns.copy()
         replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ are not matched'
         replace['longdesc'] = 'Processes 0 and 1 both call @{r}@ and @{s}@. This results in a deadlock'
-        replace['outcome1'] = 'ERROR: CallMatching'
-        replace['errormsg1'] = 'ERROR: CallMatching'
+        replace['outcome_zerob'] = 'ERROR: CallMatching'
+        replace['errormsg_zerob'] = 'ERROR: CallMatching'
+        replace['outcome_infty'] = 'ERROR: CallMatching'
+        replace['errormsg_infty'] = 'ERROR: CallMatching'
         replace['operation1a'] = gen.operation[r]("2")
         replace['fini1a'] = gen.fini[r]("2")
         replace['operation2a'] = gen.operation[s]("1")
@@ -179,10 +187,19 @@ for s in gen.send + gen.isend:
         replace = patterns.copy()
         replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ are correctly  matched'
         replace['longdesc'] = 'Process 0 calls @{s}@ and process 1 calls @{r}@.'
-        replace['outcome1'] = 'OK'
-        replace['errormsg1'] = 'OK'
-        replace['fini1a'] = gen.fini[s]("1")
-        replace['fini2a'] = gen.fini[r]("2")
+        replace['outcome_zerob'] = 'OK'
+        replace['errormsg_zerob'] = 'OK'
+        replace['outcome_infty'] = 'OK'
+        replace['errormsg_infty'] = 'OK'
+        patterns['init1'] = gen.init[s]("1")
         replace['operation1a'] = gen.operation[s]("1")
-        replace['operation2a'] = gen.operation[r]("2")
+        replace['fini1a'] = gen.fini[s]("1")
+        replace['operation2a'] = ''
+        replace['fini2a'] = ''
+        
+        patterns['init2'] = gen.init[r]("2")
+        replace['operation1b'] = gen.operation[r]("2")
+        replace['fini1b'] = gen.fini[r]("2")
+        replace['operation2b'] = ''
+        replace['fini2b'] = ''
         gen.make_file(template, f'P2PCallMatching_{s}_{r}_{r}_{s}_ok.c', replace)
index 8ed991f..ef6fb16 100644 (file)
@@ -126,7 +126,7 @@ for s in gen.send:
             # Generate a code with non distinct buffer
             replace = patterns.copy()
             replace['shortdesc'] = 'Invalid buffer on Sendrecv function.'
-            replace['longdesc'] = 'Invalid buffer on Sendrecv, the tow buffers must be distinct.'
+            replace['longdesc'] = 'Invalid buffer on Sendrecv, the two buffers must be distinct.'
             replace['outcome'] = 'ERROR: InvalidBuffer'
             replace['errormsg'] = '@{sr}@ at @{filename}@:@{line:MBIERROR}@ send buffer and recv buffer must be distinct.'
             replace['change_arg'] = gen.write[sr]("2")
index 3801ae2..af5750b 100644 (file)
@@ -358,7 +358,7 @@ start['MPI_Sendrecv'] = lambda n: ""
 operation['MPI_Sendrecv'] = lambda n: f'MPI_Sendrecv(psbuf{n}, buff_size, type, dest, stag, prbuf{n}, buff_size, type, src, rtag, newcom, &sta{n});'
 fini['MPI_Sendrecv'] = lambda n: ""
 free['MPI_Sendrecv'] = lambda n: ""
-write['MPI_Sendrecv'] = lambda n: f"prbuf{n} = &sbuf{n}[2];"
+write['MPI_Sendrecv'] = lambda n: f"prbuf{n} = &sbuf{n}[0];"
 
 
 ### P2P:nonblocking
index 3c1ca88..907abc8 100644 (file)
@@ -55,7 +55,7 @@ class Tool(mbi.AbstractTool):
         execcmd = execcmd.replace('$infty_buffer', "--cfg=smpi/buffering:infty")
 
         mbi.run_cmd(
-            buildcmd=f"smpicc {filename} -trace-call-location -g -Wl,-znorelro -Wl,-znoseparate-code -o {binary}",
+            buildcmd=f"smpicc {filename} -trace-call-location -g -o {binary}",
             execcmd=execcmd,
             cachefile=cachefile,
             filename=filename,
index f355696..8d021ea 100644 (file)
@@ -38,7 +38,7 @@ set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
 include_directories("${CMAKE_HOME_DIRECTORY}/include/smpi")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/")
 
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   if(HAVE_PRIVATIZATION)
     add_library(mtest_c STATIC util/dtypes.c util/mtest.c  util/mtestcheck.c  util/mtest_datatype.c util/mtest_datatype_gen.c)
   else()
@@ -46,7 +46,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endif()
 endif()
 
-IF(enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+IF(enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   ADD_TEST(test-smpi-mpich3-thread-f77     ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f77/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f77/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/stack-size:8000 -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION})
   SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f77 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
   ADD_TEST(test-smpi-mpich3-thread-f90     ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f90/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f90/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/factory:thread)
index acdfd5d..05d6254 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -13,7 +13,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-attr-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/attr ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/attr -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-attr-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index 6c4a1a7..c07450a 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
   # There are too many warnings with these programs
index 4bed718..86f91a2 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -15,7 +15,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-comm-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/comm ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/comm -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-comm-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index b9d31e5..2e4d7bf 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -31,7 +31,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
 
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-datatype-raw   ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/datatype ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/datatype -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-datatype-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index e941496..f16e19c 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -12,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-errhan-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/errhan ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/errhan -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-errhan-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index fee3ec3..2b8909c 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 30bbd89..de624ed 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index d28313a..f864421 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 4c55031..615b08a 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 9ac4ac9..9c4e626 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 4aac50d..0bdc36c 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 2a3e74f..6e6b127 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index f6f088d..44e53d7 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 1daf583..7b0ea93 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index f8964a5..d713eb7 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index e88db7e..b8e9ebb 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 1dc21fe..22be2e5 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index e80c514..a8a45ce 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index b4fb632..3ee04a0 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index 3ce5a7c..18906d1 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index 4ad7bd8..0004e52 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index 48f19fc..4bea7c0 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index e2f0a9b..68fab4d 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
 
index 2f3cb24..c1364f8 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -12,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-group-raw      ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/group ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/group -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-group-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index 4d6d572..068e157 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -12,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-info-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/info ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/info -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-info-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index 4a8a6e8..951fa6c 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -12,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-init-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/init ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/init -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-init-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index 643b4ab..4856c24 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -13,7 +13,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-io-raw      ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/io ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -platformfile=../../../../examples/platforms/hosts_with_disks.xml -hostfile=../../hostfile_io -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/io -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-io-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index c57bc7b..f0ec2a0 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -13,7 +13,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   endforeach()
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-perf-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/perf ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -tests=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/perf/testlist -execarg=-platform\ ${CMAKE_HOME_DIRECTORY}/examples/platforms/cluster_backbone.xml -execarg=--log=root.thr:critical -execarg=--cfg=smpi/async-small-thresh:65536 -execarg=--cfg=contexts/factory:raw -execarg=--cfg=smpi/simulate-computation:0)
 endif()
 
index 8a8431a..0a11f39 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
index 9115003..be6d1db 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -37,7 +37,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
     set_target_properties(transpose3_shm PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS} -DUSE_WIN_ALLOCATE")
 endif()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-rma-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/rma ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/rma -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-rma-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
   if (enable_thread_sanitizer OR enable_coverage)
index 671fbcd..7c032fc 100644 (file)
@@ -1,4 +1,4 @@
-if(enable_smpi AND enable_smpi_MPICH3_testsuite)
+if(enable_smpi AND enable_testsuite_smpi_MPICH3)
   set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
   set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
 
@@ -19,7 +19,7 @@ foreach(file cartcreates cartshift1 cartsuball cartzero cartmap1 dgraph_unwgt di
   set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.c)
 endforeach()
 
-if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
+if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS)
   ADD_TEST(test-smpi-mpich3-topo-raw       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/topo ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/topo -tests=testlist -execarg=--cfg=contexts/factory:raw)
   SET_TESTS_PROPERTIES(test-smpi-mpich3-topo-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
 endif()
index fb10524..d3c59bb 100644 (file)
@@ -19,18 +19,8 @@ foreach(x parallel_log_crashtest parmap_bench parmap_test signals)
   set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.cpp)
 endforeach()
 
-if(HAVE_MMALLOC)
-  add_executable       (mmalloc_test EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_test.cpp)
-  target_link_libraries(mmalloc_test simgrid sgmalloc)
-  set_target_properties(mmalloc_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mmalloc)
-  set_property(TARGET mmalloc_test APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}")
-  add_dependencies(tests mmalloc_test)
-endif()
-
-set(tesh_files    ${tesh_files}     ${CMAKE_CURRENT_SOURCE_DIR}/log_usage/log_usage_ndebug.tesh
-                                    ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_64.tesh
-                                    ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_32.tesh          PARENT_SCOPE)
-set(teshsuite_src ${teshsuite_src}  ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_test.cpp           PARENT_SCOPE)
+set(tesh_files    ${tesh_files}     ${CMAKE_CURRENT_SOURCE_DIR}/log_usage/log_usage_ndebug.tesh    PARENT_SCOPE)
+set(teshsuite_src ${teshsuite_src}                                                                 PARENT_SCOPE)
 
 foreach(x cmdline log_large parallel_log_crashtest parmap_test)
   ADD_TESH(tesh-xbt-${x} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/${x} ${x}.tesh)
@@ -46,11 +36,3 @@ if(enable_debug)
 else()
   ADD_TESH(tesh-xbt-log --cd ${CMAKE_BINARY_DIR}/teshsuite/xbt/log_usage ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/log_usage/log_usage_ndebug.tesh)
 endif()
-
-if(HAVE_MMALLOC)
-  if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits
-    ADD_TESH(tesh-xbt-mmalloc-32 --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/mmalloc --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/mmalloc mmalloc_32.tesh)
-  else()
-    ADD_TESH(tesh-xbt-mmalloc-64 --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/mmalloc --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/mmalloc mmalloc_64.tesh)
-  endif()
-endif()
diff --git a/teshsuite/xbt/mmalloc/mmalloc_32.tesh b/teshsuite/xbt/mmalloc/mmalloc_32.tesh
deleted file mode 100644 (file)
index 8bb9bac..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-$ ${bindir:=.}/mmalloc_test --log=root.fmt:%m%n
-> Allocating a new heap
-> HeapA allocated
-> 100 bytes allocated with offset 45000
-> 200 bytes allocated with offset 46000
-> 300 bytes allocated with offset 47000
-> 400 bytes allocated with offset 47200
-> 500 bytes allocated with offset 47400
-> 600 bytes allocated with offset 48000
-> 700 bytes allocated with offset 48400
-> 800 bytes allocated with offset 48800
-> 900 bytes allocated with offset 48c00
-> 1000 bytes allocated with offset 49000
-> 1100 bytes allocated with offset 4a000
-> 1200 bytes allocated with offset 4a800
-> 1300 bytes allocated with offset 4b000
-> 1400 bytes allocated with offset 4b800
-> 1500 bytes allocated with offset 4c000
-> 1600 bytes allocated with offset 4c800
-> 1700 bytes allocated with offset 4d000
-> 1800 bytes allocated with offset 4d800
-> 1900 bytes allocated with offset 4e000
-> 2000 bytes allocated with offset 4e800
-> 2100 bytes allocated with offset 4f000
-> 2200 bytes allocated with offset 50000
-> 2300 bytes allocated with offset 51000
-> 2400 bytes allocated with offset 52000
-> 2500 bytes allocated with offset 53000
-> 2600 bytes allocated with offset 54000
-> 2700 bytes allocated with offset 55000
-> 2800 bytes allocated with offset 56000
-> 2900 bytes allocated with offset 57000
-> 3000 bytes allocated with offset 58000
-> 3100 bytes allocated with offset 59000
-> 3200 bytes allocated with offset 5a000
-> 3300 bytes allocated with offset 5b000
-> 3400 bytes allocated with offset 5c000
-> 3500 bytes allocated with offset 5d000
-> 3600 bytes allocated with offset 5e000
-> 3700 bytes allocated with offset 5f000
-> 3800 bytes allocated with offset 60000
-> 3900 bytes allocated with offset 61000
-> 4000 bytes allocated with offset 62000
-> 4100 bytes allocated with offset 63000
-> 4200 bytes allocated with offset 65000
-> 4300 bytes allocated with offset 67000
-> 4400 bytes allocated with offset 69000
-> 4500 bytes allocated with offset 6b000
-> 4600 bytes allocated with offset 6d000
-> 4700 bytes allocated with offset 6f000
-> 4800 bytes allocated with offset 71000
-> 4900 bytes allocated with offset 73000
-> 5000 bytes allocated with offset 75000
-> 100 bytes allocated with offset 45080
-> 200 bytes allocated with offset 46100
-> 300 bytes allocated with offset 47600
-> 400 bytes allocated with offset 47800
-> 500 bytes allocated with offset 47a00
-> 600 bytes allocated with offset 49400
-> 700 bytes allocated with offset 49800
-> 800 bytes allocated with offset 49c00
-> 900 bytes allocated with offset 77000
-> 1000 bytes allocated with offset 77400
-> 1100 bytes allocated with offset 78000
-> 1200 bytes allocated with offset 78800
-> 1300 bytes allocated with offset 79000
-> 1400 bytes allocated with offset 79800
-> 1500 bytes allocated with offset 7a000
-> 1600 bytes allocated with offset 7a800
-> 1700 bytes allocated with offset 7b000
-> 1800 bytes allocated with offset 7b800
-> 1900 bytes allocated with offset 7c000
-> 2000 bytes allocated with offset 7c800
-> 2100 bytes allocated with offset 7d000
-> 2200 bytes allocated with offset 7e000
-> 2300 bytes allocated with offset 7f000
-> 2400 bytes allocated with offset 80000
-> 2500 bytes allocated with offset 81000
-> 2600 bytes allocated with offset 82000
-> 2700 bytes allocated with offset 83000
-> 2800 bytes allocated with offset 84000
-> 2900 bytes allocated with offset 85000
-> 3000 bytes allocated with offset 86000
-> 3100 bytes allocated with offset 87000
-> 3200 bytes allocated with offset 88000
-> 3300 bytes allocated with offset 89000
-> 3400 bytes allocated with offset 8a000
-> 3500 bytes allocated with offset 8b000
-> 3600 bytes allocated with offset 8c000
-> 3700 bytes allocated with offset 8d000
-> 3800 bytes allocated with offset 8e000
-> 3900 bytes allocated with offset 8f000
-> 4000 bytes allocated with offset 90000
-> 4100 bytes allocated with offset 91000
-> 4200 bytes allocated with offset 93000
-> 4300 bytes allocated with offset 95000
-> 4400 bytes allocated with offset 97000
-> 4500 bytes allocated with offset 99000
-> 4600 bytes allocated with offset 9b000
-> 4700 bytes allocated with offset 9d000
-> 4800 bytes allocated with offset 9f000
-> 4900 bytes allocated with offset a1000
-> 5000 bytes allocated with offset a3000
-> All blocks were correctly allocated. Free every second block
-> Memset every second block to zero (yeah, they are not currently allocated :)
-> Re-allocate every second block
-> free all blocks
-> Let's try different codepaths for mrealloc
-> Damnit, I cannot break mmalloc this time. That's SO disappointing.
diff --git a/teshsuite/xbt/mmalloc/mmalloc_64.tesh b/teshsuite/xbt/mmalloc/mmalloc_64.tesh
deleted file mode 100644 (file)
index ec276c3..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-$ ${bindir:=.}/mmalloc_test --log=root.fmt:%m%n
-> Allocating a new heap
-> HeapA allocated
-> 100 bytes allocated with offset 39000
-> 200 bytes allocated with offset 39100
-> 300 bytes allocated with offset 3a000
-> 400 bytes allocated with offset 3a200
-> 500 bytes allocated with offset 3a400
-> 600 bytes allocated with offset 3b000
-> 700 bytes allocated with offset 3b400
-> 800 bytes allocated with offset 3b800
-> 900 bytes allocated with offset 3bc00
-> 1000 bytes allocated with offset 3c000
-> 1100 bytes allocated with offset 3d000
-> 1200 bytes allocated with offset 3d800
-> 1300 bytes allocated with offset 3e000
-> 1400 bytes allocated with offset 3e800
-> 1500 bytes allocated with offset 3f000
-> 1600 bytes allocated with offset 3f800
-> 1700 bytes allocated with offset 40000
-> 1800 bytes allocated with offset 40800
-> 1900 bytes allocated with offset 41000
-> 2000 bytes allocated with offset 41800
-> 2100 bytes allocated with offset 42000
-> 2200 bytes allocated with offset 43000
-> 2300 bytes allocated with offset 44000
-> 2400 bytes allocated with offset 45000
-> 2500 bytes allocated with offset 46000
-> 2600 bytes allocated with offset 47000
-> 2700 bytes allocated with offset 48000
-> 2800 bytes allocated with offset 49000
-> 2900 bytes allocated with offset 4a000
-> 3000 bytes allocated with offset 4b000
-> 3100 bytes allocated with offset 4c000
-> 3200 bytes allocated with offset 4d000
-> 3300 bytes allocated with offset 4e000
-> 3400 bytes allocated with offset 4f000
-> 3500 bytes allocated with offset 50000
-> 3600 bytes allocated with offset 51000
-> 3700 bytes allocated with offset 52000
-> 3800 bytes allocated with offset 53000
-> 3900 bytes allocated with offset 54000
-> 4000 bytes allocated with offset 55000
-> 4100 bytes allocated with offset 56000
-> 4200 bytes allocated with offset 58000
-> 4300 bytes allocated with offset 5a000
-> 4400 bytes allocated with offset 5c000
-> 4500 bytes allocated with offset 5e000
-> 4600 bytes allocated with offset 60000
-> 4700 bytes allocated with offset 62000
-> 4800 bytes allocated with offset 64000
-> 4900 bytes allocated with offset 66000
-> 5000 bytes allocated with offset 68000
-> 100 bytes allocated with offset 39200
-> 200 bytes allocated with offset 39300
-> 300 bytes allocated with offset 3a600
-> 400 bytes allocated with offset 3a800
-> 500 bytes allocated with offset 3aa00
-> 600 bytes allocated with offset 3c400
-> 700 bytes allocated with offset 3c800
-> 800 bytes allocated with offset 3cc00
-> 900 bytes allocated with offset 6a000
-> 1000 bytes allocated with offset 6a400
-> 1100 bytes allocated with offset 6b000
-> 1200 bytes allocated with offset 6b800
-> 1300 bytes allocated with offset 6c000
-> 1400 bytes allocated with offset 6c800
-> 1500 bytes allocated with offset 6d000
-> 1600 bytes allocated with offset 6d800
-> 1700 bytes allocated with offset 6e000
-> 1800 bytes allocated with offset 6e800
-> 1900 bytes allocated with offset 6f000
-> 2000 bytes allocated with offset 6f800
-> 2100 bytes allocated with offset 70000
-> 2200 bytes allocated with offset 71000
-> 2300 bytes allocated with offset 72000
-> 2400 bytes allocated with offset 73000
-> 2500 bytes allocated with offset 74000
-> 2600 bytes allocated with offset 75000
-> 2700 bytes allocated with offset 76000
-> 2800 bytes allocated with offset 77000
-> 2900 bytes allocated with offset 78000
-> 3000 bytes allocated with offset 79000
-> 3100 bytes allocated with offset 7a000
-> 3200 bytes allocated with offset 7b000
-> 3300 bytes allocated with offset 7c000
-> 3400 bytes allocated with offset 7d000
-> 3500 bytes allocated with offset 7e000
-> 3600 bytes allocated with offset 7f000
-> 3700 bytes allocated with offset 80000
-> 3800 bytes allocated with offset 81000
-> 3900 bytes allocated with offset 82000
-> 4000 bytes allocated with offset 83000
-> 4100 bytes allocated with offset 84000
-> 4200 bytes allocated with offset 86000
-> 4300 bytes allocated with offset 88000
-> 4400 bytes allocated with offset 8a000
-> 4500 bytes allocated with offset 8c000
-> 4600 bytes allocated with offset 8e000
-> 4700 bytes allocated with offset 90000
-> 4800 bytes allocated with offset 92000
-> 4900 bytes allocated with offset 94000
-> 5000 bytes allocated with offset 96000
-> All blocks were correctly allocated. Free every second block
-> Memset every second block to zero (yeah, they are not currently allocated :)
-> Re-allocate every second block
-> free all blocks
-> Let's try different codepaths for mrealloc
-> Damnit, I cannot break mmalloc this time. That's SO disappointing.
diff --git a/teshsuite/xbt/mmalloc/mmalloc_test.cpp b/teshsuite/xbt/mmalloc/mmalloc_test.cpp
deleted file mode 100644 (file)
index c76ea46..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (c) 2012-2023. 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 "simgrid/Exception.hpp"
-#include "simgrid/engine.h"
-#include "src/xbt/mmalloc/mmalloc.h"
-#include "xbt.h"
-
-#include <array>
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <vector>
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(test,"this test");
-
-constexpr int BUFFSIZE = 204800;
-constexpr int TESTSIZE = 100;
-
-#define size_of_block(i) ((((i) % 50) + 1) * 100)
-
-static void check_block(const unsigned char* p, unsigned char b, int n)
-{
-  for (int i = 0; i < n; i++)
-    xbt_assert(p[i] == b, "value mismatch: %p[%d] = %#hhx, expected %#hhx", p, i, p[i], b);
-}
-
-int main(int argc, char**argv)
-{
-  xbt_mheap_t heapA = nullptr;
-  std::array<void*, TESTSIZE> pointers;
-  simgrid_init(&argc, argv);
-
-  XBT_INFO("Allocating a new heap");
-  unsigned long mask = ~((unsigned long)xbt_pagesize - 1);
-  auto* addr         = reinterpret_cast<void*>(((unsigned long)sbrk(0) + BUFFSIZE) & mask);
-  heapA              = xbt_mheap_new(addr, 0);
-  if (heapA == nullptr) {
-    perror("attach 1 failed");
-    fprintf(stderr, "bye\n");
-    exit(1);
-  }
-
-  XBT_INFO("HeapA allocated");
-
-  int i;
-  int size;
-  for (i = 0; i < TESTSIZE; i++) {
-    size = size_of_block(i);
-    pointers[i] = mmalloc(heapA, size);
-    XBT_INFO("%d bytes allocated with offset %zx", size, (size_t)((char*)pointers[i] - (char*)heapA));
-  }
-  XBT_INFO("All blocks were correctly allocated. Free every second block");
-  for (i = 0; i < TESTSIZE; i+=2) {
-    mfree(heapA, pointers[i]);
-  }
-  XBT_INFO("Memset every second block to zero (yeah, they are not currently allocated :)");
-  for (i = 0; i < TESTSIZE; i+=2) {
-    size = size_of_block(i);
-    memset(pointers[i],0, size);
-  }
-  XBT_INFO("Re-allocate every second block");
-  for (i = 0; i < TESTSIZE; i+=2) {
-    size = size_of_block(i);
-    pointers[i] = mmalloc(heapA, size);
-  }
-
-  XBT_INFO("free all blocks");
-  for (i = 0; i < TESTSIZE; i++)
-    mfree(heapA, pointers[i]);
-
-  XBT_INFO("Let's try different codepaths for mrealloc");
-  for (i = 0; i < TESTSIZE; i++) {
-    const std::vector<std::pair<int, unsigned char>> requests = {
-        {size_of_block(i) / 2, 0x77}, {size_of_block(i) * 2, 0xaa}, {1, 0xc0}, {0, 0}};
-    pointers[i] = nullptr;
-    for (unsigned k = 0; k < requests.size(); ++k) {
-      size        = requests[k].first;
-      pointers[i] = mrealloc(heapA, pointers[i], size);
-      if (k > 0)
-        check_block(static_cast<unsigned char*>(pointers[i]), requests[k - 1].second,
-                    std::min(size, requests[k - 1].first));
-      if (size > 0)
-        memset(pointers[i], requests[k].second, size);
-    }
-  }
-
-  XBT_INFO("Damnit, I cannot break mmalloc this time. That's SO disappointing.");
-  return 0;
-}
index d07dcdd..591f664 100644 (file)
@@ -1,5 +1,4 @@
 set(bin_files ${bin_files}    ${CMAKE_CURRENT_SOURCE_DIR}/fix-paje-trace.sh
-                              ${CMAKE_CURRENT_SOURCE_DIR}/generate-dwarf-functions
                               ${CMAKE_CURRENT_SOURCE_DIR}/normalize-pointers.py
                               ${CMAKE_CURRENT_SOURCE_DIR}/sg_xml_unit_converter.py
                               ${CMAKE_CURRENT_SOURCE_DIR}/simgrid_update_xml.pl
index 5ef4600..f1723c8 100644 (file)
@@ -17,10 +17,6 @@ if(enable_compile_warnings AND enable_compile_optimizations)
   SET(BUILDNAME "FULL_FLAGS" CACHE INTERNAL "Buildname" FORCE)
 endif()
 
-if(SIMGRID_HAVE_STATEFUL_MC)
-  SET(BUILDNAME "MODEL-CHECKING" CACHE INTERNAL "Buildname" FORCE)
-endif()
-
 if(enable_memcheck)
   SET(BUILDNAME "MEMCHECK" CACHE INTERNAL "Buildname" FORCE)
 endif()
index cee3e25..2935cf4 100644 (file)
@@ -46,29 +46,11 @@ set(EXTRA_DIST
   src/kernel/xml/simgrid_dtd.h
   src/kernel/xml/platf_sax_cb.cpp
 
-  src/xbt/automaton/automaton_lexer.yy.c
-  src/xbt/automaton/parserPromela.lex
-  src/xbt/automaton/parserPromela.tab.cacc
-  src/xbt/automaton/parserPromela.tab.hacc
-  src/xbt/automaton/parserPromela.yacc
   src/xbt/coverage.h
   src/xbt/dict_private.h
   src/xbt/log_private.hpp
   src/xbt/mallocator_private.h
   src/xbt/parmap.hpp
-
-  src/xbt/mmalloc/mmalloc.h
-  src/xbt/mmalloc/mfree.c
-  src/xbt/mmalloc/mm_legacy.c
-  src/xbt/mmalloc/mm_module.c
-  src/xbt/mmalloc/mmalloc.c
-  src/xbt/mmalloc/mmalloc.info
-  src/xbt/mmalloc/mmalloc.texi
-  src/xbt/mmalloc/mmorecore.c
-  src/xbt/mmalloc/mmprivate.h
-  src/xbt/mmalloc/mrealloc.c
-  src/xbt/mmalloc/swag.c
-  src/xbt/mmalloc/swag.h
   )
 
 set(SMPI_SRC
@@ -257,8 +239,6 @@ set(STHREAD_SRC
 set(XBT_SRC
   src/xbt/OsSemaphore.hpp
   src/xbt/PropertyHolder.cpp
-  src/xbt/automaton/automaton.c
-  src/xbt/automaton/automatonparse_promela.c
   src/xbt/backtrace.cpp
   src/xbt/config.cpp
   src/xbt/dict.cpp
@@ -292,13 +272,6 @@ set(XBT_SRC
   src/xbt/utils/iter/LazyPowerset.hpp
   )
 
-if(HAVE_MMALLOC)
-  set(SGMALLOC_SRC src/xbt/mmalloc/mm.c)
-  set(XBT_SRC      ${XBT_SRC} src/xbt/mmalloc/mm.c)
-else()
-  set(EXTRA_DIST ${EXTRA_DIST} src/xbt/mmalloc/mm.c)
-endif()
-
 set(NS3_SRC
   src/kernel/resource/models/network_ns3.cpp
   src/kernel/resource/models/ns3/ns3_simulator.cpp
@@ -322,6 +295,10 @@ set(KERNEL_SRC
   src/kernel/activity/IoImpl.hpp
   src/kernel/activity/MailboxImpl.cpp
   src/kernel/activity/MailboxImpl.hpp
+  src/kernel/activity/MessImpl.cpp
+  src/kernel/activity/MessImpl.hpp
+  src/kernel/activity/MessageQueueImpl.cpp
+  src/kernel/activity/MessageQueueImpl.hpp
   src/kernel/activity/MutexImpl.cpp
   src/kernel/activity/MutexImpl.hpp
   src/kernel/activity/SemaphoreImpl.cpp
@@ -472,6 +449,8 @@ set(S4U_SRC
   src/s4u/s4u_Io.cpp
   src/s4u/s4u_Link.cpp
   src/s4u/s4u_Mailbox.cpp
+  src/s4u/s4u_Mess.cpp
+  src/s4u/s4u_MessageQueue.cpp
   src/s4u/s4u_Mutex.cpp
   src/s4u/s4u_Netzone.cpp
   src/s4u/s4u_Semaphore.cpp
@@ -536,6 +515,28 @@ set(MC_SRC_STATELESS
   src/mc/explo/DFSExplorer.hpp
   src/mc/explo/Exploration.cpp
   src/mc/explo/Exploration.hpp
+  src/mc/explo/CommunicationDeterminismChecker.cpp
+
+  src/mc/explo/UdporChecker.cpp
+  src/mc/explo/UdporChecker.hpp
+
+  src/mc/explo/udpor/Comb.hpp
+  src/mc/explo/udpor/Configuration.hpp
+  src/mc/explo/udpor/Configuration.cpp
+  src/mc/explo/udpor/EventSet.cpp
+  src/mc/explo/udpor/EventSet.hpp
+  src/mc/explo/udpor/ExtensionSetCalculator.cpp
+  src/mc/explo/udpor/ExtensionSetCalculator.hpp
+  src/mc/explo/udpor/History.cpp
+  src/mc/explo/udpor/History.hpp
+  src/mc/explo/udpor/maximal_subsets_iterator.cpp
+  src/mc/explo/udpor/maximal_subsets_iterator.hpp
+  src/mc/explo/udpor/UnfoldingEvent.cpp
+  src/mc/explo/udpor/UnfoldingEvent.hpp
+  src/mc/explo/udpor/Unfolding.cpp
+  src/mc/explo/udpor/Unfolding.hpp
+  src/mc/explo/udpor/udpor_forward.hpp
+  src/mc/explo/udpor/udpor_tests_private.hpp
 
   src/mc/explo/odpor/Execution.cpp
   src/mc/explo/odpor/Execution.hpp
@@ -558,8 +559,8 @@ set(MC_SRC_STATELESS
   src/mc/remote/mc_protocol.h
 
   src/mc/transition/Transition.hpp
-  src/mc/transition/TransitionActorJoin.cpp
-  src/mc/transition/TransitionActorJoin.hpp
+  src/mc/transition/TransitionActor.cpp
+  src/mc/transition/TransitionActor.hpp
   src/mc/transition/TransitionAny.cpp
   src/mc/transition/TransitionAny.hpp
   src/mc/transition/TransitionComm.cpp
@@ -570,67 +571,7 @@ set(MC_SRC_STATELESS
   src/mc/transition/TransitionRandom.hpp
   src/mc/transition/TransitionSynchro.cpp
   src/mc/transition/TransitionSynchro.hpp
-  )
 
-set(MC_SRC_STATEFUL
-  src/mc/explo/CommunicationDeterminismChecker.cpp
-  src/mc/explo/LivenessChecker.cpp
-  src/mc/explo/LivenessChecker.hpp
-  src/mc/explo/UdporChecker.cpp
-  src/mc/explo/UdporChecker.hpp
-
-  src/mc/explo/udpor/Comb.hpp
-  src/mc/explo/udpor/Configuration.hpp
-  src/mc/explo/udpor/Configuration.cpp
-  src/mc/explo/udpor/EventSet.cpp
-  src/mc/explo/udpor/EventSet.hpp
-  src/mc/explo/udpor/ExtensionSetCalculator.cpp
-  src/mc/explo/udpor/ExtensionSetCalculator.hpp
-  src/mc/explo/udpor/History.cpp
-  src/mc/explo/udpor/History.hpp
-  src/mc/explo/udpor/maximal_subsets_iterator.cpp
-  src/mc/explo/udpor/maximal_subsets_iterator.hpp
-  src/mc/explo/udpor/UnfoldingEvent.cpp
-  src/mc/explo/udpor/UnfoldingEvent.hpp
-  src/mc/explo/udpor/Unfolding.cpp
-  src/mc/explo/udpor/Unfolding.hpp
-  src/mc/explo/udpor/udpor_forward.hpp
-  src/mc/explo/udpor/udpor_tests_private.hpp
-
-  src/mc/inspect/DwarfExpression.cpp
-  src/mc/inspect/DwarfExpression.hpp
-  src/mc/inspect/Frame.cpp
-  src/mc/inspect/Frame.hpp
-  src/mc/inspect/LocationList.cpp
-  src/mc/inspect/LocationList.hpp
-  src/mc/inspect/ObjectInformation.cpp
-  src/mc/inspect/ObjectInformation.hpp
-  src/mc/inspect/Type.hpp
-  src/mc/inspect/Variable.hpp
-  src/mc/inspect/mc_dwarf.cpp
-  src/mc/inspect/mc_dwarf.hpp
-  src/mc/inspect/mc_dwarf_attrnames.cpp
-  src/mc/inspect/mc_dwarf_tagnames.cpp
-  src/mc/inspect/mc_member.cpp
-  src/mc/inspect/mc_unw.cpp
-  src/mc/inspect/mc_unw.hpp
-  src/mc/inspect/mc_unw_vmread.cpp
-
-  src/mc/sosp/ChunkedData.cpp
-  src/mc/sosp/ChunkedData.hpp
-  src/mc/sosp/PageStore.cpp
-  src/mc/sosp/PageStore.hpp
-  src/mc/sosp/Region.cpp
-  src/mc/sosp/Region.hpp
-  src/mc/sosp/RemoteProcessMemory.cpp
-  src/mc/sosp/RemoteProcessMemory.hpp
-  src/mc/sosp/Snapshot.cpp
-  src/mc/sosp/Snapshot.hpp
-
-  src/mc/AddressSpace.hpp
-  src/mc/VisitedState.cpp
-  src/mc/VisitedState.hpp
-  src/mc/compare.cpp
   src/mc/mc_environ.h
   src/mc/mc_exit.hpp
   src/mc/mc_forward.hpp
@@ -642,8 +583,6 @@ set(MC_SRC_STATEFUL
   src/mc/api/strategy/MinMatchComm.hpp
   src/mc/api/strategy/Strategy.hpp
   src/mc/api/strategy/UniformStrategy.hpp
-
-  src/xbt/mmalloc/mm_interface.c
   )
 
 set(MC_SIMGRID_MC_SRC  src/mc/explo/simgrid_mc.cpp)
@@ -695,6 +634,8 @@ set(headers_to_install
   include/simgrid/s4u/Io.hpp
   include/simgrid/s4u/Link.hpp
   include/simgrid/s4u/Mailbox.hpp
+  include/simgrid/s4u/MessageQueue.hpp
+  include/simgrid/s4u/Mess.hpp
   include/simgrid/s4u/Mutex.hpp
   include/simgrid/s4u/NetZone.hpp
   include/simgrid/s4u/Semaphore.hpp
@@ -731,8 +672,6 @@ set(headers_to_install
   include/xbt.h
   include/xbt/asserts.h
   include/xbt/asserts.hpp
-  include/xbt/automaton.h
-  include/xbt/automaton.hpp
   include/xbt/backtrace.hpp
   include/xbt/base.h
   include/xbt/config.h
@@ -800,10 +739,7 @@ endif()
 if(SIMGRID_HAVE_MC)
   set(simgrid_sources  ${simgrid_sources}  ${MC_SRC_STATELESS})
 endif()
-if(SIMGRID_HAVE_STATEFUL_MC)
-  set(simgrid_sources  ${simgrid_sources}  ${MC_SRC_STATEFUL})
-endif()
-set(EXTRA_DIST ${EXTRA_DIST} ${MC_SRC_STATELESS} ${MC_SRC_STATEFUL})
+set(EXTRA_DIST ${EXTRA_DIST} ${MC_SRC_STATELESS})
 
 if(SIMGRID_HAVE_NS3)
   set(headers_to_install ${headers_to_install} include/simgrid/plugins/ns3.hpp)
@@ -1075,10 +1011,7 @@ set(CMAKE_SOURCE_FILES
   tools/cmake/MaintainerMode.cmake
   tools/cmake/MakeLib.cmake
   tools/cmake/Modules/FindGraphviz.cmake
-  tools/cmake/Modules/FindLibdw.cmake
-  tools/cmake/Modules/FindLibelf.cmake
   tools/cmake/Modules/FindLibevent.cmake
-  tools/cmake/Modules/FindLibunwind.cmake
   tools/cmake/Modules/FindNS3.cmake
   tools/cmake/Modules/FindPAPI.cmake
   tools/cmake/Modules/FindValgrind.cmake
@@ -1188,13 +1121,3 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/wifi_large_cell.xml
   examples/platforms/wifi_ns3.xml
   )
-
-set(generated_src_files
-  src/xbt/automaton/automaton_lexer.yy.c
-  src/xbt/automaton/parserPromela.tab.cacc
-  src/xbt/automaton/parserPromela.tab.hacc
-  )
-
-foreach(file ${generated_src_files})
-  set_source_files_properties(${file} PROPERTIES GENERATED true)
-endforeach(file ${generated_src_files})
index 4f0c8c7..5095296 100644 (file)
@@ -43,6 +43,9 @@ add_custom_target(simgrid_convert_TI_traces ALL
 
 # libraries
 install(TARGETS simgrid DESTINATION ${CMAKE_INSTALL_LIBDIR}/)
+if("${CMAKE_SYSTEM}" MATCHES "Linux")
+  install(TARGETS sthread DESTINATION ${CMAKE_INSTALL_LIBDIR}/)
+endif()
 
 # pkg-config files
 configure_file("${CMAKE_HOME_DIRECTORY}/tools/pkg-config/simgrid.pc.in"
index 60aeeca..e7ba000 100644 (file)
@@ -1,7 +1,7 @@
 ##
 ## This file is in charge of setting our paranoid flags with regard to warnings and optimization.
 ##
-##   It is only used for gcc and clang. MSVC builds don't load this file.
+##   It is only used for gcc, clang and Intel compilers.
 ##
 ##   These flags do break some classical CMake tests, so you don't
 ##   want to do so before the very end of the configuration.
@@ -77,13 +77,12 @@ if(enable_compile_warnings AND enable_debug)
 endif()
 
 # Activate the warnings on #if FOOBAR when FOOBAR has no value
-# It breaks on FreeBSD within Boost headers, so activate this only in Pure Hardcore debug mode.
-if(enable_maintainer_mode)
+if("${CMAKE_SYSTEM}" MATCHES "Linux") # Breaks on FreeBSD within Boost headers :(
   set(warnCFLAGS "${warnCFLAGS} -Wundef")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wundef")
 endif()
 
-# Se the optimisation flags
+# Set the optimisation flags
 # NOTE, we should CMAKE_BUILD_TYPE for this
 if(enable_compile_optimizations)
   set(optCFLAGS "-O3 -funroll-loops -fno-strict-aliasing ")
@@ -91,13 +90,12 @@ else()
   set(optCFLAGS "-O0 ")
 endif()
 
-#ARM platforms have signed char by default, switch to unsigned for consistancy
+# ARM platforms have signed char by default, switch to unsigned for consistancy
 if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
   set(optCFLAGS "${optCFLAGS} -fsigned-char")
 endif()
 
-if(enable_compile_optimizations AND CMAKE_COMPILER_IS_GNUCC
-    AND (NOT enable_model-checking))
+if(enable_compile_optimizations AND CMAKE_COMPILER_IS_GNUCC)
   # This is redundant (already in -03):
   set(optCFLAGS "${optCFLAGS} -finline-functions ")
 endif()
@@ -120,8 +118,7 @@ endif()
 # Configure LTO
 if(enable_lto) # User wants LTO. Try if we can do that
   set(enable_lto OFF)
-  if(enable_compile_optimizations
-      AND (NOT enable_model-checking))
+  if(enable_compile_optimizations)
     include(CheckIPOSupported)
     check_ipo_supported(RESULT ipo LANGUAGES C CXX)
     if(ipo)
@@ -135,11 +132,7 @@ if(enable_lto) # User wants LTO. Try if we can do that
     if(NOT enable_compile_optimizations)
       message(STATUS "LTO disabled: Compile-time optimizations turned off.")
     else()
-      if(enable_model-checking)
-        message(STATUS "LTO disabled when compiling with model-checking.")
-      else()
-        message(STATUS "LTO does not seem usable -- try updating your build chain.")
-      endif()
+      message(STATUS "LTO does not seem usable -- try updating your build chain.")
     endif()
   endif()
 else()
@@ -172,25 +165,6 @@ if(enable_lto) # User wants LTO, and it seems usable. Go for it
   endif()
 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:
-  set(src_list ${simgrid_sources})
-  # except...
-  list(FILTER src_list EXCLUDE REGEX "^src/kernel/activity/")
-  list(FILTER src_list EXCLUDE REGEX "^src/kernel/actor/")
-  list(FILTER src_list EXCLUDE REGEX "^src/kernel/context/")
-  list(FILTER src_list EXCLUDE REGEX "^src/s4u/")
-  foreach(src ${src_list})
-      set (mcCFLAGS "-O3 -funroll-loops -fno-strict-aliasing")
-      if(CMAKE_COMPILER_IS_GNUCC)
-        set (mcCFLAGS "${mcCFLAGS} -finline-functions")
-      endif()
-      set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS ${mcCFLAGS})
-  endforeach()
-endif()
-
 if (CMAKE_C_COMPILER_ID MATCHES "Intel")
   # honor parentheses when determining the order of expression evaluation.
   # disallow optimizations for floating-point arithmetic with Nans or +-Infs (breaks Eigen3)
index b31d336..9a4f3b5 100644 (file)
@@ -39,41 +39,10 @@ if(enable_maintainer_mode)
   find_program(FLEX_EXE NAMES flex)
   find_program(FLEXML_EXE NAMES flexml)
   find_program(SED_EXE NAMES sed)
-  find_program(BISON_EXE NAMES bison)
   find_program(LEX_EXE NAMES lex)
 
-  mark_as_advanced(BISON_EXE)
   mark_as_advanced(LEX_EXE)
 
-  if(BISON_EXE AND LEX_EXE)
-    add_custom_command(
-      OUTPUT
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/automaton_lexer.yy.c
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.cacc
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.hacc
-
-      DEPENDS
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.lex
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.yacc
-
-      COMMENT "Generating automaton source files"
-      COMMAND ${BISON_EXE} --name-prefix=xbt_automaton_parser_ -d -t parserPromela.yacc
-      COMMAND ${LEX_EXE} --prefix=xbt_automaton_parser_ --outfile=automaton_lexer.yy.c parserPromela.lex
-      WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/
-      )
-
-    add_custom_target(automaton_generated_src
-      DEPENDS
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/automaton_lexer.yy.c
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.cacc
-      ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.hacc
-      )
-
-    SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
-      "${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.cacc;${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.hacc;${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/automaton_parse.yy.c"
-      )
-  endif()
-
   message(STATUS "Found flex: ${FLEX_EXE}")
   IF(FLEX_EXE)
     set(HAVE_FLEX 1)
index f41f3b7..79f4e27 100644 (file)
@@ -29,6 +29,7 @@ add_dependencies(simgrid maintainer_files)
 
 if("${CMAKE_SYSTEM}" MATCHES "Linux")
   add_library(sthread SHARED ${STHREAD_SRC})
+  set_target_properties(sthread PROPERTIES VERSION ${libsimgrid_version})
   set_property(TARGET sthread
                 APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}")
   target_link_libraries(sthread simgrid)
@@ -36,12 +37,6 @@ else()
   set(EXTRA_DIST ${EXTRA_DIST} ${STHREAD_SRC})
 endif()
 
-if(HAVE_MMALLOC)
-  add_library(sgmalloc SHARED ${SGMALLOC_SRC})
-  set_property(TARGET sgmalloc
-                APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}")
-endif()
-
 if(SIMGRID_HAVE_MC)
   add_executable(simgrid-mc ${MC_SIMGRID_MC_SRC})
   target_link_libraries(simgrid-mc simgrid)
@@ -178,10 +173,6 @@ if(CMAKE_COMPILER_IS_GNUCC AND GCCLIBATOMIC_LIBRARY)
 endif()
 mark_as_advanced(GCCLIBATOMIC_LIBRARY)
 
-if(enable_model-checking AND (NOT LINKER_VERSION VERSION_LESS "2.30"))
-    set(SIMGRID_DEP   "${SIMGRID_DEP}   -Wl,-znorelro -Wl,-znoseparate-code")
-endif()
-
 target_link_libraries(simgrid  ${SIMGRID_DEP})
 
 # Dependencies from maintainer mode
@@ -189,6 +180,3 @@ target_link_libraries(simgrid       ${SIMGRID_DEP})
 if(enable_maintainer_mode)
   add_dependencies(simgrid smpi_generated_headers_call_location_tracing)
 endif()
-if(enable_maintainer_mode AND BISON_EXE AND LEX_EXE)
-  add_dependencies(simgrid automaton_generated_src)
-endif()
diff --git a/tools/cmake/Modules/FindLibdw.cmake b/tools/cmake/Modules/FindLibdw.cmake
deleted file mode 100644 (file)
index 62c52e9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-find_path(LIBDW_INCLUDE_DIR "elfutils/libdw.h"
-  HINTS
-  $ENV{SIMGRID_LIBDW_LIBRARY_PATH}
-  $ENV{LD_LIBRARY_PATH}
-  $ENV{LIBDW_LIBRARY_PATH}
-  PATH_SUFFIXES include/
-  PATHS
-  /opt
-  /opt/local
-  /opt/csw
-  /sw
-  /usr)
-find_library(LIBDW_LIBRARY
-  NAMES dw
-  HINTS
-  $ENV{SIMGRID_LIBDW_LIBRARY_PATH}
-  $ENV{LD_LIBRARY_PATH}
-  $ENV{LIBDW_LIBRARY_PATH}
-  PATH_SUFFIXES lib/
-  PATHS
-  /opt
-  /opt/local
-  /opt/csw
-  /sw
-  /usr)
-set(LIBDW_LIBRARIES "${LIBDW_LIBRARY}")
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
-  Libdw
-  DEFAULT_MSG
-  LIBDW_LIBRARIES
-  LIBDW_INCLUDE_DIR)
-mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARIES)
diff --git a/tools/cmake/Modules/FindLibelf.cmake b/tools/cmake/Modules/FindLibelf.cmake
deleted file mode 100644 (file)
index 240be29..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-find_path(LIBELF_INCLUDE_DIR "libelf.h"
-  HINTS
-  $ENV{SIMGRID_LIBELF_LIBRARY_PATH}
-  $ENV{LD_LIBRARY_PATH}
-  $ENV{LIBELF_LIBRARY_PATH}
-  PATH_SUFFIXES include/
-  PATHS
-  /opt
-  /opt/local
-  /opt/csw
-  /sw
-  /usr)
-find_library(LIBELF_LIBRARY
-  NAMES elf
-  HINTS
-  $ENV{SIMGRID_LIBELF_LIBRARY_PATH}
-  $ENV{LD_LIBRARY_PATH}
-  $ENV{LIBELF_LIBRARY_PATH}
-  PATH_SUFFIXES lib/
-  PATHS
-  /opt
-  /opt/local
-  /opt/csw
-  /sw
-  /usr)
-set(LIBELF_LIBRARIES "${LIBELF_LIBRARY}")
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
-  Libelf
-  DEFAULT_MSG
-  LIBELF_LIBRARIES
-  LIBELF_INCLUDE_DIR)
-mark_as_advanced(LIBELF_INCLUDE_DIR LIBELF_LIBRARIES)
diff --git a/tools/cmake/Modules/FindLibunwind.cmake b/tools/cmake/Modules/FindLibunwind.cmake
deleted file mode 100644 (file)
index 2066d48..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# Search for libunwind and components, both includes and libraries
-#
-# Copyright (C) 2003-2023 The SimGrid Team.
-# This is distributed under the LGPL licence but please contact us for
-# relicensing if you need. This is merely free software, no matter the licence.
-#
-#
-# Input environment variables:
-#    LIBUNWIND_HINT: path to libunwind installation (e.g., /usr)
-#                    (only needed for non-standard installs)
-#
-# You can tune the needed components here.
-# TODO: we should take this as a parameter if I knew how to do so.
-
-# SimGrid needs unwind-ptrace on Linux and FreeBSD
-if("${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD")
-  set(LIBUNWIND_COMPONENTS ${LIBUNWIND_COMPONENTS} unwind-ptrace unwind-generic)
-endif()
-
-#
-#  Output variables:
-#     HAVE_LIBUNWIND     : if all components were found was found
-#     LIBUNWIND_LIBRARIES: List of all libraries to load (-lunwind -lunwind-x86_64 and such)
-#
-#  Other effects:
-#    - Calls include_directories() on where libunwind.h lives
-#    - Calls link_directories() on where the libs live
-
-# Of course also need the core lib
-set(LIBUNWIND_COMPONENTS ${LIBUNWIND_COMPONENTS} "unwind")
-
-message(STATUS "Looking for libunwind:")
-# Let's assume we have it, and invalidate if parts are missing
-SET(HAVE_LIBUNWIND 1)
-
-#
-# Search for the header file
-#
-
-find_path(PATH_LIBUNWIND_H "libunwind.h"
-  HINTS
-    $ENV{LIBUNWIND_HINT}
-    $ENV{LD_LIBRARY_PATH}
-  PATH_SUFFIXES include/
-  PATHS /opt /opt/local /opt/csw /sw /usr)
-if(PATH_LIBUNWIND_H)
-  string(REGEX REPLACE "/libunwind.h"               "" PATH_LIBUNWIND_H   "${PATH_LIBUNWIND_H}")
-  message("   Found libunwind.h in ${PATH_LIBUNWIND_H}")
-  include_directories(${PATH_LIBUNWIND_H})
-else()
-  message("   NOT FOUND libunwind.h")
-  SET(HAVE_LIBUNWIND 0)
-endif()
-mark_as_advanced(PATH_LIBUNWIND_H)
-
-#
-# Search for the library components
-#
-
-foreach(component ${LIBUNWIND_COMPONENTS})
-  find_library(PATH_LIBUNWIND_LIB_${component}
-    NAMES ${component}
-    HINTS
-      $ENV{LIBUNWIND_HINT}
-      $ENV{LD_LIBRARY_PATH}
-    PATH_SUFFIXES lib/ lib/system
-    PATHS /opt /opt/local /opt/csw /sw /usr /usr/lib/)
-  if(PATH_LIBUNWIND_LIB_${component})
-    # message("     ${component}  ${PATH_LIBUNWIND_LIB_${component}}")
-    string(REGEX REPLACE "/lib${component}.*[.]${LIB_EXE}$" "" PATH_LIBUNWIND_LIB_${component} "${PATH_LIBUNWIND_LIB_${component}}")
-    message("   Found lib${component}.${LIB_EXE} in ${PATH_LIBUNWIND_LIB_${component}}")
-    link_directories(${PATH_LIBUNWIND_LIB_${component}})
-
-    if(${component} STREQUAL "unwind" AND APPLE)
-        # Apple forbids to link directly against its libunwind implementation
-        # So let's comply to that stupid restriction and link against the System framework
-        SET(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES} -lSystem")
-    else()
-        SET(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES} -l${component}")
-    endif()
-
-  else()
-    message("   Looking for lib${component}.${LIB_EXE} - not found")
-    SET(HAVE_LIBUNWIND 0)
-  endif()
-  mark_as_advanced(PATH_LIBUNWIND_LIB_${component})
-endforeach()
-unset(component)
-unset(LIBUNWIND_COMPONENTS)
-
-#
-# Conclude and cleanup
-#
-if(HAVE_LIBUNWIND)
-  message(STATUS "Dependencies induced by libunwind: ${LIBUNWIND_LIBRARIES}")
-else()
-  message(STATUS "Some libunwind components are missing")
-  set(LIBUNWIND_LIBRARIES "")
-endif()
index c4faa2f..e35aa12 100644 (file)
@@ -38,8 +38,8 @@ endif()
 option(minimal-bindings      "Whether to compile the Python bindings libraries with the minimal dependency set" off)
 mark_as_advanced(minimal-bindings)
 
-option(enable_model-checking "Turn this on to experiment with our prototype of model-checker" off)
-option(enable-model-checking "Please set 'enable_model-checking' instead" off)
+option(enable_model-checking "Turn this on to experiment with our prototype of model-checker" on)
+option(enable-model-checking "Please set 'enable_model-checking' instead" on)
 mark_as_advanced(enable-model-checking)
 if(enable-model-checking)
   SET(enable_model-checking ON CACHE BOOL "Whether to compile the model-checker" FORCE)
@@ -47,8 +47,22 @@ endif()
 
 option(enable_smpi "Whether SMPI is included in the library." on)
 option(enable_smpi_papi    "Whether SMPI supports PAPI bindings." off)
-option(enable_smpi_MPICH3_testsuite "Whether the test suite form MPICH 3 should be built" off)
-option(enable_smpi_MBI_testsuite "Whether the test suite from MBI should be built." off)
+
+option(enable_testsuite_smpi_MPICH3 "Whether the test suite form MPICH 3 should be built." off)
+option(enable_smpi_MPICH3_testsuite "Please use 'enable_testsuite_smpi_MPICH3' instead." off)
+mark_as_advanced(enable_smpi_MPICH3_testsuite)
+if(enable_smpi_MPICH3_testsuite)
+  SET(enable_testsuite_smpi_MPICH3 ON CACHE BOOL "Whether the test suite form MPICH 3 should be built." FORCE)
+endif()
+
+option(enable_testsuite_smpi_MBI "Whether the test suite from MBI should be built." off)
+option(enable_smpi_MBI_testsuite "Please use 'enable_testsuite_smpi_MBI' instead." off)
+mark_as_advanced(enable_smpi_MBI_testsuite)
+if(enable_smpi_MBI_testsuite)
+  SET(enable_testsuite_smpi_MBI ON CACHE BOOL "Whether the test suite from MBI should be built." FORCE)
+endif()
+
+option(enable_testsuite_McMini "Whether the test suite from McMini should be built." off)
 
 # Internal targets used by jenkins
 ###
index 6023103..c5567a0 100644 (file)
@@ -132,27 +132,19 @@ set(UNIT_TESTS  src/xbt/unit-tests_main.cpp
 
 set(MC_UNIT_TESTS src/mc/explo/odpor/ClockVector_test.cpp
                   src/mc/explo/odpor/Execution_test.cpp
-                  src/mc/explo/odpor/WakeupTree_test.cpp)
-
-set(STATEFUL_MC_UNIT_TESTS src/mc/sosp/Snapshot_test.cpp
-                           src/mc/sosp/PageStore_test.cpp
-                           src/mc/explo/udpor/Unfolding_test.cpp
-                           src/mc/explo/udpor/UnfoldingEvent_test.cpp
-                           src/mc/explo/udpor/EventSet_test.cpp
-                           src/mc/explo/udpor/ExtensionSet_test.cpp
-                           src/mc/explo/udpor/History_test.cpp
-                           src/mc/explo/udpor/Configuration_test.cpp)
-
+                  src/mc/explo/odpor/WakeupTree_test.cpp
+                  
+                  src/mc/explo/udpor/Unfolding_test.cpp
+                  src/mc/explo/udpor/UnfoldingEvent_test.cpp
+                  src/mc/explo/udpor/EventSet_test.cpp
+                  src/mc/explo/udpor/ExtensionSet_test.cpp
+                  src/mc/explo/udpor/History_test.cpp
+                  src/mc/explo/udpor/Configuration_test.cpp)
 if (SIMGRID_HAVE_MC)
   set(UNIT_TESTS ${UNIT_TESTS} ${MC_UNIT_TESTS})
 else()
   set(EXTRA_DIST ${EXTRA_DIST} ${MC_UNIT_TESTS})
 endif()
-if (SIMGRID_HAVE_STATEFUL_MC)
-  set(UNIT_TESTS ${UNIT_TESTS} ${STATEFUL_MC_UNIT_TESTS})
-else()
-  set(EXTRA_DIST ${EXTRA_DIST} ${STATEFUL_MC_UNIT_TESTS})
-endif()
 if (SIMGRID_HAVE_EIGEN3)
   set(UNIT_TESTS ${UNIT_TESTS} src/kernel/lmm/bmf_test.cpp)
 else()
index 8ce4d26..7eb4d25 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get --allow-releaseinfo-change update && \
        python3-pip \
        doxygen fig2dev \
        chrpath \
-       libdw-dev libevent-dev libunwind8-dev \
+       libevent-dev \
        python3-sphinx python3-breathe python3-sphinx-rtd-theme && \
     apt clean && apt autoclean
 
index b898611..011ae00 100644 (file)
@@ -17,6 +17,6 @@ RUN echo "DOWNLOAD_URL: ${DLURL}" && \
     make -j4 && \
     mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \
     make install && make clean && \
-    apt remove -y  g++ gcc git valgrind gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \
+    apt remove -y git valgrind libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \
     apt install `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && \
     apt autoremove -y && apt autoclean && apt clean
index 1730440..f13861d 100644 (file)
@@ -13,7 +13,7 @@ RUN apt update && apt -y upgrade
 # - Get the tutorial files (with an empty makefile advising to run cmake before make, just in case)
 # - Remove everything that was installed, and re-install what's needed by the SimGrid libraries before the Gran Final Cleanup
 # - Keep g++ gcc gfortran as any MC user will use (some of) them
-RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libeigen3-dev libboost-stacktrace-dev cmake dpkg-dev libunwind-dev libdw-dev libelf-dev libevent-dev python3-dev && \
+RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libeigen3-dev libboost-stacktrace-dev cmake dpkg-dev libdw-dev libelf-dev libevent-dev python3-dev && \
     mkdir /source/ && cd /source && git clone --depth=1 https://framagit.org/simgrid/simgrid.git simgrid.git && \
     cd simgrid.git && \
     cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_model-checking=ON -Denable_documentation=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \
@@ -21,7 +21,7 @@ RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libeigen3-dev libb
     git clone --depth=1 https://framagit.org/simgrid/tutorial-model-checking /source/tuto-mc.git && \
     printf "ndet-receive-s4u:\n\t@echo \"Please run the following command before make:\";echo \"    cmake .\"; exit 1" > /source/tuto-mc.git/Makefile &&\
     mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \
-    apt remove -y dpkg-dev libunwind-dev libdw-dev libelf-dev libevent-dev && \
+    apt remove -y dpkg-dev libdw-dev libelf-dev libevent-dev && \
     apt install -y `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && rm /tmp/deps && \
     apt autoremove -y && apt autoclean && apt clean
 
index 6ef5e42..c3bf640 100644 (file)
@@ -12,6 +12,6 @@ RUN apt-get --allow-releaseinfo-change update && apt -y upgrade && \
     make -j4 install && \
     mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \
     git reset --hard master && git clean -dfx && \
-    apt remove -y  g++ gcc git valgrind gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev python3-dev pybind11-dev && \
+    apt remove -y git valgrind libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \
     apt install `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && \
     apt autoremove -y && apt autoclean && apt clean
diff --git a/tools/generate-dwarf-functions b/tools/generate-dwarf-functions
deleted file mode 100755 (executable)
index 838d833..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env sh
-# Generate files from a given dwarf.h
-# Usage: tools/generate-dwarf-functions /usr/include/dwarf.h
-
-HEADER="\
-/* Copyright (c) 2014-$(date +%Y). 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. */
-
-/* Warning: autogenerated, do not edit! */
-
-#include \"src/mc/inspect/mc_dwarf.hpp\"
-
-#include <string>
-#include <unordered_map>"
-
-cat - > src/mc/inspect/mc_dwarf_tagnames.cpp <<EOF
-$HEADER
-
-namespace {
-const std::unordered_map<int, const char*> tagname_map = {
-    {0x00, "DW_TAG_invalid"},
-$(sed -n 's/.*\(DW_TAG_[^ ]*\) = \(0x[0-9a-f]*\).*/    {\2, "\1"},/p' -- "$1")
-};
-}
-
-namespace simgrid::dwarf {
-
-/** @brief Get the name of a dwarf tag (DW_TAG_*) from its code
- *
- *  @param tag tag code (see the DWARF specification)
- *  @return name of the tag
- */
-XBT_PRIVATE
-const char* tagname(int tag)
-{
-  auto name = tagname_map.find(tag);
-  return name == tagname_map.end() ? "DW_TAG_unknown" : name->second;
-}
-
-} // namespace simgrid::dwarf
-EOF
-
-cat - > src/mc/inspect/mc_dwarf_attrnames.cpp << EOF
-$HEADER
-
-namespace {
-const std::unordered_map<int, const char*> attrname_map = {
-$(sed -n 's/.*\(DW_AT_[^ ]*\) = \(0x[0-9a-f]*\).*/    {\2, "\1"},/p' -- "$1")
-};
-}
-
-namespace simgrid::dwarf {
-
-/** @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
- */
-XBT_PRIVATE
-const char* attrname(int attr)
-{
-  auto name = attrname_map.find(attr);
-  return name == attrname_map.end() ? "DW_AT_unknown" : name->second;
-}
-
-} // namespace simgrid::dwarf
-EOF
index 4a2012d..8558631 100755 (executable)
@@ -65,9 +65,9 @@ cmake -Denable_documentation=OFF \
       -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON \
       -Denable_mallocators=ON \
       -Denable_ns3=ON \
-      -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON -Denable_model-checking=ON \
+      -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON -Denable_model-checking=ON \
       -Denable_smpi_papi=ON \
-      -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_smpi_MBI_testsuite=ON \
+      -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_testsuite_smpi_MBI=ON -Denable_testsuite_McMini=ON \
       -Denable_coverage=ON -DLTO_EXTRA_FLAG="auto" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON "$WORKSPACE"
 
 #build with sonarqube scanner wrapper
index 41f0ba1..2f7d99f 100755 (executable)
@@ -61,7 +61,7 @@ ctest -D ExperimentalStart || true
 cmake -Denable_documentation=OFF -Denable_python=OFF \
       -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON \
       -Denable_mallocators=OFF \
-      -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=OFF -Denable_model-checking=OFF \
+      -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF -Denable_testsuite_McMini=OFF -Denable_model-checking=OFF \
       -Denable_ns3=ON \
       -Denable_memcheck_xml=ON -DLTO_EXTRA_FLAG="auto" "$WORKSPACE"
 
index e8f9198..dab4330 100755 (executable)
@@ -79,8 +79,8 @@ fi
 cmake -Denable_documentation=OFF \
       -Denable_compile_optimizations=${runtests} -Denable_compile_warnings=ON \
       -Denable_mallocators=ON -Denable_debug=${builddebug} \
-      -Denable_smpi=${buildsmpi} -Denable_smpi_MPICH3_testsuite=${buildsmpi} -Denable_model-checking=${buildmc} \
-      -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_smpi_MBI_testsuite=OFF \
+      -Denable_smpi=${buildsmpi} -Denable_testsuite_smpi_MPICH3=${buildsmpi} -Denable_model-checking=${buildmc} \
+      -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_testsuite_smpi_MBI=OFF -Denable_testsuite_McMini=OFF \
       -Denable_ns3=$(onoff test "$buildmc" != "ON") -DNS3_HINT=/builds/ns-3-dev/build/ \
       -Denable_coverage=OFF -DLTO_EXTRA_FLAG="auto" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
       "$WORKSPACE"
index 04b4737..ef5ae0e 100755 (executable)
@@ -77,9 +77,9 @@ ctest -D ExperimentalStart || true
 cmake -Denable_documentation=OFF \
       -Denable_compile_optimizations=ON -Denable_compile_warnings=ON \
       -Denable_mallocators=OFF \
-      -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON -Denable_model-checking=OFF \
+      -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON -Denable_model-checking=OFF \
       -Denable_ns3=ON \
-      -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_smpi_MBI_testsuite=OFF -Denable_coverage=OFF\
+      -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_testsuite_smpi_MBI=OFF -Denable_testsuite_McMini=OFF -Denable_coverage=OFF\
       -Denable_fortran=OFF -Denable_python=OFF -DLTO_EXTRA_FLAG="auto" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache\
       ${SANITIZER_OPTIONS} "$WORKSPACE"
 
index a9d9d64..0438427 100755 (executable)
@@ -129,6 +129,13 @@ echo "Branch built is $branch_name"
 
 NUMBER_OF_PROCESSORS="$(nproc)" || NUMBER_OF_PROCESSORS=1
 GENERATOR="Unix Makefiles"
+BUILDER=make
+VERBOSE_BUILD="VERBOSE=1"
+if which ninja 2>/dev/null >/dev/null ; then
+  GENERATOR=Ninja
+  BUILDER=ninja
+  VERBOSE_BUILD="-v"
+fi
 
 ulimit -c 0 || true
 
@@ -169,7 +176,7 @@ echo "XX   pwd: $(pwd)"
 echo "XX"
 
 cmake -G"$GENERATOR" -Denable_documentation=OFF "$WORKSPACE"
-make dist -j $NUMBER_OF_PROCESSORS
+${BUILDER} dist -j $NUMBER_OF_PROCESSORS
 SIMGRID_VERSION=$(cat VERSION)
 
 echo "XX"
@@ -204,9 +211,9 @@ fi
 cmake -G"$GENERATOR" ${INSTALL:+-DCMAKE_INSTALL_PREFIX=$INSTALL} \
   -Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \
   -Denable_model-checking=$(onoff test "$build_mode" = "ModelChecker") \
-  -Denable_smpi_MBI_testsuite=OFF \
+  -Denable_testsuite_smpi_MBI=OFF -Denable_testsuite_McMini=ON \
   -Denable_compile_optimizations=$(onoff test "$build_mode" != "DynamicAnalysis") \
-  -Denable_smpi_MPICH3_testsuite=$(onoff test "$build_mode" = "Debug") \
+  -Denable_testsuite_smpi_MPICH3=$(onoff test "$build_mode" = "Debug") \
   -Denable_mallocators=$(onoff test "$build_mode" != "DynamicAnalysis") \
   -Denable_memcheck=$(onoff test "$build_mode" = "DynamicAnalysis") \
   -Denable_compile_warnings=$(onoff test "$GENERATOR" != "MSYS Makefiles") -Denable_smpi=ON \
@@ -217,7 +224,7 @@ cmake -G"$GENERATOR" ${INSTALL:+-DCMAKE_INSTALL_PREFIX=$INSTALL} \
   -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
   "$SRCFOLDER"
 
-make -j $NUMBER_OF_PROCESSORS VERBOSE=1 tests
+${BUILDER} -j $NUMBER_OF_PROCESSORS ${VERBOSE_BUILD} tests
 
 echo "XX"
 echo "XX Run the tests"
@@ -233,7 +240,7 @@ if test -n "$INSTALL" && [ "${branch_name}" = "origin/master" ] ; then
 
   rm -rf "$INSTALL"
 
-  make install
+  ${BUILDER} install
 fi
 
 echo "XX"
index 29673a7..6833428 100755 (executable)
@@ -22,6 +22,10 @@ export PATH=$PWD/simgrid-dev/smpi_script/bin/:$PATH
 export LD_LIBRARY_PATH=$PWD/simgrid-dev/lib/:$LD_LIBRARY_PATH
 export JHBUILD_RUN_AS_ROOT=1
 
+#workaround issue with ntpoly 3.0.0
+sed -i 's|repository type="tarball" name="ntpoly" href="https://github.com/william-dawson/NTPoly/archive/"|repository type="git" name="ntpoly" href="https://github.com/william-dawson/"|' ../modulesets/hpc-upstream.modules
+sed -i 's|module="ntpoly-v3.0.0.tar.gz"|module="ntpoly"|' ../modulesets/hpc-upstream.modules
+
 ../Installer.py autogen -y
 
 ../Installer.py -f ../../tools/jenkins/gfortran-simgrid.rc -y build
index f435e01..73864b4 100755 (executable)
@@ -12,12 +12,12 @@ echo "XXXXXXXXXXXXXXXX Install APT dependencies"
 $SUDO apt-get update
 $SUDO apt-get -y install build-essential libboost-all-dev wget git xsltproc
 
-for i in master 1.3 ; do
+for i in master starpu-1.3 ; do
   echo "XXXXXXXXXXXXXXXX Build and test StarPU $i"
   rm -rf starpu*
-  wget https://files.inria.fr/starpu/simgrid/starpu-simgrid-$i.tar.gz
-  md5sum starpu-simgrid-$i.tar.gz
-  tar xf starpu-simgrid-$i.tar.gz
+  wget https://files.inria.fr/starpu/testing/$i/starpu-nightly-latest.tar.gz
+  md5sum starpu-nightly-latest.tar.gz
+  tar xf starpu-nightly-latest.tar.gz
   cd starpu-1*
 
   # NOTE: Do *not* introduce parameters to "make it work" here.
index 4a52a6f..8af5e8d 100755 (executable)
@@ -26,7 +26,7 @@ get_json(){
 }
 
 get_ns3(){
-  sed -n 's/.*-- ns-3 found (v\(3[-.0-9a-z]\+\); minor:.*/\1/p;T;q' ./consoleText
+  sed -n 's/.*-- ns-3 found (v\(3[-.0-9a-z]\+\).*/\1/p;T;q' ./consoleText
 }
 
 get_python(){
index 98a18e1..e1c3f28 100644 (file)
    fun:agconcat
 }
 
-# libunwind seems to be using msync poorly, thus triggering these
-# https://github.com/JuliaLang/julia/issues/4533
-{
-   msync unwind
-   Memcheck:Param
-   msync(start)
-   ...
-   obj:*/libpthread*.so
-   ...
-}
-
-{
-   ignore unwind cruft
-   Memcheck:Param
-   rt_sigprocmask(set)
-   ...
-   obj:/usr/lib/x86_64-linux-gnu/libunwind.so.*
-   ...
-}
-{
-   ignore unwind cruft
-   Memcheck:Param
-   msync(start)
-   ...
-   obj:/usr/lib/x86_64-linux-gnu/libunwind.so.*
-   ...
-}
-{
-   ignore unwind cruft
-   Memcheck:Param
-   write(buf)
-   ...
-   fun:_ULx86_64_step
-   obj:/usr/lib/x86_64-linux-gnu/libunwind.so.*
-}
-
-{
-   ignore unwind invalid reads
-   Memcheck:Addr8
-   fun:_Ux86_64_setcontext
-}
-
 # Ignore python cruft
 {
    ignore python cruft 1
index 2799b4f..42fede2 100644 (file)
@@ -19,7 +19,7 @@ $ perl segfault.pl
 p Check that we return the expected return value on SEGV
 ! expect return 11
 < $ perl segfault.pl
-$ ${bindir:=.}/tesh
+$ ${bindir:=.}/tesh --no-auto-valgrind
 > Test suite from stdin
 > [(stdin):1] perl segfault.pl
 > Test suite `(stdin)': NOK (<(stdin):1> got signal SIGSEGV)
index 227d93c..e308580 100644 (file)
@@ -14,6 +14,7 @@
 > @@ -0,0 +1 @@
 > +I crashed
 > Test suite `(stdin)': NOK (<(stdin):2> output mismatch)
+> In addition, <(stdin):2> got signal SIGTERM.
 $ ${bindir:=.}/tesh
 
 
index 2baa1b3..856dab0 100755 (executable)
@@ -196,6 +196,7 @@ class TeshState(Singleton):
         self.args_suffix = ""
         self.ignore_regexps_common = []
         self.jenkins = False  # not a Jenkins run by default
+        self.auto_valgrind = True
         self.timeout = 10  # default value: 10 sec
         self.wrapper = None
         self.keep = False
@@ -237,6 +238,7 @@ class Cmd:
         self.output_display = False
 
         self.sort = -1
+        self.rerun_with_valgrind = False
 
         self.ignore_regexps = TeshState().ignore_regexps_common
 
@@ -302,6 +304,14 @@ class Cmd:
             _thread.start_new_thread(Cmd._run, (self, lock))
         else:
             self._run()
+            if self.rerun_with_valgrind and TeshState().auto_valgrind:
+                print('\n\n\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
+                print(      'XXXXXXXXX Rerunning this test with valgrind to help debugging it XXXXXXXXX')
+                print(      'XXXXXXXX (this will fail if valgrind is not installed, of course) XXXXXXXX')
+                print(      'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n\n\n')
+
+                self.args = "valgrind " + self.args
+                self._run()
         return True
 
     def _run(self, lock=None):
@@ -411,13 +421,17 @@ class Cmd:
                 print('\n'.join(logs))
                 return
 
-        if self.output_display:
-            logs.append(str(stdout_data))
-
         # remove text colors
         ansi_escape = re.compile(r'\x1b[^m]*m')
         stdout_data = ansi_escape.sub('', stdout_data)
 
+        if self.output_display:
+            logs.append(str(stdout_data))
+
+        if self.rerun_with_valgrind:
+            print(str(stdout_data), file=sys.stderr)
+            return
+
         if self.ignore_output:
             logs.append("(ignoring the output of <{cmd}> as requested)".format(cmd=cmd_name))
         else:
@@ -461,6 +475,18 @@ class Cmd:
 
                 logs.append("Test suite `{file}': NOK (<{cmd}> output mismatch)".format(
                     file=FileReader().filename, cmd=cmd_name))
+
+                # Also report any failed return code and/or signal we got in case of output mismatch
+                if not proc.returncode in self.expect_return:
+                    if proc.returncode >= 0:
+                        logs.append("In addition, <{cmd}> returned code {code}.".format(
+                            cmd=cmd_name, code=proc.returncode))
+                    else:
+                        logs.append("In addition, <{cmd}> got signal {sig}.".format(cmd=cmd_name,
+                            sig=SIGNALS_TO_NAMES_DICT[-proc.returncode]))
+                    if proc.returncode == -signal.SIGSEGV:
+                        self.rerun_with_valgrind = True
+
                 if lock is not None:
                     lock.release()
                 if TeshState().keep:
@@ -495,6 +521,10 @@ class Cmd:
             logs.append("Test suite `{file}': NOK (<{cmd}> got signal {sig})".format(
                 file=FileReader().filename, cmd=cmd_name,
                 sig=SIGNALS_TO_NAMES_DICT[-proc.returncode]))
+
+            if proc.returncode == -signal.SIGSEGV:
+                self.rerun_with_valgrind = True
+
             if lock is not None:
                 lock.release()
             TeshState().set_return_code(max(-proc.returncode, 1))
@@ -535,6 +565,10 @@ def main():
         '--ignore-jenkins',
         action='store_true',
         help='ignore all cruft generated on SimGrid continuous integration servers')
+    group1.add_argument(
+        '--no-auto-valgrind',
+        action='store_true',
+        help='do not automaticall launch segfaulting commands in valgrind')
     group1.add_argument('--wrapper', metavar='arg', help='Run each command in the provided wrapper (eg valgrind)')
     group1.add_argument(
         '--keep',
@@ -560,6 +594,7 @@ def main():
             re.compile(r"For details see http://code\.google\.com/p/address-sanitizer/issues/detail\?id=189"),
             re.compile(r"For details see https://github\.com/google/sanitizers/issues/189"),
             re.compile(r"Python runtime initialized with LC_CTYPE=C .*"),
+            re.compile(r"sthread is intercepting the execution of \.*"),
             # Seen on CircleCI
             re.compile(r"cmake: /usr/local/lib/libcurl\.so\.4: no version information available \(required by cmake\)"),
             re.compile(
@@ -568,6 +603,9 @@ def main():
         ]
         TeshState().jenkins = True  # This is a Jenkins build
 
+    if options.no_auto_valgrind:
+        TeshState().auto_valgrind = False
+
     if options.teshfile is None:
         file = FileReader(None)
         print("Test suite from stdin")
@@ -672,7 +710,16 @@ def main():
             cmd.add_ignore(line[len("! ignore "):])
 
         else:
-            fatal_error(f"UNRECOGNIZED OPTION LINE: {line}")
+            fatal_error(f"UNRECOGNIZED OPTION LINE: {line}\n"
+            "Valid requests:\n"
+            "   ! output ignore\n"
+            "   ! output sort\n"
+            "   ! output display\n"
+            "   ! setenv XX=YY\n"
+            "   ! ignore XYZ\n"
+            "   ! expect return NN\n"
+            "   ! expect signal NN\n"
+            "   ! timeout NN\n")
 
         line = file.readfullline()