From 31880ce2d4d55bc634cc528493454670a998e5bd Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Tue, 10 Dec 2019 19:37:47 +0100 Subject: [PATCH] start working on adding dependencies between activities --- MANIFEST.in | 2 + examples/s4u/CMakeLists.txt | 2 +- .../s4u/exec-dependent/s4u-exec-dependent.cpp | 44 +++++++++++ .../exec-dependent/s4u-exec-dependent.tesh | 3 + include/simgrid/s4u/Activity.hpp | 73 ++++++++++++++++++- src/s4u/s4u_Activity.cpp | 1 - 6 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 examples/s4u/exec-dependent/s4u-exec-dependent.cpp create mode 100644 examples/s4u/exec-dependent/s4u-exec-dependent.tesh diff --git a/MANIFEST.in b/MANIFEST.in index 9cc9214314..bbf01b43b7 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -368,6 +368,8 @@ include examples/s4u/exec-async/s4u-exec-async.cpp include examples/s4u/exec-async/s4u-exec-async.tesh include examples/s4u/exec-basic/s4u-exec-basic.cpp include examples/s4u/exec-basic/s4u-exec-basic.tesh +include examples/s4u/exec-dependent/s4u-exec-dependent.cpp +include examples/s4u/exec-dependent/s4u-exec-dependent.tesh include examples/s4u/exec-dvfs/s4u-exec-dvfs.cpp include examples/s4u/exec-dvfs/s4u-exec-dvfs.tesh include examples/s4u/exec-ptask/s4u-exec-ptask.cpp diff --git a/examples/s4u/CMakeLists.txt b/examples/s4u/CMakeLists.txt index 7565b6ca22..839e9cb2ef 100644 --- a/examples/s4u/CMakeLists.txt +++ b/examples/s4u/CMakeLists.txt @@ -9,7 +9,7 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill cloud-capping cloud-migration cloud-simple energy-exec energy-boot energy-link energy-vm energy-exec-ptask engine-filtering - exec-async exec-basic exec-dvfs exec-ptask exec-remote exec-waitany + exec-async exec-basic exec-dvfs exec-ptask exec-remote exec-waitany exec-dependent io-async io-file-system io-file-remote io-disk-raw platform-failures platform-profile platform-properties plugin-hostload diff --git a/examples/s4u/exec-dependent/s4u-exec-dependent.cpp b/examples/s4u/exec-dependent/s4u-exec-dependent.cpp new file mode 100644 index 0000000000..1615b3330a --- /dev/null +++ b/examples/s4u/exec-dependent/s4u-exec-dependent.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example"); + +simgrid::s4u::ExecPtr second; + +static void worker() +{ + double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed(); + + simgrid::s4u::ExecPtr first = simgrid::s4u::this_actor::exec_init(computation_amount); + second = simgrid::s4u::this_actor::exec_init(computation_amount); + + first->add_successor(second.get()); + first->start(); + first->wait(); +} + +static void vetoed_worker() +{ + second->vetoable_start(); + XBT_INFO("%d %d", (int)second->get_state(), second->has_dependencies()); + second->wait(); +} + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Fafard"), worker); + simgrid::s4u::Actor::create("vetoed_worker", simgrid::s4u::Host::by_name("Fafard"), vetoed_worker); + + e.run(); + + XBT_INFO("Simulation time %g", e.get_clock()); + + return 0; +} diff --git a/examples/s4u/exec-dependent/s4u-exec-dependent.tesh b/examples/s4u/exec-dependent/s4u-exec-dependent.tesh new file mode 100644 index 0000000000..d92f9216ee --- /dev/null +++ b/examples/s4u/exec-dependent/s4u-exec-dependent.tesh @@ -0,0 +1,3 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-exec-dependent ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" diff --git a/include/simgrid/s4u/Activity.hpp b/include/simgrid/s4u/Activity.hpp index c7bc18d08c..a407160e06 100644 --- a/include/simgrid/s4u/Activity.hpp +++ b/include/simgrid/s4u/Activity.hpp @@ -7,9 +7,12 @@ #define SIMGRID_S4U_ACTIVITY_HPP #include "xbt/asserts.h" +#include "xbt/log.h" #include +#include #include #include +#include #include namespace simgrid { @@ -38,14 +41,13 @@ class XBT_PUBLIC Activity { protected: Activity() = default; virtual ~Activity() = default; - public: #ifndef DOXYGEN Activity(Activity const&) = delete; Activity& operator=(Activity const&) = delete; #endif - enum class State { INITED = 0, STARTED, CANCELED, ERRORED, FINISHED }; + enum class State { INITED = 0, STARTING, STARTED, CANCELED, ERRORED, FINISHED }; /** Starts a previously created activity. * @@ -53,7 +55,7 @@ public: */ virtual Activity* start() = 0; /** Blocks until the activity is terminated */ - virtual Activity* wait() = 0; + // virtual Activity* wait() = 0; /** Blocks until the activity is terminated, or until the timeout is elapsed * Raises: timeout exception.*/ virtual Activity* wait_for(double timeout) = 0; @@ -65,6 +67,7 @@ public: virtual Activity* cancel() = 0; /** Retrieve the current state of the activity */ Activity::State get_state() { return state_; } + void set_state(Activity::State state) { state_ = state; } /** Tests whether the given activity is terminated yet. This is a pure function. */ virtual bool test() = 0; @@ -85,12 +88,31 @@ private: double remains_ = 0; }; +// template class DependencyGuard { +// public: +// static bool activity_start_vetoer(AnyActivity* a) { return not a->has_dependencies(); } +// static void on_activity_done(AnyActivity* a); +//// { +//// while (a->has_successors()) { +//// AnyActivity* b = a->get_successor(); +//// b->remove_dependency_on(a); +//// if (not b->has_dependencies()) { +//// XBT_INFO("Activity is done and a successor can start"); +//// b->vetoable_start(); +//// } +//// a->remove_successor(); +//// } +//// } +//}; + template class Activity_T : public Activity { private: std::string name_ = ""; std::string tracing_category_ = ""; void* user_data_ = nullptr; std::atomic_int_fast32_t refcount_{0}; + std::vector successors_; + std::set dependencies_; public: #ifndef DOXYGEN @@ -103,6 +125,51 @@ public: } friend void intrusive_ptr_add_ref(AnyActivity* a) { a->refcount_.fetch_add(1, std::memory_order_relaxed); } #endif + + void add_successor(AnyActivity* a) + { + // XBT_INFO("Adding %s as a successor of %s", get_name(), a->get_name()); + successors_.push_back(a); + a->add_dependency_on(static_cast(this)); + } + void remove_successor() { successors_.pop_back(); } + AnyActivity* get_successor() { return successors_.back(); } + bool has_successors() { return not successors_.empty(); } + + void add_dependency_on(AnyActivity* a) { dependencies_.insert({a}); } + void remove_dependency_on(AnyActivity* a) { dependencies_.erase(a); } + bool has_dependencies() { return not dependencies_.empty(); } + void on_activity_done() + { + while (has_successors()) { + AnyActivity* b = get_successor(); + b->remove_dependency_on(static_cast(this)); + if (not b->has_dependencies()) { + // XBT_INFO("Activity is done and a successor can start"); + b->vetoable_start(); + } + remove_successor(); + } + } + + AnyActivity* vetoable_start() + { + set_state(State::STARTING); + if (has_dependencies()) + return static_cast(this); + // XBT_INFO("No veto, Activity can start"); + set_state(State::STARTED); + static_cast(this)->start(); + return static_cast(this); + } + + virtual AnyActivity* wait() + { + static_cast(this)->wait(); + on_activity_done(); + return static_cast(this); + } + AnyActivity* set_name(const std::string& name) { xbt_assert(get_state() == State::INITED, "Cannot change the name of an activity after its start"); diff --git a/src/s4u/s4u_Activity.cpp b/src/s4u/s4u_Activity.cpp index e52b3f2a13..14f2880d74 100644 --- a/src/s4u/s4u_Activity.cpp +++ b/src/s4u/s4u_Activity.cpp @@ -7,7 +7,6 @@ #include "simgrid/s4u/Activity.hpp" #include "simgrid/s4u/Engine.hpp" - XBT_LOG_EXTERNAL_CATEGORY(s4u); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_activity, s4u, "S4U activities"); -- 2.20.1