-/* Copyright (c) 2007-2010, 2012-2018. The SimGrid Team.
+/* Copyright (c) 2007-2019. The SimGrid Team.
* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
#include <xbt/future.hpp>
#include <xbt/signal.hpp>
-#include <map>
+#include <boost/heap/fibonacci_heap.hpp>
#include <string>
+#include <unordered_map>
XBT_PUBLIC void simcall_run_kernel(std::function<void()> const& code);
}
namespace simgrid {
-
namespace simix {
/** Execute some code in the kernel/maestro
* More importantly, this enforces a deterministic/reproducible ordering
* of the operation with respect to other simcalls.
*/
-template<class F>
-typename std::result_of<F()>::type kernelImmediate(F&& code)
+template <class F> typename std::result_of<F()>::type simcall(F&& code)
{
// If we are in the maestro, we take the fast path and execute the
// code directly without simcall mashalling/unmarshalling/dispatch:
// conveniently handles the success/failure value for us.
typedef typename std::result_of<F()>::type R;
simgrid::xbt::Result<R> result;
- simcall_run_kernel([&]{
- xbt_assert(SIMIX_is_maestro(), "Not in maestro");
- simgrid::xbt::fulfillPromise(result, std::forward<F>(code));
- });
+ simcall_run_kernel([&result, &code] { simgrid::xbt::fulfill_promise(result, std::forward<F>(code)); });
return result.get();
}
-XBT_PUBLIC const std::vector<smx_actor_t>& process_get_runnable();
-
-XBT_PUBLIC void set_maestro(std::function<void()> code);
-XBT_PUBLIC void create_maestro(std::function<void()> code);
+XBT_ATTRIB_DEPRECATED_v325("Please manifest if you actually need this function")
+ XBT_PUBLIC const std::vector<smx_actor_t>& process_get_runnable();
// What's executed as SIMIX actor code:
typedef std::function<void()> ActorCode;
-// Create ActorCode based on argv:
+// Create an ActorCode based on a std::string
typedef std::function<ActorCode(std::vector<std::string> args)> ActorCodeFactory;
-XBT_PUBLIC void registerFunction(const char* name, ActorCodeFactory factory);
+XBT_PUBLIC void register_function(const std::string& name, const ActorCodeFactory& factory);
-/** These functions will be called when we detect a deadlock: any remaining process is locked on an action
- *
- * If these functions manage to unlock some of the processes, then the deadlock will be avoided.
- */
-extern simgrid::xbt::signal<void()> onDeadlock;
-}
-}
+typedef std::pair<double, Timer*> TimerQelt;
+static boost::heap::fibonacci_heap<TimerQelt, boost::heap::compare<xbt::HeapComparator<TimerQelt>>> simix_timers;
-/*
- * Type of function that creates a process.
- * The function must accept the following parameters:
- * void* process: the process created will be stored there
- * const char *name: a name for the object. It is for user-level information and can be NULL
- * xbt_main_func_t code: is a function describing the behavior of the process
- * void *data: data a pointer to any data one may want to attach to the new object.
- * sg_host_t host: the location where the new process is executed
- * int argc, char **argv: parameters passed to code
- * std::map<std::string, std::string>* props: properties
- */
-typedef smx_actor_t (*smx_creation_func_t)(
- /* name */ const char*, std::function<void()> code,
- /* userdata */ void*,
- /* hostname */ sg_host_t,
- /* props */ std::map<std::string, std::string>*,
- /* parent_process */ smx_actor_t);
+/** @brief Timer datatype */
+class Timer {
+ double date = 0.0;
-extern "C" XBT_PUBLIC void SIMIX_function_register_process_create(smx_creation_func_t function);
+public:
+ decltype(simix_timers)::handle_type handle_;
-XBT_PUBLIC smx_actor_t simcall_process_create(const char* name, std::function<void()> code, void* data, sg_host_t host,
- std::map<std::string, std::string>* properties);
+ Timer(double date, simgrid::xbt::Task<void()>&& callback) : date(date), callback(std::move(callback)) {}
-XBT_PUBLIC smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()> callback);
+ simgrid::xbt::Task<void()> callback;
+ double get_date() { return date; }
+ void remove();
-template<class F> inline
-smx_timer_t SIMIX_timer_set(double date, F callback)
-{
- return SIMIX_timer_set(date, simgrid::xbt::Task<void()>(std::move(callback)));
-}
+ template <class F> static inline Timer* set(double date, F callback)
+ {
+ return set(date, simgrid::xbt::Task<void()>(std::move(callback)));
+ }
-template<class R, class T> inline
-smx_timer_t SIMIX_timer_set(double date, R(*callback)(T*), T* arg)
-{
- return SIMIX_timer_set(date, [=](){ callback(arg); });
-}
+ template <class R, class T>
+ XBT_ATTRIB_DEPRECATED_v325("Please use a lambda or std::bind") static inline Timer* set(double date,
+ R (*callback)(T*), T* arg)
+ {
+ return set(date, std::bind(callback, arg));
+ }
+
+ XBT_ATTRIB_DEPRECATED_v325("Please use a lambda or std::bind") static Timer* set(double date, void (*callback)(void*),
+ void* arg)
+ {
+ return set(date, std::bind(callback, arg));
+ }
+ static Timer* set(double date, simgrid::xbt::Task<void()>&& callback);
+ static double next() { return simix_timers.empty() ? -1.0 : simix_timers.top().first; }
+};
+
+} // namespace simix
+} // namespace simgrid
+
+XBT_PUBLIC smx_actor_t simcall_process_create(const std::string& name, const simgrid::simix::ActorCode& code,
+ void* data, sg_host_t host,
+ std::unordered_map<std::string, std::string>* properties);
+
+XBT_ATTRIB_DEPRECATED_v325("Please use simgrid::xbt::Timer::set") XBT_PUBLIC smx_timer_t
+ SIMIX_timer_set(double date, simgrid::xbt::Task<void()>&& callback);
#endif