From: mlaurent Date: Mon, 13 Feb 2023 14:35:36 +0000 (+0100) Subject: Merge branch 'master' of https://framagit.org/simgrid/simgrid X-Git-Tag: v3.34~436^2~16 X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/417ed3b671abe3a71fa4106d23d0a432084cc207?hp=5a006fa396cfcc8a91a8284f0d625b2a9a2565c9 Merge branch 'master' of https://framagit.org/simgrid/simgrid --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 84fe7f3210..01a299eecc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,14 +179,15 @@ set(SIMGRID_DEP "-lm") ### Determine the assembly flavor that we need today set(HAVE_RAW_CONTEXTS 0) include(CMakeDetermineSystem) +foreach(arch i686 x86_64 arm64) + set(SIMGRID_PROCESSOR_${arch} 0) +endforeach() IF(CMAKE_SYSTEM_PROCESSOR MATCHES ".86|AMD64|amd64") IF(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits message(STATUS "System processor: i686 (${CMAKE_SYSTEM_PROCESSOR}, 32 bits)") set(SIMGRID_PROCESSOR_i686 1) - set(SIMGRID_PROCESSOR_x86_64 0) ELSE() message(STATUS "System processor: x86_64 (${CMAKE_SYSTEM_PROCESSOR}, 64 bits)") - set(SIMGRID_PROCESSOR_i686 0) set(SIMGRID_PROCESSOR_x86_64 1) ENDIF() if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") @@ -194,9 +195,11 @@ IF(CMAKE_SYSTEM_PROCESSOR MATCHES ".86|AMD64|amd64") else() set(HAVE_RAW_CONTEXTS 1) endif() +ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + message(STATUS "System processor: arm64 (${CMAKE_SYSTEM_PROCESSOR}, 64 bits)") + set(SIMGRID_PROCESSOR_arm64 1) ELSE() - set(SIMGRID_PROCESSOR_i686 0) - set(SIMGRID_PROCESSOR_x86_64 0) + message(STATUS "System processor (${CMAKE_SYSTEM_PROCESSOR}) not explicitly accounted for") ENDIF() include(CheckFunctionExists) diff --git a/ChangeLog b/ChangeLog index eed2b3e954..048fed7a0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ General: S4U: - Activity::set_remaining() is not public anymore. Use for example Comm::set_payload_size() to change the size of the simulated data. + - New function: Engine::flatify_platform(), to get a fully detailed vision of the + configured platform. Kernel: - optimize an internal datastructure, leading to a potentially big @@ -38,6 +40,7 @@ Documentation: - New section in the user guide on the provided performance models. - New section presenting some technical good practices for (potential) contributors. - Add a section on errors and exceptions to the API documentation. + - Move the s4u examples to a section on their own to ease navigation. Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests) (FG: issues on Framagit; GH: issues on GitHub) diff --git a/FindSimGrid.cmake b/FindSimGrid.cmake index 4802eacf4d..209d709941 100644 --- a/FindSimGrid.cmake +++ b/FindSimGrid.cmake @@ -23,19 +23,11 @@ # Either by copying it in your tree, or (recommended) by using the # version automatically installed by SimGrid. # -# 2. Afterward, if you have CMake >= 2.8.12, this will define a -# target called 'SimGrid::Simgrid'. Use it as: +# 2. This will define a target called 'SimGrid::Simgrid'. Use it as: # target_link_libraries(your-simulator SimGrid::SimGrid) # -# With older CMake (< 2.8.12), it simply defines several variables: -# SimGrid_INCLUDE_DIR - the SimGrid include directories -# SimGrid_LIBRARY - link your simulator against it to use SimGrid -# Use as: -# include_directories("${SimGrid_INCLUDE_DIR}" SYSTEM) -# target_link_libraries(your-simulator ${SimGrid_LIBRARY}) -# -# In both cases, it also define a SimGrid_VERSION macro, that you -# can use to deal with API evolutions as follows: +# It also defines a SimGrid_VERSION macro, that you can use to deal with API +# evolutions as follows: # # #if SimGrid_VERSION < 31800 # (code to use if the installed version is lower than v3.18) @@ -110,7 +102,7 @@ find_package_handle_standard_args(SimGrid VERSION_VAR SimGrid_VERSION ) -if (SimGrid_FOUND AND NOT CMAKE_VERSION VERSION_LESS 2.8.12) +if (SimGrid_FOUND) add_library(SimGrid::SimGrid SHARED IMPORTED) set_target_properties(SimGrid::SimGrid PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${SimGrid_INCLUDE_DIR} diff --git a/docs/source/Configuring_SimGrid.rst b/docs/source/Configuring_SimGrid.rst index 31095af225..dd985e220d 100644 --- a/docs/source/Configuring_SimGrid.rst +++ b/docs/source/Configuring_SimGrid.rst @@ -466,7 +466,7 @@ Infiniband model InfiniBand network behavior can be modeled through 3 parameters ``smpi/IB-penalty-factors:"βe;βs;γs"``, as explained in `the PhD -thesis of Jean-Marc Vincent +thesis of Jérôme Vienne `_ (in French) or more concisely in `this paper `_, even if that paper does only describe models for myrinet and ethernet. diff --git a/docs/source/Doxyfile b/docs/source/Doxyfile index db9ec7e666..1595fcb1b7 100644 --- a/docs/source/Doxyfile +++ b/docs/source/Doxyfile @@ -59,10 +59,9 @@ PREDEFINED += \ SIMGRID_REGISTER_PLUGIN(id,desc,init)= \ XBT_PUBLIC= \ XBT_PUBLIC_DATA=extern \ - XBT_PUBLIC= \ - XBT_INLINE= \ - XBT_ALWAYS_INLINE= \ XBT_PRIVATE= \ + XBT_ALWAYS_INLINE= \ + XBT_ATTRIB_NOINLINE= \ XBT_ATTRIB_NORETURN= \ XBT_ATTRIB_UNUSED= \ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(cname,parent,desc)= \ diff --git a/docs/source/Start_your_own_project.rst b/docs/source/Start_your_own_project.rst index b6f5d0ac96..68e70e9e5c 100644 --- a/docs/source/Start_your_own_project.rst +++ b/docs/source/Start_your_own_project.rst @@ -30,7 +30,7 @@ of source files. .. code-block:: cmake - cmake_minimum_required(VERSION 2.8.8) + cmake_minimum_required(VERSION 2.8.12) project(MyFirstSimulator) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") diff --git a/docs/source/app_s4u.rst b/docs/source/app_s4u.rst index e5c5e71140..7d3d6b0767 100644 --- a/docs/source/app_s4u.rst +++ b/docs/source/app_s4u.rst @@ -825,6 +825,7 @@ Simulation setup .. doxygenfunction:: simgrid::s4u::Engine::load_deployment .. doxygenfunction:: simgrid::s4u::Engine::load_platform + .. doxygenfunction:: simgrid::s4u::Engine::flatify_platform .. doxygenfunction:: simgrid::s4u::Engine::register_actor(const std::string &name) .. doxygenfunction:: simgrid::s4u::Engine::register_actor(const std::string &name, F code) .. doxygenfunction:: simgrid::s4u::Engine::register_default(const std::function< void(int, char **)> &code) @@ -1582,6 +1583,7 @@ Querying info .. doxygenfunction:: simgrid::s4u::Link::get_latency() const .. doxygenfunction:: simgrid::s4u::Link::get_name() const .. doxygenfunction:: simgrid::s4u::Link::get_sharing_policy() const + .. doxygenfunction:: simgrid::s4u::Link::get_concurrency_limit() const .. doxygenfunction:: simgrid::s4u::Link::get_usage() const .. doxygenfunction:: simgrid::s4u::Link::is_used() const diff --git a/docs/source/tuto_disk/CMakeLists.txt b/docs/source/tuto_disk/CMakeLists.txt index 4cb7b1be0e..d346172c82 100644 --- a/docs/source/tuto_disk/CMakeLists.txt +++ b/docs/source/tuto_disk/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.8) +cmake_minimum_required(VERSION 2.8.12) project(tuto_disk) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") diff --git a/docs/source/tuto_network_calibration/CMakeLists.txt b/docs/source/tuto_network_calibration/CMakeLists.txt index ebcd24d441..72660b44c0 100644 --- a/docs/source/tuto_network_calibration/CMakeLists.txt +++ b/docs/source/tuto_network_calibration/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.8) +cmake_minimum_required(VERSION 2.8.12) project(tuto_network) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") diff --git a/examples/cpp/comm-dependent/s4u-comm-dependent.cpp b/examples/cpp/comm-dependent/s4u-comm-dependent.cpp index 775aa8acbd..d40c99feff 100644 --- a/examples/cpp/comm-dependent/s4u-comm-dependent.cpp +++ b/examples/cpp/comm-dependent/s4u-comm-dependent.cpp @@ -15,7 +15,7 @@ static void sender(sg4::Mailbox* mailbox) sg4::CommPtr comm = mailbox->put_init(computation_amount, 7e6); exec->set_name("exec on sender")->add_successor(comm)->start(); - comm->set_name("comm to receiver")->vetoable_start(); + comm->set_name("comm to receiver")->start(); exec->wait(); comm->wait(); } @@ -28,7 +28,7 @@ static void receiver(sg4::Mailbox* mailbox) sg4::CommPtr comm = mailbox->get_init()->set_dst_data((void**)&received, sizeof(double)); comm->set_name("comm from sender")->add_successor(exec)->start(); - exec->set_name("exec on receiver")->vetoable_start(); + exec->set_name("exec on receiver")->start(); comm->wait(); exec->wait(); diff --git a/examples/cpp/comm-dependent/s4u-comm-dependent.tesh b/examples/cpp/comm-dependent/s4u-comm-dependent.tesh index 613464dc69..7faa65ee7b 100644 --- a/examples/cpp/comm-dependent/s4u-comm-dependent.tesh +++ b/examples/cpp/comm-dependent/s4u-comm-dependent.tesh @@ -3,6 +3,8 @@ p Testing with default compound $ ${bindir:=.}/s4u-comm-dependent ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%6.2r]%e(%i:%a@%h)%e%m%n" +> [ 0.00] (1:sender@Tremblay) 'exec on sender' is assigned to a resource and all dependencies are solved. Let's start +> [ 0.00] (2:receiver@Jupiter) 'comm from sender' is assigned to a resource and all dependencies are solved. Let's start > [ 2.00] (1:sender@Tremblay) Remove a dependency from 'exec on sender' on 'comm to receiver' > [ 2.00] (1:sender@Tremblay) 'comm to receiver' is assigned to a resource and all dependencies are solved. Let's start > [ 3.07] (2:receiver@Jupiter) Remove a dependency from 'comm from sender' on 'exec on receiver' diff --git a/examples/cpp/dag-comm/s4u-dag-comm.cpp b/examples/cpp/dag-comm/s4u-dag-comm.cpp index c58c1b8a63..9e671b4dbc 100644 --- a/examples/cpp/dag-comm/s4u-dag-comm.cpp +++ b/examples/cpp/dag-comm/s4u-dag-comm.cpp @@ -42,9 +42,9 @@ int main(int argc, char* argv[]) // Set the parameters (the name is for logging purposes only) // + parent and child end after 1 second - parent->set_name("parent")->set_flops_amount(tremblay->get_speed())->vetoable_start(); - transfer->set_name("transfer")->set_payload_size(125e6)->vetoable_start(); - child->set_name("child")->set_flops_amount(jupiter->get_speed())->vetoable_start(); + parent->set_name("parent")->set_flops_amount(tremblay->get_speed())->start(); + transfer->set_name("transfer")->set_payload_size(125e6)->start(); + child->set_name("child")->set_flops_amount(jupiter->get_speed())->start(); // Schedule the different activities parent->set_host(tremblay); diff --git a/examples/cpp/dag-failure/s4u-dag-failure.cpp b/examples/cpp/dag-failure/s4u-dag-failure.cpp index fc520b8ad2..631b24c62c 100644 --- a/examples/cpp/dag-failure/s4u-dag-failure.cpp +++ b/examples/cpp/dag-failure/s4u-dag-failure.cpp @@ -36,7 +36,7 @@ int main(int argc, char** argv) /* creation of a single Exec that will poorly fail when the workstation will stop */ XBT_INFO("First test: sequential Exec activity"); - sg4::ExecPtr exec = sg4::Exec::init()->set_name("Poor task")->set_flops_amount(2e10)->vetoable_start(); + sg4::ExecPtr exec = sg4::Exec::init()->set_name("Poor task")->set_flops_amount(2e10)->start(); XBT_INFO("Schedule Activity '%s' on 'Faulty Host'", exec->get_cname()); exec->set_host(faulty); @@ -44,7 +44,7 @@ int main(int argc, char** argv) /* Add a child Exec that depends on the Poor task' */ sg4::ExecPtr child = sg4::Exec::init()->set_name("Child")->set_flops_amount(2e10)->set_host(safe); exec->add_successor(child); - child->vetoable_start(); + child->start(); XBT_INFO("Run the simulation"); e.run(); @@ -57,7 +57,7 @@ int main(int argc, char** argv) e.run(); XBT_INFO("Second test: parallel Exec activity"); - exec = sg4::Exec::init()->set_name("Poor parallel task")->set_flops_amounts({2e10, 2e10})->vetoable_start(); + exec = sg4::Exec::init()->set_name("Poor parallel task")->set_flops_amounts({2e10, 2e10})->start(); XBT_INFO("Schedule Activity '%s' on 'Safe Host' and 'Faulty Host'", exec->get_cname()); exec->set_hosts({safe, faulty}); @@ -65,7 +65,7 @@ int main(int argc, char** argv) /* Add a child Exec that depends on the Poor parallel task' */ child = sg4::Exec::init()->set_name("Child")->set_flops_amount(2e10)->set_host(safe); exec->add_successor(child); - child->vetoable_start(); + child->start(); XBT_INFO("Run the simulation"); e.run(); diff --git a/examples/cpp/dag-io/s4u-dag-io.cpp b/examples/cpp/dag-io/s4u-dag-io.cpp index 25906511a1..ee00eb03a9 100644 --- a/examples/cpp/dag-io/s4u-dag-io.cpp +++ b/examples/cpp/dag-io/s4u-dag-io.cpp @@ -50,10 +50,10 @@ int main(int argc, char* argv[]) child->set_name("child")->set_flops_amount(carl->get_speed()); // Schedule and try to start the different activities - parent->set_host(bob)->vetoable_start(); - write_output->set_disk(bob->get_disks().front())->vetoable_start(); - read_input->set_disk(carl->get_disks().front())->vetoable_start(); - child->set_host(carl)->vetoable_start(); + parent->set_host(bob)->start(); + write_output->set_disk(bob->get_disks().front())->start(); + read_input->set_disk(carl->get_disks().front())->start(); + child->set_host(carl)->start(); e.run(); diff --git a/examples/cpp/dag-simple/s4u-dag-simple.cpp b/examples/cpp/dag-simple/s4u-dag-simple.cpp index a22d3da784..aae95e7101 100644 --- a/examples/cpp/dag-simple/s4u-dag-simple.cpp +++ b/examples/cpp/dag-simple/s4u-dag-simple.cpp @@ -56,9 +56,9 @@ int main(int argc, char* argv[]) second_parent->set_host(fafard); // Start all activities that can actually start. - first_parent->vetoable_start(); - second_parent->vetoable_start(); - child->vetoable_start(); + first_parent->start(); + second_parent->start(); + child->start(); while (child->get_state() != sg4::Activity::State::FINISHED) { e.run(); diff --git a/examples/cpp/dht-chord/s4u-dht-chord-node.cpp b/examples/cpp/dht-chord/s4u-dht-chord-node.cpp index e5916388d7..9dda4d544b 100644 --- a/examples/cpp/dht-chord/s4u-dht-chord-node.cpp +++ b/examples/cpp/dht-chord/s4u-dht-chord-node.cpp @@ -8,9 +8,14 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(s4u_chord); namespace sg4 = simgrid::s4u; +void ChordMessage::destroy(void* message) +{ + delete static_cast(message); +} + /* Returns whether an id belongs to the interval [start, end]. * - * The parameters are normalized to make sure they are between 0 and nb_keys - 1). + * The parameters are normalized to make sure they are between 0 and nb_keys_ - 1). * 1 belongs to [62, 3] * 1 does not belong to [3, 62] * 63 belongs to [62, 3] @@ -23,27 +28,29 @@ namespace sg4 = simgrid::s4u; * @param end upper bound * @return true if id in in [start, end] */ -static bool is_in_interval(int id, int start, int end) +bool Node::is_in_interval(int id, int start, int end) { - int i = id % nb_keys; - int s = start % nb_keys; - int e = end % nb_keys; + int i = id % nb_keys_; + int s = start % nb_keys_; + int e = end % nb_keys_; // make sure end >= start and id >= start if (e < s) { - e += nb_keys; + e += nb_keys_; } if (i < s) { - i += nb_keys; + i += nb_keys_; } return i <= e; } -void ChordMessage::destroy(void* message) +void Node::set_parameters(int nb_bits, int nb_keys, int timeout) { - delete static_cast(message); + nb_bits_ = nb_bits; + nb_keys_ = nb_keys; + timeout_ = timeout; } /* Initializes the current node as the first one of the system */ @@ -54,10 +61,10 @@ Node::Node(std::vector args) // initialize my node id_ = std::stoi(args[1]); XBT_DEBUG("Initialize node with id: %d", id_); - random.set_seed(id_); + random_.set_seed(id_); mailbox_ = sg4::Mailbox::by_name(std::to_string(id_)); - next_finger_to_fix = 0; - fingers_.resize(nb_bits, id_); + next_finger_to_fix_ = 0; + fingers_.resize(nb_bits_, id_); if (args.size() == 3) { // first ring deadline_ = std::stod(args[2]); @@ -89,7 +96,7 @@ void Node::join(int known_id) } else { setFinger(0, successor_id); printFingerTable(); - joined = true; + joined_ = true; } } @@ -98,7 +105,7 @@ void Node::leave() { XBT_INFO("Well Guys! I Think it's time for me to leave ;)"); notifyAndQuit(); - joined = false; + joined_ = false; } /* Notifies the successor and the predecessor of the current node before leaving */ @@ -111,7 +118,7 @@ void Node::notifyAndQuit() XBT_DEBUG("Sending a 'PREDECESSOR_LEAVING' to my successor %d", fingers_[0]); try { - sg4::Mailbox::by_name(std::to_string(fingers_[0]))->put(pred_msg, 10, timeout); + sg4::Mailbox::by_name(std::to_string(fingers_[0]))->put(pred_msg, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Timeout expired when sending a 'PREDECESSOR_LEAVING' to my successor %d", fingers_[0]); delete pred_msg; @@ -125,7 +132,7 @@ void Node::notifyAndQuit() XBT_DEBUG("Sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_); try { - sg4::Mailbox::by_name(std::to_string(pred_id_))->put(succ_msg, 10, timeout); + sg4::Mailbox::by_name(std::to_string(pred_id_))->put(succ_msg, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Timeout expired when sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_); delete succ_msg; @@ -137,7 +144,7 @@ void Node::notifyAndQuit() void Node::randomLookup() { int res = id_; - int random_index = random.uniform_int(0, nb_bits - 1); + int random_index = random_.uniform_int(0, nb_bits_ - 1); int random_id = fingers_[random_index]; XBT_DEBUG("Making a lookup request for id %d", random_id); if (random_id != id_) @@ -148,7 +155,7 @@ void Node::randomLookup() /* Sets a finger of the current node. * * @param node the current node - * @param finger_index index of the finger to set (0 to nb_bits - 1) + * @param finger_index index of the finger to set (0 to nb_bits_ - 1) * @param id the id to set for this finger */ void Node::setFinger(int finger_index, int id) @@ -174,13 +181,13 @@ void Node::setPredecessor(int predecessor_id) void Node::fixFingers() { XBT_DEBUG("Fixing fingers"); - int id = findSuccessor(id_ + (1U << next_finger_to_fix)); + int id = findSuccessor(id_ + (1U << next_finger_to_fix_)); if (id != -1) { - if (id != fingers_[next_finger_to_fix]) { - setFinger(next_finger_to_fix, id); + if (id != fingers_[next_finger_to_fix_]) { + setFinger(next_finger_to_fix_, id); printFingerTable(); } - next_finger_to_fix = (next_finger_to_fix + 1) % nb_bits; + next_finger_to_fix_ = (next_finger_to_fix_ + 1) % nb_bits_; } } @@ -190,8 +197,8 @@ void Node::printFingerTable() if (XBT_LOG_ISENABLED(s4u_chord, xbt_log_priority_verbose)) { XBT_VERB("My finger table:"); XBT_VERB("Start | Succ"); - for (int i = 0; i < nb_bits; i++) { - XBT_VERB(" %3u | %3d", (id_ + (1U << i)) % nb_keys, fingers_[i]); + for (int i = 0; i < nb_bits_; i++) { + XBT_VERB(" %3u | %3d", (id_ + (1U << i)) % nb_keys_, fingers_[i]); } XBT_VERB("Predecessor: %d", pred_id_); @@ -214,7 +221,7 @@ void Node::checkPredecessor() XBT_DEBUG("Sending a 'Predecessor Alive' request to my predecessor %d", pred_id_); try { - mailbox->put(message, 10, timeout); + mailbox->put(message, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Failed to send the 'Predecessor Alive' request to %d", pred_id_); delete message; @@ -228,7 +235,7 @@ void Node::checkPredecessor() sg4::CommPtr comm = return_mailbox->get_async(&answer); try { - comm->wait_for(timeout); + comm->wait_for(timeout_); XBT_DEBUG("Received the answer to my 'Predecessor Alive': my predecessor %d is alive", pred_id_); delete answer; } catch (const simgrid::TimeoutException&) { @@ -255,7 +262,7 @@ int Node::remoteGetPredecessor(int ask_to) // send a "Get Predecessor" request to ask_to_id XBT_DEBUG("Sending a 'Get Predecessor' request to %d", ask_to); try { - mailbox->put(message, 10, timeout); + mailbox->put(message, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Failed to send the 'Get Predecessor' request to %d", ask_to); delete message; @@ -269,7 +276,7 @@ int Node::remoteGetPredecessor(int ask_to) sg4::CommPtr comm = return_mailbox->get_async(&answer); try { - comm->wait_for(timeout); + comm->wait_for(timeout_); XBT_DEBUG("Received the answer to my 'Get Predecessor' request: the predecessor of node %d is %d", ask_to, answer->answer_id); predecessor_id = answer->answer_id; @@ -289,7 +296,7 @@ int Node::remoteGetPredecessor(int ask_to) */ int Node::closestPrecedingFinger(int id) { - for (int i = nb_bits - 1; i >= 0; i--) { + for (int i = nb_bits_ - 1; i >= 0; i--) { if (is_in_interval(fingers_[i], id_ + 1, id - 1)) { return fingers_[i]; } @@ -326,7 +333,7 @@ int Node::remoteFindSuccessor(int ask_to, int id) // send a "Find Successor" request to ask_to_id XBT_DEBUG("Sending a 'Find Successor' request to %d for id %d", ask_to, id); try { - mailbox->put(message, 10, timeout); + mailbox->put(message, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Failed to send the 'Find Successor' request to %d for id %d", ask_to, id_); delete message; @@ -338,7 +345,7 @@ int Node::remoteFindSuccessor(int ask_to, int id) sg4::CommPtr comm = return_mailbox->get_async(&answer); try { - comm->wait_for(timeout); + comm->wait_for(timeout_); XBT_DEBUG("Received the answer to my 'Find Successor' request for id %d: the successor of key %d is %d", answer->request_id, id_, answer->answer_id); successor = answer->answer_id; @@ -483,12 +490,12 @@ void Node::operator()() if (known_id_ == -1) { setPredecessor(-1); // -1 means that I have no predecessor printFingerTable(); - joined = true; + joined_ = true; } else { join(known_id_); } - if (not joined) + if (not joined_) return; ChordMessage* message = nullptr; double now = sg4::Engine::get_clock(); diff --git a/examples/cpp/dht-chord/s4u-dht-chord.cpp b/examples/cpp/dht-chord/s4u-dht-chord.cpp index 0e15152b91..08934aafaf 100644 --- a/examples/cpp/dht-chord/s4u-dht-chord.cpp +++ b/examples/cpp/dht-chord/s4u-dht-chord.cpp @@ -7,10 +7,6 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_chord, "Messages specific for this s4u example"); -int nb_bits = 24; -int nb_keys = 0; -int timeout = 50; - int main(int argc, char* argv[]) { simgrid::s4u::Engine e(&argc, argv); @@ -20,6 +16,8 @@ int main(int argc, char* argv[]) argv[0], argv[0]); std::string platform_file(argv[argc - 2]); std::string deployment_file(argv[argc - 1]); + int nb_bits = 24; + int timeout = 50; for (const auto& option : std::vector(argv + 1, argv + argc - 2)) { if (option.rfind("-nb_bits=", 0) == 0) { nb_bits = std::stoi(option.substr(option.find('=') + 1)); @@ -31,12 +29,13 @@ int main(int argc, char* argv[]) xbt_die("Invalid chord option '%s'", option.c_str()); } } + int nb_keys = 1U << nb_bits; + XBT_DEBUG("Sets nb_keys to %d", nb_keys); e.load_platform(platform_file); /* Global initialization of the Chord simulation. */ - nb_keys = 1U << nb_bits; - XBT_DEBUG("Sets nb_keys to %d", nb_keys); + Node::set_parameters(nb_bits, nb_keys, timeout); e.register_actor("node"); e.load_deployment(deployment_file); diff --git a/examples/cpp/dht-chord/s4u-dht-chord.hpp b/examples/cpp/dht-chord/s4u-dht-chord.hpp index 6566ff770e..ab93cbff06 100644 --- a/examples/cpp/dht-chord/s4u-dht-chord.hpp +++ b/examples/cpp/dht-chord/s4u-dht-chord.hpp @@ -18,10 +18,6 @@ constexpr double PERIODIC_CHECK_PREDECESSOR_DELAY = 120; constexpr double PERIODIC_LOOKUP_DELAY = 10; constexpr double SLEEP_DELAY = 4.9999; -extern int nb_bits; -extern int nb_keys; -extern int timeout; - /* Types of tasks exchanged between nodes. */ enum class MessageType { FIND_SUCCESSOR, @@ -50,18 +46,26 @@ public: }; class Node { + inline static int nb_bits_; + inline static int nb_keys_; + inline static int timeout_; + int known_id_ = -1; double start_time_ = -1; double deadline_ = -1; - bool joined = false; + bool joined_ = false; int id_; // my id int pred_id_ = -1; // predecessor id - simgrid::xbt::random::XbtRandom random; // random number generator for this node - sg4::Mailbox* mailbox_; // my mailbox + simgrid::xbt::random::XbtRandom random_; // random number generator for this node + sg4::Mailbox* mailbox_; // my mailbox std::vector fingers_; // finger table,(fingers[0] is my successor) - int next_finger_to_fix; // index of the next finger to fix in fix_fingers() + int next_finger_to_fix_; // index of the next finger to fix in fix_fingers() + + static bool is_in_interval(int id, int start, int end); public: + static void set_parameters(int nb_bits, int nb_keys, int timeout); + explicit Node(std::vector args); Node(const Node&) = delete; Node& operator=(const Node&) = delete; diff --git a/examples/cpp/exec-dependent/s4u-exec-dependent.cpp b/examples/cpp/exec-dependent/s4u-exec-dependent.cpp index 3353d5af67..a62cfd0f43 100644 --- a/examples/cpp/exec-dependent/s4u-exec-dependent.cpp +++ b/examples/cpp/exec-dependent/s4u-exec-dependent.cpp @@ -37,8 +37,7 @@ static void worker() // Start the activities. first_parent->start(); second_parent->start(); - // child uses a vetoable start to force it to wait for the completion of its predecessors - child->vetoable_start(); + child->start(); // wait for the completion of all activities while (not pending_execs.empty()) { diff --git a/examples/cpp/exec-dependent/s4u-exec-dependent.tesh b/examples/cpp/exec-dependent/s4u-exec-dependent.tesh index a376e10d03..5c504006d2 100644 --- a/examples/cpp/exec-dependent/s4u-exec-dependent.tesh +++ b/examples/cpp/exec-dependent/s4u-exec-dependent.tesh @@ -1,6 +1,8 @@ #!/usr/bin/env tesh $ ${bindir:=.}/s4u-exec-dependent ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +> [ 0.000000] (1:worker@Fafard) 'parent 1' is assigned to a resource and all dependencies are solved. Let's start +> [ 0.000000] (1:worker@Fafard) 'parent 2' is assigned to a resource and all dependencies are solved. Let's start > [ 0.000000] (1:worker@Fafard) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned > [ 2.000000] (1:worker@Fafard) Remove a dependency from 'parent 1' on 'child' > [ 2.000000] (1:worker@Fafard) Exec 'parent 1' is complete diff --git a/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp b/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp index db0387c835..054f81da8f 100644 --- a/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp +++ b/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp @@ -15,7 +15,7 @@ static void worker() double computation_amount = sg4::this_actor::get_host()->get_speed(); // Create an unassigned activity and start it. It will not actually start, because it's not assigned to any host yet - sg4::ExecPtr exec = sg4::Exec::init()->set_flops_amount(computation_amount)->set_name("exec")->vetoable_start(); + sg4::ExecPtr exec = sg4::Exec::init()->set_flops_amount(computation_amount)->set_name("exec")->start(); // Wait for a while sg4::this_actor::sleep_for(10); diff --git a/examples/cpp/io-dependent/s4u-io-dependent.cpp b/examples/cpp/io-dependent/s4u-io-dependent.cpp index be5e54d29f..8788e10753 100644 --- a/examples/cpp/io-dependent/s4u-io-dependent.cpp +++ b/examples/cpp/io-dependent/s4u-io-dependent.cpp @@ -39,9 +39,9 @@ static void test() // Start the activities. bob_compute->start(); - bob_write->vetoable_start(); - carl_read->vetoable_start(); - carl_compute->vetoable_start(); + bob_write->start(); + carl_read->start(); + carl_compute->start(); // wait for the completion of all activities while (not pending_activities.empty()) { diff --git a/examples/cpp/io-dependent/s4u-io-dependent.tesh b/examples/cpp/io-dependent/s4u-io-dependent.tesh index b44775f299..8feb8524d2 100644 --- a/examples/cpp/io-dependent/s4u-io-dependent.tesh +++ b/examples/cpp/io-dependent/s4u-io-dependent.tesh @@ -2,6 +2,7 @@ ! output sort $ ${bindir:=.}/s4u-io-dependent ${platfdir}/hosts_with_disks.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +> [ 0.000000] (1:bob@bob) 'bob compute' is assigned to a resource and all dependencies are solved. Let's start > [ 1.000000] (1:bob@bob) 'bob write' is assigned to a resource and all dependencies are solved. Let's start > [ 1.000000] (1:bob@bob) Remove a dependency from 'bob compute' on 'bob write' > [ 1.000000] (1:bob@bob) Activity 'bob compute' is complete diff --git a/examples/cpp/network-ns3/s4u-network-ns3.cpp b/examples/cpp/network-ns3/s4u-network-ns3.cpp index ebc50c3f09..a8a7f9db66 100644 --- a/examples/cpp/network-ns3/s4u-network-ns3.cpp +++ b/examples/cpp/network-ns3/s4u-network-ns3.cpp @@ -10,11 +10,18 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example"); namespace sg4 = simgrid::s4u; -double start_time; -std::unordered_map workernames; -std::unordered_map masternames; - -static void master(std::vector args) +struct MasterWorkerNames { + std::string master; + std::string worker; +}; +using MasterWorkerNamesMap = std::unordered_map; + +struct Payload { + double msg_size; + double start_time; +}; + +static void master(MasterWorkerNamesMap& names, const std::vector& args) { xbt_assert(args.size() == 4, "Strange number of arguments expected 3 got %zu", args.size() - 1); @@ -24,23 +31,18 @@ static void master(std::vector args) double msg_size = std::stod(args[1]); int id = std::stoi(args[3]); // unique id to control statistics - /* worker name */ - workernames[id] = args[2]; + /* master and worker names */ + names.emplace(id, MasterWorkerNames{sg4::Host::current()->get_name(), args[2]}); sg4::Mailbox* mbox = sg4::Mailbox::by_name(args[3]); - masternames[id] = sg4::Host::current()->get_name(); - - auto* payload = new double(msg_size); - - /* time measurement */ - start_time = sg4::Engine::get_clock(); + auto* payload = new Payload{msg_size, sg4::Engine::get_clock()}; mbox->put(payload, static_cast(msg_size)); XBT_DEBUG("Finished"); } -static void worker(std::vector args) +static void worker(const MasterWorkerNamesMap& names, const std::vector& args) { xbt_assert(args.size() == 2, "Strange number of arguments expected 1 got %zu", args.size() - 1); @@ -49,12 +51,12 @@ static void worker(std::vector args) XBT_DEBUG("Worker started"); - auto payload = mbox->get_unique(); + auto payload = mbox->get_unique(); - double elapsed_time = sg4::Engine::get_clock() - start_time; + double elapsed_time = sg4::Engine::get_clock() - payload->start_time; - XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s", id, *payload, masternames.at(id).c_str(), - workernames.at(id).c_str()); + XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s", id, payload->msg_size, names.at(id).master.c_str(), + names.at(id).worker.c_str()); XBT_DEBUG("FLOW[%d] : transferred in %f seconds", id, elapsed_time); XBT_DEBUG("Finished"); @@ -70,8 +72,9 @@ int main(int argc, char* argv[]) e.load_platform(argv[1]); - e.register_function("master", master); - e.register_function("worker", worker); + MasterWorkerNamesMap master_worker_names; + e.register_function("master", [&master_worker_names](auto args) { master(master_worker_names, args); }); + e.register_function("worker", [&master_worker_names](auto args) { worker(master_worker_names, args); }); e.load_deployment(argv[2]); diff --git a/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp b/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp index f07bfa4707..0edd2ab68d 100644 --- a/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp +++ b/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp @@ -9,15 +9,11 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category"); namespace sg4 = simgrid::s4u; -sg4::MutexPtr mtx = nullptr; -sg4::ConditionVariablePtr cv = nullptr; -bool ready = false; - -static void competitor(int id) +static void competitor(int id, sg4::ConditionVariablePtr cv, sg4::MutexPtr mtx, std::shared_ptr ready) { XBT_INFO("Entering the race..."); std::unique_lock lck(*mtx); - while (not ready) { + while (not *ready) { auto now = sg4::Engine::get_clock(); if (cv->wait_until(lck, now + (id+1)*0.25) == std::cv_status::timeout) { XBT_INFO("Out of wait_until (timeout)"); @@ -29,25 +25,26 @@ static void competitor(int id) XBT_INFO("Running!"); } -static void go() +static void go(sg4::ConditionVariablePtr cv, sg4::MutexPtr mtx, std::shared_ptr ready) { XBT_INFO("Are you ready? ..."); sg4::this_actor::sleep_for(3); std::unique_lock lck(*mtx); XBT_INFO("Go go go!"); - ready = true; + *ready = true; cv->notify_all(); } static void main_actor() { - mtx = sg4::Mutex::create(); - cv = sg4::ConditionVariable::create(); + auto mtx = sg4::Mutex::create(); + auto cv = sg4::ConditionVariable::create(); + auto ready = std::make_shared(false); auto host = sg4::this_actor::get_host(); for (int i = 0; i < 10; ++i) - sg4::Actor::create("competitor", host, competitor, i); - sg4::Actor::create("go", host, go); + sg4::Actor::create("competitor", host, competitor, i, cv, mtx, ready); + sg4::Actor::create("go", host, go, cv, mtx, ready); } int main(int argc, char* argv[]) diff --git a/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp b/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp index a5b0b444de..cf1a1db372 100644 --- a/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp +++ b/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp @@ -9,10 +9,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category"); namespace sg4 = simgrid::s4u; -std::string data; -bool done = false; - -static void worker_fun(sg4::ConditionVariablePtr cv, sg4::MutexPtr mutex) +static void worker_fun(sg4::ConditionVariablePtr cv, sg4::MutexPtr mutex, std::string& data, bool& done) { std::unique_lock lock(*mutex); @@ -30,11 +27,14 @@ static void master_fun() { auto mutex = sg4::Mutex::create(); auto cv = sg4::ConditionVariable::create(); - data = "Example data"; - auto worker = sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker_fun, cv, mutex); + std::string data = "Example data"; + bool done = false; + + auto worker = sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker_fun, cv, mutex, std::ref(data), + std::ref(done)); // wait for the worker - cv->wait(std::unique_lock(*mutex), []() { return done; }); + cv->wait(std::unique_lock(*mutex), [&done]() { return done; }); XBT_INFO("data is now '%s'.", data.c_str()); worker->join(); diff --git a/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh b/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh index 2469cc31a9..2db23f3b98 100644 --- a/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh +++ b/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh @@ -5,219 +5,219 @@ p This file tests the dependencies between MUTEX transitions $ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [App ] Configuration change: Set 'actors' to '1' > [Checker] Start a DFS exploration. Reduction is: dpor. -> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner:1) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 5, state: 5, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 6, 0 interleaves) +> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 2, state: 2, 0 interleaves) +> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 3, state: 3, 0 interleaves) +> [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 4, state: 4, 0 interleaves) +> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 5, state: 5, 0 interleaves) +> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 6, 0 interleaves) > [Checker] Execution came to an end at 1;1;1;2;2;2;0 (state: 7, depth: 7) > [Checker] Backtracking from 1;1;1;2;2;2;0 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=4) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] 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] MUTEX_WAIT(mutex: 0, owner: 1) (state=2) +> [Checker] 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] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (stack depth: 2, state: 8, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 3, state: 9, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:1) (stack depth: 4, state: 10, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 5, state: 11, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 12, 0 interleaves) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) +> [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 2, state: 8, 0 interleaves) +> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 3, state: 9, 0 interleaves) +> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner: 1) (stack depth: 4, state: 10, 0 interleaves) +> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 5, state: 11, 0 interleaves) +> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 12, 0 interleaves) > [Checker] Execution came to an end at 2;1;2;2;1;1;0 (state: 13, depth: 7) > [Checker] Backtracking from 2;1;2;2;1;1;0 > [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=10) -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=11) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: 1) (state=10) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 1) (state=11) > [Checker] Backtracking from 2;1;2;2 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=8) -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=9) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=8) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 2) (state=9) > [Checker] Dependent Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=8) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=8) > [Checker] DFS exploration ended. 13 unique states visited; 3 backtracks (18 transition replays, 3 states visited overall) $ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [App ] Configuration change: Set 'actors' to '2' > [Checker] Start a DFS exploration. Reduction is: dpor. -> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner:1) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 5, state: 5, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 6, 0 interleaves) -> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (stack depth: 7, state: 7, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 8, state: 8, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 9, state: 9, 0 interleaves) -> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (stack depth: 10, state: 10, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 11, state: 11, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 12, 0 interleaves) +> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 2, state: 2, 0 interleaves) +> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 3, state: 3, 0 interleaves) +> [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 4, state: 4, 0 interleaves) +> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 5, state: 5, 0 interleaves) +> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 6, 0 interleaves) +> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (stack depth: 7, state: 7, 0 interleaves) +> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner: 3) (stack depth: 8, state: 8, 0 interleaves) +> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner: -1) (stack depth: 9, state: 9, 0 interleaves) +> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (stack depth: 10, state: 10, 0 interleaves) +> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner: 4) (stack depth: 11, state: 11, 0 interleaves) +> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner: -1) (stack depth: 12, state: 12, 0 interleaves) > [Checker] Execution came to an end at 1;1;1;2;2;2;3;3;3;4;4;4;0 (state: 13, depth: 13) > [Checker] Backtracking from 1;1;1;2;2;2;3;3;3;4;4;4;0 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:-1) (state=9) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=10) +> [Checker] MUTEX_UNLOCK(mutex: 1, owner: -1) (state=9) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=10) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=8) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=10) +> [Checker] MUTEX_WAIT(mutex: 1, owner: 3) (state=8) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=10) > [Checker] Dependent Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=10) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=10) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=6) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=6) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=5) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 2) (state=5) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=2) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 1) (state=2) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:1) (state=1) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (stack depth: 7, state: 7, 0 interleaves) -> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (stack depth: 8, state: 14, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 9, state: 15, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:3) (stack depth: 10, state: 16, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 11, state: 17, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 18, 0 interleaves) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=7) +> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (stack depth: 7, state: 7, 0 interleaves) +> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (stack depth: 8, state: 14, 0 interleaves) +> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner: 4) (stack depth: 9, state: 15, 0 interleaves) +> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner: 3) (stack depth: 10, state: 16, 0 interleaves) +> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner: 3) (stack depth: 11, state: 17, 0 interleaves) +> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner: -1) (stack depth: 12, state: 18, 0 interleaves) > [Checker] Execution came to an end at 1;1;1;2;2;2;4;3;4;4;3;3;0 (state: 19, depth: 13) > [Checker] Backtracking from 1;1;1;2;2;2;4;3;4;4;3;3;0 > [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:3) (state=16) -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=17) +> [Checker] MUTEX_UNLOCK(mutex: 1, owner: 3) (state=16) +> [Checker] MUTEX_WAIT(mutex: 1, owner: 3) (state=17) > [Checker] Backtracking from 1;1;1;2;2;2;4;3;4;4 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=14) -> [Checker] MUTEX_WAIT(mutex: 1, owner:4) (state=15) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=14) +> [Checker] MUTEX_WAIT(mutex: 1, owner: 4) (state=15) > [Checker] Dependent Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=14) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=14) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=6) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=6) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=5) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 2) (state=5) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=2) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 1) (state=2) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:1) (state=1) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=7) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=7) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=4) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] 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] MUTEX_WAIT(mutex: 0, owner: 1) (state=2) +> [Checker] 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] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (stack depth: 2, state: 20, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 3, state: 21, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:1) (stack depth: 4, state: 22, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 5, state: 23, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 24, 0 interleaves) -> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (stack depth: 7, state: 25, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 8, state: 26, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 9, state: 27, 0 interleaves) -> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (stack depth: 10, state: 28, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 11, state: 29, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 30, 0 interleaves) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) +> [Checker] Execute 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Execute 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 2, state: 20, 0 interleaves) +> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 3, state: 21, 0 interleaves) +> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner: 1) (stack depth: 4, state: 22, 0 interleaves) +> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 5, state: 23, 0 interleaves) +> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 24, 0 interleaves) +> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (stack depth: 7, state: 25, 0 interleaves) +> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner: 3) (stack depth: 8, state: 26, 0 interleaves) +> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner: -1) (stack depth: 9, state: 27, 0 interleaves) +> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (stack depth: 10, state: 28, 0 interleaves) +> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner: 4) (stack depth: 11, state: 29, 0 interleaves) +> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner: -1) (stack depth: 12, state: 30, 0 interleaves) > [Checker] Execution came to an end at 2;1;2;2;1;1;3;3;3;4;4;4;0 (state: 31, depth: 13) > [Checker] Backtracking from 2;1;2;2;1;1;3;3;3;4;4;4;0 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:-1) (state=27) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=28) +> [Checker] MUTEX_UNLOCK(mutex: 1, owner: -1) (state=27) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=28) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=26) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=28) +> [Checker] MUTEX_WAIT(mutex: 1, owner: 3) (state=26) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=28) > [Checker] Dependent Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=28) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=28) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=24) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=24) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=23) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 1) (state=23) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=22) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: 1) (state=22) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=21) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 2) (state=21) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=20) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (stack depth: 7, state: 25, 0 interleaves) -> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (stack depth: 8, state: 32, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 9, state: 33, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:3) (stack depth: 10, state: 34, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 11, state: 35, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 36, 0 interleaves) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) (state=25) +> [Checker] Execute 4: MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (stack depth: 7, state: 25, 0 interleaves) +> [Checker] Execute 3: MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (stack depth: 8, state: 32, 0 interleaves) +> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner: 4) (stack depth: 9, state: 33, 0 interleaves) +> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner: 3) (stack depth: 10, state: 34, 0 interleaves) +> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner: 3) (stack depth: 11, state: 35, 0 interleaves) +> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner: -1) (stack depth: 12, state: 36, 0 interleaves) > [Checker] Execution came to an end at 2;1;2;2;1;1;4;3;4;4;3;3;0 (state: 37, depth: 13) > [Checker] Backtracking from 2;1;2;2;1;1;4;3;4;4;3;3;0 > [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:3) (state=34) -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=35) +> [Checker] MUTEX_UNLOCK(mutex: 1, owner: 3) (state=34) +> [Checker] MUTEX_WAIT(mutex: 1, owner: 3) (state=35) > [Checker] Backtracking from 2;1;2;2;1;1;4;3;4;4 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=32) -> [Checker] MUTEX_WAIT(mutex: 1, owner:4) (state=33) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=32) +> [Checker] MUTEX_WAIT(mutex: 1, owner: 4) (state=33) > [Checker] Dependent Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=32) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=32) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=24) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: -1) (state=24) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=23) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 1) (state=23) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=22) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: 1) (state=22) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=21) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 2) (state=21) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=20) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner:4) (state=25) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 1, owner: 4) (state=25) > [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=22) -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=23) +> [Checker] MUTEX_UNLOCK(mutex: 0, owner: 1) (state=22) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 1) (state=23) > [Checker] Backtracking from 2;1;2;2 > [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=21) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=20) +> [Checker] MUTEX_WAIT(mutex: 0, owner: 2) (state=21) > [Checker] Dependent Transitions: -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner:2) (state=20) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1) +> [Checker] MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=20) > [Checker] DFS exploration ended. 37 unique states visited; 7 backtracks (76 transition replays, 33 states visited overall) $ ${bindir:=.}/../../../bin/simgrid-mc -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:3 --log=s4u_test.thres:critical diff --git a/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp b/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp index 0f512f067c..4040407811 100644 --- a/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp +++ b/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp @@ -14,22 +14,19 @@ namespace sg4 = simgrid::s4u; XBT_LOG_NEW_DEFAULT_CATEGORY(sem_test, "Simple test of the semaphore"); -const char* buffer; /* Where the data is exchanged */ -sg4::SemaphorePtr sem_empty = sg4::Semaphore::create(1); /* indicates whether the buffer is empty */ -sg4::SemaphorePtr sem_full = sg4::Semaphore::create(0); /* indicates whether the buffer is full */ - -static void producer(const std::vector& args) +static void producer(std::string& buffer, sg4::SemaphorePtr sem_empty, sg4::SemaphorePtr sem_full, + const std::vector& args) { for (auto const& str : args) { sem_empty->acquire(); XBT_INFO("Pushing '%s'", str.c_str()); - buffer = str.c_str(); + buffer = str; sem_full->release(); } XBT_INFO("Bye!"); } -static void consumer() +static void consumer(const std::string& buffer, sg4::SemaphorePtr sem_empty, sg4::SemaphorePtr sem_full) { std::string str; do { @@ -47,8 +44,14 @@ int main(int argc, char **argv) std::vector args({"one", "two", "three", ""}); sg4::Engine e(&argc, argv); e.load_platform(argc > 1 ? argv[1] : "../../platforms/two_hosts.xml"); - sg4::Actor::create("producer", e.host_by_name("Tremblay"), producer, std::cref(args)); - sg4::Actor::create("consumer", e.host_by_name("Jupiter"), consumer); + + std::string buffer; /* Where the data is exchanged */ + auto sem_empty = sg4::Semaphore::create(1); /* indicates whether the buffer is empty */ + auto sem_full = sg4::Semaphore::create(0); /* indicates whether the buffer is full */ + + sg4::Actor::create("producer", e.host_by_name("Tremblay"), producer, std::ref(buffer), sem_empty, sem_full, + std::cref(args)); + sg4::Actor::create("consumer", e.host_by_name("Jupiter"), consumer, std::cref(buffer), sem_empty, sem_full); e.run(); return 0; diff --git a/examples/smpi/replay/replay.cpp b/examples/smpi/replay/replay.cpp index 3b62cab434..d6fff83e77 100644 --- a/examples/smpi/replay/replay.cpp +++ b/examples/smpi/replay/replay.cpp @@ -20,12 +20,6 @@ static void action_blah(const simgrid::xbt::ReplayAction& /*args*/) args is a strings array containing the blank-separated parameters found in the trace for this event instance. */ } -action_fun previous_send; -static void overriding_send(simgrid::xbt::ReplayAction& args) -{ - previous_send(args); // Just call the overridden symbol. That's a toy example. -} - int main(int argc, char* argv[]) { auto properties = simgrid::s4u::Actor::self()->get_properties(); @@ -47,14 +41,17 @@ int main(int argc, char* argv[]) /* Connect your callback function to the "blah" event in the trace files */ xbt_replay_action_register("blah", action_blah); - /* The send action is an override, so we have to first save its previous value in a global */ + /* The send action is an override, so we could have saved its previous value in a global, or use a lambda capture like + * in the following */ int new_rank; MPI_Comm_rank(MPI_COMM_WORLD, &new_rank); if (new_rank != rank) XBT_WARN("Rank inconsistency. Got %d, expected %d", new_rank, rank); if (rank == 0) { - previous_send = xbt_replay_action_get("send"); - xbt_replay_action_register("send", overriding_send); + auto previous_send = xbt_replay_action_get("send"); + xbt_replay_action_register("send", [previous_send](simgrid::xbt::ReplayAction& args) { + previous_send(args); // Just call the overridden symbol. That's a toy example. + }); } /* The regular run of the replayer */ if (shared_trace != nullptr) diff --git a/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp b/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp index 0b1edf1f9d..7707303610 100644 --- a/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp +++ b/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp @@ -44,10 +44,6 @@ struct Job { int unique_job_number; //!< The job unique number in [0, n[. }; -// ugly globals to avoid creating structures for giving args to processes -static std::vector hosts; -static int noise_between_jobs; - static void smpi_replay_process(Job* job, simgrid::s4u::BarrierPtr barrier, int rank) { XBT_INFO("Replaying rank %d of job %d (smpi_app '%s')", rank, job->unique_job_number, job->smpi_app_name.c_str()); @@ -75,7 +71,7 @@ static void pop_some_processes(int nb_processes, simgrid::s4u::Host* host) } } -static int job_executor_process(Job* job) +static int job_executor_process(const std::vector& hosts, Job* job) { XBT_INFO("Executing job %d (smpi_app '%s')", job->unique_job_number, job->smpi_app_name.c_str()); @@ -96,7 +92,8 @@ static int job_executor_process(Job* job) } // Executes a workload of SMPI processes -static int workload_executor_process(const std::vector>& workload) +static int workload_executor_process(const std::vector& hosts, + const std::vector>& workload, int noise_between_jobs) { for (auto const& job : workload) { // Let's wait until the job's waiting time if needed @@ -117,7 +114,8 @@ static int workload_executor_process(const std::vector>& wo // Let's finally run the job executor char* str_pname = bprintf("job_%04d", job->unique_job_number); XBT_INFO("Launching the job executor of job %d (app '%s')", job->unique_job_number, job->smpi_app_name.c_str()); - simgrid::s4u::Actor::create(str_pname, hosts[job->allocation[0]], job_executor_process, job.get()); + simgrid::s4u::Actor::create(str_pname, hosts[job->allocation[0]], job_executor_process, std::cref(hosts), + job.get()); xbt_free(str_pname); } @@ -210,7 +208,7 @@ int main(int argc, char* argv[]) // Simulation setting simgrid::s4u::Engine e(&argc, argv); e.load_platform(argv[1]); - hosts = e.get_all_hosts(); + const auto hosts = e.get_all_hosts(); xbt_assert(hosts.size() >= 4, "The given platform should contain at least 4 hosts (found %zu).", hosts.size()); // Let's retrieve all SMPI jobs @@ -226,7 +224,7 @@ int main(int argc, char* argv[]) int initial_noise = std::stoi(argv[3]); xbt_assert(initial_noise >= 0, "Invalid initial_noise argument"); - noise_between_jobs = std::stoi(argv[4]); + int noise_between_jobs = std::stoi(argv[4]); xbt_assert(noise_between_jobs >= 0, "Invalid noise_between_jobs argument"); if (initial_noise > 0) { @@ -235,7 +233,8 @@ int main(int argc, char* argv[]) } // Let's execute the workload - simgrid::s4u::Actor::create("workload", hosts[0], workload_executor_process, std::cref(jobs)); + simgrid::s4u::Actor::create("workload", hosts[0], workload_executor_process, std::cref(hosts), std::cref(jobs), + noise_between_jobs); e.run(); XBT_INFO("Simulation finished! Final time: %g", simgrid::s4u::Engine::get_clock()); diff --git a/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh b/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh index 8070caa6a8..72324f2a60 100644 --- a/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh +++ b/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh @@ -18,14 +18,14 @@ $ ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir > [0.000000] [ker_engine/INFO] 3 actors are still running, waiting for something. > [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor (@): " > [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2) -> [0.000000] [ker_engine/INFO] Actor 2 (0:1@Lilibeth) simcall MUTEX_WAIT(mutex_id: 1owner:3) -> [0.000000] [ker_engine/INFO] Actor 3 (0:2@Lilibeth) simcall MUTEX_WAIT(mutex_id: 0owner:2) +> [0.000000] [ker_engine/INFO] Actor 2 (0:1@Lilibeth) simcall MUTEX_WAIT(mutex_id:1 owner:3) +> [0.000000] [ker_engine/INFO] Actor 3 (0:2@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2) > [0.000000] [mc_global/INFO] Counter-example execution trace: -> [0.000000] [mc_global/INFO] 2: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) -> [0.000000] [mc_global/INFO] 2: MUTEX_WAIT(mutex: 0, owner:2) -> [0.000000] [mc_global/INFO] 3: MUTEX_ASYNC_LOCK(mutex: 1, owner:3) -> [0.000000] [mc_global/INFO] 2: MUTEX_ASYNC_LOCK(mutex: 1, owner:3) -> [0.000000] [mc_global/INFO] 3: MUTEX_WAIT(mutex: 1, owner:3) -> [0.000000] [mc_global/INFO] 3: MUTEX_ASYNC_LOCK(mutex: 0, owner:2) +> [0.000000] [mc_global/INFO] 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) +> [0.000000] [mc_global/INFO] 2: MUTEX_WAIT(mutex: 0, owner: 2) +> [0.000000] [mc_global/INFO] 3: MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) +> [0.000000] [mc_global/INFO] 2: MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) +> [0.000000] [mc_global/INFO] 3: MUTEX_WAIT(mutex: 1, owner: 3) +> [0.000000] [mc_global/INFO] 3: 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;3' > [0.000000] [mc_dfs/INFO] DFS exploration ended. 19 unique states visited; 2 backtracks (22 transition replays, 2 states visited overall) diff --git a/include/simgrid/plugins/ProducerConsumer.hpp b/include/simgrid/plugins/ProducerConsumer.hpp index c45563fa37..1ecaa1e6b1 100644 --- a/include/simgrid/plugins/ProducerConsumer.hpp +++ b/include/simgrid/plugins/ProducerConsumer.hpp @@ -28,9 +28,16 @@ namespace plugin { template class ProducerConsumer; template using ProducerConsumerPtr = boost::intrusive_ptr>; -XBT_PUBLIC_DATA unsigned long pc_id; +class ProducerConsumerId { +private: + static unsigned long pc_id; + +protected: + const std::string id = "ProducerConsumer" + std::to_string(pc_id); + ProducerConsumerId() { ++pc_id; } +}; -template class ProducerConsumer { +template class ProducerConsumer : public ProducerConsumerId { public: /** This ProducerConsumer plugin can use two different transfer modes: * - TransferMode::MAILBOX: this mode induces a s4u::Comm between the actors doing the calls to put() and get(). @@ -45,8 +52,6 @@ public: enum class TransferMode { MAILBOX = 0, QUEUE }; private: - std::string id; - /* Implementation of a Monitor to handle the data exchanges */ s4u::MutexPtr mutex_; s4u::ConditionVariablePtr can_put_; @@ -75,9 +80,6 @@ private: { xbt_assert(max_queue_size > 0, "Max queue size of 0 is not allowed"); - id = "ProducerConsumer" + std::to_string(pc_id); - pc_id++; - mutex_ = s4u::Mutex::create(); can_put_ = s4u::ConditionVariable::create(); can_get_ = s4u::ConditionVariable::create(); diff --git a/include/simgrid/plugins/file_system.h b/include/simgrid/plugins/file_system.h index af744b03b9..82632b4a25 100644 --- a/include/simgrid/plugins/file_system.h +++ b/include/simgrid/plugins/file_system.h @@ -139,6 +139,7 @@ public: class XBT_PUBLIC FileDescriptorHostExt { public: static simgrid::xbt::Extension EXTENSION_ID; + static int max_file_descriptors; FileDescriptorHostExt() = default; FileDescriptorHostExt(const FileDescriptorHostExt&) = delete; FileDescriptorHostExt& operator=(const FileDescriptorHostExt&) = delete; diff --git a/include/simgrid/s4u/Activity.hpp b/include/simgrid/s4u/Activity.hpp index c22a047d4e..0e0b72aabc 100644 --- a/include/simgrid/s4u/Activity.hpp +++ b/include/simgrid/s4u/Activity.hpp @@ -63,7 +63,7 @@ protected: XBT_CVERB(s4u_activity, "Remove a dependency from '%s' on '%s'", get_cname(), b->get_cname()); b->dependencies_.erase(this); if (b->dependencies_solved()) { - b->vetoable_start(); + b->start(); } successors_.pop_back(); } @@ -118,12 +118,16 @@ public: /*! Add a callback fired when the activity is resumed after being suspended */ static void on_resumed_cb(const std::function& cb) { on_resumed.connect(cb); } - void vetoable_start() + XBT_ATTRIB_DEPRECATED_v334("All start() are vetoable now. Please use start() ") void vetoable_start() + { + start(); + } + void start() { state_ = State::STARTING; if (dependencies_solved() && is_assigned()) { XBT_CVERB(s4u_activity, "'%s' is assigned to a resource and all dependencies are solved. Let's start", get_cname()); - start(); + do_start(); } else { if (vetoed_activities_ != nullptr) vetoed_activities_->insert(this); @@ -151,7 +155,7 @@ public: * * This function is optional: you can call wait() even if you didn't call start() */ - virtual Activity* start() = 0; + virtual Activity* do_start() = 0; /** Tests whether the given activity is terminated yet. */ virtual bool test(); /*! take a vector s4u::ActivityPtr and return the rank of the first finished one (or -1 if none is done). */ @@ -269,10 +273,13 @@ public: { return get_data(); } - - AnyActivity* vetoable_start() + XBT_ATTRIB_DEPRECATED_v334("All start() are vetoable now. Please use start() ") AnyActivity* vetoable_start() + { + return start(); + } + AnyActivity* start() { - Activity::vetoable_start(); + Activity::start(); return static_cast(this); } diff --git a/include/simgrid/s4u/Comm.hpp b/include/simgrid/s4u/Comm.hpp index ba67bc32e8..c5f441c1fc 100644 --- a/include/simgrid/s4u/Comm.hpp +++ b/include/simgrid/s4u/Comm.hpp @@ -37,6 +37,7 @@ class XBT_PUBLIC Comm : public Activity_T { std::function copy_data_function_; Comm() = default; + Comm* do_start() override; public: /* signals and related callbacks */ @@ -148,7 +149,6 @@ public: Actor* get_sender() const; /* Comm life cycle */ - Comm* start() override; /** Start the comm, and ignore its result. It can be completely forgotten after that. */ Comm* detach(); /** Start the comm, and ignore its result. It can be completely forgotten after that. */ diff --git a/include/simgrid/s4u/Engine.hpp b/include/simgrid/s4u/Engine.hpp index f2a3203660..94b0202dfc 100644 --- a/include/simgrid/s4u/Engine.hpp +++ b/include/simgrid/s4u/Engine.hpp @@ -57,8 +57,31 @@ public: static s4u::Engine* get_instance(int* argc, char** argv); static bool has_instance() { return instance_ != nullptr; } + /** + * Creates a new platform, including hosts, links, and the routing table. + * + * @beginrst + * See also: :ref:`platform`. + * @endrst + */ void load_platform(const std::string& platf) const; + /** + * @brief Seals the platform, finishing the creation of its resources. + * + * This method is optional. The seal() is done automatically when you call Engine::run. + */ void seal_platform() const; + /** @brief Get a debug output of the platform. + * + * It looks like a XML platform file, but it may be very different from the input platform file: All netzones are + * flatified into a unique zone. This representation is mostly useful to debug your platform configuration and ensure + * that your assumptions over your configuration hold. This enables you to verify the exact list of links traversed + * between any two hosts, and the characteristics of every host and link. But you should not use the resulting file as + * an input platform file: it is very verbose, and thus much less efficient (in parsing time and runtime performance) + * than a regular platform file with the sufficient amount of intermediary netzones. Even if you use one zone only, + * specialized zones (such as clusters) are more efficient than the one with fully explicit routing used here. + */ + std::string flatify_platform() const; /** @verbatim embed:rst:inline Bind an actor name that could be found in :ref:`pf_tag_actor` tag to a function taking classical argc/argv parameters. See the :ref:`example `. @endverbatim */ void register_function(const std::string& name, const std::function& code); diff --git a/include/simgrid/s4u/Exec.hpp b/include/simgrid/s4u/Exec.hpp index cec0812e75..cd514ea08e 100644 --- a/include/simgrid/s4u/Exec.hpp +++ b/include/simgrid/s4u/Exec.hpp @@ -39,6 +39,7 @@ class XBT_PUBLIC Exec : public Activity_T { protected: explicit Exec(kernel::activity::ExecImplPtr pimpl); + Exec* do_start() override; void reset() const; @@ -53,7 +54,6 @@ public: static void on_start_cb(const std::function& cb) { on_start.connect(cb); } static ExecPtr init(); - Exec* start() override; /*! take a vector of s4u::ExecPtr and return when one of them is finished. * The return value is the rank of the first finished ExecPtr. */ diff --git a/include/simgrid/s4u/Io.hpp b/include/simgrid/s4u/Io.hpp index fbec00b9d6..8c626f774c 100644 --- a/include/simgrid/s4u/Io.hpp +++ b/include/simgrid/s4u/Io.hpp @@ -29,6 +29,7 @@ class XBT_PUBLIC Io : public Activity_T { protected: explicit Io(kernel::activity::IoImplPtr pimpl); + Io* do_start() override; public: enum class OpType { READ, WRITE }; @@ -36,7 +37,6 @@ public: static void on_start_cb(const std::function& cb) { on_start.connect(cb); } static IoPtr init(); - Io* start() override; /*! take a vector of s4u::IoPtr and return when one of them is finished. * The return value is the rank of the first finished IoPtr. */ static ssize_t wait_any(const std::vector& ios) { return wait_any_for(ios, -1); } diff --git a/include/simgrid/s4u/Link.hpp b/include/simgrid/s4u/Link.hpp index b4cda596ad..2195c694dd 100644 --- a/include/simgrid/s4u/Link.hpp +++ b/include/simgrid/s4u/Link.hpp @@ -111,6 +111,7 @@ public: * @param limit Number of concurrent flows */ Link* set_concurrency_limit(int limit); + int get_concurrency_limit() const; /** @brief Set the level of communication speed of the given host on this wifi link. * diff --git a/include/simgrid/s4u/Mailbox.hpp b/include/simgrid/s4u/Mailbox.hpp index 3c910f6632..75201ecb39 100644 --- a/include/simgrid/s4u/Mailbox.hpp +++ b/include/simgrid/s4u/Mailbox.hpp @@ -134,7 +134,7 @@ public: template CommPtr Mailbox::get_async(T** data) { CommPtr res = get_init()->set_dst_data(reinterpret_cast(data), sizeof(void*)); - res->vetoable_start(); + res->start(); return res; } diff --git a/include/xbt/base.h b/include/xbt/base.h index 6f4c6b67bb..4a18d1adbf 100644 --- a/include/xbt/base.h +++ b/include/xbt/base.h @@ -64,12 +64,12 @@ # define XBT_ATTRIB_DESTRUCTOR(prio) __attribute__((__destructor__)) #endif -#ifndef XBT_ALWAYS_INLINE /* defined also in libsosp */ -# if defined(__GNUC__) -# define XBT_ALWAYS_INLINE inline __attribute__ ((always_inline)) -# else -# define XBT_ALWAYS_INLINE inline -# endif +#define XBT_ATTRIB_NOINLINE __attribute__((noinline)) + +#if defined(__GNUC__) +#define XBT_ALWAYS_INLINE inline __attribute__((always_inline)) +#else +#define XBT_ALWAYS_INLINE inline #endif /* Stringify argument. */ diff --git a/include/xbt/misc.h b/include/xbt/misc.h index 11d92d74d6..da34afa2fc 100644 --- a/include/xbt/misc.h +++ b/include/xbt/misc.h @@ -15,10 +15,10 @@ SG_BEGIN_DECL /** Cache the size of a memory page for the current system. */ -XBT_PUBLIC_DATA int xbt_pagesize; +XBT_PUBLIC_DATA const int xbt_pagesize; /** Cache the number of bits of addresses inside a given page, log2(xbt_pagesize). */ -XBT_PUBLIC_DATA int xbt_pagebits; +XBT_PUBLIC_DATA const int xbt_pagebits; /** Helps ensuring that header version (SIMGRID_VERSION_MAJOR and friends) and dynamic library version do match. */ XBT_PUBLIC void sg_version_check(int lib_version_major, int lib_version_minor, int lib_version_patch); diff --git a/include/xbt/signal.hpp b/include/xbt/signal.hpp index 42c043586f..8b6cf9164d 100644 --- a/include/xbt/signal.hpp +++ b/include/xbt/signal.hpp @@ -42,8 +42,6 @@ public: void disconnect(unsigned int id) { handlers_.erase(id); } /** Remove all callbacks */ void disconnect_slots() { handlers_.clear(); } - /** Get the amount of callbacks */ - int get_slot_count() { return handlers_.size(); } }; } } diff --git a/sonar-project.properties b/sonar-project.properties index 4e39656c1e..b5370402e1 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -189,5 +189,3 @@ sonar.python.version=3 #sonar.cfamily.gcov.reportsPath #sonar.python.coverage.reportPaths #sonar.cfamily.threads -#sonar.cfamily.cache.enabled -#sonar.cfamily.cache.path diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index d098b91b2e..ef00ea49ca 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -202,9 +202,9 @@ PYBIND11_MODULE(simgrid, m) .def("get_netzone_root", [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_netzone_root() is deprecated and will be dropped after v3.3, use netzone_root instead.", - 1); + PyErr_WarnEx( + PyExc_DeprecationWarning, + "get_netzone_root() is deprecated and will be dropped after v3.33, use netzone_root instead.", 1); return self.attr("netzone_root"); }) .def_property_readonly("netzone_root", &Engine::get_netzone_root, diff --git a/src/dag/loaders.cpp b/src/dag/loaders.cpp index d3c63aa082..de7b4687f8 100644 --- a/src/dag/loaders.cpp +++ b/src/dag/loaders.cpp @@ -33,7 +33,7 @@ static void uniq_transfer_task_name(simgrid::s4u::Comm* comm) std::string new_name = parent->get_name() + "_" + comm->get_name() + "_" + child->get_name(); - comm->set_name(new_name)->vetoable_start(); + comm->set_name(new_name)->start(); } static bool check_for_cycle(const std::vector& dag) @@ -92,12 +92,12 @@ std::vector create_DAG_from_DAX(const std::string& filename) dax_lineno = 1; auto root_task = Exec::init()->set_name("root")->set_flops_amount(0); - root_task->vetoable_start(); + root_task->start(); result.push_back(root_task); auto end_task = Exec::init()->set_name("end")->set_flops_amount(0); - end_task->vetoable_start(); + end_task->start(); xbt_assert(dax_lex() == 0, "Parse error in %s: %s", filename.c_str(), dax__parse_err_msg()); dax__delete_buffer(input_buffer); @@ -198,7 +198,7 @@ std::vector create_DAG_from_dot(const std::string& filename) if (activities.find(name) == activities.end()) { XBT_DEBUG("See ", name.c_str(), amount); - act = Exec::init()->set_name(name)->set_flops_amount(amount)->vetoable_start(); + act = Exec::init()->set_name(name)->set_flops_amount(amount)->start(); activities.try_emplace(name, act); if (name != "root" && name != "end") dag.push_back(act); @@ -208,12 +208,12 @@ std::vector create_DAG_from_dot(const std::string& filename) } /*Check if 'root' and 'end' nodes have been explicitly declared. If not, create them. */ if (activities.find("root") == activities.end()) - root = Exec::init()->set_name("root")->set_flops_amount(0)->vetoable_start(); + root = Exec::init()->set_name("root")->set_flops_amount(0)->start(); else root = activities.at("root"); if (activities.find("end") == activities.end()) - end = Exec::init()->set_name("end")->set_flops_amount(0)->vetoable_start(); + end = Exec::init()->set_name("end")->set_flops_amount(0)->start(); else end = activities.at("end"); @@ -238,7 +238,7 @@ std::vector create_DAG_from_dot(const std::string& filename) std::string name = std::string(src_name) + "->" + dst_name; XBT_DEBUG("See ", name.c_str(), size); if (activities.find(name) == activities.end()) { - act = Comm::sendto_init()->set_name(name)->set_payload_size(size)->vetoable_start(); + act = Comm::sendto_init()->set_name(name)->set_payload_size(size)->start(); src->add_successor(act); act->add_successor(dst); activities.try_emplace(name, act); @@ -310,7 +310,7 @@ void STag_dax__job() std::string name = std::string(A_dax__job_id) + "@" + A_dax__job_name; runtime *= 4200000000.; /* Assume that timings were done on a 4.2GFlops machine. I mean, why not? */ XBT_DEBUG("See ", A_dax__job_id, A_dax__job_runtime, runtime); - simgrid::s4u::current_job = simgrid::s4u::Exec::init()->set_name(name)->set_flops_amount(runtime)->vetoable_start(); + simgrid::s4u::current_job = simgrid::s4u::Exec::init()->set_name(name)->set_flops_amount(runtime)->start(); simgrid::s4u::jobs.try_emplace(A_dax__job_id, simgrid::s4u::current_job); simgrid::s4u::result.push_back(simgrid::s4u::current_job); } catch (const std::invalid_argument&) { diff --git a/src/internal_config.h.in b/src/internal_config.h.in index a6dcbd59c4..e13c6ffa7d 100644 --- a/src/internal_config.h.in +++ b/src/internal_config.h.in @@ -48,6 +48,7 @@ /* Variables for the raw contexts (to select the right assembly code) */ #cmakedefine01 SIMGRID_PROCESSOR_i686 #cmakedefine01 SIMGRID_PROCESSOR_x86_64 +#cmakedefine01 SIMGRID_PROCESSOR_arm64 /* Variables for the SysV contexts */ @sg_makecontext_stack_addr@ diff --git a/src/kernel/actor/SimcallObserver.cpp b/src/kernel/actor/SimcallObserver.cpp index 24a2192646..2d2cf8827e 100644 --- a/src/kernel/actor/SimcallObserver.cpp +++ b/src/kernel/actor/SimcallObserver.cpp @@ -7,6 +7,7 @@ #include "simgrid/s4u/Host.hpp" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/activity/MailboxImpl.hpp" +#include "src/kernel/activity/MutexImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/mc/mc_config.hpp" @@ -51,7 +52,8 @@ void ConditionWaitSimcall::serialize(std::stringstream& stream) const } std::string ConditionWaitSimcall::to_string() const { - THROW_UNIMPLEMENTED; + return "ConditionWait(cond_id:" + ptr_to_id(get_cond()) + + " mutex_id:" + std::to_string(get_mutex()->get_id()) + ")"; } ActorJoinSimcall::ActorJoinSimcall(ActorImpl* actor, ActorImpl* other, double timeout) diff --git a/src/kernel/actor/SynchroObserver.cpp b/src/kernel/actor/SynchroObserver.cpp index e22d6cc9f0..efe5bffd31 100644 --- a/src/kernel/actor/SynchroObserver.cpp +++ b/src/kernel/actor/SynchroObserver.cpp @@ -30,8 +30,8 @@ void MutexObserver::serialize(std::stringstream& stream) const } std::string MutexObserver::to_string() const { - return std::string(mc::Transition::to_c_str(type_)) + "(mutex_id: " + std::to_string(get_mutex()->get_id()) + - "owner:" + std::to_string(get_mutex()->get_owner()->get_pid()) + ")"; + return std::string(mc::Transition::to_c_str(type_)) + "(mutex_id:" + std::to_string(get_mutex()->get_id()) + + " owner:" + std::to_string(get_mutex()->get_owner()->get_pid()) + ")"; } bool MutexObserver::is_enabled() @@ -52,7 +52,7 @@ void SemaphoreObserver::serialize(std::stringstream& stream) const } std::string SemaphoreObserver::to_string() const { - return std::string(mc::Transition::to_c_str(type_)) + "(sem_id: " + std::to_string(get_sem()->get_id()) + ")"; + return std::string(mc::Transition::to_c_str(type_)) + "(sem_id:" + std::to_string(get_sem()->get_id()) + ")"; } SemaphoreAcquisitionObserver::SemaphoreAcquisitionObserver(ActorImpl* actor, mc::Transition::Type type, @@ -71,7 +71,7 @@ void SemaphoreAcquisitionObserver::serialize(std::stringstream& stream) const std::string SemaphoreAcquisitionObserver::to_string() const { return std::string(mc::Transition::to_c_str(type_)) + - "(sem_id: " + std::to_string(acquisition_->semaphore_->get_id()) + ' ' + + "(sem_id:" + std::to_string(acquisition_->semaphore_->get_id()) + ' ' + (acquisition_->granted_ ? "granted)" : "not granted)"); } @@ -94,7 +94,7 @@ void BarrierObserver::serialize(std::stringstream& stream) const std::string BarrierObserver::to_string() const { return std::string(mc::Transition::to_c_str(type_)) + - "(barrier_id: " + std::to_string(barrier_ != nullptr ? barrier_->get_id() : acquisition_->barrier_->get_id()) + + "(barrier_id:" + std::to_string(barrier_ != nullptr ? barrier_->get_id() : acquisition_->barrier_->get_id()) + ")"; } bool BarrierObserver::is_enabled() diff --git a/src/kernel/resource/LinkImpl.hpp b/src/kernel/resource/LinkImpl.hpp index e9b43c50ae..f7f269f212 100644 --- a/src/kernel/resource/LinkImpl.hpp +++ b/src/kernel/resource/LinkImpl.hpp @@ -40,6 +40,8 @@ public: virtual void set_latency_profile(kernel::profile::Profile* profile) = 0; /** @brief Set the concurrency limit for this link */ virtual void set_concurrency_limit(int limit) const = 0; + /** @brief Get the concurrency limit of this link */ + virtual int get_concurrency_limit() const = 0; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/NetworkModelFactors.cpp b/src/kernel/resource/NetworkModelFactors.cpp index ffd1b69866..06ea79c810 100644 --- a/src/kernel/resource/NetworkModelFactors.cpp +++ b/src/kernel/resource/NetworkModelFactors.cpp @@ -5,7 +5,6 @@ #include "src/kernel/resource/NetworkModelFactors.hpp" #include "simgrid/sg_config.hpp" -#include "src/kernel/resource/FactorSet.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); @@ -14,9 +13,6 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); *********/ namespace simgrid::kernel::resource { -static FactorSet cfg_latency_factor("network/latency-factor"); -static FactorSet cfg_bandwidth_factor("network/bandwidth-factor"); - config::Flag cfg_latency_factor_str( "network/latency-factor", std::initializer_list{"smpi/lat-factor"}, "Correction factor to apply to the provided latency (default value overridden by network model)", "1.0"); @@ -24,6 +20,9 @@ static config::Flag cfg_bandwidth_factor_str( "network/bandwidth-factor", std::initializer_list{"smpi/bw-factor"}, "Correction factor to apply to the provided bandwidth (default value overridden by network model)", "1.0"); +FactorSet NetworkModelFactors::cfg_latency_factor("network/latency-factor"); +FactorSet NetworkModelFactors::cfg_bandwidth_factor("network/bandwidth-factor"); + double NetworkModelFactors::get_bandwidth_factor() const { xbt_assert(not bw_factor_cb_, diff --git a/src/kernel/resource/NetworkModelFactors.hpp b/src/kernel/resource/NetworkModelFactors.hpp index e9e4ee6a79..40a4fae5a4 100644 --- a/src/kernel/resource/NetworkModelFactors.hpp +++ b/src/kernel/resource/NetworkModelFactors.hpp @@ -7,6 +7,7 @@ #define SIMGRID_KERNEL_RESOURCE_NETWORKMODELFACTORS_HPP #include "simgrid/sg_config.hpp" +#include "src/kernel/resource/FactorSet.hpp" #include "xbt/asserts.h" #include @@ -18,6 +19,9 @@ namespace simgrid::kernel::resource { /** This Trait of NetworkModel is in charge of handling the network factors (bw and lat) */ class XBT_PUBLIC NetworkModelFactors { + static FactorSet cfg_latency_factor; + static FactorSet cfg_bandwidth_factor; + using NetworkFactorCb = double(double size, const s4u::Host* src, const s4u::Host* dst, const std::vector& links, const std::unordered_set& netzones); diff --git a/src/kernel/resource/SplitDuplexLinkImpl.cpp b/src/kernel/resource/SplitDuplexLinkImpl.cpp index cf8c0311f2..d5b08c9a06 100644 --- a/src/kernel/resource/SplitDuplexLinkImpl.cpp +++ b/src/kernel/resource/SplitDuplexLinkImpl.cpp @@ -85,6 +85,11 @@ void SplitDuplexLinkImpl::set_latency_profile(profile::Profile* profile) link_down_->set_latency_profile(profile); } +int SplitDuplexLinkImpl::get_concurrency_limit() const +{ + return link_up_->get_concurrency_limit(); +} + void SplitDuplexLinkImpl::set_concurrency_limit(int limit) const { link_up_->set_concurrency_limit(limit); diff --git a/src/kernel/resource/SplitDuplexLinkImpl.hpp b/src/kernel/resource/SplitDuplexLinkImpl.hpp index fe81c42bce..8708018e4e 100644 --- a/src/kernel/resource/SplitDuplexLinkImpl.hpp +++ b/src/kernel/resource/SplitDuplexLinkImpl.hpp @@ -66,6 +66,7 @@ public: * Profile must contain absolute values */ void set_latency_profile(kernel::profile::Profile* profile) override; void set_concurrency_limit(int limit) const override; + int get_concurrency_limit() const override; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/StandardLinkImpl.cpp b/src/kernel/resource/StandardLinkImpl.cpp index 40932ef4f2..30471d020b 100644 --- a/src/kernel/resource/StandardLinkImpl.cpp +++ b/src/kernel/resource/StandardLinkImpl.cpp @@ -140,5 +140,9 @@ void StandardLinkImpl::set_concurrency_limit(int limit) const } get_constraint()->set_concurrency_limit(limit); } +int StandardLinkImpl::get_concurrency_limit() const +{ + return get_constraint()->get_concurrency_limit(); +} } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/StandardLinkImpl.hpp b/src/kernel/resource/StandardLinkImpl.hpp index 1c5c8b7775..4a10210074 100644 --- a/src/kernel/resource/StandardLinkImpl.hpp +++ b/src/kernel/resource/StandardLinkImpl.hpp @@ -72,6 +72,7 @@ public: void set_latency_profile(kernel::profile::Profile* profile) override; void set_concurrency_limit(int limit) const override; + int get_concurrency_limit() const override; }; } // namespace simgrid::kernel::resource diff --git a/src/mc/api/RemoteApp.cpp b/src/mc/api/RemoteApp.cpp index cc7be72a7c..d9f5782580 100644 --- a/src/mc/api/RemoteApp.cpp +++ b/src/mc/api/RemoteApp.cpp @@ -42,7 +42,7 @@ static simgrid::config::Flag _sg_mc_setenv{ namespace simgrid::mc { -static void run_child_process(int socket, const std::vector& args) +XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector& 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 diff --git a/src/mc/inspect/mc_unw.cpp b/src/mc/inspect/mc_unw.cpp index 2c66603693..746fb3155d 100644 --- a/src/mc/inspect/mc_unw.cpp +++ b/src/mc/inspect/mc_unw.cpp @@ -225,7 +225,7 @@ void UnwindContext::initialize(simgrid::mc::RemoteProcess* process, unw_context_ // Take a copy of the context for our own purpose: this->unwind_context_ = *c; -#if SIMGRID_PROCESSOR_x86_64 || SIMGRID_PROCESSOR_i686 || defined(__aarch64__) +#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 @@ -234,6 +234,12 @@ void UnwindContext::initialize(simgrid::mc::RemoteProcess* process, unw_context_ // 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. diff --git a/src/mc/mc_mmu.hpp b/src/mc/mc_mmu.hpp index 83f57e8843..bbeedf1e7d 100644 --- a/src/mc/mc_mmu.hpp +++ b/src/mc/mc_mmu.hpp @@ -6,18 +6,10 @@ #ifndef SIMGRID_MC_MMU_HPP #define SIMGRID_MC_MMU_HPP +#include "xbt/misc.h" #include #include -#ifndef XBT_ALWAYS_INLINE -#define XBT_ALWAYS_INLINE inline __attribute__((always_inline)) -#endif - -/** Size of a memory page for the current system. */ -extern "C" int xbt_pagesize; -/** Number of bits of addresses inside a given page, log2(xbt_pagesize). */ -extern "C" int xbt_pagebits; - namespace simgrid::mc::mmu { // TODO, do not depend on xbt_pagesize/xbt_pagebits but our own chunk size diff --git a/src/mc/transition/TransitionSynchro.cpp b/src/mc/transition/TransitionSynchro.cpp index e918e7ad4d..a93e27b5cf 100644 --- a/src/mc/transition/TransitionSynchro.cpp +++ b/src/mc/transition/TransitionSynchro.cpp @@ -49,7 +49,7 @@ bool BarrierTransition::depends(const Transition* o) const std::string MutexTransition::to_string(bool verbose) const { - return xbt::string_printf("%s(mutex: %" PRIxPTR ", owner:%ld)", Transition::to_c_str(type_), mutex_, owner_); + return xbt::string_printf("%s(mutex: %" PRIxPTR ", owner: %ld)", Transition::to_c_str(type_), mutex_, owner_); } MutexTransition::MutexTransition(aid_t issuer, int times_considered, Type type, std::stringstream& stream) diff --git a/src/plugins/ProducerConsumer.cpp b/src/plugins/ProducerConsumer.cpp index d5215229e4..2614a1b580 100644 --- a/src/plugins/ProducerConsumer.cpp +++ b/src/plugins/ProducerConsumer.cpp @@ -8,5 +8,5 @@ XBT_LOG_NEW_CATEGORY(producer_consumer, "Producer-Consumer plugin logging category"); namespace simgrid::plugin { -unsigned long pc_id = 0; +unsigned long ProducerConsumerId::pc_id = 0; } diff --git a/src/plugins/file_system/s4u_FileSystem.cpp b/src/plugins/file_system/s4u_FileSystem.cpp index 4d6db1ac27..929cf17441 100644 --- a/src/plugins/file_system/s4u_FileSystem.cpp +++ b/src/plugins/file_system/s4u_FileSystem.cpp @@ -23,7 +23,6 @@ #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_file, s4u, "S4U files"); -int sg_storage_max_file_descriptors = 1024; /** @defgroup plugin_filesystem Plugin FileSystem * @@ -38,6 +37,7 @@ template class xbt::Extendable; namespace s4u { simgrid::xbt::Extension FileSystemDiskExt::EXTENSION_ID; simgrid::xbt::Extension FileDescriptorHostExt::EXTENSION_ID; +int FileDescriptorHostExt::max_file_descriptors; const Disk* File::find_local_disk_on(const Host* host) { @@ -78,9 +78,9 @@ File::File(const std::string& fullpath, const_sg_host_t host, void* userdata) : local_disk_ = find_local_disk_on(host); // assign a file descriptor id to the newly opened File - auto* ext = host->extension(); + auto* ext = host->extension(); if (ext->file_descriptor_table == nullptr) { - ext->file_descriptor_table = std::make_unique>(sg_storage_max_file_descriptors); + ext->file_descriptor_table = std::make_unique>(FileDescriptorHostExt::max_file_descriptors); std::iota(ext->file_descriptor_table->rbegin(), ext->file_descriptor_table->rend(), 0); // Fill with ..., 1, 0. } xbt_assert(not ext->file_descriptor_table->empty(), "Too much files are opened! Some have to be closed."); @@ -119,8 +119,7 @@ File* File::open(const std::string& fullpath, const_sg_host_t host, void* userda void File::close() { - std::vector* desc_table = - Host::current()->extension()->file_descriptor_table.get(); + std::vector* desc_table = Host::current()->extension()->file_descriptor_table.get(); kernel::actor::simcall_answered([this, desc_table] { desc_table->push_back(this->desc_id); }); delete this; } @@ -248,7 +247,7 @@ sg_size_t File::tell() const void File::move(const std::string& fullpath) const { /* Check if the new full path is on the same mount point */ - if (fullpath.compare(0, mount_point_.length(), mount_point_) == 0) { + if (fullpath.rfind(mount_point_, 0) == 0) { std::map>* content = nullptr; content = local_disk_->extension()->get_content(); if (content) { @@ -470,8 +469,8 @@ static void on_simulation_end() */ void sg_storage_file_system_init() { - sg_storage_max_file_descriptors = 1024; - simgrid::config::bind_flag(sg_storage_max_file_descriptors, "storage/max_file_descriptors", + FileDescriptorHostExt::max_file_descriptors = 1024; + simgrid::config::bind_flag(FileDescriptorHostExt::max_file_descriptors, "storage/max_file_descriptors", "Maximum number of concurrently opened files per host. Default is 1024"); if (not FileSystemDiskExt::EXTENSION_ID.valid()) { diff --git a/src/s4u/s4u_Activity.cpp b/src/s4u/s4u_Activity.cpp index 383f6a039a..7b38f61bb2 100644 --- a/src/s4u/s4u_Activity.cpp +++ b/src/s4u/s4u_Activity.cpp @@ -52,7 +52,7 @@ void Activity::wait_until(double time_limit) Activity* Activity::wait_for(double timeout) { if (state_ == State::INITED) - vetoable_start(); + start(); if (state_ == State::FAILED) { if (dynamic_cast(this)) @@ -82,7 +82,7 @@ bool Activity::test() return true; if (state_ == State::INITED || state_ == State::STARTING) - this->vetoable_start(); + this->start(); kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); kernel::actor::ActivityTestSimcall observer{issuer, pimpl_.get()}; diff --git a/src/s4u/s4u_Actor.cpp b/src/s4u/s4u_Actor.cpp index 57aef00408..284faaa1f4 100644 --- a/src/s4u/s4u_Actor.cpp +++ b/src/s4u/s4u_Actor.cpp @@ -359,7 +359,7 @@ void execute(double flops) void execute(double flops, double priority) { - exec_init(flops)->set_priority(priority)->vetoable_start()->wait(); + exec_init(flops)->set_priority(priority)->start()->wait(); } void parallel_execute(const std::vector& hosts, const std::vector& flops_amounts, @@ -407,7 +407,7 @@ ExecPtr exec_init(const std::vector& hosts, const std::vectorvetoable_start(); + res->start(); return res; } diff --git a/src/s4u/s4u_Comm.cpp b/src/s4u/s4u_Comm.cpp index ad42fb4e86..dcacfd0b3e 100644 --- a/src/s4u/s4u_Comm.cpp +++ b/src/s4u/s4u_Comm.cpp @@ -178,7 +178,7 @@ CommPtr Comm::set_source(Host* from) if (state_ == State::STARTING && remains_ <= 0) XBT_DEBUG("This communication has a payload size of 0 byte. It cannot start yet"); else - vetoable_start(); + start(); return this; } @@ -196,7 +196,7 @@ CommPtr Comm::set_destination(Host* to) if (state_ == State::STARTING && remains_ <= 0) XBT_DEBUG("This communication has a payload size of 0 byte. It cannot start yet"); else - vetoable_start(); + start(); return this; } @@ -293,7 +293,7 @@ bool Comm::is_assigned() const mailbox_ != nullptr; } -Comm* Comm::start() +Comm* Comm::do_start() { xbt_assert(get_state() == State::INITED || get_state() == State::STARTING, "You cannot use %s() once your communication started (not implemented)", __FUNCTION__); @@ -356,7 +356,7 @@ Comm* Comm::detach() "You cannot use %s() once your communication is %s (not implemented)", __FUNCTION__, get_state_str()); xbt_assert(dst_buff_ == nullptr && dst_buff_size_ == 0, "You can only detach sends, not recvs"); detached_ = true; - vetoable_start(); + start(); return this; } @@ -386,7 +386,7 @@ Comm* Comm::wait_for(double timeout) case State::INITED: case State::STARTING: // It's not started yet. Do it in one simcall if it's a regular communication if (get_source() != nullptr || get_destination() != nullptr) { - return vetoable_start()->wait_for(timeout); // In the case of host2host comm, do it in two simcalls + return start()->wait_for(timeout); // In the case of host2host comm, do it in two simcalls } else if (src_buff_ != nullptr) { on_send(*this); send(sender_, mailbox_, remains_, rate_, src_buff_, src_buff_size_, match_fun_, copy_data_function_, diff --git a/src/s4u/s4u_Disk.cpp b/src/s4u/s4u_Disk.cpp index 5e5fea5f8b..9e3d59f8b3 100644 --- a/src/s4u/s4u_Disk.cpp +++ b/src/s4u/s4u_Disk.cpp @@ -120,38 +120,38 @@ IoPtr Disk::io_init(sg_size_t size, Io::OpType type) const IoPtr Disk::read_async(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::READ))->vetoable_start(); + return IoPtr(io_init(size, Io::OpType::READ))->start(); } sg_size_t Disk::read(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::READ))->vetoable_start()->wait()->get_performed_ioops(); + return IoPtr(io_init(size, Io::OpType::READ))->start()->wait()->get_performed_ioops(); } sg_size_t Disk::read(sg_size_t size, double priority) const { return IoPtr(io_init(size, Io::OpType::READ)) ->set_priority(priority) - ->vetoable_start() + ->start() ->wait() ->get_performed_ioops(); } IoPtr Disk::write_async(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::WRITE)->vetoable_start()); + return IoPtr(io_init(size, Io::OpType::WRITE)->start()); } sg_size_t Disk::write(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::WRITE))->vetoable_start()->wait()->get_performed_ioops(); + return IoPtr(io_init(size, Io::OpType::WRITE))->start()->wait()->get_performed_ioops(); } sg_size_t Disk::write(sg_size_t size, double priority) const { return IoPtr(io_init(size, Io::OpType::WRITE)) ->set_priority(priority) - ->vetoable_start() + ->start() ->wait() ->get_performed_ioops(); } diff --git a/src/s4u/s4u_Engine.cpp b/src/s4u/s4u_Engine.cpp index e808263551..d994ec074c 100644 --- a/src/s4u/s4u_Engine.cpp +++ b/src/s4u/s4u_Engine.cpp @@ -107,28 +107,154 @@ const std::vector& Engine::get_all_models() c return pimpl->get_all_models(); } -/** - * Creates a new platform, including hosts, links, and the routing table. - * - * @beginrst - * See also: :ref:`platform`. - * @endrst - */ void Engine::load_platform(const std::string& platf) const { pimpl->load_platform(platf); } -/** - * @brief Seals the platform, finishing the creation of its resources. - * - * This method is optional. The seal() is done automatically when you call Engine::run. - */ void Engine::seal_platform() const { pimpl->seal_platform(); } +static void flatify_hosts(Engine const& engine, std::stringstream& ss) +{ + // Regular hosts + std::vector hosts = engine.get_all_hosts(); + + for (auto const* h : hosts) { + ss << " get_name() << "\" speed=\"" << h->get_speed() << "\""; + const std::unordered_map* props = h->get_properties(); + if (h->get_core_count() > 1) + ss << " core=\"" << h->get_core_count() << "\""; + + // Sort the properties before displaying them, so that the tests are perfectly reproducible + std::vector keys; + for (auto const& [key, _] : *props) + keys.push_back(key); + if (not keys.empty()) { + ss << ">\n"; + std::sort(keys.begin(), keys.end()); + for (const std::string& key : keys) + ss << " at(key) << "\"/>\n"; + ss << " \n"; + } else { + ss << "/>\n"; + } + } + + // Routers + std::vector netpoints = engine.get_all_netpoints(); + std::sort(netpoints.begin(), netpoints.end(), + [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { + return a->get_name() < b->get_name(); + }); + + for (auto const& src : netpoints) + if (src->is_router()) + ss << " get_name() << "\"/>\n"; +} + +static void flatify_links(Engine const& engine, std::stringstream& ss) +{ + std::vector links = engine.get_all_links(); + + std::sort(links.begin(), links.end(), [](const Link* a, const Link* b) { return a->get_name() < b->get_name(); }); + + for (auto const* link : links) { + ss << " get_name() << "\""; + ss << " bandwidth=\"" << link->get_bandwidth() << "\""; + ss << " latency=\"" << link->get_latency() << "\""; + if (link->get_concurrency_limit() != -1) + ss << " concurrency=\"" << link->get_concurrency_limit() << "\""; + if (link->is_shared()) { + ss << "/>\n"; + } else { + ss << " sharing_policy=\"FATPIPE\"/>\n"; + } + } +} + +static void flatify_routes(Engine const& engine, std::stringstream& ss) +{ + auto hosts = engine.get_all_hosts(); + auto netpoints = engine.get_all_netpoints(); + std::sort(netpoints.begin(), netpoints.end(), + [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { + return a->get_name() < b->get_name(); + }); + + for (auto const* src_host : hosts) { // Routes from host + const simgrid::kernel::routing::NetPoint* src = src_host->get_netpoint(); + for (auto const* dst_host : hosts) { // Routes to host + std::vector route; + const simgrid::kernel::routing::NetPoint* dst = dst_host->get_netpoint(); + simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr); + if (route.empty()) + continue; + ss << " get_name() << "\" dst=\"" << dst_host->get_name() << "\">\n "; + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + + for (auto const& dst : netpoints) { // to router + if (not dst->is_router()) + continue; + ss << " get_name() << "\" dst=\"" << dst->get_name() << "\">\n "; + std::vector route; + simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr); + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + } + + for (auto const& value1 : netpoints) { // Routes from router + if (not value1->is_router()) + continue; + for (auto const& value2 : netpoints) { // to router + if (not value2->is_router()) + continue; + std::vector route; + simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, value2, route, nullptr); + if (route.empty()) + continue; + ss << " get_name() << "\" dst=\"" << value2->get_name() << "\">\n "; + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + for (auto const* dst_host : hosts) { // Routes to host + ss << " get_name() << "\" dst=\"" << dst_host->get_name() << "\">\n "; + std::vector route; + const simgrid::kernel::routing::NetPoint* netcardDst = dst_host->get_netpoint(); + simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, netcardDst, route, nullptr); + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + } +} +std::string Engine::flatify_platform() const +{ + std::string version = "4.1"; + std::stringstream ss; + + ss << "\n"; + ss << "\n"; + ss << "\n"; + ss << "get_name() << "\" routing=\"Full\">\n"; + + flatify_hosts(*this, ss); + flatify_links(*this, ss); + flatify_routes(*this, ss); + + ss << "\n"; + ss << "\n"; + return ss.str(); +} + /** Registers the main function of an actor that will be launched from the deployment file */ void Engine::register_function(const std::string& name, const std::function& code) { diff --git a/src/s4u/s4u_Exec.cpp b/src/s4u/s4u_Exec.cpp index 5e4770db6f..597120ebeb 100644 --- a/src/s4u/s4u_Exec.cpp +++ b/src/s4u/s4u_Exec.cpp @@ -42,7 +42,7 @@ ExecPtr Exec::init() return ExecPtr(static_cast(pimpl->get_iface())); } -Exec* Exec::start() +Exec* Exec::do_start() { kernel::actor::simcall_answered([this] { (*boost::static_pointer_cast(pimpl_)) @@ -180,8 +180,8 @@ ExecPtr Exec::set_host(Host* host) pimpl_.get(), [this, host] { boost::static_pointer_cast(pimpl_)->set_host(host); }); if (state_ == State::STARTING) - // Setting the host may allow to start the activity, let's try - vetoable_start(); + // Setting the host may allow to start the activity, let's try + start(); return this; } @@ -198,7 +198,7 @@ ExecPtr Exec::set_hosts(const std::vector& hosts) // Setting the host may allow to start the activity, let's try if (state_ == State::STARTING) - vetoable_start(); + start(); return this; } @@ -213,7 +213,7 @@ ExecPtr Exec::unset_host() if (state_ == State::STARTED) cancel(); - vetoable_start(); + start(); return this; } @@ -287,7 +287,7 @@ double sg_exec_get_remaining_ratio(const_sg_exec_t exec) void sg_exec_start(sg_exec_t exec) { - exec->vetoable_start(); + exec->start(); } void sg_exec_cancel(sg_exec_t exec) diff --git a/src/s4u/s4u_Host.cpp b/src/s4u/s4u_Host.cpp index 67936f54da..b762e63859 100644 --- a/src/s4u/s4u_Host.cpp +++ b/src/s4u/s4u_Host.cpp @@ -396,7 +396,7 @@ void Host::execute(double flops) const void Host::execute(double flops, double priority) const { - this_actor::exec_init(flops)->set_priority(1 / priority)->vetoable_start()->wait(); + this_actor::exec_init(flops)->set_priority(1 / priority)->start()->wait(); } Host* Host::seal() diff --git a/src/s4u/s4u_Io.cpp b/src/s4u/s4u_Io.cpp index c88c7dc01a..191abc17ad 100644 --- a/src/s4u/s4u_Io.cpp +++ b/src/s4u/s4u_Io.cpp @@ -58,7 +58,7 @@ IoPtr Io::set_source(Host* from, const Disk* from_disk) if (state_ == State::STARTING && remains_ <= 0) XBT_DEBUG("This IO has a size of 0 byte. It cannot start yet"); else - vetoable_start(); + start(); return this; } @@ -76,12 +76,12 @@ IoPtr Io::set_destination(Host* to, const Disk* to_disk) if (state_ == State::STARTING && remains_ <= 0) XBT_DEBUG("This IO has a size of 0 byte. It cannot start yet"); else - vetoable_start(); + start(); return this; } -Io* Io::start() +Io* Io::do_start() { kernel::actor::simcall_answered( [this] { (*boost::static_pointer_cast(pimpl_)).set_name(get_name()).start(); }); @@ -111,7 +111,7 @@ IoPtr Io::set_disk(const_sg_disk_t disk) // Setting the disk may allow to start the activity, let's try if (state_ == State::STARTING) - vetoable_start(); + start(); return this; } diff --git a/src/s4u/s4u_Link.cpp b/src/s4u/s4u_Link.cpp index 5243121671..8d41270893 100644 --- a/src/s4u/s4u_Link.cpp +++ b/src/s4u/s4u_Link.cpp @@ -119,6 +119,11 @@ void Link::set_host_wifi_rate(const s4u::Host* host, int level) const wlink->set_host_rate(host, level); } +int Link::get_concurrency_limit() const +{ + return pimpl_->get_concurrency_limit(); +} + Link* Link::set_concurrency_limit(int limit) { kernel::actor::simcall_object_access(pimpl_, [this, limit] { pimpl_->set_concurrency_limit(limit); }); diff --git a/src/s4u/s4u_Mailbox.cpp b/src/s4u/s4u_Mailbox.cpp index 0ebd9cfc62..6ce4a0339b 100644 --- a/src/s4u/s4u_Mailbox.cpp +++ b/src/s4u/s4u_Mailbox.cpp @@ -101,7 +101,7 @@ CommPtr Mailbox::put_async(void* payload, uint64_t simulated_size_in_bytes) xbt_assert(payload != nullptr, "You cannot send nullptr"); CommPtr res = put_init(payload, simulated_size_in_bytes); - res->vetoable_start(); + res->start(); return res; } @@ -109,7 +109,7 @@ void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes) { xbt_assert(payload != nullptr, "You cannot send nullptr"); - put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->vetoable_start()->wait(); + put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->start()->wait(); } /** Blocking send with timeout */ @@ -117,7 +117,7 @@ void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes, double timeou { xbt_assert(payload != nullptr, "You cannot send nullptr"); - put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->vetoable_start()->wait_for(timeout); + put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->start()->wait_for(timeout); } CommPtr Mailbox::get_init() diff --git a/src/smpi/bindings/smpi_mpi.cpp b/src/smpi/bindings/smpi_mpi.cpp index 0957079e21..16e8250043 100644 --- a/src/smpi/bindings/smpi_mpi.cpp +++ b/src/smpi/bindings/smpi_mpi.cpp @@ -26,13 +26,13 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi, "Logging specific to SMPI ,(mpi) #define NOT_YET_IMPLEMENTED_NOFAIL \ { \ - static bool warning_todo = true; \ - if (warning_todo) \ + if (static bool warned_todo = false; not warned_todo) { \ XBT_WARN("Not yet implemented: %s. " \ "Please contact the SimGrid team if support is needed. " \ "Run with --log=smpi_mpi.thresh:error to hide", \ __func__); \ - warning_todo = false; \ + warned_todo = true; \ + } \ return MPI_SUCCESS; \ } diff --git a/src/surf/network_constant.hpp b/src/surf/network_constant.hpp index 72d5727739..ec9f384398 100644 --- a/src/surf/network_constant.hpp +++ b/src/surf/network_constant.hpp @@ -24,7 +24,7 @@ public: class NetworkConstantAction final : public NetworkAction { public: NetworkConstantAction(NetworkConstantModel* model_, s4u::Host& src, s4u::Host& dst, double size); - void update_remains_lazy(double now) override; + XBT_ATTRIB_NORETURN void update_remains_lazy(double now) override; }; } // namespace simgrid::kernel::resource diff --git a/src/surf/network_ns3.cpp b/src/surf/network_ns3.cpp index 6e84927851..5ab5965842 100644 --- a/src/surf/network_ns3.cpp +++ b/src/surf/network_ns3.cpp @@ -262,16 +262,13 @@ static void routeCreation_cb(bool symmetrical, const simgrid::kernel::routing::N XBT_DEBUG("\tLink (%s) bw:%fbps lat:%fs", link->get_cname(), link->get_bandwidth(), link->get_latency()); ns3_add_direct_route(src, dst, link->get_bandwidth(), link->get_latency(), link->get_sharing_policy()); - } else { - static bool warned_about_long_routes = false; - - if (not warned_about_long_routes) - XBT_WARN("Ignoring a route between %s and %s of length %zu: Only routes of length 1 are considered with ns-3.\n" - "WARNING: You can ignore this warning if your hosts can still communicate when only considering routes " - "of length 1.\n" - "WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently " - "ignored.", - src->get_cname(), dst->get_cname(), link_list.size()); + } else if (static bool warned_about_long_routes = false; not warned_about_long_routes) { + XBT_WARN("Ignoring a route between %s and %s of length %zu: Only routes of length 1 are considered with ns-3.\n" + "WARNING: You can ignore this warning if your hosts can still communicate when only considering routes " + "of length 1.\n" + "WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently " + "ignored.", + src->get_cname(), dst->get_cname(), link_list.size()); warned_about_long_routes = true; } } diff --git a/src/xbt/mmalloc/mm_legacy.c b/src/xbt/mmalloc/mm_legacy.c index 07176055d0..5cd89d50d9 100644 --- a/src/xbt/mmalloc/mm_legacy.c +++ b/src/xbt/mmalloc/mm_legacy.c @@ -15,7 +15,6 @@ /* ***** Whether to use `mmalloc` of the underlying malloc ***** */ static int __malloc_use_mmalloc; -int mmalloc_pagesize = 0; int malloc_use_mmalloc(void) { @@ -127,7 +126,6 @@ XBT_ATTRIB_CONSTRUCTOR(101) static void mm_legacy_constructor() mm_real_calloc = dlsym(RTLD_NEXT, "calloc"); #endif } - mmalloc_pagesize = getpagesize(); mm_initializing = 0; mm_initialized = 1; diff --git a/src/xbt/mmalloc/mm_module.c b/src/xbt/mmalloc/mm_module.c index 5e9b9402e6..f4bd97ad91 100644 --- a/src/xbt/mmalloc/mm_module.c +++ b/src/xbt/mmalloc/mm_module.c @@ -141,9 +141,8 @@ void *xbt_mheap_destroy(xbt_mheap_t mdp) xbt_mheap_t mmalloc_preinit(void) { if (__mmalloc_default_mdp == NULL) { - if (!mmalloc_pagesize) - mmalloc_pagesize = getpagesize(); - unsigned long mask = ~((unsigned long)mmalloc_pagesize - 1); + 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); } diff --git a/src/xbt/mmalloc/mmorecore.c b/src/xbt/mmalloc/mmorecore.c index 3601a79f1a..a5f9ff52ac 100644 --- a/src/xbt/mmalloc/mmorecore.c +++ b/src/xbt/mmalloc/mmorecore.c @@ -22,7 +22,7 @@ #define MAP_ANONYMOUS MAP_ANON #endif -#define PAGE_ALIGN(addr) (void*)(((long)(addr) + mmalloc_pagesize - 1) & ~((long)mmalloc_pagesize - 1)) +#define PAGE_ALIGN(addr) (void*)(((unsigned long)(addr) + mmalloc_pagesize - 1) & ~(mmalloc_pagesize - 1)) /** @brief Add memory to this heap * @@ -47,9 +47,9 @@ void *mmorecore(struct mdesc *mdp, ssize_t size) return mdp->breakval; } - if (mmalloc_pagesize == 0) { // Not initialized yet - mmalloc_pagesize = (int)sysconf(_SC_PAGESIZE); - } + 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 @@ -78,7 +78,7 @@ void *mmorecore(struct mdesc *mdp, ssize_t size) if (mapto == MAP_FAILED) { char buff[1024]; - fprintf(stderr, "Internal error: mmap returned MAP_FAILED! pagesize:%d error: %s\n", mmalloc_pagesize, + 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); diff --git a/src/xbt/mmalloc/mmprivate.h b/src/xbt/mmalloc/mmprivate.h index 76b459c107..216e5eb2d9 100644 --- a/src/xbt/mmalloc/mmprivate.h +++ b/src/xbt/mmalloc/mmprivate.h @@ -31,7 +31,6 @@ } \ } while (0) -XBT_PUBLIC_DATA int mmalloc_pagesize; XBT_PRIVATE xbt_mheap_t mmalloc_preinit(void); #define MMALLOC_MAGIC "mmalloc" /* Mapped file magic number */ diff --git a/src/xbt/xbt_main.cpp b/src/xbt/xbt_main.cpp index 7825a35936..4d41e07467 100644 --- a/src/xbt/xbt_main.cpp +++ b/src/xbt/xbt_main.cpp @@ -45,26 +45,25 @@ simgrid::config::Flag cfg_dbg_clean_atexit{ "Whether to cleanup SimGrid at exit. Disable it if your code segfaults after its end.", true}; -int xbt_pagesize; -int xbt_pagebits = 0; +const int xbt_pagesize = static_cast(sysconf(_SC_PAGESIZE)); +const int xbt_pagebits = static_cast(log2(xbt_pagesize)); /* Declare xbt_preinit and xbt_postexit as constructor/destructor of the library. * This is crude and rather compiler-specific, unfortunately. */ static void xbt_preinit() XBT_ATTRIB_CONSTRUCTOR(200); static void xbt_postexit(); -void sthread_enable() +XBT_ATTRIB_NOINLINE void sthread_enable() { // These symbols are used from ContextSwapped in any case, but they are only useful + asm(""); } -void sthread_disable() +XBT_ATTRIB_NOINLINE void sthread_disable() { // when libsthread is LD_PRELOADED. In this case, sthread's implem gets used instead. + asm(""); } static void xbt_preinit() { - xbt_pagesize = static_cast(sysconf(_SC_PAGESIZE)); - xbt_pagebits = static_cast(log2(xbt_pagesize)); - xbt_log_preinit(); xbt_dict_preinit(); atexit(xbt_postexit); diff --git a/src/xbt/xbt_replay.cpp b/src/xbt/xbt_replay.cpp index 987887b3bc..d58bab1efc 100644 --- a/src/xbt/xbt_replay.cpp +++ b/src/xbt/xbt_replay.cpp @@ -128,7 +128,7 @@ int replay_runner(const char* actor_name, const char* trace_filename) simgrid::xbt::ReplayAction evt; simgrid::xbt::ReplayReader reader(trace_filename); while (reader.get(&evt)) { - if (evt.front().compare(actor_name) == 0) { + if (evt.front() == actor_name) { simgrid::xbt::handle_action(evt); } else { XBT_WARN("Ignore trace element not for me (target='%s', I am '%s')", evt.front().c_str(), actor_name); @@ -150,7 +150,7 @@ int replay_runner(const char* actor_name, const char* trace_filename) * The argument of the function is the line describing the action, fields separated by spaces. * * @param action_name the reference name of the action. - * @param function prototype given by the type: void...(const char** action) + * @param function prototype given by the type: void...(simgrid::xbt::ReplayAction& action) */ void xbt_replay_action_register(const char* action_name, const action_fun& function) { diff --git a/teshsuite/platforms/flatifier.cpp b/teshsuite/platforms/flatifier.cpp index 6141996f3f..bce6303dff 100644 --- a/teshsuite/platforms/flatifier.cpp +++ b/teshsuite/platforms/flatifier.cpp @@ -13,18 +13,19 @@ #include #include +#include XBT_LOG_NEW_DEFAULT_CATEGORY(flatifier, "Logging specific to this platform parsing tool"); namespace sg4 = simgrid::s4u; -static bool parse_cmdline(int* timings, char** platformFile, int argc, char** argv) +static bool parse_cmdline(bool* timings, char** platformFile, int argc, char** argv) { bool parse_ok = true; for (int i = 1; i < argc; i++) { if (std::strlen(argv[i]) > 1 && argv[i][0] == '-' && argv[i][1] == '-') { if (not std::strcmp(argv[i], "--timings")) { - *timings = 1; + *timings = true; } else { parse_ok = false; break; @@ -33,184 +34,31 @@ static bool parse_cmdline(int* timings, char** platformFile, int argc, char** ar *platformFile = argv[i]; } } - return parse_ok; -} - -static void create_environment(xbt_os_timer_t parse_time, const std::string& platformFile) -{ - xbt_os_cputimer_start(parse_time); - sg4::Engine::get_instance()->load_platform(platformFile); - sg4::Engine::get_instance()->seal_platform(); - xbt_os_cputimer_stop(parse_time); -} - -static void dump_hosts() -{ - std::vector hosts = sg4::Engine::get_instance()->get_all_hosts(); - - for (auto const* h : hosts) { - std::printf(" get_cname(), h->get_speed()); - const std::unordered_map* props = h->get_properties(); - if (h->get_core_count() > 1) { - std::printf(" core=\"%d\"", h->get_core_count()); - } - // Sort the properties before displaying them, so that the tests are perfectly reproducible - std::vector keys; - for (auto const& [key, _] : *props) - keys.push_back(key); - if (not keys.empty()) { - std::printf(">\n"); - std::sort(keys.begin(), keys.end()); - for (const std::string& key : keys) - std::printf(" \n", key.c_str(), props->at(key).c_str()); - std::printf(" \n"); - } else { - std::printf("/>\n"); - } - } -} - -static void dump_links() -{ - std::vector links = sg4::Engine::get_instance()->get_all_links(); - - std::sort(links.begin(), links.end(), - [](const sg4::Link* a, const sg4::Link* b) { return a->get_name() < b->get_name(); }); - - for (auto const* link : links) { - std::printf(" get_cname(), link->get_bandwidth(), - link->get_latency()); - if (link->is_shared()) { - std::printf("/>\n"); - } else { - std::printf(" sharing_policy=\"FATPIPE\"/>\n"); - } - } -} - -static void dump_routers() -{ - std::vector netpoints = sg4::Engine::get_instance()->get_all_netpoints(); - std::sort(netpoints.begin(), netpoints.end(), - [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { - return a->get_name() < b->get_name(); - }); - - for (auto const& src : netpoints) - if (src->is_router()) - std::printf(" \n", src->get_cname()); -} - -static void dump_routes() -{ - std::vector hosts = sg4::Engine::get_instance()->get_all_hosts(); - std::vector netpoints = sg4::Engine::get_instance()->get_all_netpoints(); - std::sort(netpoints.begin(), netpoints.end(), - [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { - return a->get_name() < b->get_name(); - }); - - for (auto const* src_host : hosts) { // Routes from host - const simgrid::kernel::routing::NetPoint* src = src_host->get_netpoint(); - for (auto const* dst_host : hosts) { // Routes to host - std::vector route; - const simgrid::kernel::routing::NetPoint* dst = dst_host->get_netpoint(); - simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr); - if (route.empty()) - continue; - std::printf(" \n ", src_host->get_cname(), dst_host->get_cname()); - for (auto const& link : route) - std::printf("", link->get_cname()); - std::printf("\n \n"); - } - - for (auto const& dst : netpoints) { // to router - if (not dst->is_router()) - continue; - std::printf(" \n ", src_host->get_cname(), dst->get_cname()); - std::vector route; - simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr); - for (auto const& link : route) - std::printf("", link->get_cname()); - std::printf("\n \n"); - } - } - - for (auto const& value1 : netpoints) { // Routes from router - if (not value1->is_router()) - continue; - for (auto const& value2 : netpoints) { // to router - if (not value2->is_router()) - continue; - std::vector route; - simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, value2, route, nullptr); - if (route.empty()) - continue; - std::printf(" \n ", value1->get_cname(), value2->get_cname()); - for (auto const& link : route) - std::printf("", link->get_cname()); - std::printf("\n \n"); - } - for (auto const* dst_host : hosts) { // Routes to host - std::printf(" \n ", value1->get_cname(), dst_host->get_cname()); - std::vector route; - const simgrid::kernel::routing::NetPoint* netcardDst = dst_host->get_netpoint(); - simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, netcardDst, route, nullptr); - for (auto const& link : route) - std::printf("", link->get_cname()); - std::printf("\n \n"); - } - } -} - -static void dump_platform() -{ - int version = 4; - - std::printf("\n"); - std::printf("\n"); - std::printf("\n", version); - std::printf("\n"); - - // Hosts - dump_hosts(); - - // Routers - dump_routers(); - - // Links - dump_links(); - - // Routes - dump_routes(); - - std::printf("\n"); - std::printf("\n"); + return parse_ok && platformFile != nullptr; } int main(int argc, char** argv) { char* platformFile = nullptr; - int timings = 0; + bool timings = false; xbt_os_timer_t parse_time = xbt_os_timer_new(); sg4::Engine e(&argc, argv); - xbt_assert(parse_cmdline(&timings, &platformFile, argc, argv) && platformFile, + xbt_assert(parse_cmdline(&timings, &platformFile, argc, argv), "Invalid command line arguments: expected [--timings] platformFile"); - XBT_DEBUG("%d,%s", timings, platformFile); - - create_environment(parse_time, platformFile); + xbt_os_cputimer_start(parse_time); + e.load_platform(platformFile); + e.seal_platform(); + xbt_os_cputimer_stop(parse_time); if (timings) { XBT_INFO("Parsing time: %fs (%zu hosts, %zu links)", xbt_os_timer_elapsed(parse_time), e.get_host_count(), e.get_link_count()); } else { - dump_platform(); + std::printf("%s", e.flatify_platform().c_str()); } xbt_os_timer_free(parse_time); diff --git a/teshsuite/platforms/flatifier.tesh b/teshsuite/platforms/flatifier.tesh index 8b7373e63e..75836a00c7 100644 --- a/teshsuite/platforms/flatifier.tesh +++ b/teshsuite/platforms/flatifier.tesh @@ -2,26 +2,26 @@ $ ${bindir:=.}/flatifier ./one_cluster.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> -> +> +> +> +> +> > -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -133,25 +133,25 @@ $ ${bindir:=.}/flatifier ./one_cluster.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]% $ ${bindir:=.}/flatifier ./one_cluster_multicore.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> -> +> +> +> +> +> > -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -263,18 +263,18 @@ $ ${bindir:=.}/flatifier ./one_cluster_multicore.xml "--log=root.fmt:[%10.6r]%e[ $ ${bindir:=.}/flatifier ./host_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> +> +> +> +> > > > > -> -> +> +> > > > @@ -296,14 +296,14 @@ $ ${bindir:=.}/flatifier ./host_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@ $ ${bindir:=.}/flatifier ./link_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> -> -> +> +> +> +> +> +> > > > @@ -313,15 +313,15 @@ $ ${bindir:=.}/flatifier ./link_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@ $ ${bindir:=.}/flatifier ./three_hosts_non_symmetric_route.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> -> -> -> +> +> +> +> +> +> +> > > > @@ -355,26 +355,26 @@ $ ${bindir:=.}/flatifier ./three_hosts_non_symmetric_route.xml "--log=root.fmt:[ $ ${bindir:=.}/flatifier ./two_clusters.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> +> +> +> +> > > -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -483,14 +483,14 @@ $ ${bindir:=.}/flatifier ./two_clusters.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h] $ ${bindir:=.}/flatifier ./two_hosts_multi_hop.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> -> -> +> +> +> +> +> +> > > > @@ -509,12 +509,12 @@ $ ${bindir:=.}/flatifier ./two_hosts_multi_hop.xml "--log=root.fmt:[%10.6r]%e[%i $ ${bindir:=.}/flatifier ./two_hosts_one_link.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> +> +> +> +> > > > @@ -533,25 +533,25 @@ $ ${bindir:=.}/flatifier ./two_hosts_one_link.xml "--log=root.fmt:[%10.6r]%e[%i: $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/bypassZoneRoute.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> +> +> +> > > > -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -657,105 +657,105 @@ $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/bypassZoneRoute.xml "-- $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/cluster_torus.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1194,41 +1194,41 @@ $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/cluster_torus.xml "--lo $ ${bindir:=.}/flatifier ./cluster_dragonfly_noncontiguous_rad.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1283,49 +1283,49 @@ $ ${bindir:=.}/flatifier ./cluster_dragonfly_noncontiguous_rad.xml "--log=root.f $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1380,45 +1380,45 @@ $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fm $ ${bindir:=.}/flatifier ./cluster_torus_noncontiguous_rad.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1473,13 +1473,13 @@ $ ${bindir:=.}/flatifier ./cluster_torus_noncontiguous_rad.xml "--log=root.fmt:[ $ ${bindir:=.}/flatifier ./two_hosts_one_link_splitduplex.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> +> > -> -> -> -> -> +> +> +> +> +> > > > diff --git a/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp b/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp index fb881c8c0b..3843601619 100644 --- a/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp +++ b/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp @@ -159,21 +159,23 @@ class SendAgent { // Make sure we have a clean slate xbt_assert(not mbox_.eager->listen(), "Eager mailbox should be empty when starting a test"); xbt_assert(not mbox_.rdv->listen(), "RDV mailbox should be empty when starting a test"); - for (; step_index < s.steps.size(); step_index++) { - const Step& step = s.steps[step_index]; - if (step.entity != Step::Entity::SND || step.type != Step::Type::ACTION) - continue; - try { + + Action current_action; + try { + for (; step_index < s.steps.size(); step_index++) { + const Step& step = s.steps[step_index]; + if (step.entity != Step::Entity::SND || step.type != Step::Type::ACTION) + continue; + + current_action = Action::SLEEP; sg4::this_actor::sleep_until(s.start_time + step.rel_time); - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what()); - break; - } - // Check if the other host is still OK. - if (not other_host_->is_on()) - break; - // Perform the action - try { + + // Check if the other host is still OK. + if (not other_host_->is_on()) + break; + + // Perform the action + current_action = step.action_type; switch (step.action_type) { case Action::PUT: comm = do_put(s.type, send_value); @@ -187,11 +189,10 @@ class SendAgent { default: xbt_die("Not a valid action for SND"); } - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_c_str(step.action_type), - typeid(e).name(), e.what()); - break; } + } catch (const simgrid::Exception& e) { + XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_c_str(current_action), + typeid(e).name(), e.what()); } try { sg4::this_actor::sleep_until(end_time); @@ -283,21 +284,21 @@ class ReceiveAgent { // Make sure we have a clean slate xbt_assert(not mbox_.eager->listen(), "Eager mailbox should be empty when starting a test"); xbt_assert(not mbox_.rdv->listen(), "RDV mailbox should be empty when starting a test"); - for (; step_index < s.steps.size(); step_index++) { - const Step& step = s.steps[step_index]; - if (step.entity != Step::Entity::RCV || step.type != Step::Type::ACTION) - continue; - try { + + Action current_action; + try { + for (; step_index < s.steps.size(); step_index++) { + const Step& step = s.steps[step_index]; + if (step.entity != Step::Entity::RCV || step.type != Step::Type::ACTION) + continue; + + current_action = Action::SLEEP; sg4::this_actor::sleep_until(s.start_time + step.rel_time); - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During Sleep, failed to receive message because of a %s exception (%s)", typeid(e).name(), e.what()); - break; - } - // Check if the other host is still OK. - if (not other_host_->is_on()) - break; - // Perform the action - try { + + // Check if the other host is still OK. + if (not other_host_->is_on()) + break; + // Perform the action switch (step.action_type) { case Action::GET: comm = do_get(type, receive_ptr); @@ -311,11 +312,10 @@ class ReceiveAgent { default: xbt_die("Not a valid action for RCV"); } - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_c_str(step.action_type), - typeid(e).name(), e.what()); - break; } + } catch (const simgrid::Exception& e) { + XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_c_str(current_action), + typeid(e).name(), e.what()); } try { sg4::this_actor::sleep_until(end_time - .1); diff --git a/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp b/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp index 1bd94aff8f..d81bce5219 100644 --- a/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp +++ b/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp @@ -25,11 +25,11 @@ int main(int argc, char** argv) auto host = e.host_by_name("cpu0"); /* creation of the tasks and their dependencies */ - simgrid::s4u::ExecPtr Init = simgrid::s4u::Exec::init()->set_name("Init")->set_flops_amount(0)->vetoable_start(); - simgrid::s4u::CommPtr A = simgrid::s4u::Comm::sendto_init()->set_name("A")->set_payload_size(1e9)->vetoable_start(); - simgrid::s4u::CommPtr B = simgrid::s4u::Comm::sendto_init()->set_name("B")->vetoable_start(); - simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->vetoable_start(); - simgrid::s4u::CommPtr D = simgrid::s4u::Comm::sendto_init()->set_name("D")->set_payload_size(1e9)->vetoable_start(); + simgrid::s4u::ExecPtr Init = simgrid::s4u::Exec::init()->set_name("Init")->set_flops_amount(0)->start(); + simgrid::s4u::CommPtr A = simgrid::s4u::Comm::sendto_init()->set_name("A")->set_payload_size(1e9)->start(); + simgrid::s4u::CommPtr B = simgrid::s4u::Comm::sendto_init()->set_name("B")->start(); + simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->start(); + simgrid::s4u::CommPtr D = simgrid::s4u::Comm::sendto_init()->set_name("D")->set_payload_size(1e9)->start(); std::vector activities = {Init, A, B, C, D}; Init->add_successor(A); diff --git a/teshsuite/s4u/dependencies/dependencies.cpp b/teshsuite/s4u/dependencies/dependencies.cpp index 9ac2c0b64b..b229d70e80 100644 --- a/teshsuite/s4u/dependencies/dependencies.cpp +++ b/teshsuite/s4u/dependencies/dependencies.cpp @@ -22,10 +22,10 @@ int main(int argc, char** argv) }); /* creation of the activities and their dependencies */ - simgrid::s4u::ExecPtr A = simgrid::s4u::Exec::init()->set_name("A")->vetoable_start(); - simgrid::s4u::ExecPtr B = simgrid::s4u::Exec::init()->set_name("B")->vetoable_start(); - simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->vetoable_start(); - simgrid::s4u::ExecPtr D = simgrid::s4u::Exec::init()->set_name("D")->vetoable_start(); + simgrid::s4u::ExecPtr A = simgrid::s4u::Exec::init()->set_name("A")->start(); + simgrid::s4u::ExecPtr B = simgrid::s4u::Exec::init()->set_name("B")->start(); + simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->start(); + simgrid::s4u::ExecPtr D = simgrid::s4u::Exec::init()->set_name("D")->start(); B->add_successor(A); C->add_successor(A); diff --git a/teshsuite/surf/maxmin_bench/maxmin_bench.cpp b/teshsuite/surf/maxmin_bench/maxmin_bench.cpp index 7450918847..d316afdf42 100644 --- a/teshsuite/surf/maxmin_bench/maxmin_bench.cpp +++ b/teshsuite/surf/maxmin_bench/maxmin_bench.cpp @@ -136,8 +136,8 @@ int main(int argc, char **argv) mode=3; if(mode==1) - xbt_log_control_set("ker_lmm.threshold:DEBUG ker_lmm.fmt:\'[%r]: [%c/%p] %m%n\' " - "kernel.threshold:DEBUG kernel.fmt:\'[%r]: [%c/%p] %m%n\' "); + xbt_log_control_set("ker_lmm.threshold:DEBUG ker_lmm.fmt:'[%r]: [%c/%p] %m%n' " + "kernel.threshold:DEBUG kernel.fmt:'[%r]: [%c/%p] %m%n' "); if(mode==2) xbt_log_control_set("ker_lmm.threshold:DEBUG kernel.threshold:DEBUG"); diff --git a/tools/cmake/Flags.cmake b/tools/cmake/Flags.cmake index 2c71772f11..7ba00168ed 100644 --- a/tools/cmake/Flags.cmake +++ b/tools/cmake/Flags.cmake @@ -104,14 +104,12 @@ endif() # Do not leak the current directory into the binaries if(CMAKE_COMPILER_IS_GNUCC AND NOT enable_coverage) - execute_process(COMMAND realpath --relative-to=${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE RESULT OUTPUT_VARIABLE RELATIVE_SOURCE_DIR ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(RESULT EQUAL 0) - message(STATUS "Relative source directory is \"${RELATIVE_SOURCE_DIR}\".") - else() - message(WARNING "Failed to find relative source directory. Using \".\".") - set(RELATIVE_SOURCE_DIR ".") + if (CMAKE_VERSION VERSION_LESS "3.20") + file(RELATIVE_PATH RELATIVE_SOURCE_DIR ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + else() # cmake >= 3.20 + cmake_path(RELATIVE_PATH CMAKE_SOURCE_DIR BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE RELATIVE_SOURCE_DIR) endif() + message(STATUS "Relative source directory is \"${RELATIVE_SOURCE_DIR}\".") if (CMAKE_C_COMPILER_VERSION VERSION_LESS "8.0") set(optCFLAGS "${optCFLAGS} -fdebug-prefix-map=\"${CMAKE_SOURCE_DIR}=${RELATIVE_SOURCE_DIR}\"") else()