Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[s4u] More support for C++-style time and durations
authorGabriel Corona <gabriel.corona@loria.fr>
Wed, 20 Jul 2016 12:56:40 +0000 (14:56 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Wed, 20 Jul 2016 12:56:40 +0000 (14:56 +0200)
include/simgrid/chrono.hpp [new file with mode: 0644]
include/simgrid/s4u/actor.hpp
include/simgrid/s4u/conditionVariable.hpp
tools/cmake/DefinePackages.cmake

diff --git a/include/simgrid/chrono.hpp b/include/simgrid/chrono.hpp
new file mode 100644 (file)
index 0000000..4395b41
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright (c) 2016. 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_CHRONO_HPP
+#define SIMGRID_CHRONO_HPP
+
+/** @file chrono.hpp Time support
+ *
+ *  Define clock, duration types, time point types compatible with the standard
+ *  C++ library API.
+ */
+
+#include <chrono>
+#include <ratio>
+
+#include <simgrid/simix.h>
+
+namespace simgrid {
+
+/** A C++ compatible TrivialClock working with simulated-time */
+struct SimulationClock {
+  using rep        = double;
+  using period     = std::ratio<1>;
+  using duration   = std::chrono::duration<rep, period>;
+  using time_point = std::chrono::time_point<SimulationClock, duration>;
+  static constexpr bool is_steady = true;
+  static time_point now()
+  {
+    return time_point(duration(SIMIX_get_clock()));
+  }
+};
+
+/** Default duration for simulated time */
+using SimulationClockDuration  = SimulationClock::duration;
+
+/** Default time point for simulated time */
+using SimulationClockTimePoint = SimulationClock::time_point;
+
+// Durations based on doubles:
+using nanoseconds = std::chrono::duration<double, std::nano>;
+using microseconds = std::chrono::duration<double, std::micro>;
+using milliseconds = std::chrono::duration<double, std::milli>;
+using seconds = std::chrono::duration<double>;
+using minutes = std::chrono::duration<double, std::ratio<60>>;
+using hours = std::chrono::duration<double, std::ratio<3600>>;
+
+/** A time point in the simulated time */
+template<class Duration>
+using SimulationTimePoint = std::chrono::time_point<SimulationClock, Duration>;
+
+}
+
+#endif
index 8e1b703..5039f84 100644 (file)
@@ -7,6 +7,7 @@
 #define SIMGRID_S4U_ACTOR_HPP
 
 #include <atomic>
 #define SIMGRID_S4U_ACTOR_HPP
 
 #include <atomic>
+#include <chrono>
 #include <functional>
 #include <memory>
 #include <stdexcept>
 #include <functional>
 #include <memory>
 #include <stdexcept>
@@ -20,6 +21,7 @@
 #include <xbt/base.h>
 #include <xbt/functional.hpp>
 
 #include <xbt/base.h>
 #include <xbt/functional.hpp>
 
+#include <simgrid/chrono.hpp>
 #include <simgrid/simix.h>
 #include <simgrid/s4u/forward.hpp>
 
 #include <simgrid/simix.h>
 #include <simgrid/s4u/forward.hpp>
 
@@ -258,6 +260,13 @@ namespace this_actor {
   /** Block the actor sleeping for that amount of seconds (may throws hostFailure) */
   XBT_PUBLIC(void) sleep(double duration);
 
   /** Block the actor sleeping for that amount of seconds (may throws hostFailure) */
   XBT_PUBLIC(void) sleep(double duration);
 
+  template<class Rep, class Period>
+  inline void sleep(std::chrono::duration<Rep, Period> duration)
+  {
+    auto seconds = std::chrono::duration_cast<SimulationClockDuration>(duration);
+    sleep(seconds.count());
+  }
+
   /** Block the actor, computing the given amount of flops */
   XBT_PUBLIC(e_smx_state_t) execute(double flop);
 
   /** Block the actor, computing the given amount of flops */
   XBT_PUBLIC(e_smx_state_t) execute(double flop);
 
index 2db6fb8..3b03bca 100644 (file)
@@ -17,6 +17,7 @@
 #include <xbt/base.h>
 
 #include <simgrid/simix.h>
 #include <xbt/base.h>
 
 #include <simgrid/simix.h>
+#include <simgrid/chrono.hpp>
 #include <simgrid/s4u/mutex.hpp>
 
 namespace simgrid {
 #include <simgrid/s4u/mutex.hpp>
 
 namespace simgrid {
@@ -46,41 +47,20 @@ public:
 
   static Ptr createConditionVariable();
 
 
   static Ptr createConditionVariable();
 
-  //  Wait functions:
+  //  Wait functions without time:
 
   void wait(std::unique_lock<Mutex>& lock);
 
   void wait(std::unique_lock<Mutex>& lock);
-  std::cv_status wait_until(std::unique_lock<Mutex>& lock, double timeout_time);
-  std::cv_status wait_for(std::unique_lock<Mutex>& lock, double duration);
-
-  /** Wait for a given duraiton
-   *
-   *  This version gives us the ability to do (in C++):
-   *
-   *  <code>
-   *  using namespace std::literals::chrono_literals;
-   *
-   *  cond->wait_for(lock, 1ms);
-   *  cond->wait_for(lock, 1s);
-   *  cond->wait_for(lock, 1min);
-   *  cond->wait_for(lock, 1h);
-   *  </code>
-   */
-  template<class Rep, class Period>
-  std::cv_status wait_for(std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> duration)
-  {
-    typedef std::chrono::duration<double> SecondsDouble;
-    auto seconds = std::chrono::duration_cast<SecondsDouble>(duration);
-    return this->wait_for(lock, duration.count());
-  }
-
-  // Variants which takes a predicate:
-
   template<class P>
   void wait(std::unique_lock<Mutex>& lock, P pred)
   {
     while (!pred())
       wait(lock);
   }
   template<class P>
   void wait(std::unique_lock<Mutex>& lock, P pred)
   {
     while (!pred())
       wait(lock);
   }
+
+  // Wait function taking a plain double as time:
+
+  std::cv_status wait_until(std::unique_lock<Mutex>& lock, double timeout_time);
+  std::cv_status wait_for(std::unique_lock<Mutex>& lock, double duration);
   template<class P>
   bool wait_until(std::unique_lock<Mutex>& lock, double timeout_time, P pred)
   {
   template<class P>
   bool wait_until(std::unique_lock<Mutex>& lock, double timeout_time, P pred)
   {
@@ -94,13 +74,39 @@ public:
   {
     return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred));
   }
   {
     return this->wait_until(lock, SIMIX_get_clock() + duration, std::move(pred));
   }
+
+  // Wait function taking a C++ style time:
+
   template<class Rep, class Period, class P>
   template<class Rep, class Period, class P>
-  bool wait_for(std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> duration, P pred)
+  bool wait_for(
+    std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> duration,
+    P pred)
   {
   {
-    typedef std::chrono::duration<double> SecondsDouble;
-    auto seconds = std::chrono::duration_cast<SecondsDouble>(duration);
+    auto seconds = std::chrono::duration_cast<SimulationClockDuration>(duration);
     return this->wait_for(lock, seconds.count(), pred);
   }
     return this->wait_for(lock, seconds.count(), pred);
   }
+  template<class Rep, class Period>
+  std::cv_status wait_for(
+    std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> duration)
+  {
+    auto seconds = std::chrono::duration_cast<SimulationClockDuration>(duration);
+    return this->wait_for(lock, seconds.count());
+  }
+  template<class Duration>
+  std::cv_status wait_until(std::unique_lock<Mutex>& lock,
+    const SimulationTimePoint<Duration>& timeout_time)
+  {
+    auto timeout_native = std::chrono::time_point_cast<SimulationClockDuration>(timeout_time);
+    return this->wait_until(lock, timeout_native.time_since_epoch().count());
+  }
+  template<class Duration, class P>
+  bool wait_until(std::unique_lock<Mutex>& lock,
+    const SimulationTimePoint<Duration>& timeout_time, P pred)
+  {
+    auto timeout_native = std::chrono::time_point_cast<SimulationClockDuration>(timeout_time);
+    return this->wait_until(lock, timeout_native.time_since_epoch().count(),
+      std::move(pred));
+  }
 
   // Notify functions
 
 
   // Notify functions
 
index 28348f0..87bdcd2 100644 (file)
@@ -627,7 +627,7 @@ set(headers_to_install
   include/msg/datatypes.h
   include/simdag/simdag.h
   include/simdag/datatypes.h
   include/msg/datatypes.h
   include/simdag/simdag.h
   include/simdag/datatypes.h
-  
+  include/simgrid/chrono.hpp
   include/simgrid/plugins/energy.h
   include/simgrid/instr.h
   include/simgrid/msg.h
   include/simgrid/plugins/energy.h
   include/simgrid/instr.h
   include/simgrid/msg.h