From: Paul Bédaride Date: Thu, 5 Sep 2013 12:44:21 +0000 (+0200) Subject: CpuCas01 in C++ X-Git-Tag: v3_11_beta~297^2~15 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/83ff63f9a846dd01995a4bbb8979d2fa909ed34b?hp=de74e33ac31948d22f805fed0807be831cb8fdbd CpuCas01 in C++ --- diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index 9538a0de9f..afb7198747 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -42,6 +42,7 @@ set(EXTRA_DIST src/smpi/smpi_mpi_dt_private.h src/surf/cpu.hpp src/surf/cpu_ti.hpp + src/surf/cpu_cas01.hpp src/surf/cpu_ti_private.h src/surf/gtnets/gtnets_interface.h src/surf/gtnets/gtnets_simulator.h @@ -53,6 +54,7 @@ set(EXTRA_DIST src/surf/network_gtnets_private.h src/surf/network_ns3_private.h src/surf/network_private.h + src/surf/network.hpp src/surf/ns3/my-point-to-point-helper.h src/surf/ns3/ns3_interface.h src/surf/ns3/ns3_simulator.h @@ -288,7 +290,9 @@ set(NS3_SRC ) set(SURF_SRC + src/surf/cpu.cpp src/surf/cpu_ti.cpp + src/surf/cpu_cas01.cpp src/surf/cpu_cas01.c src/surf/cpu_ti.c src/surf/fair_bottleneck.cpp @@ -297,6 +301,7 @@ set(SURF_SRC src/surf/lagrange.cpp src/surf/solver.cpp src/surf/solver_c.cpp + src/surf/network.cpp src/surf/network.c src/surf/network_constant.c src/surf/platf_generator.c diff --git a/src/surf/cpu.cpp b/src/surf/cpu.cpp new file mode 100644 index 0000000000..a1ac6ea6cb --- /dev/null +++ b/src/surf/cpu.cpp @@ -0,0 +1,167 @@ +#include "cpu.hpp" + +//TODO: resolve dependencies +static int TRACE_is_enabled(void) {return 0;} +static void TRACE_surf_host_set_utilization(const char *resource, + const char *category, + double value, + double now, + double delta){} +static double TRACE_last_timestamp_to_dump = 0; + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_cpu, surfpp, + "Logging specific to the SURF cpu module"); + + +/********* + * Model * + *********/ + +void CpuModel::updateActionsStateLazy(double now, double delta) +{ + void *_action; + ActionLmmPtr action; + while ((xbt_heap_size(p_actionHeap) > 0) + && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) { + action = (ActionLmmPtr) xbt_heap_pop(p_actionHeap); + XBT_DEBUG("Something happened to action %p", action); +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + CpuPtr cpu = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var(p_maxminSystem, action->p_variable, 0)); + TRACE_surf_host_set_utilization(cpu->m_name, action->p_category, + lmm_variable_getvalue(action->p_variable), + action->m_lastUpdate, + now - action->m_lastUpdate); + } +#endif + + action->m_finish = surf_get_clock(); + XBT_DEBUG("Action %p finished", action); + + /* set the remains to 0 due to precision problems when updating the remaining amount */ + action->m_remains = 0; + action->setState(SURF_ACTION_DONE); + action->heapRemove(p_actionHeap); //FIXME: strange call since action was already popped + } +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + //defining the last timestamp that we can safely dump to trace file + //without losing the event ascending order (considering all CPU's) + double smaller = -1; + xbt_swag_foreach(_action, p_runningActionSet) { + action = (ActionLmmPtr) _action; + if (smaller < 0) { + smaller = action->m_lastUpdate; + continue; + } + if (action->m_lastUpdate < smaller) { + smaller = action->m_lastUpdate; + } + } + if (smaller > 0) { + TRACE_last_timestamp_to_dump = smaller; + } + } +#endif + return; +} + +void CpuModel::updateActionsStateFull(double now, double delta) +{ + void *_action, *_next_action; + ActionLmmPtr action = NULL; + ActionLmmPtr next_action = NULL; + xbt_swag_t running_actions = p_runningActionSet; + + xbt_swag_foreach_safe(_action, _next_action, running_actions) { + action = (ActionLmmPtr) _action; +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + CpuPtr x = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var + (p_maxminSystem, action->p_variable, 0)); + + TRACE_surf_host_set_utilization(x->m_name, + action->p_category, + lmm_variable_getvalue(action->p_variable), + now - delta, + delta); + TRACE_last_timestamp_to_dump = now - delta; + } +#endif + + double_update(&(action->m_remains), + lmm_variable_getvalue(action->p_variable) * delta); + + + if (action->m_maxDuration != NO_MAX_DURATION) + double_update(&(action->m_maxDuration), delta); + + + if ((action->m_remains <= 0) && + (lmm_get_variable_weight(action->p_variable) > 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + + } else if ((action->m_maxDuration != NO_MAX_DURATION) && + (action->m_maxDuration <= 0)) { + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + } + } + + return; +} + +/************ + * Resource * + ************/ + +double Cpu::getSpeed(double load) +{ + return load * m_powerPeak; +} + +double Cpu::getAvailableSpeed() +{ +/* number between 0 and 1 */ + return m_powerScale; +} + +int Cpu::getCore() +{ + return m_core; +} + +/********** + * Action * + **********/ + +void CpuActionLmm::updateRemainingLazy(double now) +{ + double delta = 0.0; + + xbt_assert(p_stateSet == p_model->p_runningActionSet, + "You're updating an action that is not running."); + + /* bogus priority, skip it */ + xbt_assert(m_priority > 0, + "You're updating an action that seems suspended."); + + delta = now - m_lastUpdate; + + if (m_remains > 0) { + XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate); + double_update(&(m_remains), m_lastValue * delta); + +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + CpuPtr cpu = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)); + TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate); + } +#endif + XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains); + } + + m_lastUpdate = now; + m_lastValue = lmm_variable_getvalue(p_variable); +} diff --git a/src/surf/cpu.hpp b/src/surf/cpu.hpp index 73ee3d1e8d..c7779e2db6 100644 --- a/src/surf/cpu.hpp +++ b/src/surf/cpu.hpp @@ -12,9 +12,15 @@ typedef CpuModel *CpuModelPtr; class Cpu; typedef Cpu *CpuPtr; +class CpuLmm; +typedef CpuLmm *CpuLmmPtr; + class CpuAction; typedef CpuAction *CpuActionPtr; +class CpuActionLmm; +typedef CpuActionLmm *CpuActionLmmPtr; + /********* * Model * *********/ @@ -22,6 +28,8 @@ class CpuModel : public Model { public: CpuModel(string name) : Model(name) {}; CpuPtr createResource(string name); + void updateActionsStateLazy(double now, double delta); + void updateActionsStateFull(double now, double delta); virtual void addTraces() =0; }; @@ -29,8 +37,9 @@ public: /************ * Resource * ************/ -class Cpu : public Resource { +class Cpu : virtual public Resource { public: + Cpu(){}; Cpu(CpuModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {}; CpuActionPtr execute(double size); CpuActionPtr sleep(double duration); @@ -40,18 +49,37 @@ public: double getAvailableSpeed(); void addTraces(void); + double m_powerPeak; /*< CPU power peak */ + double m_powerScale; /*< Percentage of CPU disponible */ protected: - double m_powerPeak; + int m_core; + //virtual boost::shared_ptr execute(double size) = 0; //virtual boost::shared_ptr sleep(double duration) = 0; }; +class CpuLmm : public ResourceLmm, public Cpu { +public: + CpuLmm(){}; + CpuLmm(CpuModelPtr model, const char* name, xbt_dict_t properties) : ResourceLmm(), Cpu(model, name, properties) {}; + +}; + /********** * Action * **********/ -class CpuAction : public Action { +class CpuAction : virtual public Action { public: + CpuAction(){}; CpuAction(ModelPtr model, double cost, bool failed): Action(model, cost, failed) {}; }; +class CpuActionLmm : public ActionLmm, public CpuAction { +public: + CpuActionLmm(){}; + CpuActionLmm(ModelPtr model, double cost, bool failed): ActionLmm(model, cost, failed), CpuAction(model, cost, failed) {}; + void updateRemainingLazy(double now); +}; + + #endif /* SURF_MODEL_CPU_H_ */ diff --git a/src/surf/cpu_cas01.cpp b/src/surf/cpu_cas01.cpp new file mode 100644 index 0000000000..6eb404c545 --- /dev/null +++ b/src/surf/cpu_cas01.cpp @@ -0,0 +1,326 @@ +/* Copyright (c) 2009-2011. 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 "cpu_cas01.hpp" +#include "cpu_ti.hpp" +#include "surf.hpp" +#include "maxmin_private.h" +#include "simgrid/sg_config.h" + +//TODO: resolve dependencies +static void TRACE_surf_host_set_power(double date, const char *resource, double power) {} + + +static ModelPtr surf_cpu_model = NULL; + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_cpu_cas, surfpp, + "Logging specific to the SURF CPU IMPROVED module"); + +static xbt_swag_t + cpu_running_action_set_that_does_not_need_being_checked = NULL; + +/********* + * Model * + *********/ +void surf_cpu_model_init_Cas01() +{ + char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim"); + + if (surf_cpu_model) + return; + + if (!strcmp(optim, "TI")) { + surf_cpu_model = new CpuTiModel(); + return; + } + + surf_cpu_model = new CpuCas01Model(); + xbt_dynar_push(model_list, &surf_cpu_model); +} + +CpuCas01Model::CpuCas01Model() : CpuModel("cpu") +{ + CpuCas01ActionLmm action; + + char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim"); + int select = xbt_cfg_get_boolean(_sg_cfg_set, "cpu/maxmin_selective_update"); + + if (!strcmp(optim, "Full")) { + p_updateMechanism = UM_FULL; + m_selectiveUpdate = select; + } else if (!strcmp(optim, "Lazy")) { + p_updateMechanism = UM_LAZY; + m_selectiveUpdate = 1; + xbt_assert((select == 1) + || + (xbt_cfg_is_default_value + (_sg_cfg_set, "cpu/maxmin_selective_update")), + "Disabling selective update while using the lazy update mechanism is dumb!"); + } else { + xbt_die("Unsupported optimization (%s) for this model", optim); + } + + cpu_running_action_set_that_does_not_need_being_checked = + xbt_swag_new(xbt_swag_offset(action, p_stateHookup)); + + if (p_updateMechanism == UM_LAZY) { + shareResources = &CpuCas01Model::shareResourcesLazy; + updateActionsState = &CpuCas01Model::updateActionsStateLazy; + + } else if (p_updateMechanism == UM_FULL) { + shareResources = &CpuCas01Model::shareResourcesFull; + updateActionsState = &CpuCas01Model::updateActionsStateFull; + } else + xbt_die("Invalid cpu update mechanism!"); + + if (!p_maxminSystem) { + p_maxminSystem = lmm_system_new(m_selectiveUpdate); + } + + if (p_updateMechanism == UM_LAZY) { + p_actionHeap = xbt_heap_new(8, NULL); + xbt_heap_set_update_callback(p_actionHeap, surf_action_lmm_update_index_heap); + p_modifiedSet = xbt_swag_new(xbt_swag_offset(action, p_actionListHookup)); + //TOREPAIR: cpu_model->model_private->maxmin_system->m_keepTrack = cpu_model->model_private->modified_set; + } + /* Define callbacks */ + //TODO sg_platf_host_add_cb(parse_cpu_init); + //TODO sg_platf_postparse_add_cb(cpu_add_traces_cpu); +} + +CpuCas01Model::~CpuCas01Model() +{ + lmm_system_free(p_maxminSystem); + p_maxminSystem = NULL; + + if (p_actionHeap) + xbt_heap_free(p_actionHeap); + xbt_swag_free(p_modifiedSet); + + surf_cpu_model = NULL; + + xbt_swag_free(cpu_running_action_set_that_does_not_need_being_checked); + cpu_running_action_set_that_does_not_need_being_checked = NULL; +} + +void CpuCas01Model::parseInit(sg_platf_host_cbarg_t host) +{ + createResource(host->id, + host->power_peak, + host->power_scale, + host->power_trace, + host->core_amount, + host->initial_state, + host->state_trace, + host->properties); +} +CpuCas01LmmPtr CpuCas01Model::createResource(const char *name, double power_peak, double power_scale, + tmgr_trace_t power_trace, int core, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties) +{ + CpuCas01LmmPtr cpu = NULL; + + xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)), + "Host '%s' declared several times in the platform file", + name); + xbt_assert(power_peak > 0, "Power has to be >0"); + xbt_assert(core > 0, "Invalid number of cores %d", core); + + cpu = new CpuCas01Lmm(this, name, power_peak, power_scale, power_trace, core, state_initial, state_trace, cpu_properties); + + xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, this); + + return (CpuCas01LmmPtr) xbt_lib_get_elm_or_null(host_lib, name);; +} + +double CpuCas01Model::shareResourcesFull(double now) +{ + CpuCas01ActionLmm action; + Model::shareResourcesFull(p_runningActionSet, + xbt_swag_offset(action, p_variable), + p_maxminSystem, lmm_solve); + return 0; +} + +void CpuCas01Model::addTraces() +{ + xbt_dict_cursor_t cursor = NULL; + char *trace_name, *elm; + static int called = 0; + if (called) + return; + called = 1; + + /* connect all traces relative to hosts */ + xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuCas01LmmPtr host = (CpuCas01LmmPtr) surf_cpu_resource_by_name(elm); + + xbt_assert(host, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + host->p_stateEvent = + tmgr_history_add_trace(history, trace, 0.0, 0, host); + } + + xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuCas01LmmPtr host = (CpuCas01LmmPtr) surf_cpu_resource_by_name(elm); + + xbt_assert(host, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + host->p_powerEvent = + tmgr_history_add_trace(history, trace, 0.0, 0, host); + } +} + +/************ + * Resource * + ************/ +CpuCas01Lmm::CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, double powerPeak, + double powerScale, tmgr_trace_t powerTrace, int core, + e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, + xbt_dict_t properties) : + CpuLmm(model, name, properties) { + m_powerPeak = powerPeak; + m_powerScale = powerScale; + m_core = core; + p_stateCurrent = stateInitial; + if (powerTrace) + p_powerEvent = tmgr_history_add_trace(history, powerTrace, 0.0, 0, this); + + if (stateTrace) + p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, this); + + p_constraint = lmm_constraint_new(p_model->p_maxminSystem, this, m_core * m_powerScale * m_powerPeak); +} + +bool CpuCas01Lmm::isUsed() +{ + return lmm_constraint_used(p_model->p_maxminSystem, p_constraint); +} + +void CpuCas01Lmm::updateState(tmgr_trace_event_t event_type, double value, double date) +{ + lmm_variable_t var = NULL; + lmm_element_t elem = NULL; + + surf_watched_hosts(); + + if (event_type == p_powerEvent) { + m_powerScale = value; + lmm_update_constraint_bound(surf_cpu_model->p_maxminSystem, p_constraint, + m_core * m_powerScale * + m_powerPeak); +#ifdef HAVE_TRACING + TRACE_surf_host_set_power(date, m_name, + m_core * m_powerScale * + m_powerPeak); +#endif + while ((var = lmm_get_var_from_cnst + (surf_cpu_model->p_maxminSystem, p_constraint, &elem))) { + CpuCas01ActionLmmPtr action = (CpuCas01ActionLmmPtr) lmm_variable_id(var); + lmm_update_variable_bound(surf_cpu_model->p_maxminSystem, + action->p_variable, + m_powerScale * m_powerPeak); + } + if (tmgr_trace_event_free(event_type)) + p_powerEvent = NULL; + } else if (event_type == p_stateEvent) { + if (value > 0) + p_stateCurrent = SURF_RESOURCE_ON; + else { + lmm_constraint_t cnst = p_constraint; + + p_stateCurrent = SURF_RESOURCE_OFF; + + while ((var = lmm_get_var_from_cnst(surf_cpu_model->p_maxminSystem, cnst, &elem))) { + ActionPtr action = (ActionPtr) lmm_variable_id(var); + + if (action->getState() == SURF_ACTION_RUNNING || + action->getState() == SURF_ACTION_READY || + action->getState() == SURF_ACTION_NOT_IN_THE_SYSTEM) { + action->m_finish = date; + action->setState(SURF_ACTION_FAILED); + } + } + } + if (tmgr_trace_event_free(event_type)) + p_stateEvent = NULL; + } else { + XBT_CRITICAL("Unknown event ! \n"); + xbt_abort(); + } + + return; +} + +CpuActionPtr CpuCas01Lmm::execute(double size) +{ + + XBT_IN("(%s,%g)", m_name, size); + CpuCas01ActionLmmPtr action = new CpuCas01ActionLmm(surf_cpu_model, size, p_stateCurrent != SURF_RESOURCE_ON); + + action->m_suspended = 0; /* Should be useless because of the + calloc but it seems to help valgrind... */ + + action->p_variable = + lmm_variable_new(surf_cpu_model->p_maxminSystem, action, + action->m_priority, + m_powerScale * m_powerPeak, 1); + if (surf_cpu_model->p_updateMechanism == UM_LAZY) { + action->m_indexHeap = -1; + action->m_lastUpdate = surf_get_clock(); + action->m_lastValue = 0.0; + } + lmm_expand(surf_cpu_model->p_maxminSystem, p_constraint, + action->p_variable, 1.0); + XBT_OUT(); + return action; +} + +CpuActionPtr CpuCas01Lmm::sleep(double duration) +{ + if (duration > 0) + duration = MAX(duration, MAXMIN_PRECISION); + + XBT_IN("(%s,%g)", m_name, duration); + CpuCas01ActionLmmPtr action = (CpuCas01ActionLmmPtr) execute(1.0); + + // FIXME: sleep variables should not consume 1.0 in lmm_expand + action->m_maxDuration = duration; + action->m_suspended = 2; + if (duration == NO_MAX_DURATION) { + /* Move to the *end* of the corresponding action set. This convention + is used to speed up update_resource_state */ + xbt_swag_remove(action, action->p_stateSet); + action->p_stateSet = cpu_running_action_set_that_does_not_need_being_checked; + xbt_swag_insert(action, action->p_stateSet); + } + + lmm_update_variable_weight(surf_cpu_model->p_maxminSystem, + action->p_variable, 0.0); + if (surf_cpu_model->p_updateMechanism == UM_LAZY) { // remove action from the heap + action->heapRemove(surf_cpu_model->p_actionHeap); + // this is necessary for a variable with weight 0 since such + // variables are ignored in lmm and we need to set its max_duration + // correctly at the next call to share_resources + xbt_swag_insert_at_head(action, surf_cpu_model->p_modifiedSet); + } + + XBT_OUT(); + return action; +} + + +/********** + * Action * + **********/ + + diff --git a/src/surf/cpu_cas01.hpp b/src/surf/cpu_cas01.hpp new file mode 100644 index 0000000000..7b2a76e966 --- /dev/null +++ b/src/surf/cpu_cas01.hpp @@ -0,0 +1,64 @@ +#include "cpu.hpp" + +/*********** + * Classes * + ***********/ +class CpuCas01Model; +typedef CpuCas01Model *CpuCas01ModelPtr; + +class CpuCas01Lmm; +typedef CpuCas01Lmm *CpuCas01LmmPtr; + +class CpuCas01ActionLmm; +typedef CpuCas01ActionLmm *CpuCas01ActionLmmPtr; + +/********* + * Model * + *********/ +class CpuCas01Model : public CpuModel { +public: + CpuCas01Model(); + ~CpuCas01Model(); + + double (CpuCas01Model::*shareResources)(double now); + void (CpuCas01Model::*updateActionsState)(double now, double delta); + + void parseInit(sg_platf_host_cbarg_t host); + CpuCas01LmmPtr createResource(const char *name, double power_peak, double power_scale, + tmgr_trace_t power_trace, int core, + e_surf_resource_state_t state_initial, + tmgr_trace_t state_trace, + xbt_dict_t cpu_properties); + double shareResourcesFull(double now); + void addTraces(); +}; + +/************ + * Resource * + ************/ +class CpuCas01Lmm : public CpuLmm { +public: + CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, double powerPeak, + double powerScale, tmgr_trace_t powerTrace, int core, + e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, + xbt_dict_t properties) ; + void updateState(tmgr_trace_event_t event_type, double value, double date); + CpuActionPtr execute(double size); + CpuActionPtr sleep(double duration); + + bool isUsed(); + + tmgr_trace_event_t p_powerEvent; +}; + +/********** + * Action * + **********/ +class CpuCas01ActionLmm: public CpuActionLmm { +public: + CpuCas01ActionLmm() {}; + CpuCas01ActionLmm(ModelPtr model, double cost, bool failed): CpuActionLmm(model, cost, failed) {}; + int unref() {return 0;};//TODO + void cancel() {};//TODO + void recycle() {};//TODO +}; diff --git a/src/surf/cpu_ti.cpp b/src/surf/cpu_ti.cpp index 6a1eaeeb46..a9446205f5 100644 --- a/src/surf/cpu_ti.cpp +++ b/src/surf/cpu_ti.cpp @@ -383,10 +383,18 @@ CpuTiModel::CpuTiModel() : CpuModel("cpu_ti") { xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen."); surf_cpu_model = this; + CpuTiAction action; + CpuTi cpu; + + cpu_ti_running_action_set_that_does_not_need_being_checked = + xbt_swag_new(xbt_swag_offset(action, p_stateHookup)); + + cpu_ti_modified_cpu = + xbt_swag_new(xbt_swag_offset(cpu, p_modifiedCpuHookup)); + cpu_ti_action_heap = xbt_heap_new(8, NULL); xbt_heap_set_update_callback(cpu_ti_action_heap, cpu_ti_action_update_index_heap); - /* Define callbacks */ //TODO sg_platf_host_add_cb(parse_cpu_ti_init); //TODO sg_platf_postparse_add_cb(add_traces_cpu_ti); @@ -491,6 +499,62 @@ void CpuTiModel::updateActionsState(double now, double delta) } } +void CpuTiModel::addTraces() +{ + xbt_dict_cursor_t cursor = NULL; + char *trace_name, *elm; + + static int called = 0; + + if (called) + return; + called = 1; + +/* connect all traces relative to hosts */ + xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuTiPtr cpu = (CpuTiPtr) surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)); + + xbt_assert(cpu, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + if (cpu->p_stateEvent) { + XBT_DEBUG("Trace already configured for this CPU(%s), ignoring it", + elm); + continue; + } + XBT_DEBUG("Add state trace: %s to CPU(%s)", trace_name, elm); + cpu->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, cpu); + } + + xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) { + tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); + CpuTiPtr cpu = (CpuTiPtr) surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)); + + xbt_assert(cpu, "Host %s undefined", elm); + xbt_assert(trace, "Trace %s undefined", trace_name); + + XBT_DEBUG("Add power trace: %s to CPU(%s)", trace_name, elm); + if (cpu->p_availTrace) + delete cpu->p_availTrace; + + cpu->p_availTrace = new CpuTiTgmr(trace, cpu->m_powerScale); + + /* add a fake trace event if periodicity == 0 */ + if (trace && xbt_dynar_length(trace->s_list.event_list) > 1) { + s_tmgr_event_t val; + xbt_dynar_get_cpy(trace->s_list.event_list, + xbt_dynar_length(trace->s_list.event_list) - 1, &val); + if (val.delta == 0) { + tmgr_trace_t empty_trace; + empty_trace = tmgr_empty_trace_new(); + cpu->p_powerEvent = + tmgr_history_add_trace(history, empty_trace, + cpu->p_availTrace->m_lastTime, 0, cpu); + } + } + } +} /************ * Resource * @@ -499,8 +563,10 @@ CpuTi::CpuTi(CpuTiModelPtr model, const char *name, double powerPeak, double powerScale, tmgr_trace_t powerTrace, int core, e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, xbt_dict_t properties) : - Cpu(model, name, properties), m_powerPeak(powerPeak), m_powerScale(powerScale), - p_stateCurrent(stateInitial) { + Cpu(model, name, properties), p_stateCurrent(stateInitial) { + m_powerPeak = powerPeak; + m_powerScale = powerScale; + m_core = core; tmgr_trace_t empty_trace; s_tmgr_event_t val; xbt_assert(core==1,"Multi-core not handled with this model yet"); @@ -676,78 +742,12 @@ bool CpuTi::isUsed() return xbt_swag_size(p_actionSet); } -e_surf_resource_state_t CpuTi::getState() -{ - return m_stateCurrent; -} -double CpuTi::getSpeed(double load) -{ - return load * m_powerPeak; -} double CpuTi::getAvailableSpeed() { m_powerScale = p_availTrace->getPowerScale(surf_get_clock()); -/* number between 0 and 1 */ - return m_powerScale; -} - -void CpuTi::addTraces() -{ - xbt_dict_cursor_t cursor = NULL; - char *trace_name, *elm; - - static int called = 0; - - if (called) - return; - called = 1; - -/* connect all traces relative to hosts */ - xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) { - tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); - CpuTiPtr cpu = (CpuTiPtr) surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)); - - xbt_assert(cpu, "Host %s undefined", elm); - xbt_assert(trace, "Trace %s undefined", trace_name); - - if (cpu->p_stateEvent) { - XBT_DEBUG("Trace already configured for this CPU(%s), ignoring it", - elm); - continue; - } - XBT_DEBUG("Add state trace: %s to CPU(%s)", trace_name, elm); - cpu->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, cpu); - } - - xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) { - tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name); - CpuTiPtr cpu = (CpuTiPtr) surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)); - - xbt_assert(cpu, "Host %s undefined", elm); - xbt_assert(trace, "Trace %s undefined", trace_name); - - XBT_DEBUG("Add power trace: %s to CPU(%s)", trace_name, elm); - if (cpu->p_availTrace) - delete cpu->p_availTrace; - - cpu->p_availTrace = new CpuTiTgmr(trace, cpu->m_powerScale); - - /* add a fake trace event if periodicity == 0 */ - if (trace && xbt_dynar_length(trace->s_list.event_list) > 1) { - s_tmgr_event_t val; - xbt_dynar_get_cpy(trace->s_list.event_list, - xbt_dynar_length(trace->s_list.event_list) - 1, &val); - if (val.delta == 0) { - tmgr_trace_t empty_trace; - empty_trace = tmgr_empty_trace_new(); - cpu->p_powerEvent = - tmgr_history_add_trace(history, empty_trace, - cpu->p_availTrace->m_lastTime, 0, cpu); - } - } - } + return Cpu::getAvailableSpeed(); } /** diff --git a/src/surf/cpu_ti.hpp b/src/surf/cpu_ti.hpp index 79a8045fce..d37cce4aab 100644 --- a/src/surf/cpu_ti.hpp +++ b/src/surf/cpu_ti.hpp @@ -89,6 +89,7 @@ public: CpuTiActionPtr createAction(double cost, bool failed); double shareResources(double now); void updateActionsState(double now, double delta); + void addTraces(); protected: void NotifyResourceTurnedOn(ResourcePtr r){}; @@ -104,6 +105,7 @@ protected: ************/ class CpuTi : public Cpu { public: + CpuTi() {}; CpuTi(CpuTiModelPtr model, const char *name, double powerPeak, double powerScale, tmgr_trace_t powerTrace, int core, e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace, @@ -113,17 +115,12 @@ public: void updateState(tmgr_trace_event_t event_type, double value, double date); void updateActionFinishDate(double now); bool isUsed(); - double getSpeed (double load); - double getAvailableSpeed (); - void addTraces(); void printCpuTiModel(); CpuTiModelPtr getModel(); CpuActionPtr execute(double size); CpuActionPtr sleep(double duration); - e_surf_resource_state_t getState(); - - double m_powerPeak; /*< CPU power peak */ - double m_powerScale; /*< Percentage of CPU disponible */ + double getAvailableSpeed(); + CpuTiTgmrPtr p_availTrace; /*< Structure with data needed to integrate trace file */ e_surf_resource_state_t p_stateCurrent; /*< CPU current state (ON or OFF) */ tmgr_trace_event_t p_stateEvent; /*< trace file with states events (ON or OFF) */ @@ -140,6 +137,7 @@ public: **********/ class CpuTiAction: public CpuAction { public: + CpuTiAction() {}; CpuTiAction(CpuTiModelPtr model, double cost, bool failed): CpuAction(model, cost, failed) {}; void setState(e_surf_action_state_t state); diff --git a/src/surf/network.cpp b/src/surf/network.cpp new file mode 100644 index 0000000000..ea5060a573 --- /dev/null +++ b/src/surf/network.cpp @@ -0,0 +1,149 @@ +#include "network.hpp" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_network, surfpp, + "Logging specific to the SURF network module"); + +//TODO: resolve dependencies +static int TRACE_is_enabled(void) {return 0;} +static void TRACE_surf_host_set_utilization(const char *resource, + const char *category, + double value, + double now, + double delta){} +static void TRACE_surf_link_set_utilization(const char *resource, + const char *category, + double value, + double now, + double delta){} +static double TRACE_last_timestamp_to_dump = 0; + +/********* + * Utils * + *********/ + +static xbt_dict_t gap_lookup = NULL;//TODO: remove static + +/********* + * Model * + *********/ + +void NetworkModel::updateActionsStateLazy(double now, double delta) +{ + NetworkCm02ActionLmmPtr action; + while ((xbt_heap_size(p_actionHeap) > 0) + && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) { + action = (NetworkCm02ActionLmmPtr) xbt_heap_pop(p_actionHeap); + XBT_DEBUG("Something happened to action %p", action); +#ifdef HAVE_TRACING + if (TRACE_is_enabled()) { + int n = lmm_get_number_of_cnst_from_var(p_maxminSystem, action->p_variable); + unsigned int i; + for (i = 0; i < n; i++){ + lmm_constraint_t constraint = lmm_get_cnst_from_var(p_maxminSystem, + action->p_variable, + i); + NetworkCm02LinkPtr link = (NetworkCm02LinkPtr) lmm_constraint_id(constraint); + TRACE_surf_link_set_utilization(link->m_name, + action->p_category, + (lmm_variable_getvalue(action->p_variable)* + lmm_get_cnst_weight_from_var(p_maxminSystem, + action->p_variable, + i)), + action->m_lastUpdate, + now - action->m_lastUpdate); + } + } +#endif + + // if I am wearing a latency hat + if (action->m_hat == LATENCY) { + XBT_DEBUG("Latency paid for action %p. Activating", action); + lmm_update_variable_weight(p_maxminSystem, action->p_variable, action->m_weight); + action->heapRemove(p_actionHeap); + action->m_lastUpdate = surf_get_clock(); + + // if I am wearing a max_duration or normal hat + } else if (action->m_hat == MAX_DURATION || + action->m_hat == NORMAL) { + // no need to communicate anymore + // assume that flows that reached max_duration have remaining of 0 + action->m_finish = surf_get_clock(); + XBT_DEBUG("Action %p finished", action); + action->m_remains = 0; + action->m_finish = surf_get_clock(); + action->setState(SURF_ACTION_DONE); + action->heapRemove(p_actionHeap); + + gapRemove(action); + } + } + return; +} + +void NetworkModel::gapRemove(ActionLmmPtr lmm_action) +{ + xbt_fifo_t fifo; + size_t size; + NetworkCm02ActionLmmPtr action = (NetworkCm02ActionLmmPtr)lmm_action; + + if (sg_sender_gap > 0.0 && action->p_senderLinkName + && action->p_senderFifoItem) { + fifo = + (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, + action->p_senderLinkName); + xbt_fifo_remove_item(fifo, action->p_senderFifoItem); + size = xbt_fifo_size(fifo); + if (size == 0) { + xbt_fifo_free(fifo); + xbt_dict_remove(gap_lookup, action->p_senderLinkName); + size = xbt_dict_length(gap_lookup); + if (size == 0) { + xbt_dict_free(&gap_lookup); + } + } + } +} + +/************ + * Resource * + ************/ + +/********** + * Action * + **********/ +void NetworkCm02ActionLmm::updateRemainingLazy(double now) +{ + double delta = 0.0; + + if (m_suspended != 0) + return; + + delta = now - m_lastUpdate; + + if (m_remains > 0) { + XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate); + double_update(&(m_remains), m_lastValue * delta); + + XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains); + } + + if (m_maxDuration != NO_MAX_DURATION) + double_update(&m_maxDuration, delta); + + if (m_remains <= 0 && + (lmm_get_variable_weight(p_variable) > 0)) { + m_finish = surf_get_clock(); + setState(SURF_ACTION_DONE); + + heapRemove(p_model->p_actionHeap); + } else if (((m_maxDuration != NO_MAX_DURATION) + && (m_maxDuration <= 0))) { + m_finish = surf_get_clock(); + setState(SURF_ACTION_DONE); + heapRemove(p_model->p_actionHeap); + } + + m_lastUpdate = now; + m_lastValue = lmm_variable_getvalue(p_variable); +} + diff --git a/src/surf/network.hpp b/src/surf/network.hpp new file mode 100644 index 0000000000..aa21a7efe1 --- /dev/null +++ b/src/surf/network.hpp @@ -0,0 +1,75 @@ +#include "surf.hpp" +#include "xbt/fifo.h" + +#ifndef SURF_MODEL_NETWORK_H_ +#define SURF_MODEL_NETWORK_H_ + +/*********** + * Classes * + ***********/ +class NetworkModel; +typedef NetworkModel *NetworkModelPtr; + +class NetworkCm02Link; +typedef NetworkCm02Link *NetworkCm02LinkPtr; + +class NetworkCm02Action; +typedef NetworkCm02Action *NetworkCm02ActionPtr; + +class NetworkCm02ActionLmm; +typedef NetworkCm02ActionLmm *NetworkCm02ActionLmmPtr; + +/********* + * Model * + *********/ +class NetworkModel : public Model { +public: + NetworkModel(string name) : Model(name) {}; + NetworkCm02LinkPtr createResource(string name); + void updateActionsStateLazy(double now, double delta); + void updateActionsStateFull(double now, double delta); + void gapRemove(ActionLmmPtr action); + + virtual void addTraces() =0; +}; + +/************ + * Resource * + ************/ +class NetworkCm02Link : public Resource { +public: + NetworkCm02Link(NetworkModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {}; + + /* Using this object with the public part of + model does not make sense */ + double lat_current; + tmgr_trace_event_t lat_event; +}; + +/********** + * Action * + **********/ +class NetworkCm02Action : virtual public Action { +public: + NetworkCm02Action(ModelPtr model, double cost, bool failed): Action(model, cost, failed) {}; + double m_latency; + double m_latCurrent; + double m_weight; + double m_rate; + const char* p_senderLinkName; + double m_senderGap; + double m_senderSize; + xbt_fifo_item_t p_senderFifoItem; +#ifdef HAVE_LATENCY_BOUND_TRACKING + int m_latencyLimited; +#endif + +}; + +class NetworkCm02ActionLmm : public ActionLmm, public NetworkCm02Action { +public: + NetworkCm02ActionLmm(ModelPtr model, double cost, bool failed): ActionLmm(model, cost, failed), NetworkCm02Action(model, cost, failed) {}; + void updateRemainingLazy(double now); +}; + +#endif /* SURF_MODEL_NETWORK_H_ */ diff --git a/src/surf/surf.cpp b/src/surf/surf.cpp index 297721c229..6508e38abd 100644 --- a/src/surf/surf.cpp +++ b/src/surf/surf.cpp @@ -1,4 +1,5 @@ #include "surf.hpp" +#include "cpu.hpp" #include "simix/smx_host_private.h" XBT_LOG_NEW_CATEGORY(surfpp, "All SURF categories"); @@ -9,7 +10,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_kernel, surfpp, * Utils * *********/ -//TODO:RENAME NOW double NOWW = 0; XBT_INLINE double surf_get_clock(void) @@ -78,6 +78,151 @@ static void remove_watched_host(void *key) * Model * *********/ +double Model::shareResourcesLazy(double now) +{ + ActionLmmPtr action = NULL; + double min = -1; + double value; + + XBT_DEBUG + ("Before share resources, the size of modified actions set is %d", + xbt_swag_size(p_modifiedSet)); + + lmm_solve(p_maxminSystem); + + XBT_DEBUG + ("After share resources, The size of modified actions set is %d", + xbt_swag_size(p_modifiedSet)); + + while((action = (ActionLmmPtr) xbt_swag_extract(p_modifiedSet))) { + int max_dur_flag = 0; + + if (action->p_stateSet != p_runningActionSet) + continue; + + /* bogus priority, skip it */ + if (action->m_priority <= 0) + continue; + + action->updateRemainingLazy(now); + + min = -1; + value = lmm_variable_getvalue(action->p_variable); + if (value > 0) { + if (action->m_remains > 0) { + value = action->m_remains / value; + min = now + value; + } else { + value = 0.0; + min = now; + } + } + + if ((action->m_maxDuration != NO_MAX_DURATION) + && (min == -1 + || action->m_start + + action->m_maxDuration < min)) { + min = action->m_start + + action->m_maxDuration; + max_dur_flag = 1; + } + + XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action, + action->m_start, now + value, + action->m_maxDuration); + + if (min != -1) { + action->heapRemove(p_actionHeap); + action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL); + XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min, + now); + } else DIE_IMPOSSIBLE; + } + + //hereafter must have already the min value for this resource model + if (xbt_heap_size(p_actionHeap) > 0) + min = xbt_heap_maxkey(p_actionHeap) - now; + else + min = -1; + + XBT_DEBUG("The minimum with the HEAP %lf", min); + + return min; +} + +double Model::shareResourcesFull(xbt_swag_t running_actions, + size_t offset, + lmm_system_t sys, + void (*solve) (lmm_system_t)) +{ + void *_action = NULL; + ActionPtr action = NULL; + double min = -1; + double value = -1; +#define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset)))) + + solve(sys); + + xbt_swag_foreach(_action, running_actions) { + action = (ActionPtr)_action; + value = lmm_variable_getvalue(VARIABLE(action)); + if ((value > 0) || (action->m_maxDuration >= 0)) + break; + } + + if (!action) + return -1.0; + + if (value > 0) { + if (action->m_remains > 0) + min = action->m_remains / value; + else + min = 0.0; + if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) + min = action->m_maxDuration; + } else + min = action->m_maxDuration; + + + for (action = (ActionPtr) xbt_swag_getNext(action, running_actions->offset); + action; + action = (ActionPtr) xbt_swag_getNext(action, running_actions->offset)) { + value = lmm_variable_getvalue(VARIABLE(action)); + if (value > 0) { + if (action->m_remains > 0) + value = action->m_remains / value; + else + value = 0.0; + if (value < min) { + min = value; + XBT_DEBUG("Updating min (value) with %p: %f", action, min); + } + } + if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) { + min = action->m_maxDuration; + XBT_DEBUG("Updating min (duration) with %p: %f", action, min); + } + } + XBT_DEBUG("min value : %f", min); + +#undef VARIABLE + return min; +} + +void Model::gapRemove(ActionLmmPtr action) {} + + +void Model::updateActionsStateLazy(double now, double delta) +{ + +} + +void Model::updateActionsStateFull(double now, double delta) +{ + +} + + void Model::addTurnedOnCallback(ResourceCallback rc) { m_resOnCB = rc; @@ -137,6 +282,11 @@ string Resource::getName() { return m_name; } +e_surf_resource_state_t Resource::getState() +{ + return m_stateCurrent; +} + bool Resource::isOn() { return m_running; @@ -161,6 +311,16 @@ void Resource::turnOff() /********** * Action * **********/ +/* added to manage the communication action's heap */ +void surf_action_lmm_update_index_heap(void *action, int i) { + ((ActionLmmPtr)action)->updateIndexHeap(i); +} + +void ActionLmm::updateIndexHeap(int i) +{ + m_indexHeap = i; +} + /*TODO/const char *surf_action_state_names[6] = { "SURF_ACTION_READY", "SURF_ACTION_RUNNING", @@ -205,21 +365,62 @@ void Action::setState(e_surf_action_state_t state) XBT_OUT(); } -double Action::getStartTime() +double Action::getStartTime() { return m_start; } -double Action::getFinishTime() +double Action::getFinishTime() { - return m_finish; + /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */ + return m_remains == 0 ? m_finish : -1; } -void Action::setData(void* data) +void Action::setData(void* data) { p_data = data; } +#ifdef HAVE_TRACING +void Action::setCategory(const char *category) +{ + XBT_IN("(%p,%s)", this, category); + p_category = xbt_strdup(category); + XBT_OUT(); +} +#endif + +/* insert action on heap using a given key and a hat (heap_action_type) + * a hat can be of three types for communications: + * + * NORMAL = this is a normal heap entry stating the date to finish transmitting + * LATENCY = this is a heap entry to warn us when the latency is payed + * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached + */ +void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat) +{ + m_hat = hat; + xbt_heap_push(heap, this, key); +} + +void ActionLmm::heapRemove(xbt_heap_t heap) +{ + m_hat = NOTSET; + if (m_indexHeap >= 0) { + xbt_heap_remove(heap, m_indexHeap); + } +} + +double ActionLmm::getRemains() +{ + XBT_IN("(%p)", this); + /* update remains before return it */ + if (p_updateMechanism == UM_LAZY) /* update remains before return it */ + updateRemainingLazy(surf_get_clock()); + XBT_OUT(); + return m_remains; +} + /*void Action::cancel() { p_model->notifyActionCancel(this); diff --git a/src/surf/surf.hpp b/src/surf/surf.hpp index 636d6a4327..6deea66080 100644 --- a/src/surf/surf.hpp +++ b/src/surf/surf.hpp @@ -43,6 +43,7 @@ XBT_PUBLIC(void) surf_watched_hosts(void); } #endif +extern double sg_sender_gap; XBT_PUBLIC(int) SURF_CPU_LEVEL; //Surf cpu level /*********** @@ -59,6 +60,22 @@ class Action; typedef Action* ActionPtr; typedef boost::function ActionCallback; +class ActionLmm; +typedef ActionLmm* ActionLmmPtr; + +enum heap_action_type{ + LATENCY = 100, + MAX_DURATION, + NORMAL, + NOTSET +}; + +typedef enum { + UM_FULL, + UM_LAZY, + UM_UNDEFINED +} e_UM_t; + /********* * Trace * *********/ @@ -91,10 +108,18 @@ public: } ResourcePtr createResource(string name); ActionPtr createAction(double _cost, bool _failed); - double shareResources(double now); - void updateActionsState(double now, double delta); + double (Model::*shareResources)(double now); + double shareResourcesLazy(double now); + double shareResourcesFull(xbt_swag_t running_actions, + size_t offset, + lmm_system_t sys, + void (*solve) (lmm_system_t)); + void (Model::*updateActionsState)(double now, double delta); + void updateActionsStateLazy(double now, double delta); + void updateActionsStateFull(double now, double delta); string getName() {return m_name;}; + void gapRemove(ActionLmmPtr action); void addTurnedOnCallback(ResourceCallback rc); void notifyResourceTurnedOn(ResourcePtr r); @@ -109,6 +134,12 @@ public: void addActionSuspendCallback(ActionCallback ac); void notifyActionSuspend(ActionPtr a); + lmm_system_t p_maxminSystem; + e_UM_t p_updateMechanism; + xbt_swag_t p_modifiedSet; + xbt_heap_t p_actionHeap; + int m_selectiveUpdate; + xbt_swag_t p_readyActionSet; /**< Actions in state SURF_ACTION_READY */ xbt_swag_t p_runningActionSet; /**< Actions in state SURF_ACTION_RUNNING */ xbt_swag_t p_failedActionSet; /**< Actions in state SURF_ACTION_FAILED */ @@ -126,8 +157,19 @@ private: /************ * Resource * ************/ + +/** + * Resource which have a metric handled by a maxmin system + */ +typedef struct { + double scale; + double peak; + tmgr_trace_event_t event; +} s_surf_metric_t; + class Resource { public: + Resource() {}; Resource(ModelPtr model, const char *name, xbt_dict_t properties): m_name(name),m_running(true),p_model(model),m_properties(properties) {}; virtual ~Resource() {}; @@ -146,19 +188,29 @@ public: void setName(string name); string getName(); ModelPtr getModel() {return p_model;}; + e_surf_resource_state_t getState(); void printModel() { std::cout << p_model->getName() << "<