*/
void MSG_vm_start(msg_vm_t vm)
{
- simgrid::simix::kernelImmediate([vm]() {
- simgrid::vm::VmHostExt::ensureVmExtInstalled();
-
- simgrid::s4u::Host* pm = vm->pimpl_vm_->getPm();
- if (pm->extension<simgrid::vm::VmHostExt>() == nullptr)
- pm->extension_set(new simgrid::vm::VmHostExt());
-
- long pm_ramsize = pm->extension<simgrid::vm::VmHostExt>()->ramsize;
- int pm_overcommit = pm->extension<simgrid::vm::VmHostExt>()->overcommit;
- long vm_ramsize = vm->getRamsize();
-
- if (pm_ramsize && not pm_overcommit) { /* Only verify that we don't overcommit on need */
- /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
- long total_ramsize_of_vms = 0;
- for (simgrid::s4u::VirtualMachine* ws_vm : simgrid::vm::VirtualMachineImpl::allVms_)
- if (pm == ws_vm->pimpl_vm_->getPm())
- total_ramsize_of_vms += ws_vm->pimpl_vm_->getRamsize();
-
- if (vm_ramsize > pm_ramsize - total_ramsize_of_vms) {
- XBT_WARN("cannnot start %s@%s due to memory shortage: vm_ramsize %ld, free %ld, pm_ramsize %ld (bytes).",
- vm->getCname(), pm->getCname(), vm_ramsize, pm_ramsize - total_ramsize_of_vms, pm_ramsize);
- THROWF(vm_error, 0, "Memory shortage on host '%s', VM '%s' cannot be started", pm->getCname(), vm->getCname());
- }
- }
-
- vm->pimpl_vm_->setState(SURF_VM_STATE_RUNNING);
- });
-
+ vm->start();
if (TRACE_msg_vm_is_enabled()) {
container_t vm_container = PJ_container_get(vm->getCname());
type_t type = PJ_type_get("MSG_VM_STATE", vm_container->type);
- val_t value = PJ_value_get_or_new("start", "0 0 1", type); // start is blue
- new PushStateEvent(MSG_get_clock(), vm_container, type, value);
+ value* val = value::get_or_new("start", "0 0 1", type); // start is blue
+ new PushStateEvent(MSG_get_clock(), vm_container, type, val);
}
}
*/
void MSG_vm_shutdown(msg_vm_t vm)
{
- smx_actor_t issuer=SIMIX_process_self();
+ smx_actor_t issuer = SIMIX_process_self();
simgrid::simix::kernelImmediate([vm, issuer]() { vm->pimpl_vm_->shutdown(issuer); });
- // Make sure that the processes in the VM are killed in this scheduling round before processing
- // (eg with the VM destroy)
+ // Make sure that processes in the VM are killed in this scheduling round before processing (eg with the VM destroy)
MSG_process_sleep(0.);
}
-static inline char *get_mig_process_tx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
+static std::string get_mig_process_tx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
{
- return bprintf("__pr_mig_tx:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+ return std::string("__pr_mig_tx:") + vm->getName() + "(" + src_pm->getName() + "-" + dst_pm->getName() + ")";
}
-static inline char *get_mig_process_rx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
+static std::string get_mig_process_rx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
{
- return bprintf("__pr_mig_rx:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+ return std::string("__pr_mig_rx:") + vm->getName() + "(" + src_pm->getName() + "-" + dst_pm->getName() + ")";
}
static inline char *get_mig_task_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, int stage)
static void start_dirty_page_tracking(msg_vm_t vm)
{
vm->pimpl_vm_->dp_enabled = 1;
- if (not vm->pimpl_vm_->dp_objs)
+ if (vm->pimpl_vm_->dp_objs.empty())
return;
- char *key = nullptr;
- xbt_dict_cursor_t cursor = nullptr;
- dirty_page_t dp = nullptr;
- xbt_dict_foreach (vm->pimpl_vm_->dp_objs, cursor, key, dp) {
+ for (auto elm : vm->pimpl_vm_->dp_objs) {
+ dirty_page_t dp = elm.second;
double remaining = MSG_task_get_flops_amount(dp->task);
dp->prev_clock = MSG_get_clock();
dp->prev_remaining = remaining;
-
- // XBT_INFO("%s@%s remaining %f", key, sg_host_name(vm), remaining);
+ XBT_DEBUG("%s@%s remaining %f", elm.first.c_str(), vm->getCname(), remaining);
}
}
vm->pimpl_vm_->dp_enabled = 0;
}
-static double get_computed(char *key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
+static double get_computed(const char* key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
{
double computed = dp->prev_remaining - remaining;
double duration = clock - dp->prev_clock;
{
double total = 0;
- char *key = nullptr;
- xbt_dict_cursor_t cursor = nullptr;
- dirty_page_t dp = nullptr;
- xbt_dict_foreach (vm->pimpl_vm_->dp_objs, cursor, key, dp) {
+ for (auto elm : vm->pimpl_vm_->dp_objs) {
+ const char* key = elm.first.c_str();
+ dirty_page_t dp = elm.second;
double remaining = MSG_task_get_flops_amount(dp->task);
double clock = MSG_get_clock();
dp->prev_clock = MSG_get_clock();
dp->prev_remaining = remaining;
}
- if (not vm->pimpl_vm_->dp_objs)
- vm->pimpl_vm_->dp_objs = xbt_dict_new_homogeneous(nullptr);
- xbt_assert(xbt_dict_get_or_null(vm->pimpl_vm_->dp_objs, key) == nullptr);
- xbt_dict_set(vm->pimpl_vm_->dp_objs, key, dp, nullptr);
+ vm->pimpl_vm_->dp_objs.insert({key, dp});
XBT_DEBUG("add %s on %s (remaining %f, dp_enabled %d)", key, host->getCname(), remaining, vm->pimpl_vm_->dp_enabled);
xbt_free(key);
return;
char *key = bprintf("%s-%p", task->name, task);
- dirty_page_t dp = (dirty_page_t)(vm->pimpl_vm_->dp_objs ? xbt_dict_get_or_null(vm->pimpl_vm_->dp_objs, key) : NULL);
- xbt_assert(dp->task == task);
+ dirty_page_t dp = nullptr;
+ if (vm->pimpl_vm_->dp_objs.find(key) != vm->pimpl_vm_->dp_objs.end())
+ dp = vm->pimpl_vm_->dp_objs.at(key);
+ xbt_assert(dp && dp->task == task);
/* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep
* the information for the lookup_() function that will called soon. */
vm->pimpl_vm_->dp_updated_by_deleted_tasks += updated;
}
- if (vm->pimpl_vm_->dp_objs)
- xbt_dict_remove(vm->pimpl_vm_->dp_objs, key);
+
+ vm->pimpl_vm_->dp_objs.erase(key);
xbt_free(dp);
XBT_DEBUG("del %s on %s", key, host->getCname());
ms->mbox_ctl = bprintf("__mbox_mig_ctl:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
ms->mbox = bprintf("__mbox_mig_src_dst:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
- char *pr_rx_name = get_mig_process_rx_name(vm, src_pm, dst_pm);
- char *pr_tx_name = get_mig_process_tx_name(vm, src_pm, dst_pm);
+ std::string pr_rx_name = get_mig_process_rx_name(vm, src_pm, dst_pm);
+ std::string pr_tx_name = get_mig_process_tx_name(vm, src_pm, dst_pm);
- char** argv = xbt_new(char*, 2);
- argv[0] = pr_rx_name;
- argv[1] = nullptr;
- MSG_process_create_with_arguments(pr_rx_name, migration_rx_fun, ms, dst_pm, 1, argv);
+ MSG_process_create(pr_rx_name.c_str(), migration_rx_fun, ms, dst_pm);
- argv = xbt_new(char*, 2);
- argv[0] = pr_tx_name;
- argv[1] = nullptr;
- MSG_process_create_with_arguments(pr_tx_name, migration_tx_fun, ms, src_pm, 1, argv);
+ MSG_process_create(pr_tx_name.c_str(), migration_tx_fun, ms, src_pm);
/* wait until the migration have finished or on error has occurred */
XBT_DEBUG("wait for reception of the final ACK (i.e. migration has been correctly performed");
if (TRACE_msg_vm_is_enabled()) {
container_t vm_container = PJ_container_get(vm->getCname());
type_t type = PJ_type_get("MSG_VM_STATE", vm_container->type);
- val_t value = PJ_value_get_or_new("suspend", "1 0 0", type); // suspend is red
- new PushStateEvent(MSG_get_clock(), vm_container, type, value);
+ value* val = value::get_or_new("suspend", "1 0 0", type); // suspend is red
+ new PushStateEvent(MSG_get_clock(), vm_container, type, val);
}
}