- Comm.wait_any_for()
- Comm.wait_all_for() [example: examples/python/comm-waitallfor/]
- Mutex [example: examples/python/synchro-mutex/]
+ - Barrier [example: examples/python/synchro-barrier/]
Build System:
- Remove target "make uninstall" which was incomplete and no longer maintained.
Barrier
================
-.. doxygenclass:: simgrid::s4u::Barrier
+.. tabs::
+
+ .. group-tab:: C++
+
+ .. doxygenclass:: simgrid::s4u::Barrier
+
+ .. group-tab:: Python
+
+ .. autoclass:: simgrid.Barrier
.. tabs::
.. doxygenfunction:: simgrid::s4u::Barrier::create(unsigned int expected_actors)
.. doxygenfunction:: simgrid::s4u::Barrier::wait()
+ .. group-tab:: Python
+
+ .. code-block:: Python
+
+ from simgrid import Barrier
+ barrier = Barrier(2)
+
+ .. automethod:: simgrid.Barrier.wait()
+
.. group-tab:: C
.. code-block:: C
.. example-tab:: examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp
+ .. example-tab:: examples/python/synchro-barrier/synchro-barrier.py
+
Condition variable: basic usage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--- /dev/null
+from argparse import ArgumentParser
+import sys
+
+from simgrid import Actor, Barrier, Engine, Host, this_actor
+
+
+def create_parser() -> ArgumentParser:
+ parser = ArgumentParser()
+ parser.add_argument(
+ '--platform',
+ type=str,
+ required=True,
+ help='path to the platform description'
+ )
+ parser.add_argument(
+ "--actors",
+ type=int,
+ required=True,
+ help="Number of actors to start"
+ )
+ return parser
+
+
+def worker(barrier: Barrier):
+ """ Wait on the barrier and exits.
+ :param barrier: Barrier to be awaited
+ """
+ this_actor.info(f"Waiting on the barrier")
+ barrier.wait()
+ this_actor.info("Bye")
+
+
+def master(actor_count: int):
+ """ Create barrier with `actor_count` expected actors, spawns `actor_count - 1` workers, then wait on the barrier
+ and exits.
+ :param actor_count: Spawn actor_count-1 workers and do a barrier with them
+ """
+ barrier = Barrier(actor_count)
+ workers_count = actor_count - 1
+ this_actor.info(f"Spawning {workers_count} workers")
+ for i in range(workers_count):
+ Actor.create(f"worker-{i}", Host.by_name("Jupiter"), worker, barrier)
+ this_actor.info(f"Waiting on the barrier")
+ barrier.wait()
+ this_actor.info("Bye")
+
+
+def main():
+ settings = create_parser().parse_known_args()[0]
+ if settings.actors < 1:
+ raise ValueError("--actors must be greater than 0")
+ e = Engine(sys.argv)
+ e.load_platform(settings.platform)
+ Actor.create("master", Host.by_name("Tremblay"), master, settings.actors)
+ e.run()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env tesh
+
+p Testing Barrier
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/synchro-barrier.py --platform ${platfdir}/two_hosts.xml --actors 1 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+>[ 0.000000] (1:master@Tremblay) Spawning 0 workers
+>[ 0.000000] (1:master@Tremblay) Waiting on the barrier
+>[ 0.000000] (1:master@Tremblay) Bye
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/synchro-barrier.py --platform ${platfdir}/two_hosts.xml --actors 2 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+>[ 0.000000] (1:master@Tremblay) Spawning 1 workers
+>[ 0.000000] (2:worker-0@Jupiter) Waiting on the barrier
+>[ 0.000000] (1:master@Tremblay) Waiting on the barrier
+>[ 0.000000] (2:worker-0@Jupiter) Bye
+>[ 0.000000] (1:master@Tremblay) Bye
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/synchro-barrier.py --platform ${platfdir}/two_hosts.xml --actors 10 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+>[ 0.000000] (1:master@Tremblay) Spawning 9 workers
+>[ 0.000000] (2:worker-0@Jupiter) Waiting on the barrier
+>[ 0.000000] (3:worker-1@Jupiter) Waiting on the barrier
+>[ 0.000000] (4:worker-2@Jupiter) Waiting on the barrier
+>[ 0.000000] (5:worker-3@Jupiter) Waiting on the barrier
+>[ 0.000000] (6:worker-4@Jupiter) Waiting on the barrier
+>[ 0.000000] (7:worker-5@Jupiter) Waiting on the barrier
+>[ 0.000000] (8:worker-6@Jupiter) Waiting on the barrier
+>[ 0.000000] (9:worker-7@Jupiter) Waiting on the barrier
+>[ 0.000000] (10:worker-8@Jupiter) Waiting on the barrier
+>[ 0.000000] (1:master@Tremblay) Waiting on the barrier
+>[ 0.000000] (2:worker-0@Jupiter) Bye
+>[ 0.000000] (3:worker-1@Jupiter) Bye
+>[ 0.000000] (4:worker-2@Jupiter) Bye
+>[ 0.000000] (5:worker-3@Jupiter) Bye
+>[ 0.000000] (6:worker-4@Jupiter) Bye
+>[ 0.000000] (7:worker-5@Jupiter) Bye
+>[ 0.000000] (8:worker-6@Jupiter) Bye
+>[ 0.000000] (9:worker-7@Jupiter) Bye
+>[ 0.000000] (10:worker-8@Jupiter) Bye
+>[ 0.000000] (1:master@Tremblay) Bye
#include "simgrid/kernel/routing/NetPoint.hpp"
#include <simgrid/Exception.hpp>
#include <simgrid/s4u/Actor.hpp>
+#include <simgrid/s4u/Barrier.hpp>
#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Disk.hpp>
#include <simgrid/s4u/Engine.hpp>
namespace py = pybind11;
using simgrid::s4u::Actor;
using simgrid::s4u::ActorPtr;
+using simgrid::s4u::Barrier;
+using simgrid::s4u::BarrierPtr;
using simgrid::s4u::Engine;
using simgrid::s4u::Host;
using simgrid::s4u::Link;
.def("__exit__", [](Mutex* self, py::object&, py::object&, py::object&){ self->unlock(); },
py::call_guard<py::gil_scoped_release>());
+ /* Class Barrier */
+ py::class_<Barrier, BarrierPtr>(m, "Barrier",
+ "A classical barrier, but blocking in the simulation world.")
+ .def(py::init<>(&Barrier::create), py::call_guard<py::gil_scoped_release>(), py::arg("expected_actors"))
+ .def("wait", &Barrier::wait, py::call_guard<py::gil_scoped_release>(),
+ "Blocks into the barrier. Every waiting actors will be unlocked once the expected amount of actors reaches "
+ "the barrier");
+
/* Class Actor */
py::class_<simgrid::s4u::Actor, ActorPtr>(m, "Actor",
"An actor is an independent stream of execution in your distributed "