Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
CpuCas01 in C++
authorPaul Bédaride <paul.bedaride@gmail.com>
Thu, 5 Sep 2013 12:44:21 +0000 (14:44 +0200)
committerPaul Bédaride <paul.bedaride@gmail.com>
Thu, 5 Sep 2013 12:44:21 +0000 (14:44 +0200)
buildtools/Cmake/DefinePackages.cmake
src/surf/cpu.cpp [new file with mode: 0644]
src/surf/cpu.hpp
src/surf/cpu_cas01.cpp [new file with mode: 0644]
src/surf/cpu_cas01.hpp [new file with mode: 0644]
src/surf/cpu_ti.cpp
src/surf/cpu_ti.hpp
src/surf/network.cpp [new file with mode: 0644]
src/surf/network.hpp [new file with mode: 0644]
src/surf/surf.cpp
src/surf/surf.hpp

index 9538a0d..afb7198 100644 (file)
@@ -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 (file)
index 0000000..a1ac6ea
--- /dev/null
@@ -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);
+}
index 73ee3d1..c7779e2 100644 (file)
@@ -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<Action> execute(double size) = 0;
   //virtual boost::shared_ptr<Action> 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 (file)
index 0000000..6eb404c
--- /dev/null
@@ -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 (file)
index 0000000..7b2a76e
--- /dev/null
@@ -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
+};
index 6a1eaee..a944620 100644 (file)
@@ -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();
 }
 
 /**
index 79a8045..d37cce4 100644 (file)
@@ -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 (file)
index 0000000..ea5060a
--- /dev/null
@@ -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 (file)
index 0000000..aa21a7e
--- /dev/null
@@ -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_ */
index 297721c..6508e38 100644 (file)
@@ -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);
index 636d6a4..6deea66 100644 (file)
@@ -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<void (ActionPtr a)> 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() << "<<plop"<<std::endl;};
   void *p_resource;
   e_surf_resource_state_t m_stateCurrent;
+  const char *m_name;
 
 protected:
   ModelPtr p_model;
-  const char *m_name;
   xbt_dict_t m_properties;
 
 private:
   bool m_running;  
 };
 
+class ResourceLmm: virtual public Resource {
+public:
+  ResourceLmm() {};
+  lmm_constraint_t p_constraint;
+  e_surf_resource_state_t p_stateCurrent;
+  tmgr_trace_event_t p_stateEvent;
+  s_surf_metric_t p_power;
+};
+
 static inline void *surf_cpu_resource_priv(const void *host) {
   return xbt_lib_get_level((xbt_dictelm_t)host, SURF_CPU_LEVEL);
 }
@@ -201,14 +253,9 @@ typedef enum {
                                 /**< Not in the system anymore. Why did you ask ? */
 } e_surf_action_state_t;
 
-typedef enum {
-  UM_FULL,
-  UM_LAZY,
-  UM_UNDEFINED
-} e_UM_t;
-
 class Action {
 public:
+  Action() {};
   Action(ModelPtr model, double cost, bool failed):
         m_cost(cost), p_model(model), m_failed(failed),
         m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
@@ -220,6 +267,7 @@ public:
   };
   virtual ~Action() {};
   
+  s_xbt_swag_hookup_t p_stateHookup;
   e_surf_action_state_t getState(); /**< get the state*/
   void setState(e_surf_action_state_t state); /**< Change state*/
   double getStartTime(); /**< Return the start time of an action */
@@ -242,6 +290,7 @@ public:
 #ifdef HAVE_LATENCY_BOUND_TRACKING
   int getLatencyLimited();     /**< Return 1 if action is limited by latency, 0 otherwise */
 #endif
+
   xbt_swag_t p_stateSet;
 
   double m_priority; /**< priority (1.0 by default) */
@@ -254,14 +303,15 @@ public:
   int m_latencyLimited;               /**< Set to 1 if is limited by latency, 0 otherwise */
   #endif
   double m_maxDuration; /*< max_duration (may fluctuate until the task is completed) */  
+  char *p_category;               /**< tracing category for categorized resource utilization monitoring */  
 protected:
   ModelPtr p_model;  
   int    m_cost;
   int    m_refcount;
   void *p_data; /**< for your convenience */
 #ifdef HAVE_TRACING
-  char *p_category;               /**< tracing category for categorized resource utilization monitoring */
 #endif
+  e_UM_t p_updateMechanism;
 
 private:
   int resourceUsed(void *resource_id);
@@ -275,10 +325,32 @@ private:
   void finalize(void);
 
   lmm_system_t p_maxminSystem;
-  e_UM_t p_updateMechanism;
   xbt_swag_t p_modifiedSet;
   xbt_heap_t p_actionHeap;
   int m_selectiveUpdate;
 };
 
+void surf_action_lmm_update_index_heap(void *action, int i);
+
+class ActionLmm: virtual public Action {
+public:
+  ActionLmm() {};      
+  ActionLmm(ModelPtr model, double cost, bool failed) {};
+
+  virtual void updateRemainingLazy(double now)=0;
+  void heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat);
+  void heapRemove(xbt_heap_t heap);
+  double getRemains();     /**< Get the remains of an action */
+  void updateIndexHeap(int i);
+
+
+  lmm_variable_t p_variable;
+  //bool m_suspended;
+  s_xbt_swag_hookup_t p_actionListHookup;
+  int m_indexHeap;
+  double m_lastUpdate;
+  double m_lastValue;
+  enum heap_action_type m_hat;
+};
+
 #endif /* SURF_MODEL_H_ */