X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/4871b54f42ce85370d6acdbcb7e42bf75a63b389..3880211b850704febd20f1a482b4617919ed9025:/src/surf/vm_workstation_hl13.cpp diff --git a/src/surf/vm_workstation_hl13.cpp b/src/surf/vm_workstation_hl13.cpp index b8f6eccffe..563c3dba29 100644 --- a/src/surf/vm_workstation_hl13.cpp +++ b/src/surf/vm_workstation_hl13.cpp @@ -1,18 +1,18 @@ -/* - * vm_workstation.cpp - * - * Created on: Nov 12, 2013 - * Author: bedaride - */ +/* Copyright (c) 2013-2014. 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. */ + #include "vm_workstation_hl13.hpp" #include "cpu_cas01.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_vm_workstation); -void surf_vm_workstation_model_init_current_default(void){ +void surf_vm_workstation_model_init_HL13(void){ if (surf_cpu_model_vm) { surf_vm_workstation_model = new WorkstationVMHL13Model(); - ModelPtr model = static_cast(surf_vm_workstation_model); + ModelPtr model = surf_vm_workstation_model; xbt_dynar_push(model_list, &model); xbt_dynar_push(model_list_invoke, &model); @@ -27,31 +27,32 @@ WorkstationVMHL13Model::WorkstationVMHL13Model() : WorkstationVMModel() { p_cpuModel = surf_cpu_model_vm; } -xbt_dynar_t WorkstationVMHL13Model::getRoute(WorkstationPtr src, WorkstationPtr dst){ - return WorkstationCLM03Model::getRoute(src, dst); +void WorkstationVMHL13Model::updateActionsState(double /*now*/, double /*delta*/){ + return; } ActionPtr WorkstationVMHL13Model::communicate(WorkstationPtr src, WorkstationPtr dst, double size, double rate){ - return WorkstationCLM03Model::communicate(src, dst, size, rate); + return surf_network_model->communicate(src->p_netElm, dst->p_netElm, size, rate); } /* ind means ''indirect'' that this is a reference on the whole dict_elm * structure (i.e not on the surf_resource_private infos) */ -void WorkstationVMHL13Model::createResource(const char *name, void *ind_phys_workstation) +WorkstationVMPtr WorkstationVMHL13Model::createWorkstationVM(const char *name, surf_resource_t ind_phys_workstation) { - WorkstationVMHL13LmmPtr ws = new WorkstationVMHL13Lmm(this, name, NULL, static_cast(ind_phys_workstation)); + WorkstationVMHL13Ptr ws = new WorkstationVMHL13(this, name, NULL, ind_phys_workstation); - xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, static_cast(ws)); + xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, ws); /* TODO: * - check how network requests are scheduled between distinct processes competing for the same card. */ + return ws; } -static inline double get_solved_value(CpuActionLmmPtr cpu_action) +static inline double get_solved_value(CpuActionPtr cpu_action) { - return cpu_action->p_variable->value; + return cpu_action->getVariable()->value; } /* In the real world, processes on the guest operating system will be somewhat @@ -69,10 +70,10 @@ double WorkstationVMHL13Model::shareResources(double now) /* 0. Make sure that we already calculated the resource share at the physical * machine layer. */ { - ModelPtr ws_model = static_cast(surf_workstation_model); - ModelPtr vm_ws_model = static_cast(surf_vm_workstation_model); - unsigned int index_of_pm_ws_model = xbt_dynar_search(model_list_invoke, &ws_model); - unsigned int index_of_vm_ws_model = xbt_dynar_search(model_list_invoke, &vm_ws_model); + _XBT_GNUC_UNUSED ModelPtr ws_model = surf_workstation_model; + _XBT_GNUC_UNUSED ModelPtr vm_ws_model = surf_vm_workstation_model; + _XBT_GNUC_UNUSED unsigned int index_of_pm_ws_model = xbt_dynar_search(model_list_invoke, &ws_model); + _XBT_GNUC_UNUSED unsigned int index_of_vm_ws_model = xbt_dynar_search(model_list_invoke, &vm_ws_model); xbt_assert((index_of_pm_ws_model < index_of_vm_ws_model), "Cannot assume surf_workstation_model comes before"); /* Another option is that we call sub_ws->share_resource() here. The @@ -105,58 +106,59 @@ double WorkstationVMHL13Model::shareResources(double now) * **/ - /* iterate for all hosts including virtual machines */ - xbt_lib_cursor_t cursor; - char *key; - void **ind_host; - xbt_lib_foreach(host_lib, cursor, key, ind_host) { - WorkstationPtr ws = dynamic_cast( - static_cast(ind_host[SURF_WKS_LEVEL])); - CpuLmmPtr cpu = dynamic_cast( - static_cast(ind_host[SURF_CPU_LEVEL])); - - if (!ws) - continue; - /* skip if it is not a virtual machine */ - if (ws->p_model != static_cast(surf_vm_workstation_model)) - continue; - xbt_assert(cpu, "cpu-less workstation"); + /* iterate for all virtual machines */ + for (WorkstationVMModel::vm_list_t::iterator iter = + WorkstationVMModel::ws_vms.begin(); + iter != WorkstationVMModel::ws_vms.end(); ++iter) { - /* It is a virtual machine, so we can cast it to workstation_VM2013_t */ - WorkstationVMPtr ws_vm = dynamic_cast(ws); + WorkstationVMPtr ws_vm = &*iter; + CpuPtr cpu = ws_vm->p_cpu; + xbt_assert(cpu, "cpu-less workstation"); - double solved_value = get_solved_value(reinterpret_cast(ws_vm->p_action)); + double solved_value = get_solved_value(ws_vm->p_action); XBT_DEBUG("assign %f to vm %s @ pm %s", solved_value, - ws->m_name, ws_vm->p_subWs->m_name); + ws_vm->getName(), ws_vm->p_subWs->getName()); // TODO: check lmm_update_constraint_bound() works fine instead of the below manual substitution. // cpu_cas01->constraint->bound = solved_value; - xbt_assert(cpu->p_model == static_cast(surf_cpu_model_vm)); - lmm_system_t vcpu_system = cpu->p_model->p_maxminSystem; - lmm_update_constraint_bound(vcpu_system, cpu->p_constraint, virt_overhead * solved_value); + xbt_assert(cpu->getModel() == surf_cpu_model_vm); + lmm_system_t vcpu_system = cpu->getModel()->getMaxminSystem(); + lmm_update_constraint_bound(vcpu_system, cpu->getConstraint(), virt_overhead * solved_value); } /* 2. Calculate resource share at the virtual machine layer. */ - double ret = WorkstationCLM03Model::shareResources(now); - + adjustWeightOfDummyCpuActions(); + + double min_by_cpu = p_cpuModel->shareResources(now); + double min_by_net = (strcmp(surf_network_model->getName(), "network NS3")) ? surf_network_model->shareResources(now) : -1; + double min_by_sto = -1; + if (p_cpuModel == surf_cpu_model_pm) + min_by_sto = surf_storage_model->shareResources(now); + + XBT_DEBUG("model %p, %s min_by_cpu %f, %s min_by_net %f, %s min_by_sto %f", + this, surf_cpu_model_pm->getName(), min_by_cpu, + surf_network_model->getName(), min_by_net, + surf_storage_model->getName(), min_by_sto); + + double ret = max(max(min_by_cpu, min_by_net), min_by_sto); + if (min_by_cpu >= 0.0 && min_by_cpu < ret) + ret = min_by_cpu; + if (min_by_net >= 0.0 && min_by_net < ret) + ret = min_by_net; + if (min_by_sto >= 0.0 && min_by_sto < ret) + ret = min_by_sto; /* FIXME: 3. do we have to re-initialize our cpu_action object? */ #if 0 - /* iterate for all hosts including virtual machines */ - xbt_lib_foreach(host_lib, cursor, key, ind_host) { - WorkstationCLM03Ptr ws_clm03 = ind_host[SURF_WKS_LEVEL]; + /* iterate for all virtual machines */ + for (WorkstationVMModel::vm_list_t::iterator iter = + WorkstationVMModel::ws_vms.begin(); + iter != WorkstationVMModel::ws_vms.end(); ++iter) { - /* skip if it is not a virtual machine */ - if (!ws_clm03) - continue; - if (ws_clm03->p_model != surf_vm_workstation_model) - continue; - - /* It is a virtual machine, so we can cast it to workstation_VM2013_t */ { #if 0 - WorkstationVM2013Ptr ws_vm2013 = (workstation_VM2013_t) ws_clm03; + WorkstationVM2013Ptr ws_vm2013 = static_cast(&*iter); XBT_INFO("cost %f remains %f start %f finish %f", ws_vm2013->cpu_action->cost, ws_vm2013->cpu_action->remains, ws_vm2013->cpu_action->start, @@ -164,7 +166,7 @@ double WorkstationVMHL13Model::shareResources(double now) ); #endif #if 0 - void *ind_sub_host = xbt_lib_get_elm_or_null(host_lib, ws_vm2013->sub_ws->generic_resource.name); + void *ind_sub_host = xbt_lib_get_elm_or_null(host_lib, ws_vm2013->sub_ws->generic_resource.getName); surf_cpu_model_pm->action_unref(ws_vm2013->cpu_action); /* FIXME: this means busy loop? */ // ws_vm2013->cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_sub_host, GUESTOS_NOISE); @@ -179,29 +181,59 @@ double WorkstationVMHL13Model::shareResources(double now) return ret; } +ActionPtr WorkstationVMHL13Model::executeParallelTask(int workstation_nb, + void **workstation_list, + double *computation_amount, + double *communication_amount, + double rate){ +#define cost_or_zero(array,pos) ((array)?(array)[pos]:0.0) + if ((workstation_nb == 1) + && (cost_or_zero(communication_amount, 0) == 0.0)) + return ((WorkstationCLM03Ptr)workstation_list[0])->execute(computation_amount[0]); + else if ((workstation_nb == 1) + && (cost_or_zero(computation_amount, 0) == 0.0)) + return communicate((WorkstationCLM03Ptr)workstation_list[0], (WorkstationCLM03Ptr)workstation_list[0],communication_amount[0], rate); + else if ((workstation_nb == 2) + && (cost_or_zero(computation_amount, 0) == 0.0) + && (cost_or_zero(computation_amount, 1) == 0.0)) { + int i,nb = 0; + double value = 0.0; + + for (i = 0; i < workstation_nb * workstation_nb; i++) { + if (cost_or_zero(communication_amount, i) > 0.0) { + nb++; + value = cost_or_zero(communication_amount, i); + } + } + if (nb == 1) + return communicate((WorkstationCLM03Ptr)workstation_list[0], (WorkstationCLM03Ptr)workstation_list[1],value, rate); + } +#undef cost_or_zero + + THROW_UNIMPLEMENTED; /* This model does not implement parallel tasks */ + return NULL; +} + /************ * Resource * ************/ -WorkstationVMHL13Lmm::WorkstationVMHL13Lmm(WorkstationVMModelPtr model, const char* name, xbt_dict_t props, + +WorkstationVMHL13::WorkstationVMHL13(WorkstationVMModelPtr model, const char* name, xbt_dict_t props, surf_resource_t ind_phys_workstation) - : Resource(model, name, props) - , WorkstationVMLmm(NULL, NULL) - , WorkstationCLM03Lmm(model, name, props, NULL, NULL, NULL) + : WorkstationVM(model, name, props, NULL, NULL) { - WorkstationPtr sub_ws = dynamic_cast( - static_cast( - surf_workstation_resource_priv(ind_phys_workstation))); + WorkstationPtr sub_ws = static_cast(surf_workstation_resource_priv(ind_phys_workstation)); /* Currently, we assume a VM has no storage. */ p_storage = NULL; /* Currently, a VM uses the network resource of its physical host. In - * host_lib, this network resource object is refered from two different keys. + * host_lib, this network resource object is referred from two different keys. * When deregistering the reference that points the network resource object * from the VM name, we have to make sure that the system does not call the * free callback for the network resource object. The network resource object * is still used by the physical machine. */ - p_netElm = static_cast(xbt_lib_get_or_null(host_lib, sub_ws->m_name, ROUTING_HOST_LEVEL)); + p_netElm = new RoutingEdgeWrapper(static_cast(xbt_lib_get_or_null(host_lib, sub_ws->getName(), ROUTING_HOST_LEVEL))); xbt_lib_set(host_lib, name, ROUTING_HOST_LEVEL, p_netElm); p_subWs = sub_ws; @@ -209,16 +241,14 @@ WorkstationVMHL13Lmm::WorkstationVMHL13Lmm(WorkstationVMModelPtr model, const ch // //// CPU RELATED STUFF //// // Roughly, create a vcpu resource by using the values of the sub_cpu one. - CpuCas01LmmPtr sub_cpu = dynamic_cast( - static_cast( - surf_cpu_resource_priv(ind_phys_workstation))); + CpuCas01Ptr sub_cpu = static_cast(surf_cpu_resource_priv(ind_phys_workstation)); /* We can assume one core and cas01 cpu for the first step. * Do xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, cpu) if you get the resource. */ - p_cpu = static_cast(surf_cpu_model_vm)->createResource(name, // name - sub_cpu->p_powerPeakList, // host->power_peak, - sub_cpu->m_pstate, + p_cpu = surf_cpu_model_vm->createCpu(name, // name + sub_cpu->getPowerPeakList(), // host->power_peak, + sub_cpu->getPState(), 1, // host->power_scale, NULL, // host->power_trace, 1, // host->core_amount, @@ -229,7 +259,7 @@ WorkstationVMHL13Lmm::WorkstationVMHL13Lmm(WorkstationVMModelPtr model, const ch /* We create cpu_action corresponding to a VM process on the host operating system. */ /* FIXME: TODO: we have to peridocally input GUESTOS_NOISE to the system? how ? */ // vm_ws->cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_phys_workstation, GUESTOS_NOISE); - p_action = dynamic_cast(sub_cpu->execute(0)); + p_action = sub_cpu->execute(0); /* The SURF_WKS_LEVEL at host_lib saves workstation_CLM03 objects. Please * note workstation_VM2013 objects, inheriting the workstation_CLM03 @@ -238,76 +268,52 @@ WorkstationVMHL13Lmm::WorkstationVMHL13Lmm(WorkstationVMModelPtr model, const ch * If you want to get a workstation_VM2013 object from host_lib, see * ws->generic_resouce.model->type first. If it is * SURF_MODEL_TYPE_VM_WORKSTATION, you can cast ws to vm_ws. */ - XBT_INFO("Create VM(%s)@PM(%s) with %ld mounted disks", name, sub_ws->m_name, xbt_dynar_length(p_storage)); + XBT_INFO("Create VM(%s)@PM(%s) with %ld mounted disks", name, sub_ws->getName(), xbt_dynar_length(p_storage)); } /* - * A physical host does not disapper in the current SimGrid code, but a VM may - * disapper during a simulation. + * A physical host does not disappear in the current SimGrid code, but a VM may + * disappear during a simulation. */ -WorkstationVMHL13Lmm::~WorkstationVMHL13Lmm() +WorkstationVMHL13::~WorkstationVMHL13() { - /* ind_phys_workstation equals to smx_host_t */ - surf_resource_t ind_vm_workstation = xbt_lib_get_elm_or_null(host_lib, m_name); - - /* Before clearing the entries in host_lib, we have to pick up resources. */ - CpuCas01LmmPtr cpu = dynamic_cast( - static_cast( - surf_cpu_resource_priv(ind_vm_workstation))); - - /* We deregister objects from host_lib, without invoking the freeing callback - * of each level. - * - * Do not call xbt_lib_remove() here. It deletes all levels of the key, - * including MSG_HOST_LEVEL and others. We should unregister only what we know. - */ - xbt_lib_unset(host_lib, m_name, SURF_CPU_LEVEL, 0); - xbt_lib_unset(host_lib, m_name, ROUTING_HOST_LEVEL, 0); - xbt_lib_unset(host_lib, m_name, SURF_WKS_LEVEL, 0); - - /* TODO: comment out when VM stroage is implemented. */ - // xbt_lib_unset(host_lib, name, SURF_STORAGE_LEVEL, 0); - - /* Free the cpu_action of the VM. */ - int ret = p_action->unref(); + _XBT_GNUC_UNUSED int ret = p_action->unref(); xbt_assert(ret == 1, "Bug: some resource still remains"); +} - /* Free the cpu resource of the VM. If using power_trace, we will have to */ - delete cpu; - - /* Free the network resource of the VM. */ - // Nothing has to be done, because net_elmts is just a pointer on the physical one - - /* Free the storage resource of the VM. */ - // Not relevant yet +void WorkstationVMHL13::updateState(tmgr_trace_event_t /*event_type*/, double /*value*/, double /*date*/) { + THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */ +} - /* Free the workstation resource of the VM. */ +bool WorkstationVMHL13::isUsed() { + THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */ + return -1; } -e_surf_resource_state_t WorkstationVMHL13Lmm::getState() +e_surf_resource_state_t WorkstationVMHL13::getState() { return (e_surf_resource_state_t) p_currentState; } -void WorkstationVMHL13Lmm::setState(e_surf_resource_state_t state) +void WorkstationVMHL13::setState(e_surf_resource_state_t state) { p_currentState = (e_surf_vm_state_t) state; } -void WorkstationVMHL13Lmm::suspend() +void WorkstationVMHL13::suspend() { p_action->suspend(); p_currentState = SURF_VM_STATE_SUSPENDED; } -void WorkstationVMHL13Lmm::resume() +void WorkstationVMHL13::resume() { p_action->resume(); p_currentState = SURF_VM_STATE_RUNNING; } -void WorkstationVMHL13Lmm::save() +void WorkstationVMHL13::save() { p_currentState = SURF_VM_STATE_SAVING; @@ -316,7 +322,7 @@ void WorkstationVMHL13Lmm::save() p_currentState = SURF_VM_STATE_SAVED; } -void WorkstationVMHL13Lmm::restore() +void WorkstationVMHL13::restore() { p_currentState = SURF_VM_STATE_RESTORING; @@ -328,15 +334,13 @@ void WorkstationVMHL13Lmm::restore() /* * Update the physical host of the given VM */ -void WorkstationVMHL13Lmm::migrate(surf_resource_t ind_dst_pm) +void WorkstationVMHL13::migrate(surf_resource_t ind_dst_pm) { /* ind_phys_workstation equals to smx_host_t */ - WorkstationPtr ws_dst = dynamic_cast( - static_cast( - surf_workstation_resource_priv(ind_dst_pm))); - const char *vm_name = m_name; - const char *pm_name_src = p_subWs->m_name; - const char *pm_name_dst = ws_dst->m_name; + WorkstationPtr ws_dst = static_cast(surf_workstation_resource_priv(ind_dst_pm)); + const char *vm_name = getName(); + const char *pm_name_src = p_subWs->getName(); + const char *pm_name_dst = ws_dst->getName(); xbt_assert(ws_dst); @@ -344,7 +348,7 @@ void WorkstationVMHL13Lmm::migrate(surf_resource_t ind_dst_pm) /* update net_elm with that of the destination physical host */ RoutingEdgePtr old_net_elm = p_netElm; - RoutingEdgePtr new_net_elm = static_cast(xbt_lib_get_or_null(host_lib, pm_name_dst, ROUTING_HOST_LEVEL)); + RoutingEdgePtr new_net_elm = new RoutingEdgeWrapper(static_cast(xbt_lib_get_or_null(host_lib, pm_name_dst, ROUTING_HOST_LEVEL))); xbt_assert(new_net_elm); /* Unregister the current net_elm from host_lib. Do not call the free callback. */ @@ -369,18 +373,23 @@ void WorkstationVMHL13Lmm::migrate(surf_resource_t ind_dst_pm) #endif /* create a cpu action bound to the pm model at the destination. */ - CpuActionLmmPtr new_cpu_action = dynamic_cast( - dynamic_cast( - static_cast( - surf_cpu_resource_priv(ind_dst_pm)))->execute(0)); + CpuActionPtr new_cpu_action = static_cast( + static_cast(surf_cpu_resource_priv(ind_dst_pm))->execute(0)); e_surf_action_state_t state = p_action->getState(); if (state != SURF_ACTION_DONE) XBT_CRITICAL("FIXME: may need a proper handling, %d", state); - if (p_action->m_remains > 0) - XBT_CRITICAL("FIXME: need copy the state(?), %f", p_action->m_remains); + if (p_action->getRemainsNoUpdate() > 0) + XBT_CRITICAL("FIXME: need copy the state(?), %f", p_action->getRemainsNoUpdate()); - int ret = p_action->unref(); + /* keep the bound value of the cpu action of the VM. */ + double old_bound = p_action->getBound(); + if (old_bound != 0) { + XBT_INFO("migrate VM(%s): set bound (%f) at %s", vm_name, old_bound, pm_name_dst); + new_cpu_action->setBound(old_bound); + } + + _XBT_GNUC_UNUSED int ret = p_action->unref(); xbt_assert(ret == 1, "Bug: some resource still remains"); p_action = new_cpu_action; @@ -388,38 +397,43 @@ void WorkstationVMHL13Lmm::migrate(surf_resource_t ind_dst_pm) XBT_DEBUG("migrate VM(%s): change net_elm (%p to %p)", vm_name, old_net_elm, new_net_elm); XBT_DEBUG("migrate VM(%s): change PM (%s to %s)", vm_name, pm_name_src, pm_name_dst); + delete old_net_elm; } -void WorkstationVMHL13Lmm::setBound(double bound){ +void WorkstationVMHL13::setBound(double bound){ p_action->setBound(bound); } -void WorkstationVMHL13Lmm::setAffinity(CpuLmmPtr cpu, unsigned long mask){ +void WorkstationVMHL13::setAffinity(CpuPtr cpu, unsigned long mask){ p_action->setAffinity(cpu, mask); } /* - * A surf level object will be useless in the upper layer. Returing the + * A surf level object will be useless in the upper layer. Returning the * dict_elm of the host. **/ -surf_resource_t WorkstationVMHL13Lmm::getPm() +surf_resource_t WorkstationVMHL13::getPm() { - return xbt_lib_get_elm_or_null(host_lib, p_subWs->m_name); + return xbt_lib_get_elm_or_null(host_lib, p_subWs->getName()); } /* Adding a task to a VM updates the VCPU task on its physical machine. */ -ActionPtr WorkstationVMHL13Lmm::execute(double size) +ActionPtr WorkstationVMHL13::execute(double size) { - double old_cost = p_action->m_cost; + double old_cost = p_action->getCost(); double new_cost = old_cost + size; XBT_DEBUG("VM(%s)@PM(%s): update dummy action's cost (%f -> %f)", - m_name, p_subWs->m_name, + getName(), p_subWs->getName(), old_cost, new_cost); - p_action->m_cost = new_cost; + p_action->setCost(new_cost); + + return p_cpu->execute(size); +} - return WorkstationCLM03Lmm::execute(size); +ActionPtr WorkstationVMHL13::sleep(double duration) { + return p_cpu->sleep(duration); } /**********