+
+Task::Task(std::string name, double flops_amount, double bytes_amount, void* data)
+ : name_(std::move(name)), userdata_(data), flops_amount(flops_amount), bytes_amount(bytes_amount)
+{
+ static std::atomic_ullong counter{0};
+ id_ = counter++;
+ if (MC_is_active())
+ MC_ignore_heap(&(id_), sizeof(id_));
+}
+
+Task::Task(std::string name, std::vector<s4u::Host*> hosts, std::vector<double> flops_amount,
+ std::vector<double> bytes_amount, void* data)
+ : Task(std::move(name), 1.0, 0, data)
+{
+ parallel_ = true;
+ hosts_ = std::move(hosts);
+ flops_parallel_amount = std::move(flops_amount);
+ bytes_parallel_amount = std::move(bytes_amount);
+}
+
+Task* Task::create(std::string name, double flops_amount, double bytes_amount, void* data)
+{
+ return new Task(std::move(name), flops_amount, bytes_amount, data);
+}
+
+Task* Task::create_parallel(std::string name, int host_nb, const msg_host_t* host_list, double* flops_amount,
+ double* bytes_amount, void* data)
+{
+ std::vector<s4u::Host*> hosts;
+ std::vector<double> flops;
+ std::vector<double> bytes;
+
+ for (int i = 0; i < host_nb; i++) {
+ hosts.push_back(host_list[i]);
+ if (flops_amount != nullptr)
+ flops.push_back(flops_amount[i]);
+ if (bytes_amount != nullptr) {
+ for (int j = 0; j < host_nb; j++)
+ bytes.push_back(bytes_amount[host_nb * i + j]);
+ }
+ }
+ return new Task(std::move(name), std::move(hosts), std::move(flops), std::move(bytes), data);
+}
+
+msg_error_t Task::execute()
+{
+ /* checking for infinite values */
+ xbt_assert(std::isfinite(flops_amount), "flops_amount is not finite!");
+
+ msg_error_t status = MSG_OK;
+ s4u::Host* host = SIMIX_process_self()->get_host();
+
+ set_used();
+
+ compute = simix::simcall([this, host] {
+ return kernel::activity::ExecImplPtr(new kernel::activity::ExecImpl(name_, tracing_category_, host));
+ });
+
+ try {
+ compute->start(flops_amount, priority_, bound_);
+ e_smx_state_t comp_state = simcall_execution_wait(compute);
+
+ set_not_used();
+ XBT_DEBUG("Execution task '%s' finished in state %d", get_cname(), (int)comp_state);
+ } catch (HostFailureException& e) {
+ status = MSG_HOST_FAILURE;
+ } catch (TimeoutError& e) {
+ status = MSG_TIMEOUT;
+ } catch (CancelException& e) {
+ status = MSG_TASK_CANCELED;
+ }
+
+ /* action ended, set comm and compute = nullptr, the actions is already destroyed in the main function */
+ flops_amount = 0.0;
+ comm = nullptr;
+ compute = nullptr;
+
+ return status;
+}
+
+void Task::cancel()
+{
+ if (compute) {
+ simgrid::simix::simcall([this] { compute->cancel(); });
+ } else if (comm) {
+ comm->cancel();
+ }
+ set_not_used();
+}
+
+void Task::set_priority(double priority)
+{
+ xbt_assert(std::isfinite(1.0 / priority), "priority is not finite!");
+ priority_ = 1.0 / priority;
+}
+
+s4u::Actor* Task::get_sender()