--- /dev/null
+/* 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
#define SIMGRID_S4U_ACTOR_HPP
#include <atomic>
+#include <chrono>
#include <functional>
#include <memory>
#include <stdexcept>
#include <xbt/base.h>
#include <xbt/functional.hpp>
+#include <simgrid/chrono.hpp>
#include <simgrid/simix.h>
#include <simgrid/s4u/forward.hpp>
/** 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);
#include <xbt/base.h>
#include <simgrid/simix.h>
+#include <simgrid/chrono.hpp>
#include <simgrid/s4u/mutex.hpp>
namespace simgrid {
static Ptr createConditionVariable();
- // Wait functions:
+ // Wait functions without time:
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);
}
+
+ // 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)
{
{
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>
- 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);
}
+ 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