Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into 'photovoltaic-revamp'
authorAdrien <adrien.gougeon@ens-rennes.fr>
Thu, 21 Sep 2023 07:31:03 +0000 (07:31 +0000)
committerAdrien <adrien.gougeon@ens-rennes.fr>
Thu, 21 Sep 2023 07:31:03 +0000 (07:31 +0000)
# Conflicts:
#   examples/cpp/CMakeLists.txt
#   tools/cmake/DefinePackages.cmake

15 files changed:
ChangeLog
MANIFEST.in
docs/source/Plugins.rst
examples/cpp/CMakeLists.txt
examples/cpp/chiller-simple/s4u-chiller-simple.cpp [new file with mode: 0644]
examples/cpp/chiller-simple/s4u-chiller-simple.tesh [new file with mode: 0644]
examples/cpp/task-microservice/s4u-task-microservice.cpp [new file with mode: 0644]
examples/cpp/task-microservice/s4u-task-microservice.tesh [new file with mode: 0644]
examples/cpp/task-parallelism/s4u-task-parallelism.cpp [new file with mode: 0644]
examples/cpp/task-parallelism/s4u-task-parallelism.tesh [new file with mode: 0644]
include/simgrid/plugins/chiller.hpp [new file with mode: 0644]
include/simgrid/s4u/Task.hpp
src/plugins/chiller.cpp [new file with mode: 0644]
src/s4u/s4u_Task.cpp
tools/cmake/DefinePackages.cmake

index 26cdda0..a39a236 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -27,6 +27,8 @@ C API:
 Plugins:
  - Revamp the battery plugin: rewrite completely the API, for a better usability.
    The examples were updated accordingly.
+ - Add chiller plugin: enable the management of chillers consuming electrical energy
+   to compensate heat generated by hosts.
 
 ----------------------------------------------------------------------------
 
index 493259a..d33f19f 100644 (file)
@@ -173,6 +173,8 @@ include examples/cpp/battery-energy/s4u-battery-energy.cpp
 include examples/cpp/battery-energy/s4u-battery-energy.tesh
 include examples/cpp/battery-simple/s4u-battery-simple.cpp
 include examples/cpp/battery-simple/s4u-battery-simple.tesh
+include examples/cpp/chiller-simple/s4u-chiller-simple.cpp
+include examples/cpp/chiller-simple/s4u-chiller-simple.tesh
 include examples/cpp/cloud-capping/s4u-cloud-capping.cpp
 include examples/cpp/cloud-capping/s4u-cloud-capping.tesh
 include examples/cpp/cloud-migration/s4u-cloud-migration.cpp
@@ -394,6 +396,10 @@ include examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp
 include examples/cpp/synchro-semaphore/s4u-synchro-semaphore.tesh
 include examples/cpp/task-io/s4u-task-io.cpp
 include examples/cpp/task-io/s4u-task-io.tesh
+include examples/cpp/task-microservice/s4u-task-microservice.cpp
+include examples/cpp/task-microservice/s4u-task-microservice.tesh
+include examples/cpp/task-parallelism/s4u-task-parallelism.cpp
+include examples/cpp/task-parallelism/s4u-task-parallelism.tesh
 include examples/cpp/task-simple/s4u-task-simple.cpp
 include examples/cpp/task-simple/s4u-task-simple.tesh
 include examples/cpp/task-storm/s4u-task-storm.cpp
@@ -1935,6 +1941,7 @@ include include/simgrid/modelchecker.h
 include include/simgrid/mutex.h
 include include/simgrid/plugins/ProducerConsumer.hpp
 include include/simgrid/plugins/battery.hpp
+include include/simgrid/plugins/chiller.hpp
 include include/simgrid/plugins/dvfs.h
 include include/simgrid/plugins/energy.h
 include include/simgrid/plugins/file_system.h
@@ -2311,6 +2318,7 @@ include src/mc/transition/TransitionSynchro.hpp
 include src/plugins/ProducerConsumer.cpp
 include src/plugins/battery.cpp
 include src/plugins/chaos_monkey.cpp
+include src/plugins/chiller.cpp
 include src/plugins/file_system/s4u_FileSystem.cpp
 include src/plugins/host_dvfs.cpp
 include src/plugins/host_energy.cpp
index 003b81f..683bb4f 100644 (file)
@@ -231,4 +231,9 @@ Solar Panel
 
 .. doxygengroup:: plugin_solar_panel
 
+Chiller
+===========
+
+.. doxygengroup:: plugin_chiller
+
 ..  LocalWords:  SimGrid
index 4907fdf..2ddf038 100644 (file)
@@ -158,6 +158,7 @@ foreach (example activityset-testany activityset-waitany activityset-waitall act
                  actor-lifetime actor-migrate actor-suspend actor-yield actor-stacksize
                  app-bittorrent app-chainsend app-token-ring
                  battery-degradation battery-simple battery-energy
+                 chiller-simple
                  comm-pingpong comm-ready comm-suspend comm-wait comm-waituntil
                  comm-dependent comm-host2host comm-failure comm-throttling
                  cloud-capping cloud-migration cloud-simple
@@ -171,7 +172,7 @@ foreach (example activityset-testany activityset-waitany activityset-waitall act
                  mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-bugged2-liveness mc-centralized-mutex mc-electric-fence mc-failing-assert
                  network-ns3 network-ns3-wifi network-wifi
                  io-async io-priority io-degradation io-file-system io-file-remote io-disk-raw io-dependent
-                 task-io task-simple task-variable-load task-storm task-switch-host
+                 task-io task-microservice task-parallelism task-simple task-storm task-switch-host task-variable-load 
                  solar-panel-simple
                  platform-comm-serialize platform-failures platform-profile platform-properties
                  plugin-host-load plugin-jbod plugin-link-load plugin-prodcons
diff --git a/examples/cpp/chiller-simple/s4u-chiller-simple.cpp b/examples/cpp/chiller-simple/s4u-chiller-simple.cpp
new file mode 100644 (file)
index 0000000..c5a45b3
--- /dev/null
@@ -0,0 +1,78 @@
+/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "simgrid/plugins/chiller.hpp"
+#include "simgrid/plugins/energy.h"
+#include "simgrid/s4u.hpp"
+#include <xbt/log.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(chiller_simple, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
+
+static void manager(simgrid::plugins::ChillerPtr c)
+{
+  XBT_INFO("Initial state: ");
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+
+  XBT_INFO("The machines slowly heat up the room.");
+  simgrid::s4u::this_actor::sleep_until(400);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_until(800);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_until(1000);
+  XBT_INFO("The Chiller now compensates the heat generated by the machines.");
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_until(1200);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+
+  XBT_INFO("Let's compute something.");
+  sg4::this_actor::exec_async(1e10);
+  simgrid::s4u::this_actor::sleep_until(1250);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+
+  simgrid::s4u::this_actor::sleep_until(1300);
+  XBT_INFO("Computation done.");
+
+  simgrid::s4u::this_actor::sleep_until(1400);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+
+  XBT_INFO("Now let's stress the chiller by decreasing the goal temperature to 23°C.");
+  c->set_goal_temp(23);
+  simgrid::s4u::this_actor::sleep_until(1600);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_until(1800);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_until(2000);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+  simgrid::s4u::this_actor::sleep_until(2200);
+  XBT_INFO("%s: Power: %fW T_in: %f°C Energy consumed: %fJ", c->get_cname(), c->get_power(), c->get_temp_in(),
+           c->get_energy_consumed());
+}
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+  sg_host_energy_plugin_init();
+
+  auto chiller = simgrid::plugins::Chiller::init("Chiller", 294, 1006, 0.2, 0.9, 23, 24, 1000);
+  chiller->add_host(e.host_by_name("MyHost1"));
+  chiller->add_host(e.host_by_name("MyHost2"));
+  chiller->add_host(e.host_by_name("MyHost3"));
+  sg4::Actor::create("sender", e.host_by_name("MyHost1"), manager, chiller);
+
+  e.run();
+  return 0;
+}
diff --git a/examples/cpp/chiller-simple/s4u-chiller-simple.tesh b/examples/cpp/chiller-simple/s4u-chiller-simple.tesh
new file mode 100644 (file)
index 0000000..c1d4c27
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-chiller-simple ${platfdir}/energy_platform.xml
+> [MyHost1:sender:(1) 0.000000] [chiller_simple/INFO] Initial state: 
+> [MyHost1:sender:(1) 0.000000] [chiller_simple/INFO] Chiller: Power: 0.000000W T_in: 23.000000°C Energy consumed: 0.000000J
+> [MyHost1:sender:(1) 0.000000] [chiller_simple/INFO] The machines slowly heat up the room.
+> [MyHost1:sender:(1) 400.000000] [chiller_simple/INFO] Chiller: Power: 0.000000W T_in: 23.486875°C Energy consumed: 0.000000J
+> [MyHost1:sender:(1) 800.000000] [chiller_simple/INFO] Chiller: Power: 0.000000W T_in: 23.973749°C Energy consumed: 0.000000J
+> [MyHost1:sender:(1) 1000.000000] [chiller_simple/INFO] The Chiller now compensates the heat generated by the machines.
+> [MyHost1:sender:(1) 1000.000000] [chiller_simple/INFO] Chiller: Power: 356.866667W T_in: 24.000000°C Energy consumed: 71373.333333J
+> [MyHost1:sender:(1) 1200.000000] [chiller_simple/INFO] Chiller: Power: 400.000000W T_in: 24.000000°C Energy consumed: 151373.333333J
+> [MyHost1:sender:(1) 1200.000000] [chiller_simple/INFO] Let's compute something.
+> [MyHost1:sender:(1) 1250.000000] [chiller_simple/INFO] Chiller: Power: 426.666667W T_in: 24.000000°C Energy consumed: 172706.666667J
+> [MyHost1:sender:(1) 1300.000000] [chiller_simple/INFO] Computation done.
+> [MyHost1:sender:(1) 1400.000000] [chiller_simple/INFO] Chiller: Power: 400.000000W T_in: 24.000000°C Energy consumed: 234040.000000J
+> [MyHost1:sender:(1) 1400.000000] [chiller_simple/INFO] Now let's stress the chiller by decreasing the goal temperature to 23°C.
+> [MyHost1:sender:(1) 1600.000000] [chiller_simple/INFO] Chiller: Power: 1000.000000W T_in: 23.634844°C Energy consumed: 434040.000000J
+> [MyHost1:sender:(1) 1800.000000] [chiller_simple/INFO] Chiller: Power: 1000.000000W T_in: 23.269688°C Energy consumed: 634040.000000J
+> [MyHost1:sender:(1) 2000.000000] [chiller_simple/INFO] Chiller: Power: 843.133333W T_in: 23.000000°C Energy consumed: 802666.666667J
+> [MyHost1:sender:(1) 2200.000000] [chiller_simple/INFO] Chiller: Power: 400.000000W T_in: 23.000000°C Energy consumed: 882666.666667J
+> [2200.000000] [host_energy/INFO] Total energy consumption: 662000.000000 Joules (used hosts: 222000.000000 Joules; unused/idle hosts: 440000.000000)
+> [2200.000000] [host_energy/INFO] Energy consumption of host MyHost1: 222000.000000 Joules
+> [2200.000000] [host_energy/INFO] Energy consumption of host MyHost2: 220000.000000 Joules
+> [2200.000000] [host_energy/INFO] Energy consumption of host MyHost3: 220000.000000 Joules
diff --git a/examples/cpp/task-microservice/s4u-task-microservice.cpp b/examples/cpp/task-microservice/s4u-task-microservice.cpp
new file mode 100644 (file)
index 0000000..5c449e8
--- /dev/null
@@ -0,0 +1,145 @@
+/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+/* This example illustrates how to use Simgrid Tasks to reproduce the workflow 2.a of the article
+ * "Automated performance prediction of microservice applications using simulation" by Clément Courageux-Sudan et al.
+ *
+ * To build this workflow we create;
+ *   - each Execution Task
+ *   - each Communication Task
+ *   - the links between the Tasks, i.e. the graph
+ *
+ * We also increase the parallelism degree of each Task to 10.
+ *
+ * In this scenario we send 500 requests per second (RPS) to the entry point of the graph for 7 seconds,
+ * and we count the number of processed requests between 2 and 7 seconds to evaluate the number of requests processed
+ * per second.
+ */
+
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(task_microservice, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
+
+static void request_sender(sg4::TaskPtr t, int requests_per_second)
+{
+  for (int i = 0; i < requests_per_second * 7; i++) {
+    t->enqueue_firings(1);
+    sg4::this_actor::sleep_for(1.0 / requests_per_second);
+  }
+}
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+
+  // Retrieve Hosts
+  auto pm0 = e.host_by_name("PM0");
+  auto pm1 = e.host_by_name("PM1");
+
+  // Set concurrency limit
+  pm0->set_concurrency_limit(10);
+  pm1->set_concurrency_limit(10);
+
+  // Create Exec Tasks
+  auto nginx_web_server        = sg4::ExecTask::init("nginx_web_server", 783 * pm0->get_speed() / 1e6, pm0);
+  auto compose_post_service_0  = sg4::ExecTask::init("compose_post_service_0", 682 * pm0->get_speed() / 1e6, pm0);
+  auto unique_id_service       = sg4::ExecTask::init("unique_id_service", 12 * pm0->get_speed() / 1e6, pm0);
+  auto compose_post_service_1  = sg4::ExecTask::init("compose_post_service_1", 140 * pm0->get_speed() / 1e6, pm0);
+  auto media_service           = sg4::ExecTask::init("media_service", 6 * pm1->get_speed() / 1e6, pm1);
+  auto compose_post_service_2  = sg4::ExecTask::init("compose_post_service_2", 135 * pm0->get_speed() / 1e6, pm0);
+  auto user_service            = sg4::ExecTask::init("user_service", 5 * pm0->get_speed() / 1e6, pm0);
+  auto compose_post_service_3  = sg4::ExecTask::init("compose_post_service_3", 147 * pm0->get_speed() / 1e6, pm0);
+  auto text_service_0          = sg4::ExecTask::init("text_service_0", 296 * pm0->get_speed() / 1e6, pm0);
+  auto text_service_1          = sg4::ExecTask::init("text_service_1", 350 * pm0->get_speed() / 1e6, pm0);
+  auto text_service_2          = sg4::ExecTask::init("text_service_2", 146 * pm0->get_speed() / 1e6, pm0);
+  auto user_mention_service    = sg4::ExecTask::init("user_mention_service", 934 * pm0->get_speed() / 1e6, pm0);
+  auto url_shorten_service     = sg4::ExecTask::init("url_shorten_service", 555 * pm0->get_speed() / 1e6, pm0);
+  auto compose_post_service_4  = sg4::ExecTask::init("compose_post_service_4", 138 * pm0->get_speed() / 1e6, pm0);
+  auto home_timeline_service_0 = sg4::ExecTask::init("home_timeline_service_0", 243 * pm0->get_speed() / 1e6, pm0);
+  auto social_graph_service    = sg4::ExecTask::init("home_timeline_service_0", 707 * pm0->get_speed() / 1e6, pm0);
+  auto home_timeline_service_1 = sg4::ExecTask::init("home_timeline_service_0", 7 * pm0->get_speed() / 1e6, pm0);
+  auto compose_post_service_5  = sg4::ExecTask::init("compose_post_service_5", 192 * pm0->get_speed() / 1e6, pm0);
+  auto user_timeline_service   = sg4::ExecTask::init("user_timeline_service", 913 * pm0->get_speed() / 1e6, pm0);
+  auto compose_post_service_6  = sg4::ExecTask::init("compose_post_service_6", 508 * pm0->get_speed() / 1e6, pm0);
+  auto post_storage_service    = sg4::ExecTask::init("post_storage_service", 391 * pm1->get_speed() / 1e6, pm1);
+
+  // Create Comm Tasks
+  auto compose_post_service_1_to_media_service =
+      sg4::CommTask::init("compose_post_service_1_to_media_service", 100, pm0, pm1);
+  auto media_service_to_compose_post_service_2 =
+      sg4::CommTask::init("media_service_to_compose_post_service_2", 100, pm1, pm0);
+  auto compose_post_service_6_to_post_storage_service =
+      sg4::CommTask::init("media_service_to_compose_post_service_2", 100, pm1, pm0);
+
+  // Create the graph
+  nginx_web_server->add_successor(compose_post_service_0);
+  compose_post_service_0->add_successor(unique_id_service);
+  unique_id_service->add_successor(compose_post_service_1);
+  compose_post_service_1->add_successor(compose_post_service_1_to_media_service);
+  compose_post_service_1_to_media_service->add_successor(media_service);
+  media_service->add_successor(media_service_to_compose_post_service_2);
+  media_service_to_compose_post_service_2->add_successor(compose_post_service_2);
+  compose_post_service_2->add_successor(user_service);
+  user_service->add_successor(compose_post_service_3);
+  compose_post_service_3->add_successor(text_service_0);
+  text_service_0->add_successor(text_service_1);
+  text_service_0->add_successor(text_service_2);
+  text_service_1->add_successor(user_mention_service);
+  text_service_2->add_successor(url_shorten_service);
+  user_mention_service->add_successor(compose_post_service_4);
+  compose_post_service_4->add_successor(home_timeline_service_0);
+  home_timeline_service_0->add_successor(social_graph_service);
+  social_graph_service->add_successor(home_timeline_service_1);
+  home_timeline_service_1->add_successor(compose_post_service_5);
+  compose_post_service_5->add_successor(user_timeline_service);
+  user_timeline_service->add_successor(compose_post_service_6);
+  compose_post_service_6->add_successor(compose_post_service_6_to_post_storage_service);
+  compose_post_service_6_to_post_storage_service->add_successor(post_storage_service);
+
+  // Dispatch Exec Tasks
+  std::vector<sg4::TaskPtr> exec_tasks = {nginx_web_server,
+                                          compose_post_service_0,
+                                          unique_id_service,
+                                          compose_post_service_1,
+                                          compose_post_service_1_to_media_service,
+                                          media_service,
+                                          media_service_to_compose_post_service_2,
+                                          compose_post_service_2,
+                                          user_service,
+                                          compose_post_service_3,
+                                          text_service_0,
+                                          text_service_1,
+                                          text_service_2,
+                                          user_mention_service,
+                                          url_shorten_service,
+                                          compose_post_service_4,
+                                          home_timeline_service_0,
+                                          social_graph_service,
+                                          home_timeline_service_1,
+                                          compose_post_service_5,
+                                          user_timeline_service,
+                                          compose_post_service_6,
+                                          compose_post_service_6_to_post_storage_service,
+                                          post_storage_service};
+  for (auto t : exec_tasks)
+    t->set_parallelism_degree(10);
+
+  // Create the actor that will inject requests during the simulation
+  sg4::Actor::create("request_sender", pm0, request_sender, nginx_web_server, 500);
+
+  // Add a function to be called when tasks end for log purpose
+  int requests_processed = 0;
+  sg4::Task::on_completion_cb([&e, &requests_processed](const sg4::Task* t) {
+    if (t->get_name() == "post_storage_service" and e.get_clock() < 7 and e.get_clock() > 2)
+      requests_processed++;
+  });
+
+  // Start the simulation
+  e.run();
+  XBT_INFO("Requests processed per second: %f", requests_processed / 5.0);
+  return 0;
+}
diff --git a/examples/cpp/task-microservice/s4u-task-microservice.tesh b/examples/cpp/task-microservice/s4u-task-microservice.tesh
new file mode 100644 (file)
index 0000000..9a95e44
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-task-microservice ${platfdir}/three_multicore_hosts.xml
+> [7.008495] [task_microservice/INFO] Requests processed per second: 500.000000
\ No newline at end of file
diff --git a/examples/cpp/task-parallelism/s4u-task-parallelism.cpp b/examples/cpp/task-parallelism/s4u-task-parallelism.cpp
new file mode 100644 (file)
index 0000000..c9f70da
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+/* This example tests increasing and decreasing parallelism degree of Tasks.
+ * First we increase and decrease parallelism degree while the Task is idle,
+ * then we increase and decrease parallelism degree while the Task has queued firings.
+ */
+
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(task_parallelism, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
+
+static void manager(sg4::ExecTaskPtr t)
+{
+  t->set_parallelism_degree(1);
+  t->enqueue_firings(2);
+  sg4::this_actor::sleep_for(300);
+
+  t->set_parallelism_degree(2);
+  t->enqueue_firings(4);
+  sg4::this_actor::sleep_for(300);
+
+  t->set_parallelism_degree(1);
+  t->enqueue_firings(2);
+  sg4::this_actor::sleep_for(300);
+
+  t->enqueue_firings(11);
+  t->set_parallelism_degree(2);
+  sg4::this_actor::sleep_for(150);
+  t->set_parallelism_degree(1);
+  sg4::this_actor::sleep_for(200);
+  t->set_parallelism_degree(3);
+}
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+  auto pm0 = e.host_by_name("PM0");
+  auto t   = sg4::ExecTask::init("exec_A", 100 * pm0->get_speed(), pm0);
+  sg4::Task::on_completion_cb(
+      [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_cname(), t->get_count()); });
+  sg4::Task::on_start_cb([](const sg4::Task* t) { XBT_INFO("Task %s start", t->get_cname()); });
+  sg4::Actor::create("sender", pm0, manager, t);
+
+  e.run();
+  return 0;
+}
diff --git a/examples/cpp/task-parallelism/s4u-task-parallelism.tesh b/examples/cpp/task-parallelism/s4u-task-parallelism.tesh
new file mode 100644 (file)
index 0000000..938ad96
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-task-parallelism ${platfdir}/three_multicore_hosts.xml
+> [0.000000] [task_parallelism/INFO] Task exec_A start
+> [100.000000] [task_parallelism/INFO] Task exec_A finished (1)
+> [100.000000] [task_parallelism/INFO] Task exec_A start
+> [200.000000] [task_parallelism/INFO] Task exec_A finished (2)
+> [300.000000] [task_parallelism/INFO] Task exec_A start
+> [300.000000] [task_parallelism/INFO] Task exec_A start
+> [400.000000] [task_parallelism/INFO] Task exec_A finished (3)
+> [400.000000] [task_parallelism/INFO] Task exec_A start
+> [400.000000] [task_parallelism/INFO] Task exec_A finished (4)
+> [400.000000] [task_parallelism/INFO] Task exec_A start
+> [500.000000] [task_parallelism/INFO] Task exec_A finished (5)
+> [500.000000] [task_parallelism/INFO] Task exec_A finished (6)
+> [600.000000] [task_parallelism/INFO] Task exec_A start
+> [700.000000] [task_parallelism/INFO] Task exec_A finished (7)
+> [700.000000] [task_parallelism/INFO] Task exec_A start
+> [800.000000] [task_parallelism/INFO] Task exec_A finished (8)
+> [900.000000] [task_parallelism/INFO] Task exec_A start
+> [900.000000] [task_parallelism/INFO] Task exec_A start
+> [1000.000000] [task_parallelism/INFO] Task exec_A finished (9)
+> [1000.000000] [task_parallelism/INFO] Task exec_A start
+> [1000.000000] [task_parallelism/INFO] Task exec_A finished (10)
+> [1000.000000] [task_parallelism/INFO] Task exec_A start
+> [1100.000000] [task_parallelism/INFO] Task exec_A finished (11)
+> [1100.000000] [task_parallelism/INFO] Task exec_A finished (12)
+> [1100.000000] [task_parallelism/INFO] Task exec_A start
+> [1200.000000] [task_parallelism/INFO] Task exec_A finished (13)
+> [1200.000000] [task_parallelism/INFO] Task exec_A start
+> [1250.000000] [task_parallelism/INFO] Task exec_A start
+> [1250.000000] [task_parallelism/INFO] Task exec_A start
+> [1300.000000] [task_parallelism/INFO] Task exec_A finished (14)
+> [1300.000000] [task_parallelism/INFO] Task exec_A start
+> [1350.000000] [task_parallelism/INFO] Task exec_A finished (15)
+> [1350.000000] [task_parallelism/INFO] Task exec_A start
+> [1350.000000] [task_parallelism/INFO] Task exec_A finished (16)
+> [1350.000000] [task_parallelism/INFO] Task exec_A start
+> [1400.000000] [task_parallelism/INFO] Task exec_A finished (17)
+> [1450.000000] [task_parallelism/INFO] Task exec_A finished (18)
+> [1450.000000] [task_parallelism/INFO] Task exec_A finished (19)
\ No newline at end of file
diff --git a/include/simgrid/plugins/chiller.hpp b/include/simgrid/plugins/chiller.hpp
new file mode 100644 (file)
index 0000000..b60e03d
--- /dev/null
@@ -0,0 +1,102 @@
+/* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+#ifndef SIMGRID_PLUGINS_CHILLER_H_
+#define SIMGRID_PLUGINS_CHILLER_H_
+
+#include <simgrid/kernel/resource/Model.hpp>
+#include <simgrid/s4u/Activity.hpp>
+#include <xbt/Extendable.hpp>
+
+namespace simgrid::plugins {
+
+class Chiller;
+using ChillerPtr = boost::intrusive_ptr<Chiller>;
+XBT_PUBLIC void intrusive_ptr_release(Chiller* o);
+XBT_PUBLIC void intrusive_ptr_add_ref(Chiller* o);
+
+class ChillerModel : public kernel::resource::Model {
+  std::vector<ChillerPtr> chillers_;
+
+public:
+  explicit ChillerModel();
+
+  void add_chiller(ChillerPtr b);
+  void update_actions_state(double now, double delta) override;
+  double next_occurring_event(double now) override;
+};
+
+class Chiller {
+
+  friend ChillerModel;
+
+private:
+  static std::shared_ptr<ChillerModel> chiller_model_;
+
+  std::string name_;
+  double air_mass_kg_;
+  double specific_heat_j_per_kg_per_c_;
+  double alpha_;
+  double cooling_efficiency_;
+  double temp_in_c_;
+  double temp_out_c_;
+  double goal_temp_c_;
+  double max_power_w_;
+
+  std::set<const s4u::Host*> hosts_ = {};
+  bool active_                      = true;
+  double power_w_                   = 0;
+  double energy_consumed_j_         = 0;
+  double last_updated_              = 0;
+
+  explicit Chiller(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha,
+                   double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w);
+
+  static void init_plugin();
+  void update();
+
+  std::atomic_int_fast32_t refcount_{0};
+#ifndef DOXYGEN
+  friend void intrusive_ptr_release(Chiller* o)
+  {
+    if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
+      std::atomic_thread_fence(std::memory_order_acquire);
+      delete o;
+    }
+  }
+  friend void intrusive_ptr_add_ref(Chiller* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); }
+#endif
+
+public:
+  static ChillerPtr init(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha,
+                         double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w);
+
+  ChillerPtr set_name(std::string name);
+  ChillerPtr set_air_mass(double air_mass_kg);
+  ChillerPtr set_specific_heat(double specific_heat_j_per_kg_per_c);
+  ChillerPtr set_alpha(double alpha);
+  ChillerPtr set_cooling_efficiency(double cooling_efficiency);
+  ChillerPtr set_goal_temp(double goal_temp_c);
+  ChillerPtr set_max_power(double max_power_w);
+  ChillerPtr set_active(bool active);
+  ChillerPtr add_host(s4u::Host* host);
+  ChillerPtr remove_host(s4u::Host* host);
+
+  std::string get_name() { return name_; }
+  const char* get_cname() { return name_.c_str(); }
+  double get_air_mass() { return air_mass_kg_; }
+  double get_specific_heat() { return specific_heat_j_per_kg_per_c_; }
+  double get_alpha() { return alpha_; }
+  double get_cooling_efficiency() { return cooling_efficiency_; }
+  double get_goal_temp() { return goal_temp_c_; }
+  double get_max_power() { return max_power_w_; }
+  bool is_active() { return active_; }
+  double get_temp_in() { return temp_in_c_; }
+  double get_temp_out() { return temp_out_c_; }
+  double get_power() { return power_w_; }
+  double get_energy_consumed() { return energy_consumed_j_; }
+};
+
+} // namespace simgrid::plugins
+#endif
index f854adb..36e6e0d 100644 (file)
@@ -29,9 +29,10 @@ class XBT_PUBLIC Token : public xbt::Extendable<Token> {};
 class Task {
   std::string name_;
   double amount_;
-  int queued_firings_ = 0;
-  int count_          = 0;
-  bool working_       = false;
+  int queued_firings_     = 0;
+  int count_              = 0;
+  int running_instances_  = 0;
+  int parallelism_degree_ = 1;
 
   std::set<Task*> successors_                 = {};
   std::map<Task*, unsigned int> predecessors_ = {};
@@ -42,8 +43,7 @@ class Task {
 
   std::shared_ptr<Token> token_ = nullptr;
   std::deque<std::map<TaskPtr, std::shared_ptr<Token>>> tokens_received_;
-  ActivityPtr previous_activity_;
-  ActivityPtr current_activity_;
+  std::deque<ActivityPtr> current_activities_;
 
   inline static xbt::signal<void(Task*)> on_start;
   xbt::signal<void(Task*)> on_this_start;
@@ -57,14 +57,17 @@ protected:
   virtual void fire();
   void complete();
 
-  void set_current_activity(ActivityPtr a) { current_activity_ = a; }
+  void store_activity(ActivityPtr a) { current_activities_.push_back(a); }
 
 public:
+  void set_name(std::string name);
   const std::string& get_name() const { return name_; }
   const char* get_cname() const { return name_.c_str(); }
   void set_amount(double amount);
   double get_amount() const { return amount_; }
   int get_count() const { return count_; }
+  void set_parallelism_degree(int n);
+  int get_parallelism_degree() { return parallelism_degree_; }
 
   void set_token(std::shared_ptr<Token> token);
   std::shared_ptr<Token> get_next_token_from(TaskPtr t);
diff --git a/src/plugins/chiller.cpp b/src/plugins/chiller.cpp
new file mode 100644 (file)
index 0000000..8000377
--- /dev/null
@@ -0,0 +1,287 @@
+/* Copyright (c) 2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+#include <simgrid/Exception.hpp>
+#include <simgrid/plugins/chiller.hpp>
+#include <simgrid/plugins/energy.h>
+#include <simgrid/simix.hpp>
+#include <xbt/asserts.h>
+#include <xbt/log.h>
+
+#include "src/kernel/resource/CpuImpl.hpp"
+#include "src/simgrid/module.hpp"
+
+SIMGRID_REGISTER_PLUGIN(chiller, "Chiller management", nullptr)
+
+/** @defgroup plugin_chiller Plugin Chiller
+
+  @beginrst
+
+This is the chiller plugin, enabling management of chillers.
+
+Chiller
+....................
+
+A chiller is placed inside a room with several machines. The role of the chiller is to keep the temperature of the room
+below a threshold. This plugin and its equations are based on the paper "Co-simulation of FMUs and Distributed
+Applications with SimGrid" by Camus et al. (https://hal.science/hal-01762540).
+
+The heat generated inside the room :math:`Q_{room}` depends on the heat from the machines :math:`Q_{machines}` and
+from the heat of the other devices, such as lighing, accounted using a factor :math:`\alpha` such as:
+
+.. math::
+
+  Q_{room} = (1 + \alpha) \times Q_{machines}
+
+This energy heats the input temperature :math:`T_{in}` and gives an output temperature :math:`T_{out}` based on the the
+mass of air inside the room :math:`m_{air}` and its specific heat :math:`C_{p}`:
+
+.. math::
+
+  T_{out} = T_{in} + {Q_{room} \over m_{air} \times C_{p}}
+
+If the output temperature is above the goal temperature :math:`T_{goal}` the chiller compensates the excessive heat
+using electrical energy :math:`Q_{cooling}` depending on its cooling efficiency :math:`\eta_{cooling}` :
+
+.. math::
+
+  Q_{cooling} = (T_{out} - T_{goal}) \times m_{air} \times C_{p} / \eta_{cooling}
+
+The chiller has a power threshold that cannot be exceeded. If the power needed is above this threshold, or if the
+chiller is not active, the temperature of the room increases.
+
+  @endrst
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Chiller, kernel, "Logging specific to the solar panel plugin");
+
+namespace simgrid::plugins {
+
+/* ChillerModel */
+
+ChillerModel::ChillerModel() : Model("ChillerModel") {}
+
+void ChillerModel::add_chiller(ChillerPtr c)
+{
+  chillers_.push_back(c);
+}
+
+void ChillerModel::update_actions_state(double now, double delta)
+{
+  for (auto chiller : chillers_)
+    chiller->update();
+}
+
+double ChillerModel::next_occurring_event(double now)
+{
+  return -1;
+}
+
+/* Chiller */
+
+std::shared_ptr<ChillerModel> Chiller::chiller_model_;
+
+void Chiller::init_plugin()
+{
+  auto model = std::make_shared<ChillerModel>();
+  simgrid::s4u::Engine::get_instance()->add_model(model);
+  Chiller::chiller_model_ = model;
+}
+
+void Chiller::update()
+{
+  simgrid::kernel::actor::simcall_answered([this] {
+    double now          = s4u::Engine::get_clock();
+    double time_delta_s = now - last_updated_;
+
+    if (time_delta_s <= 0)
+      return;
+
+    double hosts_power_w = 0;
+    for (auto const& host : hosts_)
+      hosts_power_w += sg_host_get_current_consumption(host);
+    double heat_generated_j = hosts_power_w * (1 + alpha_) * time_delta_s;
+    temp_out_c_             = temp_in_c_ + heat_generated_j / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
+    double delta_temp_c     = temp_out_c_ - goal_temp_c_;
+
+    if (not active_ or delta_temp_c < 0) {
+      temp_in_c_    = temp_out_c_;
+      power_w_      = 0;
+      last_updated_ = now;
+      return;
+    }
+
+    double cooling_demand_w = delta_temp_c * air_mass_kg_ * specific_heat_j_per_kg_per_c_ / time_delta_s;
+    if (cooling_demand_w / cooling_efficiency_ <= max_power_w_) {
+      power_w_   = cooling_demand_w / cooling_efficiency_;
+      temp_in_c_ = temp_out_c_ -
+                   (power_w_ * time_delta_s * cooling_efficiency_) / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
+    } else {
+      power_w_   = max_power_w_;
+      temp_in_c_ = temp_out_c_ -
+                   (power_w_ * time_delta_s * cooling_efficiency_) / (air_mass_kg_ * specific_heat_j_per_kg_per_c_);
+    }
+
+    energy_consumed_j_ += power_w_ * time_delta_s;
+    last_updated_ = now;
+  });
+}
+
+Chiller::Chiller(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha,
+                 double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w)
+    : name_(name)
+    , air_mass_kg_(air_mass_kg)
+    , specific_heat_j_per_kg_per_c_(specific_heat_j_per_kg_per_c)
+    , alpha_(alpha)
+    , cooling_efficiency_(cooling_efficiency)
+    , temp_in_c_(initial_temp_c)
+    , temp_out_c_(initial_temp_c)
+    , goal_temp_c_(goal_temp_c)
+    , max_power_w_(max_power_w)
+{
+  xbt_assert(air_mass_kg > 0, ": air mass must be > 0 (provided: %f)", air_mass_kg);
+  xbt_assert(specific_heat_j_per_kg_per_c > 0, ": specific heat must be > 0 (provided: %f)",
+             specific_heat_j_per_kg_per_c);
+  xbt_assert(alpha >= 0, ": alpha must be >= 0 (provided: %f)", alpha);
+  xbt_assert(cooling_efficiency >= 0 and cooling_efficiency <= 1,
+             ": cooling efficiency must be in [0,1] (provided: %f)", cooling_efficiency);
+  xbt_assert(max_power_w >= 0, ": maximal power must be >=0 (provided: %f)", max_power_w);
+}
+
+/** @ingroup plugin_chiller
+ *  @param name The name of the Chiller.
+ *  @param air_mass_kg The air mass of the room managed by the Chiller in kg (> 0).
+ *  @param specific_heat_j_per_kg_per_c The specific heat of air in J per kg per °C (> 0).
+ *  @param alpha The ratio of the other devices in the total heat dissipation (e.g. lighting, Power Distribution Unit)
+ * (>= 0).
+ *  @param cooling_efficiency The cooling efficiency of the Chiller [0, 1].
+ *  @param initial_temp_c The initial temperature of the room managed by the Chiller.
+ *  @param goal_temp_c The goal temperature of the room. The Chiller is idle below this temperature.
+ *  @param max_power_w The maximal power delivered by the Chiller in W (> 0). If this power is reached the room
+ * temperature will raise above the goal temperature.
+ *  @return A ChillerPtr pointing to the new Chiller.
+ */
+ChillerPtr Chiller::init(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha,
+                         double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w)
+{
+  static bool plugin_inited = false;
+  if (not plugin_inited) {
+    init_plugin();
+    plugin_inited = true;
+  }
+  auto chiller = ChillerPtr(new Chiller(name, air_mass_kg, specific_heat_j_per_kg_per_c, alpha, cooling_efficiency,
+                                        initial_temp_c, goal_temp_c, max_power_w));
+  chiller_model_->add_chiller(chiller);
+  return chiller;
+}
+
+/** @ingroup plugin_chiller
+ *  @param name The new name of the Chiller.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_name(std::string name)
+{
+  simgrid::kernel::actor::simcall_answered([this, name] { name_ = name; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param air_mass_kg The new air mass of the Chiller in kg.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_air_mass(double air_mass_kg)
+{
+  xbt_assert(air_mass_kg > 0, ": air mass must be > 0 (provided: %f)", air_mass_kg);
+  simgrid::kernel::actor::simcall_answered([this, air_mass_kg] { air_mass_kg_ = air_mass_kg; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param specific_heat_j_per_kg_per_c The specific heat of the Chiller in J per kg per °C.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_specific_heat(double specific_heat_j_per_kg_per_c)
+{
+  xbt_assert(specific_heat_j_per_kg_per_c > 0, ": specific heat must be > 0 (provided: %f)",
+             specific_heat_j_per_kg_per_c);
+  simgrid::kernel::actor::simcall_answered(
+      [this, specific_heat_j_per_kg_per_c] { specific_heat_j_per_kg_per_c_ = specific_heat_j_per_kg_per_c; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param alpha The new alpha of the Chiller.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_alpha(double alpha)
+{
+  xbt_assert(alpha >= 0, ": alpha must be >= 0 (provided: %f)", alpha);
+  simgrid::kernel::actor::simcall_answered([this, alpha] { alpha_ = alpha; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param cooling_efficiency The new coolingefficiency of the Chiller.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_cooling_efficiency(double cooling_efficiency)
+{
+  xbt_assert(cooling_efficiency >= 0 and cooling_efficiency <= 1,
+             ": cooling efficiency must be in [0,1] (provided: %f)", cooling_efficiency);
+  simgrid::kernel::actor::simcall_answered([this, cooling_efficiency] { cooling_efficiency_ = cooling_efficiency; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param goal_temp_c The new goal temperature of the Chiller in °C.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_goal_temp(double goal_temp_c)
+{
+  simgrid::kernel::actor::simcall_answered([this, goal_temp_c] { goal_temp_c_ = goal_temp_c; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param max_power_w The new maximal power of the Chiller in W.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_max_power(double max_power_w)
+{
+  xbt_assert(max_power_w >= 0, ": maximal power must be >=0 (provided: %f)", max_power_w);
+  simgrid::kernel::actor::simcall_answered([this, max_power_w] { max_power_w_ = max_power_w; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param active The new active status of the Chiller.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::set_active(bool active)
+{
+  simgrid::kernel::actor::simcall_answered([this, active] { active_ = active; });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param host The host to add to the room managed by the Chiller.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::add_host(s4u::Host* host)
+{
+  simgrid::kernel::actor::simcall_answered([this, host] { hosts_.insert(host); });
+  return this;
+}
+
+/** @ingroup plugin_chiller
+ *  @param host The host to remove from the room managed by the Chiller.
+ *  @return A ChillerPtr pointing to the modified Chiller.
+ */
+ChillerPtr Chiller::remove_host(s4u::Host* host)
+{
+  simgrid::kernel::actor::simcall_answered([this, host] { hosts_.erase(host); });
+  return this;
+}
+
+} // namespace simgrid::plugins
index ee75342..d84357f 100644 (file)
@@ -33,7 +33,7 @@ Task::Task(const std::string& name) : name_(name) {}
  */
 bool Task::ready_to_run() const
 {
-  return not working_ && queued_firings_ > 0;
+  return running_instances_ < parallelism_degree_ && queued_firings_ > 0;
 }
 
 /**
@@ -75,18 +75,32 @@ void Task::receive(Task* source)
 void Task::complete()
 {
   xbt_assert(Actor::is_maestro());
-  working_ = false;
+  running_instances_--;
   count_++;
   on_this_completion(this);
   on_completion(this);
-  if (current_activity_)
-    previous_activity_ = std::move(current_activity_);
   for (auto const& t : successors_)
     t->receive(this);
   if (ready_to_run())
     fire();
 }
 
+/** @param n The new parallelism degree of the Task.
+ *  @brief Set the parallelism degree of the Task to inscrease or decrease horizontal scaling.
+ *  @note When increasing the degree the function starts new instances if there is queued firings.
+ *        When decreasing the degree the function does NOT stop running instances.
+
+ */
+void Task::set_parallelism_degree(int n)
+{
+  xbt_assert(n > 0, "Parallelism degree of Tasks must be above 0.");
+  simgrid::kernel::actor::simcall_answered([this, n] {
+    parallelism_degree_ = n;
+    while (ready_to_run())
+      fire();
+  });
+}
+
 /** @param n The number of firings to enqueue.
  *  @brief Enqueue firing.
  *  @note Immediatly fire an activity if possible.
@@ -95,11 +109,19 @@ void Task::enqueue_firings(int n)
 {
   simgrid::kernel::actor::simcall_answered([this, n] {
     queued_firings_ += n;
-    if (ready_to_run())
+    while (ready_to_run())
       fire();
   });
 }
 
+/** @param name The new name to set.
+ *  @brief Set the name of the Task.
+ */
+void Task::set_name(std::string name)
+{
+  name_ = name;
+}
+
 /** @param amount The amount to set.
  *  @brief Set the amout of work to do.
  *  @note Amount in flop for ExecTask and in bytes for CommTask.
@@ -128,9 +150,12 @@ std::shared_ptr<Token> Task::get_next_token_from(TaskPtr t)
 
 void Task::fire()
 {
+  if ((int)current_activities_.size() > parallelism_degree_) {
+    current_activities_.pop_front();
+  }
   on_this_start(this);
   on_start(this);
-  working_        = true;
+  running_instances_++;
   queued_firings_ = std::max(queued_firings_ - 1, 0);
   if (not tokens_received_.empty())
     tokens_received_.pop_front();
@@ -194,7 +219,7 @@ ExecTaskPtr ExecTask::init(const std::string& name, double flops, Host* host)
 
 /**
  *  @brief Do one execution of the Task.
- *  @note Call the on_this_start() func. Set its working status as true.
+ *  @note Call the on_this_start() func.
  *  Init and start the underlying Activity.
  */
 void ExecTask::fire()
@@ -202,8 +227,8 @@ void ExecTask::fire()
   Task::fire();
   auto exec = Exec::init()->set_name(get_name())->set_flops_amount(get_amount())->set_host(host_);
   exec->start();
-  exec->on_this_completion_cb([this](Exec const&) { this->complete(); });
-  set_current_activity(exec);
+  exec->on_this_completion_cb([this](Exec const&) { complete(); });
+  store_activity(exec);
 }
 
 /** @ingroup plugin_task
@@ -248,7 +273,7 @@ CommTaskPtr CommTask::init(const std::string& name, double bytes, Host* source,
 
 /**
  *  @brief Do one execution of the Task.
- *  @note Call the on_this_start() func. Set its working status as true.
+ *  @note Call the on_this_start() func.
  *  Init and start the underlying Activity.
  */
 void CommTask::fire()
@@ -256,8 +281,8 @@ void CommTask::fire()
   Task::fire();
   auto comm = Comm::sendto_init(source_, destination_)->set_name(get_name())->set_payload_size(get_amount());
   comm->start();
-  comm->on_this_completion_cb([this](Comm const&) { this->complete(); });
-  set_current_activity(comm);
+  comm->on_this_completion_cb([this](Comm const&) { complete(); });
+  store_activity(comm);
 }
 
 /** @ingroup plugin_task
@@ -341,8 +366,8 @@ void IoTask::fire()
   Task::fire();
   auto io = Io::init()->set_name(get_name())->set_size(get_amount())->set_disk(disk_)->set_op_type(type_);
   io->start();
-  io->on_this_completion_cb([this](Io const&) { this->complete(); });
-  set_current_activity(io);
+  io->on_this_completion_cb([this](Io const&) { complete(); });
+  store_activity(io);
 }
 
 } // namespace simgrid::s4u
index 267162f..cee3e25 100644 (file)
@@ -453,6 +453,7 @@ set(PLUGINS_SRC
   src/plugins/vm/VmLiveMigration.hpp
   src/plugins/vm/dirty_page_tracking.cpp
   src/plugins/battery.cpp
+  src/plugins/chiller.cpp
   src/plugins/solar_panel.cpp
   )
 
@@ -657,6 +658,7 @@ set(headers_to_install
   include/simgrid/Exception.hpp
   include/simgrid/chrono.hpp
   include/simgrid/plugins/battery.hpp
+  include/simgrid/plugins/chiller.hpp
   include/simgrid/plugins/dvfs.h
   include/simgrid/plugins/energy.h
   include/simgrid/plugins/file_system.h