include/simgrid/simdag.h
Simix
- * simgrid::simix::kernel() is the closure callback. It ensures that
+ * simgrid::simix::kernelImmediate() is the closure callback. It ensures that
the lambda or closure passed as a parameter will run in kernel mode.
All the callback functions should be rewritten to that interface at some point.
}
};
-/** Result of some (possibly ongoing, asynchronous) operation in the SimGrid kernel
+/** Result of some (probably) asynchronous operation in the SimGrid kernel
*
- * As the operation may not be completed yet, the result might be an exception.
+ * @ref simgrid::simix::Future and @ref simgrid::simix::Future provide an
+ * abstration for asynchronous stuff happening in the SimGrid kernel. They
+ * are based on C++1z futures.
+ *
+ * The future represents a value which will be available at some point when this
+ * asynchronous operaiont is finished. Alternatively, if this operations fails,
+ * the result of the operation might be an exception.
+ *
+ * As the operation is possibly no terminated yet, we cannot get the result
+ * yet. Moreover, as we cannot block in the SimGrid kernel we cannot wait for
+ * it. However, we can attach some code/callback/continuation which will be
+ * executed when the operation terminates.
*
* Example of the API (`simgrid::kernel::createProcess` does not exist):
* <pre>
#include <simgrid/simix.h>
XBT_PUBLIC(void) simcall_run_kernel(std::function<void()> const& code);
+
+/** Execute some code in the kernel and block
+ *
+ * run_blocking() is a generic blocking simcall. It is given a callback
+ * which is executed immediately in the SimGrid kernel. The callback is
+ * responsible for setting the suitable logic for waking up the process
+ * when needed.
+ *
+ * @ref simix::kernelSync() is a higher level wrapper for this.
+ */
XBT_PUBLIC(void) simcall_run_blocking(std::function<void()> const& code);
template<class F> inline
* of the operation with respect to other simcalls.
*/
template<class F>
-typename std::result_of<F()>::type kernel(F&& code)
+typename std::result_of<F()>::type kernelImmediate(F&& code)
{
// If we are in the maestro, we take the fast path and execute the
// code directly without simcall mashalling/unmarshalling/dispatch:
/** Execute some code in kernel mode and wakes up the process when
* the result is available.
*
- * The code given is executed in SimGrid kernel and expected to return
- * a `simgrid::kernel::Future`. The current process is resumed whenever
- * the Future becomes ready and gets the value or exception of the future:
+ * It is given a callback which is executed in the kernel SimGrid and
+ * returns a simgrid::kernel::Future<T>. The kernel blocks the process
+ * until the Future is ready and either the value wrapped in the future
+ * to the process or raises the exception stored in the Future in the process.
*
- * This can be used to implement blocking calls in without adding new simcalls.
- * One downside of this approach is that we don't have any semantic on what
- * the process is waiting. This might be a problem for the model-checker and
- * we'll have to device a way to make it work.
+ * This can be used to implement blocking calls without adding new simcalls.
+ * One downside of this approach is that we don't have any semantic on what
+ * the process is waiting. This might be a problem for the model-checker and
+ * we'll have to devise a way to make it work.
*
- * @param code Kernel code returning a `simgrid::kernel::Future<T>`
- * @return Value of the kernel future
- * @exception Exception from the kernel future
+ * @param code Kernel code returning a `simgrid::kernel::Future<T>`
+ * @return Value of the kernel future
+ * @exception Exception from the kernel future
*/
template<class F>
-auto blocking_simcall(F code) -> decltype(code().get())
+auto kernelSync(F code) -> decltype(code().get())
{
typedef decltype(code().get()) T;
if (SIMIX_is_maestro())
* @return User future
*/
template<class F>
-auto asynchronous_simcall(F code)
+auto kernelAsync(F code)
-> Future<decltype(code().get())>
{
typedef decltype(code().get()) T;
// Execute the code in the kernel and get the kernel simcall:
simgrid::kernel::Future<T> future =
- simgrid::simix::kernel(std::move(code));
+ simgrid::simix::kernelImmediate(std::move(code));
// Wrap tyhe kernel simcall in a user simcall:
return simgrid::simix::Future<T>(std::move(future));
#include <type_traits>
+
+
namespace simgrid {
namespace xbt {
}
void Host::turnOn() {
- simgrid::simix::kernel(std::bind(SIMIX_host_on, this));
+ simgrid::simix::kernelImmediate(std::bind(SIMIX_host_on, this));
}
void Host::turnOff() {
- simgrid::simix::kernel(std::bind(SIMIX_host_off, this, SIMIX_process_self()));
+ simgrid::simix::kernelImmediate(std::bind(SIMIX_host_off, this, SIMIX_process_self()));
}
bool Host::isOn() {
/** Get the properties assigned to a host */
xbt_dict_t Host::properties() {
- return simgrid::simix::kernel([&] {
+ return simgrid::simix::kernelImmediate([&] {
simgrid::surf::HostImpl* surf_host = this->extension<simgrid::surf::HostImpl>();
return surf_host->getProperties();
});
return surf_host->getProperty(key);
}
void Host::setProperty(const char*key, const char *value){
- simgrid::simix::kernel([&] {
+ simgrid::simix::kernelImmediate([&] {
simgrid::surf::HostImpl* surf_host = this->extension<simgrid::surf::HostImpl>();
surf_host->setProperty(key,value);
});
/** Get the processes attached to the host */
xbt_swag_t Host::processes()
{
- return simgrid::simix::kernel([&]() {
+ return simgrid::simix::kernelImmediate([&]() {
return ((smx_host_priv_t)this->extension(SIMIX_HOST_LEVEL))->process_list;
});
}
/** Get the peak power of a host */
double Host::getPstateSpeedCurrent()
{
- return simgrid::simix::kernel([&] {
+ return simgrid::simix::kernelImmediate([&] {
return this->pimpl_cpu->getPstateSpeedCurrent();
});
}
/** Get one power peak (in flops/s) of a host at a given pstate */
double Host::getPstateSpeed(int pstate_index)
{
- return simgrid::simix::kernel([&] {
+ return simgrid::simix::kernelImmediate([&] {
return this->pimpl_cpu->getPstateSpeed(pstate_index);
});
}
/** @brief Set the pstate at which the host should run */
void Host::setPstate(int pstate_index)
{
- simgrid::simix::kernel(std::bind(
+ simgrid::simix::kernelImmediate(std::bind(
&simgrid::surf::Cpu::setPState, pimpl_cpu, pstate_index
));
}
void Host::parameters(vm_params_t params)
{
- simgrid::simix::kernel([&]() {
+ simgrid::simix::kernelImmediate([&]() {
this->extension<simgrid::surf::HostImpl>()->getParams(params);
});
}
void Host::setParameters(vm_params_t params)
{
- simgrid::simix::kernel([&]() {
+ simgrid::simix::kernelImmediate([&]() {
this->extension<simgrid::surf::HostImpl>()->setParams(params);
});
}
*/
xbt_dict_t Host::mountedStoragesAsDict()
{
- return simgrid::simix::kernel([&] {
+ return simgrid::simix::kernelImmediate([&] {
return this->extension<simgrid::surf::HostImpl>()->getMountedStorageList();
});
}
*/
xbt_dynar_t Host::attachedStorages()
{
- return simgrid::simix::kernel([&] {
+ return simgrid::simix::kernelImmediate([&] {
return this->extension<simgrid::surf::HostImpl>()->getAttachedStorageList();
});
}
*/
void* simcall_vm_create(const char *name, sg_host_t phys_host)
{
- return simgrid::simix::kernel(std::bind(SIMIX_vm_create, name, phys_host));
+ return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_create, name, phys_host));
}
/**
*/
void simcall_vm_start(sg_host_t vm)
{
- return simgrid::simix::kernel(std::bind(SIMIX_vm_start, vm));
+ return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_start, vm));
}
/**
*/
int simcall_vm_get_state(sg_host_t vm)
{
- return simgrid::simix::kernel(std::bind(SIMIX_vm_get_state, vm));
+ return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_get_state, vm));
}
/**
*/
void *simcall_vm_get_pm(sg_host_t vm)
{
- return simgrid::simix::kernel(std::bind(SIMIX_vm_get_pm, vm));
+ return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_get_pm, vm));
}
void simcall_vm_set_bound(sg_host_t vm, double bound)
{
- simgrid::simix::kernel(std::bind(SIMIX_vm_set_bound, vm, bound));
+ simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_set_bound, vm, bound));
}
void simcall_vm_set_affinity(sg_host_t vm, sg_host_t pm, unsigned long mask)
{
- simgrid::simix::kernel(std::bind(SIMIX_vm_set_affinity, vm, pm, mask));
+ simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_set_affinity, vm, pm, mask));
}
/**
*/
void simcall_vm_migrate(sg_host_t vm, sg_host_t host)
{
- return simgrid::simix::kernel(std::bind(SIMIX_vm_migrate, vm, host));
+ return simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_migrate, vm, host));
}
/**
*/
void simcall_vm_destroy(sg_host_t vm)
{
- simgrid::simix::kernel(std::bind(SIMIX_vm_destroy, vm));
+ simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_destroy, vm));
}
/**
*/
void simcall_vm_migratefrom_resumeto(sg_host_t vm, sg_host_t src_pm, sg_host_t dst_pm)
{
- simgrid::simix::kernel(std::bind(
+ simgrid::simix::kernelImmediate(std::bind(
SIMIX_vm_migratefrom_resumeto, vm, src_pm, dst_pm));
}
*/
int simcall_process_count(void)
{
- return simgrid::simix::kernel(SIMIX_process_count);
+ return simgrid::simix::kernelImmediate(SIMIX_process_count);
}
/**
*/
void simcall_process_set_data(smx_process_t process, void *data)
{
- simgrid::simix::kernel(std::bind(SIMIX_process_set_data, process, data));
+ simgrid::simix::kernelImmediate(std::bind(SIMIX_process_set_data, process, data));
}
/**
*/
void simcall_comm_cancel(smx_synchro_t synchro)
{
- simgrid::simix::kernel([synchro]{
+ simgrid::simix::kernelImmediate([synchro]{
simgrid::simix::Comm *comm = static_cast<simgrid::simix::Comm*>(synchro);
comm->cancel();
});
/** Kernel code for run_blocking
*
- * This looks a lot like SIMIX_run_kernel ^^
+ * The implementtion looks a lot like SIMIX_run_kernel ^^
*
* However, this `run_blocking` is blocking so the process will not be woken
* up until `SIMIX_simcall_answer(simcall)`` is called by the kernel.
if (name == nullptr)
name = "";
smx_process_t self = SIMIX_process_self();
- return simgrid::simix::kernel([&] {
+ return simgrid::simix::kernelImmediate([&] {
return SIMIX_process_create(name,
std::move(code), data, hostname,
kill_time, properties, auto_restart,
double HostEnergy::getConsumedEnergy()
{
if (last_updated < surf_get_clock()) // We need to simcall this as it modifies the environment
- simgrid::simix::kernel(std::bind(&HostEnergy::update, this));
+ simgrid::simix::kernelImmediate(std::bind(&HostEnergy::update, this));
return total_energy;
}
{
// Test the simple immediate execution:
XBT_INFO("Start");
- simgrid::simix::kernel([] {
+ simgrid::simix::kernelImmediate([] {
XBT_INFO("kernel");
});
XBT_INFO("kernel, returned");
// Synchronize on a successful Future<void>:
- simgrid::simix::blocking_simcall([&] {
+ simgrid::simix::kernelSync([&] {
return kernel_defer(10, [] {
- XBT_INFO("blocking_simcall with void");
+ XBT_INFO("kernelSync with void");
});
});
- XBT_INFO("blocking_simcall with void, returned");
+ XBT_INFO("kernelSync with void, returned");
// Synchronize on a failing Future<void>:
try {
- simgrid::simix::blocking_simcall([&] {
+ simgrid::simix::kernelSync([&] {
return kernel_defer(20, [] {
throw std::runtime_error("Exception throwed from kernel_defer");
});
}
// Synchronize on a successul Future<int> and get the value:
- int res = simgrid::simix::blocking_simcall([&] {
+ int res = simgrid::simix::kernelSync([&] {
return kernel_defer(30, [] {
- XBT_INFO("blocking_simcall with value");
+ XBT_INFO("kernelSync with value");
return 42;
});
});
- XBT_INFO("blocking_simcall with value returned with %i", res);
+ XBT_INFO("kernelSync with value returned with %i", res);
// Synchronize on a successul Future<int> and get the value:
- simgrid::simix::Future<int> future = simgrid::simix::asynchronous_simcall([&] {
+ simgrid::simix::Future<int> future = simgrid::simix::kernelAsync([&] {
return kernel_defer(50, [] {
- XBT_INFO("asynchronous_simcall with value");
+ XBT_INFO("kernelAsync with value");
return 43;
});
});
res = future.get();
- XBT_INFO("asynchronous_simcall with value returned with %i", res);
+ XBT_INFO("kernelAsync with value returned with %i", res);
return 0;
}
> [Tremblay:master:(0) 0.000000] [test/INFO] Start
> [0.000000] [test/INFO] kernel
> [Tremblay:master:(0) 0.000000] [test/INFO] kernel, returned
-> [10.000000] [test/INFO] blocking_simcall with void
-> [Tremblay:master:(0) 10.000000] [test/INFO] blocking_simcall with void, returned
+> [10.000000] [test/INFO] kernelSync with void
+> [Tremblay:master:(0) 10.000000] [test/INFO] kernelSync with void, returned
> [Tremblay:master:(0) 20.000000] [test/INFO] Exception caught: Exception throwed from kernel_defer
-> [30.000000] [test/INFO] blocking_simcall with value
-> [Tremblay:master:(0) 30.000000] [test/INFO] blocking_simcall with value returned with 42
-> [50.000000] [test/INFO] asynchronous_simcall with value
-> [Tremblay:master:(0) 50.000000] [test/INFO] asynchronous_simcall with value returned with 43
+> [30.000000] [test/INFO] kernelSync with value
+> [Tremblay:master:(0) 30.000000] [test/INFO] kernelSync with value returned with 42
+> [50.000000] [test/INFO] kernelAsync with value
+> [Tremblay:master:(0) 50.000000] [test/INFO] kernelAsync with value returned with 43