src/surf/gtnets/gtnets_simulator.h
src/surf/gtnets/gtnets_topology.h
src/surf/maxmin_private.h
- #src/surf/network_gtnets_private.h
- src/surf/network_gtnets_private.h
+ src/surf/network_gtnets.hpp
src/surf/network_ns3_private.h
src/surf/network_private.h
+ src/surf/network.hpp
+ src/surf/network_smpi.hpp
+ src/surf/network_constant.hpp
src/surf/ns3/my-point-to-point-helper.h
src/surf/ns3/ns3_interface.h
src/surf/ns3/ns3_simulator.h
/*******************************************/
/*** Config Globals **************************/
/*******************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
XBT_PUBLIC_DATA(xbt_cfg_t) _sg_cfg_set;
+ XBT_PUBLIC_DATA(int) _sg_cfg_init_status;
+ XBT_PUBLIC_DATA(int) _sg_cfg_exit_asap;
XBT_PUBLIC(int) sg_cfg_get_int(const char* name);
XBT_PUBLIC(double) sg_cfg_get_double(const char* name);
XBT_PUBLIC(char*) sg_cfg_get_string(const char* name);
* An action is some working amount on a model.
* It is represented as a cost, a priority, a duration and a state.
*/
-typedef struct surf_action *surf_action_t;
-typedef struct surf_file *surf_file_t;
+//FIXME:typedef struct surf_action *surf_action_t;
+//FIXME:typedef struct surf_file *surf_file_t;
+ typedef struct surf_storage *surf_storage_t;
typedef struct surf_stat *surf_stat_t;
typedef struct lmm_element *lmm_element_t;
SURF_NETWORK_ELEMENT_AS /* AS type */
} e_surf_network_element_type_t;
+#ifdef __cplusplus
+class Model;
+class CpuModel;
+class WorkstationModel;
+class NetworkCm02Model;
++class StorageModel;
+class Resource;
+class ResourceLmm;
+class WorkstationCLM03;
+class NetworkCm02Link;
+class Cpu;
+class Action;
+class ActionLmm;
+class StorageActionLmm;
+class As;
+class RoutingEdge;
+class RoutingPlatf;
+#else
+typedef struct Model Model;
+typedef struct CpuModel CpuModel;
+typedef struct WorkstationModel WorkstationModel;
+typedef struct NetworkCm02Model NetworkCm02Model;
++typedef struct StorageModel StorageModel;
+typedef struct Resource Resource;
+typedef struct ResourceLmm ResourceLmm;
+typedef struct WorkstationCLM03 WorkstationCLM03;
+typedef struct NetworkCm02Link NetworkCm02Link;
+typedef struct Cpu Cpu;
+typedef struct Action Action;
+typedef struct ActionLmm ActionLmm;
+typedef struct StorageActionLmm StorageActionLmm;
+typedef struct As As;
+typedef struct RoutingEdge RoutingEdge;
+typedef struct RoutingPlatf RoutingPlatf;
+#endif
+
+/** \ingroup SURF_models
+ * \brief Model datatype
+ *
+ * Generic data structure for a model. The workstations,
+ * the CPUs and the network links are examples of models.
+ */
+typedef Model *surf_model_t;
+typedef CpuModel *surf_cpu_model_t;
+typedef WorkstationModel *surf_workstation_model_t;
+typedef NetworkCm02Model *surf_network_model_t;
++typedef StorageModel *surf_storage_model_t;
+
+typedef xbt_dictelm_t surf_resource_t;
+typedef Resource *surf_cpp_resource_t;
+typedef WorkstationCLM03 *surf_workstation_CLM03_t;
+typedef NetworkCm02Link *surf_network_link_t;
+typedef Cpu *surf_cpu_t;
+
+/** \ingroup SURF_actions
+ * \brief Action structure
+ *
+ * Never create s_surf_action_t by yourself ! The actions are created
+ * on the fly when you call execute or communicate on a model.
+ *
+ * \see e_surf_action_state_t
+ */
+typedef Action *surf_action_t;
+typedef ActionLmm *surf_action_lmm_t;
+typedef StorageActionLmm *surf_storage_action_lmm_t;
+
+typedef As *AS_t;
+typedef RoutingEdge *routing_edge_t;
+typedef RoutingPlatf *routing_platf_t;
+
+typedef struct surf_file *surf_file_t;
+
XBT_PUBLIC(e_surf_network_element_type_t)
routing_get_network_element_type(const char* name);
} s_surf_model_extension_workstation_t;
-
-
-/** \ingroup SURF_models
- * \brief Model datatype
- *
- * Generic data structure for a model. The workstations,
- * the CPUs and the network links are examples of models.
- */
-typedef struct surf_model {
- const char *name; /**< Name of this model */
- s_surf_action_state_t states; /**< Any living action on this model */
-
- e_surf_action_state_t(*action_state_get) (surf_action_t action);
- /**< Return the state of an action */
- void (*action_state_set) (surf_action_t action,
- e_surf_action_state_t state);
- /**< Change an action state*/
-
- double (*action_get_start_time) (surf_action_t action); /**< Return the start time of an action */
- double (*action_get_finish_time) (surf_action_t action); /**< Return the finish time of an action */
- int (*action_unref) (surf_action_t action); /**< Specify that we don't use that action anymore. Returns true if the action was destroyed and false if someone still has references on it. */
- void (*action_cancel) (surf_action_t action); /**< Cancel a running action */
- void (*action_recycle) (surf_action_t action); /**< Recycle an action */
- void (*action_data_set) (surf_action_t action, void *data); /**< Set the user data of an action */
- void (*suspend) (surf_action_t action); /**< Suspend an action */
- void (*resume) (surf_action_t action); /**< Resume a suspended action */
- int (*is_suspended) (surf_action_t action); /**< Return whether an action is suspended */
- void (*set_max_duration) (surf_action_t action, double duration); /**< Set the max duration of an action*/
- void (*set_priority) (surf_action_t action, double priority); /**< Set the priority of an action */
-#ifdef HAVE_TRACING
- void (*set_category) (surf_action_t action, const char *category); /**< Set the category of an action */
-#endif
- double (*get_remains) (surf_action_t action); /**< Get the remains of an action */
-#ifdef HAVE_LATENCY_BOUND_TRACKING
- int (*get_latency_limited) (surf_action_t action); /**< Return 1 if action is limited by latency, 0 otherwise */
-#endif
-
- void (*gap_remove) (surf_action_lmm_t action);
-
- surf_model_private_t model_private;
-
- union extension {
- s_surf_model_extension_cpu_t cpu;
- s_surf_model_extension_network_t network;
- s_surf_model_extension_storage_t storage;
- s_surf_model_extension_workstation_t workstation;
- /*******************************************/
- /* TUTORIAL: New model */
- s_surf_model_extension_new_model_t new_model;
- /*******************************************/
- } extension;
-} s_surf_model_t;
-
-surf_model_t surf_model_init(void);
-void surf_model_exit(surf_model_t model);
-
static inline void *surf_cpu_resource_priv(const void *host) {
- return xbt_lib_get_level((void *)host, SURF_CPU_LEVEL);
+ return xbt_lib_get_level((xbt_dictelm_t)host, SURF_CPU_LEVEL);
}
static inline void *surf_workstation_resource_priv(const void *host){
- return xbt_lib_get_level((void *)host, SURF_WKS_LEVEL);
+ return (void*)xbt_lib_get_level((xbt_dictelm_t)host, SURF_WKS_LEVEL);
}
- static inline void *surf_storage_resource_priv(const void *host){
- return (void*)xbt_lib_get_level((xbt_dictelm_t)host, SURF_STORAGE_LEVEL);
+ static inline void *surf_storage_resource_priv(const void *storage){
- return xbt_lib_get_level((void *)storage, SURF_STORAGE_LEVEL);
++ return (void*)xbt_lib_get_level((xbt_dictelm_t)storage, SURF_STORAGE_LEVEL);
}
static inline void *surf_cpu_resource_by_name(const char *name) {
return xbt_lib_get_elm_or_null(storage_lib, name);
}
-typedef struct surf_resource {
- surf_model_t model;
- char *name;
- xbt_dict_t properties;
- void_f_pvoid_t free_f;
-} s_surf_resource_t, *surf_resource_t;
-
-/**
- * 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;
-
-typedef struct surf_resource_lmm {
- s_surf_resource_t generic_resource;
- lmm_constraint_t constraint;
- e_surf_resource_state_t state_current;
- tmgr_trace_event_t state_event;
- s_surf_metric_t power;
-} s_surf_resource_lmm_t, *surf_resource_lmm_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+char *surf_routing_edge_name(sg_routing_edge_t edge);
+void *surf_as_cluster_get_backbone(AS_t as);
+void surf_as_cluster_set_backbone(AS_t as, void* backbone);
+const char *surf_model_name(surf_model_t model);
+xbt_swag_t surf_model_done_action_set(surf_model_t model);
+xbt_swag_t surf_model_failed_action_set(surf_model_t model);
+xbt_swag_t surf_model_ready_action_set(surf_model_t model);
+xbt_swag_t surf_model_running_action_set(surf_model_t model);
+surf_action_t surf_workstation_model_execute_parallel_task(surf_workstation_model_t model,
+ int workstation_nb,
+ void **workstation_list,
+ double *computation_amount,
+ double *communication_amount,
+ double rate);
+surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst, double size, double rate);
+xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst);
+surf_action_t surf_network_model_communicate(surf_network_model_t model, sg_routing_edge_t src, sg_routing_edge_t dst, double size, double rate);
+const char *surf_resource_name(surf_cpp_resource_t resource);
+xbt_dict_t surf_resource_get_properties(surf_cpp_resource_t resource);
+e_surf_resource_state_t surf_resource_get_state(surf_cpp_resource_t resource);
+double surf_workstation_get_speed(surf_resource_t resource, double load);
+double surf_workstation_get_available_speed(surf_resource_t resource);
+int surf_workstation_get_core(surf_resource_t resource);
+surf_action_t surf_workstation_execute(surf_resource_t resource, double size);
+surf_action_t surf_workstation_sleep(surf_resource_t resource, double duration);
+surf_action_t surf_workstation_open(surf_resource_t workstation, const char* mount, const char* path);
+surf_action_t surf_workstation_close(surf_resource_t workstation, surf_file_t fd);
++surf_action_t surf_workstation_read(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size);
++surf_action_t surf_workstation_write(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size);
++xbt_dynar_t surf_workstation_get_info(surf_resource_t resource, surf_file_t fd);
++sg_storage_size_t surf_workstation_get_free_size(surf_resource_t resource, const char* name);
++sg_storage_size_t surf_workstation_get_used_size(surf_resource_t resource, const char* name);
+surf_action_t surf_cpu_execute(surf_resource_t cpu, double size);
+surf_action_t surf_cpu_sleep(surf_resource_t cpu, double duration);
++double surf_workstation_get_current_power_peak(surf_resource_t host);
++double surf_workstation_get_power_peak_at(surf_resource_t host, int pstate_index);
++int surf_workstation_get_nb_pstates(surf_resource_t host);
++void surf_workstation_set_power_peak_at(surf_resource_t host, int pstate_index);
++double surf_workstation_get_consumed_energy(surf_resource_t host);
++xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation);
+int surf_workstation_unlink(surf_resource_t workstation, surf_file_t fd);
+surf_action_t surf_workstation_ls(surf_resource_t workstation, const char* mount, const char *path);
+size_t surf_workstation_get_size(surf_resource_t workstation, surf_file_t fd);
- surf_action_t surf_workstation_read(surf_resource_t resource, void *ptr, size_t size, surf_file_t fd);
- surf_action_t surf_workstation_write(surf_resource_t resource, const void *ptr, size_t size, surf_file_t fd);
+int surf_network_link_is_shared(surf_cpp_resource_t link);
+double surf_network_link_get_bandwidth(surf_cpp_resource_t link);
+double surf_network_link_get_latency(surf_cpp_resource_t link);
++xbt_dict_t surf_storage_get_content(surf_resource_t resource);
++sg_storage_size_t surf_storage_get_size(surf_resource_t resource);
+void *surf_action_get_data(surf_action_t action);
+void surf_action_set_data(surf_action_t action, void *data);
+void surf_action_unref(surf_action_t action);
+double surf_action_get_start_time(surf_action_t action);
+double surf_action_get_finish_time(surf_action_t action);
+double surf_action_get_remains(surf_action_t action);
+void surf_action_suspend(surf_action_t action);
+void surf_action_resume(surf_action_t action);
+void surf_action_cancel(surf_action_t action);
+void surf_action_set_priority(surf_action_t action, double priority);
+void surf_action_set_category(surf_action_t action, const char *category);
+e_surf_action_state_t surf_action_get_state(surf_action_t action);
+int surf_action_get_cost(surf_action_t action);
+surf_file_t surf_storage_action_get_file(surf_action_t action);
+xbt_dict_t surf_storage_action_get_ls_dict(surf_action_t action);
+
+#ifdef __cplusplus
+}
+#endif
/**************************************/
/* Implementations of model object */
*/
XBT_PUBLIC_DATA(s_surf_model_description_t) surf_storage_model_description[];
-XBT_PUBLIC_DATA(surf_model_t) surf_storage_model;
++XBT_PUBLIC_DATA(surf_storage_model_t) surf_storage_model;
+
/** \ingroup SURF_models
* \brief The workstation model
*
#ifndef SURF_RESOURCE_H
#define SURF_RESOURCE_H
-static XBT_INLINE
+/*FIXME:DELETEstatic XBT_INLINE
surf_resource_t surf_resource_new(size_t childsize,
surf_model_t model, const char *name,
- xbt_dict_t props)
+ xbt_dict_t props, void_f_pvoid_t free_f)
{
surf_resource_t res = xbt_malloc0(childsize);
res->model = model;
extern xbt_dict_t user_link_variables;
extern double TRACE_last_timestamp_to_dump;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* instr_paje_header.c */
- void TRACE_header(int basic);
+ void TRACE_header(int basic, int size);
/* from paje.c */
void TRACE_paje_start(void);
}
}
- return surf_workstation_model->extension.workstation.get_storage_list(workstation);
+ /**
+ * \brief Return the list of mounted storages on a workstation.
+ *
+ * \param workstation a workstation
+ * \return a dynar containing all mounted storages on the workstation
+ */
+ xbt_dict_t SD_workstation_get_storage_list(SD_workstation_t workstation){
++ return surf_workstation_get_storage_list(workstation);
+ }
+
/* Returns whether a task can start now on a workstation*/
/*
int __SD_workstation_can_start(SD_workstation_t workstation, SD_task_t task) {
surf_storage_model_description[i].name);
sprintf(p,
".\n (use 'help' as a value to see the long description of each model)");
- default_value = xbt_strdup("default");
- xbt_cfg_register(&_sg_cfg_set, "storage/model", description, xbt_cfgelm_string,
- &default_value, 1, 1, &_sg_cfg_cb__storage_mode,
- NULL);
+ xbt_cfg_register(&_sg_cfg_set, "storage/model", description,
+ xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
+ xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
- /* ********************************************************************* */
- /* TUTORIAL: New model */
- sprintf(description,
- "The model to use for the New model. Possible values: ");
- p = description;
- while (*(++p) != '\0');
- for (i = 0; surf_new_model_description[i].name; i++)
- p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
- surf_new_model_description[i].name);
- sprintf(p,
- ".\n (use 'help' as a value to see the long description of each model)");
- xbt_cfg_register(&_sg_cfg_set, "new_model/model", description,
- xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
- xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default");
- /* ********************************************************************* */
-
sprintf(description,
"The model to use for the network. Possible values: ");
p = description;
((void (*)(void*))timer->func)(timer->args);
xbt_free(timer);
}
+
/* Wake up all processes waiting for a Surf action to finish */
xbt_dynar_foreach(model_list, iter, model) {
- set = model->states.failed_action_set;
+ set = surf_model_failed_action_set(model);
while ((action = xbt_swag_extract(set)))
- SIMIX_simcall_post((smx_action_t) action->data);
- set = model->states.done_action_set;
+ SIMIX_simcall_post((smx_action_t) surf_action_get_data(action));
+ set = surf_model_done_action_set(model);
while ((action = xbt_swag_extract(set)))
- SIMIX_simcall_post((smx_action_t) action->data);
+ SIMIX_simcall_post((smx_action_t) surf_action_get_data(action));
}
+ /* Autorestart all process */
+ if(host_that_restart) {
+ char *hostname = NULL;
+ xbt_dynar_foreach(host_that_restart,iter,hostname) {
+ XBT_INFO("Restart processes on host: %s",hostname);
+ SIMIX_host_autorestart(SIMIX_host_get_by_name(hostname));
+ }
+ xbt_dynar_reset(host_that_restart);
+ }
+
/* Clean processes to destroy */
SIMIX_process_empty_trash();
int SIMIX_host_get_core(smx_host_t host){
xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
- return surf_workstation_model->extension.workstation.
- get_core(host);
+ return surf_workstation_get_core(host);
}
+ xbt_swag_t SIMIX_pre_host_get_process_list(smx_simcall_t simcall, smx_host_t host){
+ return SIMIX_host_get_process_list(host);
+ }
+
+ xbt_swag_t SIMIX_host_get_process_list(smx_host_t host){
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+ smx_host_priv_t host_priv = SIMIX_host_priv(host);
+
+ return host_priv->process_list;
+ }
double SIMIX_pre_host_get_available_speed(smx_simcall_t simcall, smx_host_t host){
double SIMIX_host_get_available_speed(smx_host_t host){
xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
- return surf_workstation_model->extension.workstation.
- get_available_speed(host);
+ return surf_workstation_get_available_speed(host);
}
- return surf_workstation_model->extension.workstation.
- get_current_power_peak(host);
+ double SIMIX_pre_host_get_current_power_peak(smx_simcall_t simcall, smx_host_t host){
+ return SIMIX_host_get_current_power_peak(host);
+ }
+ double SIMIX_host_get_current_power_peak(smx_host_t host) {
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
- return surf_workstation_model->extension.workstation.
- get_power_peak_at(host, pstate_index);
++ return surf_workstation_get_current_power_peak(host);
+ }
+
+ double SIMIX_pre_host_get_power_peak_at(smx_simcall_t simcall, smx_host_t host, int pstate_index){
+ return SIMIX_host_get_power_peak_at(host, pstate_index);
+ }
+ double SIMIX_host_get_power_peak_at(smx_host_t host, int pstate_index) {
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+
- return surf_workstation_model->extension.workstation.
- get_nb_pstates(host);
++ return surf_workstation_get_power_peak_at(host, pstate_index);
+ }
+
+ int SIMIX_pre_host_get_nb_pstates(smx_simcall_t simcall, smx_host_t host){
+ return SIMIX_host_get_nb_pstates(host);
+ }
+ int SIMIX_host_get_nb_pstates(smx_host_t host) {
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+
- surf_workstation_model->extension.workstation.
- set_power_peak_at(host, pstate_index);
++ return surf_workstation_get_nb_pstates(host);
+ }
+
+
+ void SIMIX_pre_host_set_power_peak_at(smx_simcall_t simcall, smx_host_t host, int pstate_index){
+ SIMIX_host_set_power_peak_at(host, pstate_index);
+ }
+ void SIMIX_host_set_power_peak_at(smx_host_t host, int pstate_index) {
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+
- return surf_workstation_model->extension.workstation.
- get_consumed_energy(host);
++ surf_workstation_set_power_peak_at(host, pstate_index);
+ }
+
+ double SIMIX_pre_host_get_consumed_energy(smx_simcall_t simcall, smx_host_t host){
+ return SIMIX_host_get_consumed_energy(host);
+ }
+ double SIMIX_host_get_consumed_energy(smx_host_t host) {
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
++ return surf_workstation_get_consumed_energy(host);
+ }
+
int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){
return SIMIX_host_get_state(host);
}
}
#endif
- return surf_workstation_model->extension.workstation.get_storage_list(host);
+ xbt_dict_t SIMIX_pre_host_get_storage_list(smx_simcall_t simcall, smx_host_t host){
+ return SIMIX_host_get_storage_list(host);
+ }
+ xbt_dict_t SIMIX_host_get_storage_list(smx_host_t host){
+ xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+
++ return surf_workstation_get_storage_list(host);
+ }
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "smx_private.h"
--#include "surf/storage_private.h"
++//#include "surf/storage_private.h"
#include "xbt/sysdep.h"
#include "xbt/log.h"
#include "xbt/dict.h"
#endif
action->io.host = host;
- action->io.surf_io = surf_workstation_read(host, ptr, size, fd->surf_file);
- action->io.surf_io =
- surf_workstation_model->extension.workstation.read(host, fd->surf_file, size);
++ action->io.surf_io = surf_workstation_read(host, fd->surf_file, size);
- surf_workstation_model->action_data_set(action->io.surf_io, action);
+ surf_action_set_data(action->io.surf_io, action);
XBT_DEBUG("Create io action %p", action);
return action;
#endif
action->io.host = host;
- action->io.surf_io = surf_workstation_write(host, ptr, size, fd->surf_file);
- action->io.surf_io =
- surf_workstation_model->extension.workstation.write(host, fd->surf_file, size);
++ action->io.surf_io = surf_workstation_write(host, fd->surf_file, size);
- surf_workstation_model->action_data_set(action->io.surf_io, action);
+ surf_action_set_data(action->io.surf_io, action);
XBT_DEBUG("Create io action %p", action);
return action;
sg_host_name(host));
}
- if (surf_workstation_model->extension.workstation.unlink(host, fd->surf_file)){
+ if (surf_workstation_unlink(host, fd->surf_file)){
- fd->surf_file = NULL;
+ xbt_free(fd);
return 1;
} else
return 0;
return SIMIX_file_get_size(simcall->issuer, fd);
}
- size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
+ sg_storage_size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
{
smx_host_t host = process->smx_host;
- return surf_workstation_model->extension.workstation.get_size(host,
- fd->surf_file);
+ return surf_workstation_get_size(host, fd->surf_file);
}
- return surf_workstation_model->extension.workstation.get_info(host,
- fd->surf_file);
+ xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd)
+ {
+ return SIMIX_file_get_info(simcall->issuer, fd);
+ }
+
+ xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd)
+ {
+ smx_host_t host = process->smx_host;
- return surf_workstation_model->extension.workstation.get_free_size(host,name);
++ return surf_workstation_get_info(host, fd->surf_file);
+ }
+
+ sg_storage_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const char* name)
+ {
+ return SIMIX_storage_get_free_size(simcall->issuer, name);
+ }
+
+ sg_storage_size_t SIMIX_storage_get_free_size(smx_process_t process, const char* name)
+ {
+ smx_host_t host = process->smx_host;
- return surf_workstation_model->extension.workstation.get_used_size(host,name);
++ return surf_workstation_get_free_size(host, name);
+ }
+
+ sg_storage_size_t SIMIX_pre_storage_get_used_size(smx_simcall_t simcall, const char* name)
+ {
+ return SIMIX_storage_get_used_size(simcall->issuer, name);
+ }
+
+ sg_storage_size_t SIMIX_storage_get_used_size(smx_process_t process, const char* name)
+ {
+ smx_host_t host = process->smx_host;
- return surf_storage_model->extension.storage.get_properties(storage);
++ return surf_workstation_get_used_size(host, name);
+ }
+
+ xbt_dict_t SIMIX_pre_storage_get_properties(smx_simcall_t simcall, smx_storage_t storage){
+ return SIMIX_storage_get_properties(storage);
+ }
+ xbt_dict_t SIMIX_storage_get_properties(smx_storage_t storage){
+ xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
- return surf_storage_model->extension.storage.get_content(storage);
++ return surf_resource_get_properties(surf_workstation_resource_priv(storage));
+ }
+
+ const char* SIMIX_pre_storage_get_name(smx_simcall_t simcall, smx_storage_t storage){
+ return SIMIX_storage_get_name(storage);
+ }
+
+ const char* SIMIX_storage_get_name(smx_storage_t storage){
+ xbt_assert((storage != NULL), "Invalid parameters");
+ return sg_storage_name(storage);
+ }
+
+ void SIMIX_pre_storage_set_data(smx_simcall_t simcall, smx_storage_t storage, void *data) {
+ SIMIX_storage_set_data(storage, data);
+ }
+ void SIMIX_storage_set_data(smx_storage_t storage, void *data){
+ xbt_assert((storage != NULL), "Invalid parameters");
+ xbt_assert((SIMIX_storage_priv(storage)->data == NULL), "Data already set");
+
+ SIMIX_storage_priv(storage)->data = data;
+ }
+
+ void* SIMIX_pre_storage_get_data(smx_simcall_t simcall,smx_storage_t storage){
+ return SIMIX_storage_get_data(storage);
+ }
+
+ void* SIMIX_storage_get_data(smx_storage_t storage){
+ xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
+
+ return SIMIX_storage_priv(storage)->data;
+ }
+
+ xbt_dict_t SIMIX_pre_storage_get_content(smx_simcall_t simcall, smx_storage_t storage){
+ return SIMIX_storage_get_content(storage);
+ }
+
+ xbt_dict_t SIMIX_storage_get_content(smx_storage_t storage){
+ xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
- return surf_storage_model->extension.storage.get_size(storage);
++ return surf_storage_get_content(storage);
+ }
+
+ sg_storage_size_t SIMIX_storage_get_size(smx_storage_t storage){
+ xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
++ return surf_storage_get_size(storage);
+ }
void SIMIX_post_io(smx_action_t action)
{
/* the list of simcalls definitions */
#define SIMCALL_LIST1(ACTION, sep) \
-ACTION(SIMCALL_HOST_GET_BY_NAME, host_get_by_name, WITH_ANSWER, TSPEC(result, smx_host_t), TSTRING(name)) sep \
-ACTION(SIMCALL_HOST_GET_NAME, host_get_name, WITH_ANSWER, TSTRING(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_PROPERTIES, host_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_CORE, host_get_core, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_PROCESS_LIST, host_get_process_list, WITH_ANSWER, TSPEC(result, xbt_swag_t), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_SPEED, host_get_speed, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_AVAILABLE_SPEED, host_get_available_speed, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_STATE, host_get_state, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_DATA, host_get_data, WITH_ANSWER, TPTR(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_SET_DATA, host_set_data, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t), TPTR(data)) sep \
-ACTION(SIMCALL_HOST_GET_CURRENT_POWER_PEAK, host_get_current_power_peak, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_GET_POWER_PEAK_AT, host_get_power_peak_at, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t), TINT(pstate_index)) sep \
-ACTION(SIMCALL_HOST_GET_NB_PSTATES, host_get_nb_pstates, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_SET_POWER_PEAK_AT, host_set_power_peak_at, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t), TINT(pstate_index)) sep \
-ACTION(SIMCALL_HOST_GET_CONSUMED_ENERGY, host_get_consumed_energy, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority)) sep \
-ACTION(SIMCALL_HOST_PARALLEL_EXECUTE, host_parallel_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TINT(host_nb), TSPEC(host_list, smx_host_t*), TSPEC(computation_amount, double*), TSPEC(communication_amount, double*), TDOUBLE(amount), TDOUBLE(rate)) sep \
-ACTION(SIMCALL_HOST_EXECUTION_DESTROY, host_execution_destroy, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t)) sep \
-ACTION(SIMCALL_HOST_EXECUTION_CANCEL, host_execution_cancel, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t)) sep \
-ACTION(SIMCALL_HOST_EXECUTION_GET_REMAINS, host_execution_get_remains, WITH_ANSWER, TDOUBLE(result), TSPEC(execution, smx_action_t)) sep \
-ACTION(SIMCALL_HOST_EXECUTION_GET_STATE, host_execution_get_state, WITH_ANSWER, TINT(result), TSPEC(execution, smx_action_t)) sep \
-ACTION(SIMCALL_HOST_EXECUTION_SET_PRIORITY, host_execution_set_priority, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t), TDOUBLE(priority)) sep \
-ACTION(SIMCALL_HOST_EXECUTION_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TSPEC(execution, smx_action_t)) sep \
-ACTION(SIMCALL_HOST_GET_STORAGE_LIST, host_get_storage_list, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_PROCESS_CREATE, process_create, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t*), TSTRING(name), TSPEC(code, xbt_main_func_t), TPTR(data), TSTRING(hostname), TDOUBLE(kill_time), TINT(argc), TSPEC(argv, char**), TSPEC(properties, xbt_dict_t), TINT(auto_restart)) sep \
-ACTION(SIMCALL_PROCESS_KILL, process_kill, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_HOST_GET_BY_NAME, host_get_by_name, WITH_ANSWER, TDSPEC(result, smx_host_t), TSTRING(name)) sep \
+ACTION(SIMCALL_HOST_GET_NAME, host_get_name, WITH_ANSWER, TSTRING(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_PROPERTIES, host_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_CORE, host_get_core, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \
++ACTION(SIMCALL_HOST_GET_PROCESS_LIST, host_get_process_list, WITH_ANSWER, TDSPEC(result, xbt_swag_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_SPEED, host_get_speed, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_AVAILABLE_SPEED, host_get_available_speed, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_STATE, host_get_state, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_DATA, host_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_SET_DATA, host_set_data, WITH_ANSWER, TVOID(result), TDSPEC(host, smx_host_t), TDPTR(data)) sep \
++ACTION(SIMCALL_HOST_GET_CURRENT_POWER_PEAK, host_get_current_power_peak, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
++ACTION(SIMCALL_HOST_GET_POWER_PEAK_AT, host_get_power_peak_at, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t), TINT(pstate_index)) sep \
++ACTION(SIMCALL_HOST_GET_NB_PSTATES, host_get_nb_pstates, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \
++ACTION(SIMCALL_HOST_SET_POWER_PEAK_AT, host_set_power_peak_at, WITH_ANSWER, TVOID(result), TDSPEC(host, smx_host_t), TINT(pstate_index)) sep \
++ACTION(SIMCALL_HOST_GET_CONSUMED_ENERGY, host_get_consumed_energy, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TDSPEC(result, smx_action_t), TSTRING(name), TDSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority)) sep \
+ACTION(SIMCALL_HOST_PARALLEL_EXECUTE, host_parallel_execute, WITH_ANSWER, TDSPEC(result, smx_action_t), TSTRING(name), TINT(host_nb), TDSPEC(host_list, smx_host_t*), TDSPEC(computation_amount, double*), TDSPEC(communication_amount, double*), TDOUBLE(amount), TDOUBLE(rate)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_DESTROY, host_execution_destroy, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_CANCEL, host_execution_cancel, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_GET_REMAINS, host_execution_get_remains, WITH_ANSWER, TDOUBLE(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_GET_STATE, host_execution_get_state, WITH_ANSWER, TINT(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_SET_PRIORITY, host_execution_set_priority, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t), TDOUBLE(priority)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TDSPEC(execution, smx_action_t)) sep \
++ACTION(SIMCALL_HOST_GET_STORAGE_LIST, host_get_storage_list, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_PROCESS_CREATE, process_create, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t*), TSTRING(name), TFSPEC(code, xbt_main_func_t), TDPTR(data), TSTRING(hostname), TDOUBLE(kill_time), TINT(argc), TDSPEC(argv, char**), TDSPEC(properties, xbt_dict_t), TINT(auto_restart)) sep \
+ACTION(SIMCALL_PROCESS_KILL, process_kill, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
ACTION(SIMCALL_PROCESS_KILLALL, process_killall, WITH_ANSWER, TVOID(result), TINT(reset_pid)) sep \
-ACTION(SIMCALL_PROCESS_CLEANUP, process_cleanup, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_CHANGE_HOST, process_change_host, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TSPEC(dest, smx_host_t)) sep \
-ACTION(SIMCALL_PROCESS_SUSPEND, process_suspend, WITHOUT_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_RESUME, process_resume, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_CLEANUP, process_cleanup, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_CHANGE_HOST, process_change_host, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TDSPEC(dest, smx_host_t)) sep \
+ACTION(SIMCALL_PROCESS_SUSPEND, process_suspend, WITHOUT_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_RESUME, process_resume, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
ACTION(SIMCALL_PROCESS_COUNT, process_count, WITH_ANSWER, TINT(result)) sep \
-ACTION(SIMCALL_PROCESS_GET_PID, process_get_PID, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_GET_PPID, process_get_PPID, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_GET_DATA, process_get_data, WITH_ANSWER, TPTR(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_SET_DATA, process_set_data, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TPTR(data)) sep \
-ACTION(SIMCALL_PROCESS_GET_HOST, process_get_host, WITH_ANSWER, TSPEC(result, smx_host_t), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_GET_NAME, process_get_name, WITH_ANSWER, TSTRING(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_IS_SUSPENDED, process_is_suspended, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_GET_PROPERTIES, process_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_PID, process_get_PID, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_PPID, process_get_PPID, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_DATA, process_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_SET_DATA, process_set_data, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TDPTR(data)) sep \
+ACTION(SIMCALL_PROCESS_GET_HOST, process_get_host, WITH_ANSWER, TDSPEC(result, smx_host_t), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_NAME, process_get_name, WITH_ANSWER, TSTRING(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_IS_SUSPENDED, process_is_suspended, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_PROPERTIES, process_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(process, smx_process_t)) sep \
ACTION(SIMCALL_PROCESS_SLEEP, process_sleep, WITHOUT_ANSWER, TINT(result), TDOUBLE(duration)) sep \
-ACTION(SIMCALL_PROCESS_ON_EXIT, process_on_exit, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TSPEC(fun, int_f_pvoid_t), TPTR(data)) sep \
-ACTION(SIMCALL_PROCESS_AUTO_RESTART_SET, process_auto_restart_set, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TINT(auto_restart)) sep \
-ACTION(SIMCALL_PROCESS_RESTART, process_restart, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_RDV_CREATE, rdv_create, WITH_ANSWER, TSPEC(result, smx_rdv_t), TSTRING(name)) sep \
-ACTION(SIMCALL_RDV_DESTROY, rdv_destroy, WITH_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t)) sep \
-ACTION(SIMCALL_RDV_GET_BY_NAME, rdv_get_by_name, WITH_ANSWER, TSPEC(result, smx_host_t), TSTRING(name)) sep \
-ACTION(SIMCALL_RDV_COMM_COUNT_BY_HOST, rdv_comm_count_by_host, WITH_ANSWER, TUINT(result), TSPEC(rdv, smx_rdv_t), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_RDV_GET_HEAD, rdv_get_head, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t)) sep \
-ACTION(SIMCALL_RDV_SET_RECV, rdv_set_receiver, WITH_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TSPEC(receiver, smx_process_t)) sep \
-ACTION(SIMCALL_RDV_GET_RECV, rdv_get_receiver, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(rdv, smx_rdv_t)) sep \
-ACTION(SIMCALL_COMM_IPROBE, comm_iprobe, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TINT(src), TINT(tag), TSPEC(match_fun, simix_match_func_t), TPTR(data)) sep \
-ACTION(SIMCALL_COMM_SEND, comm_send, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TPTR(src_buff), TSIZE(src_buff_size), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COMM_ISEND, comm_isend, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TPTR(src_buff), TSIZE(src_buff_size), TSPEC(match_fun, simix_match_func_t), TSPEC(clean_fun, simix_clean_func_t), TPTR(data), TINT(detached)) sep \
-ACTION(SIMCALL_COMM_RECV, comm_recv, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COMM_IRECV, comm_irecv, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data)) sep \
-ACTION(SIMCALL_COMM_RECV_BOUNDED, comm_recv_bounded, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout), TDOUBLE(rate)) sep \
-ACTION(SIMCALL_COMM_IRECV_BOUNDED, comm_irecv_bounded, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(rate)) sep \
-ACTION(SIMCALL_COMM_DESTROY, comm_destroy, WITH_ANSWER, TVOID(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_CANCEL, comm_cancel, WITH_ANSWER, TVOID(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_WAITANY, comm_waitany, WITHOUT_ANSWER, TINT(result), TSPEC(comms, xbt_dynar_t)) sep \
-ACTION(SIMCALL_COMM_WAIT, comm_wait, WITHOUT_ANSWER, TVOID(result), TSPEC(comm, smx_action_t), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COMM_TEST, comm_test, WITHOUT_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_TESTANY, comm_testany, WITHOUT_ANSWER, TINT(result), TSPEC(comms, xbt_dynar_t)) sep \
-ACTION(SIMCALL_COMM_GET_REMAINS, comm_get_remains, WITH_ANSWER, TDOUBLE(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_STATE, comm_get_state, WITH_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_SRC_DATA, comm_get_src_data, WITH_ANSWER, TPTR(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_DST_DATA, comm_get_dst_data, WITH_ANSWER, TPTR(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_SRC_PROC, comm_get_src_proc, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_DST_PROC, comm_get_dst_proc, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_MUTEX_INIT, mutex_init, WITH_ANSWER, TSPEC(result, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_DESTROY, mutex_destroy, WITH_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_LOCK, mutex_lock, WITHOUT_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_TRYLOCK, mutex_trylock, WITH_ANSWER, TINT(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_UNLOCK, mutex_unlock, WITH_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_COND_INIT, cond_init, WITH_ANSWER, TSPEC(result, smx_cond_t)) sep \
-ACTION(SIMCALL_COND_DESTROY, cond_destroy, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \
-ACTION(SIMCALL_COND_SIGNAL, cond_signal, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \
-ACTION(SIMCALL_COND_WAIT, cond_wait, WITHOUT_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_COND_WAIT_TIMEOUT, cond_wait_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t), TSPEC(mutex, smx_mutex_t), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COND_BROADCAST, cond_broadcast, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \
-ACTION(SIMCALL_SEM_INIT, sem_init, WITH_ANSWER, TSPEC(result, smx_sem_t), TINT(capacity)) sep \
-ACTION(SIMCALL_SEM_DESTROY, sem_destroy, WITH_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_RELEASE, sem_release, WITH_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_would_block, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_FILE_GET_DATA, file_get_data, WITH_ANSWER, TPTR(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TSPEC(fd, smx_file_t), TPTR(data)) sep \
-ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \
-ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \
-ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \
-ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \
-ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_GET_INFO, file_get_info, WITH_ANSWER, TSPEC(result, xbt_dynar_t), TSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_PROCESS_ON_EXIT, process_on_exit, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TFSPEC(fun, int_f_pvoid_t), TDPTR(data)) sep \
+ACTION(SIMCALL_PROCESS_AUTO_RESTART_SET, process_auto_restart_set, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TINT(auto_restart)) sep \
+ACTION(SIMCALL_PROCESS_RESTART, process_restart, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_RDV_CREATE, rdv_create, WITH_ANSWER, TDSPEC(result, smx_rdv_t), TSTRING(name)) sep \
+ACTION(SIMCALL_RDV_DESTROY, rdv_destroy, WITH_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t)) sep \
+ACTION(SIMCALL_RDV_GET_BY_NAME, rdv_get_by_name, WITH_ANSWER, TDSPEC(result, smx_host_t), TSTRING(name)) sep \
+ACTION(SIMCALL_RDV_COMM_COUNT_BY_HOST, rdv_comm_count_by_host, WITH_ANSWER, TUINT(result), TDSPEC(rdv, smx_rdv_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_RDV_GET_HEAD, rdv_get_head, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t)) sep \
+ACTION(SIMCALL_RDV_SET_RECV, rdv_set_receiver, WITH_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDSPEC(receiver, smx_process_t)) sep \
+ACTION(SIMCALL_RDV_GET_RECV, rdv_get_receiver, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(rdv, smx_rdv_t)) sep \
+ACTION(SIMCALL_COMM_IPROBE, comm_iprobe, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TINT(src), TINT(tag), TFSPEC(match_fun, simix_match_func_t), TDPTR(data)) sep \
+ACTION(SIMCALL_COMM_SEND, comm_send, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TDPTR(src_buff), TSIZE(src_buff_size), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COMM_ISEND, comm_isend, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TDPTR(src_buff), TSIZE(src_buff_size), TFSPEC(match_fun, simix_match_func_t), TFSPEC(clean_fun, simix_clean_func_t), TDPTR(data), TINT(detached)) sep \
+ACTION(SIMCALL_COMM_RECV, comm_recv, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COMM_IRECV, comm_irecv, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data)) sep \
+ACTION(SIMCALL_COMM_RECV_BOUNDED, comm_recv_bounded, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout), TDOUBLE(rate)) sep \
+ACTION(SIMCALL_COMM_IRECV_BOUNDED, comm_irecv_bounded, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(rate)) sep \
+ACTION(SIMCALL_COMM_DESTROY, comm_destroy, WITH_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_CANCEL, comm_cancel, WITH_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_WAITANY, comm_waitany, WITHOUT_ANSWER, TINT(result), TDSPEC(comms, xbt_dynar_t)) sep \
+ACTION(SIMCALL_COMM_WAIT, comm_wait, WITHOUT_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COMM_TEST, comm_test, WITHOUT_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_TESTANY, comm_testany, WITHOUT_ANSWER, TINT(result), TDSPEC(comms, xbt_dynar_t)) sep \
+ACTION(SIMCALL_COMM_GET_REMAINS, comm_get_remains, WITH_ANSWER, TDOUBLE(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_STATE, comm_get_state, WITH_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_SRC_DATA, comm_get_src_data, WITH_ANSWER, TDPTR(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_DST_DATA, comm_get_dst_data, WITH_ANSWER, TDPTR(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_SRC_PROC, comm_get_src_proc, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_DST_PROC, comm_get_dst_proc, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_MUTEX_INIT, mutex_init, WITH_ANSWER, TDSPEC(result, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_DESTROY, mutex_destroy, WITH_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_LOCK, mutex_lock, WITHOUT_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_TRYLOCK, mutex_trylock, WITH_ANSWER, TINT(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_UNLOCK, mutex_unlock, WITH_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_COND_INIT, cond_init, WITH_ANSWER, TDSPEC(result, smx_cond_t)) sep \
+ACTION(SIMCALL_COND_DESTROY, cond_destroy, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \
+ACTION(SIMCALL_COND_SIGNAL, cond_signal, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \
+ACTION(SIMCALL_COND_WAIT, cond_wait, WITHOUT_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_COND_WAIT_TIMEOUT, cond_wait_timeout, WITHOUT_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t), TDSPEC(mutex, smx_mutex_t), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COND_BROADCAST, cond_broadcast, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \
+ACTION(SIMCALL_SEM_INIT, sem_init, WITH_ANSWER, TDSPEC(result, smx_sem_t), TINT(capacity)) sep \
+ACTION(SIMCALL_SEM_DESTROY, sem_destroy, WITH_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_RELEASE, sem_release, WITH_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_would_block, WITH_ANSWER, TINT(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TDSPEC(sem, smx_sem_t)) sep \
- ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TDPTR(ptr), TSIZE(size), TDSPEC(fd, smx_file_t)) sep \
- ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TCPTR(ptr), TSIZE(size), TDSPEC(fd, smx_file_t)) sep \
++ACTION(SIMCALL_FILE_GET_DATA, file_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(fd, smx_file_t)) sep \
++ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TDSPEC(fd, smx_file_t), TDPTR(data)) sep \
++ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t), TSIZE(size)) sep \
++ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t), TSIZE(size)) sep \
+ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TDSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \
+ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TDSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TDSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \
+ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t)) sep \
- ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(name)) sep
++ACTION(SIMCALL_FILE_GET_INFO, file_get_info, WITH_ANSWER, TDSPEC(result, xbt_dynar_t), TDSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_STORAGE_GET_FREE_SIZE, storage_get_free_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \
+ ACTION(SIMCALL_STORAGE_GET_USED_SIZE, storage_get_used_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \
-ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \
-ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \
-ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(name)) sep
++ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(storage, smx_storage_t)) sep \
++ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(storage, smx_storage_t)) sep \
++ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(name)) sep
/* SIMCALL_COMM_IS_LATENCY_BOUNDED and SIMCALL_SET_CATEGORY make things complicated
* because they are not always present */
#ifdef HAVE_MC
#define SIMCALL_LIST4(ACTION, sep) \
-ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TPTR(result)) sep \
-ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TPTR(s1), TPTR(s2)) sep \
+ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TDPTR(result)) sep \
+ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TDPTR(s1), TDPTR(s2)) sep \
- ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result)) sep
+ ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result), TINT(min), TINT(max)) sep
#else
#define SIMCALL_LIST4(ACTION, sep)
#endif
--- /dev/null
- ActionLmmPtr action;
+#include "cpu.hpp"
+
+extern "C" {
++XBT_LOG_EXTERNAL_CATEGORY(surf_kernel);
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf,
+ "Logging specific to the SURF cpu module");
+}
+
+CpuModelPtr surf_cpu_model;
+
+/*********
+ * Model *
+ *********/
+
+void CpuModel::updateActionsStateLazy(double now, double delta)
+{
+ void *_action;
- action = (ActionLmmPtr) xbt_heap_pop(p_actionHeap);
- XBT_DEBUG("Something happened to action %p", action);
++ CpuActionLmmPtr action;
+ while ((xbt_heap_size(p_actionHeap) > 0)
+ && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) {
- XBT_DEBUG("Action %p finished", action);
++ action = dynamic_cast<CpuActionLmmPtr>(static_cast<ActionLmmPtr>(xbt_heap_pop(p_actionHeap)));
++ XBT_CDEBUG(surf_kernel, "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();
- action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
++ XBT_CDEBUG(surf_kernel, "Action %p finished", action);
++
++ action->updateEnergy();
+
+ /* 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) {
- ActionLmmPtr action = NULL;
- ActionLmmPtr next_action = NULL;
++ action = dynamic_cast<CpuActionLmmPtr>(static_cast<ActionPtr>(_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;
- action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
++ CpuActionLmmPtr action = NULL;
+ xbt_swag_t running_actions = p_runningActionSet;
+
+ xbt_swag_foreach_safe(_action, _next_action, running_actions) {
- XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate);
++ action = dynamic_cast<CpuActionLmmPtr>(static_cast<ActionPtr>(_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);
+ }
++ action->updateEnergy();
+ }
+
+ 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 is now %lf", this, m_remains);
++ XBT_CDEBUG(surf_kernel, "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_CDEBUG(surf_kernel, "Updating action(%p): remains is now %lf", this, m_remains);
+ }
+
+ m_lastUpdate = now;
+ m_lastValue = lmm_variable_getvalue(p_variable);
+}
--- /dev/null
+#include "surf.hpp"
+
+#ifndef SURF_MODEL_CPU_H_
+#define SURF_MODEL_CPU_H_
+
+/***********
+ * Classes *
+ ***********/
+class CpuModel;
+typedef CpuModel *CpuModelPtr;
+
+class Cpu;
+typedef Cpu *CpuPtr;
+
+class CpuLmm;
+typedef CpuLmm *CpuLmmPtr;
+
+class CpuAction;
+typedef CpuAction *CpuActionPtr;
+
+class CpuActionLmm;
+typedef CpuActionLmm *CpuActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+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;
+};
+
+/************
+ * Resource *
+ ************/
+class Cpu : virtual public Resource {
+public:
+ Cpu(){};
+ Cpu(CpuModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {};
+ virtual ActionPtr execute(double size)=0;
+ virtual ActionPtr sleep(double duration)=0;
+ virtual int getCore();
+ virtual double getSpeed(double load);
+ virtual double getAvailableSpeed();
++
++ virtual double getCurrentPowerPeak()=0;
++ virtual double getPowerPeakAt(int pstate_index)=0;
++ virtual int getNbPstates()=0;
++ virtual void setPowerPeakAt(int pstate_index)=0;
++ virtual double getConsumedEnergy()=0;
++
+ void addTraces(void);
+ double m_powerPeak; /*< CPU power peak */
+ double m_powerScale; /*< Percentage of CPU disponible */
+protected:
+ 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 : 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)
+ : Action(model, cost, failed), ActionLmm(model, cost, failed), CpuAction(model, cost, failed) {};
+ void updateRemainingLazy(double now);
++ virtual void updateEnergy()=0;
+};
+
+
+#endif /* SURF_MODEL_CPU_H_ */
--- /dev/null
- XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf,
+/* 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"
+
+extern "C" {
- CpuCas01LmmPtr CpuCas01Model::createResource(const char *name, double power_peak, double power_scale,
++XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf_cpu,
+ "Logging specific to the SURF CPU IMPROVED module");
+}
+
+static xbt_swag_t
+ cpu_running_action_set_that_does_not_need_being_checked = NULL;
+
+/*************
+ * CallBacks *
+ *************/
+
+static void parse_cpu_init(sg_platf_host_cbarg_t host){
+ ((CpuCas01ModelPtr)surf_cpu_model)->parseInit(host);
+}
+
+static void cpu_add_traces_cpu(){
+ surf_cpu_model->addTraces();
+}
+
+static void cpu_define_callbacks()
+{
+ sg_platf_host_add_cb(parse_cpu_init);
+ sg_platf_postparse_add_cb(cpu_add_traces_cpu);
+}
+
+/*********
+ * 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_init_ti();
+ return;
+ }
+
+ surf_cpu_model = new CpuCas01Model();
+ cpu_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_cpu_model);
+ xbt_dynar_push(model_list, &model);
+}
+
+CpuCas01Model::CpuCas01Model() : CpuModel("cpu")
+{
+ ActionPtr action;
+ ActionLmmPtr actionlmm;
+
+ 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(*actionlmm, p_actionListHookup));
+ p_maxminSystem->keep_track = p_modifiedSet;
+ }
+}
+
+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->pstate,
+ host->power_scale,
+ host->power_trace,
+ host->core_amount,
+ host->initial_state,
+ host->state_trace,
+ host->properties);
+}
+
- cpu = new CpuCas01Lmm(this, name, power_peak, power_scale, power_trace, core, state_initial, state_trace, cpu_properties);
++CpuCas01LmmPtr CpuCas01Model::createResource(const char *name, xbt_dynar_t power_peak,
++ int pstate, 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)
+{
+ CpuPtr 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);
+
- CpuCas01Lmm::CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, double powerPeak,
- double powerScale, tmgr_trace_t powerTrace, int core,
++ cpu = new CpuCas01Lmm(this, name, power_peak, pstate, power_scale, power_trace, core, state_initial, state_trace, cpu_properties);
+ xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
+
+ return (CpuCas01LmmPtr) xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+double CpuCas01Model::shareResourcesFull(double now)
+{
+ return Model::shareResourcesMaxMin(p_runningActionSet,
+ p_maxminSystem, lmm_solve);
+}
+
+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 = static_cast<CpuCas01LmmPtr>(surf_cpu_resource_priv(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, static_cast<ResourcePtr>(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 = dynamic_cast<CpuCas01LmmPtr>(static_cast<ResourcePtr>(surf_cpu_resource_priv(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, static_cast<ResourcePtr>(host));
+ }
+}
+
+/************
+ * Resource *
+ ************/
- m_powerPeak = powerPeak;
++CpuCas01Lmm::CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, xbt_dynar_t powerPeak,
++ int pstate, 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), Resource(model, name, properties) {
- surf_watched_hosts();
-
++ m_powerPeak = xbt_dynar_get_as(powerPeak, pstate, double);
++ p_powerPeakList = powerPeak;
++ m_pstate = pstate;
++
++ p_energy = xbt_new(s_energy_cpu_cas01_t, 1);
++ p_energy->total_energy = 0;
++ p_energy->power_range_watts_list = getWattsRangeList();
++ p_energy->last_updated = surf_get_clock();
++
++ XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate);
++
+ m_powerScale = powerScale;
+ m_core = core;
+ p_stateCurrent = stateInitial;
+ if (powerTrace)
+ p_powerEvent = tmgr_history_add_trace(history, powerTrace, 0.0, 0, static_cast<ResourcePtr>(this));
+
+ if (stateTrace)
+ p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, static_cast<ResourcePtr>(this));
+
+ p_constraint = lmm_constraint_new(p_model->p_maxminSystem, this, m_core * m_powerScale * m_powerPeak);
+}
+
++CpuCas01Lmm::~CpuCas01Lmm(){
++ unsigned int iter;
++ xbt_dynar_t power_tuple = NULL;
++ xbt_dynar_foreach(p_energy->power_range_watts_list, iter, power_tuple)
++ xbt_dynar_free(&power_tuple);
++ xbt_dynar_free(&p_energy->power_range_watts_list);
++ xbt_dynar_free(&p_powerPeakList);
++ xbt_free(p_energy);
++ return;
++}
++
+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;
+
- if (value > 0)
+ 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 = static_cast<CpuCas01ActionLmmPtr>(static_cast<ActionLmmPtr>(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) {
- else {
++ if (value > 0) {
++ if(p_stateCurrent == SURF_RESOURCE_OFF)
++ xbt_dynar_push_as(host_that_restart, char*, (char *)m_name);
+ 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))) {
+ ActionLmmPtr action = static_cast<ActionLmmPtr>(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;
+}
+
+ActionPtr 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, static_cast<ActionLmmPtr>(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;
+}
+
+ActionPtr CpuCas01Lmm::sleep(double duration)
+{
+ if (duration > 0)
+ duration = MAX(duration, MAXMIN_PRECISION);
+
+ XBT_IN("(%s,%g)", m_name, duration);
+ CpuCas01ActionLmmPtr action = dynamic_cast<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(static_cast<ActionPtr>(action), action->p_stateSet);
+ action->p_stateSet = cpu_running_action_set_that_does_not_need_being_checked;
+ xbt_swag_insert(static_cast<ActionPtr>(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(static_cast<ActionLmmPtr>(action), surf_cpu_model->p_modifiedSet);
+ }
+
+ XBT_OUT();
+ return action;
+}
+
++xbt_dynar_t CpuCas01Lmm::getWattsRangeList()
++{
++ xbt_dynar_t power_range_list;
++ xbt_dynar_t power_tuple;
++ int i = 0, pstate_nb=0;
++ xbt_dynar_t current_power_values;
++ double min_power, max_power;
++
++ if (m_properties == NULL)
++ return NULL;
++
++ char* all_power_values_str = (char*)xbt_dict_get_or_null(m_properties, "power_per_state");
++
++ if (all_power_values_str == NULL)
++ return NULL;
++
++
++ power_range_list = xbt_dynar_new(sizeof(xbt_dynar_t), NULL);
++ xbt_dynar_t all_power_values = xbt_str_split(all_power_values_str, ",");
++
++ pstate_nb = xbt_dynar_length(all_power_values);
++ for (i=0; i< pstate_nb; i++)
++ {
++ /* retrieve the power values associated with the current pstate */
++ current_power_values = xbt_str_split(xbt_dynar_get_as(all_power_values, i, char*), ":");
++ xbt_assert(xbt_dynar_length(current_power_values) > 1,
++ "Power properties incorrectly defined - could not retrieve min and max power values for host %s",
++ m_name);
++
++ /* min_power corresponds to the idle power (cpu load = 0) */
++ /* max_power is the power consumed at 100% cpu load */
++ min_power = atof(xbt_dynar_get_as(current_power_values, 0, char*));
++ max_power = atof(xbt_dynar_get_as(current_power_values, 1, char*));
++
++ power_tuple = xbt_dynar_new(sizeof(double), NULL);
++ xbt_dynar_push_as(power_tuple, double, min_power);
++ xbt_dynar_push_as(power_tuple, double, max_power);
++
++ xbt_dynar_push_as(power_range_list, xbt_dynar_t, power_tuple);
++ xbt_dynar_free(¤t_power_values);
++ }
++ xbt_dynar_free(&all_power_values);
++ return power_range_list;
++}
++
++/**
++ * Computes the power consumed by the host according to the current pstate and processor load
++ *
++ */
++double CpuCas01Lmm::getCurrentWattsValue(double cpu_load)
++{
++ xbt_dynar_t power_range_list = p_energy->power_range_watts_list;
++
++ if (power_range_list == NULL)
++ {
++ XBT_DEBUG("No power range properties specified for host %s", m_name);
++ return 0;
++ }
++ xbt_assert(xbt_dynar_length(power_range_list) == xbt_dynar_length(p_powerPeakList),
++ "The number of power ranges in the properties does not match the number of pstates for host %s",
++ m_name);
++
++ /* retrieve the power values associated with the current pstate */
++ xbt_dynar_t current_power_values = xbt_dynar_get_as(power_range_list, m_pstate, xbt_dynar_t);
++
++ /* min_power corresponds to the idle power (cpu load = 0) */
++ /* max_power is the power consumed at 100% cpu load */
++ double min_power = xbt_dynar_get_as(current_power_values, 0, double);
++ double max_power = xbt_dynar_get_as(current_power_values, 1, double);
++ double power_slope = max_power - min_power;
++
++ double current_power = min_power + cpu_load * power_slope;
++
++ XBT_DEBUG("[get_current_watts] min_power=%f, max_power=%f, slope=%f", min_power, max_power, power_slope);
++ XBT_DEBUG("[get_current_watts] Current power (watts) = %f, load = %f", current_power, cpu_load);
++
++ return current_power;
++}
++
++/**
++ * Updates the total energy consumed as the sum of the current energy and
++ * the energy consumed by the current action
++ */
++void CpuCas01Lmm::updateEnergy(double cpu_load)
++{
++ double start_time = p_energy->last_updated;
++ double finish_time = surf_get_clock();
++
++ XBT_DEBUG("[cpu_update_energy] action time interval=(%f-%f), current power peak=%f, current pstate=%d",
++ start_time, finish_time, m_powerPeak, m_pstate);
++ double current_energy = p_energy->total_energy;
++ double action_energy = getCurrentWattsValue(cpu_load)*(finish_time-start_time);
++
++ p_energy->total_energy = current_energy + action_energy;
++ p_energy->last_updated = finish_time;
++
++ XBT_DEBUG("[cpu_update_energy] old_energy_value=%f, action_energy_value=%f", current_energy, action_energy);
++}
++
++double CpuCas01Lmm::getCurrentPowerPeak()
++{
++ return m_powerPeak;
++}
++
++double CpuCas01Lmm::getPowerPeakAt(int pstate_index)
++{
++ xbt_dynar_t plist = p_powerPeakList;
++ xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)");
++
++ return xbt_dynar_get_as(plist, pstate_index, double);
++}
++
++int CpuCas01Lmm::getNbPstates()
++{
++ return xbt_dynar_length(p_powerPeakList);
++}
++
++void CpuCas01Lmm::setPowerPeakAt(int pstate_index)
++{
++ xbt_dynar_t plist = p_powerPeakList;
++ xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)");
++
++ double new_power_peak = xbt_dynar_get_as(plist, pstate_index, double);
++ m_pstate = pstate_index;
++ m_powerPeak = new_power_peak;
++}
++
++double CpuCas01Lmm::getConsumedEnergy()
++{
++ return p_energy->total_energy;
++}
+
+/**********
+ * Action *
+ **********/
+
++/**
++ * Update the CPU total energy for a finished action
++ *
++ */
++void CpuCas01ActionLmm::updateEnergy()
++{
++ CpuCas01LmmPtr cpu = static_cast<CpuCas01LmmPtr>(lmm_constraint_id(lmm_get_cnst_from_var
++ (p_model->p_maxminSystem,
++ p_variable, 0)));
+
++ if(cpu->p_energy->last_updated < surf_get_clock()) {
++ double load = lmm_constraint_get_usage(cpu->p_constraint) / cpu->m_powerPeak;
++ cpu->updateEnergy(load);
++ }
++}
--- /dev/null
- CpuCas01LmmPtr createResource(const char *name, double power_peak, double power_scale,
+#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);
- CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, double powerPeak,
- double powerScale, tmgr_trace_t powerTrace, int core,
++ CpuCas01LmmPtr createResource(const char *name, xbt_dynar_t power_peak, int pstate,
++ 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 *
+ ************/
++/*
++ * Energy-related properties for the cpu_cas01 model
++ */
++typedef struct energy_cpu_cas01 {
++ xbt_dynar_t power_range_watts_list; /*< List of (min_power,max_power) pairs corresponding to each cpu pstate */
++ double total_energy; /*< Total energy consumed by the host */
++ double last_updated; /*< Timestamp of the last energy update event*/
++} s_energy_cpu_cas01_t, *energy_cpu_cas01_t;
++
+class CpuCas01Lmm : public CpuLmm {
+public:
++ CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, xbt_dynar_t power_peak,
++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+ e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+ xbt_dict_t properties) ;
++ ~CpuCas01Lmm();
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+ ActionPtr execute(double size);
+ ActionPtr sleep(double duration);
+
++ xbt_dynar_t getWattsRangeList();
++ double getCurrentWattsValue(double cpu_load);
++ void updateEnergy(double cpu_load);
++
++ double getCurrentPowerPeak();
++ double getPowerPeakAt(int pstate_index);
++ int getNbPstates();
++ void setPowerPeakAt(int pstate_index);
++ double getConsumedEnergy();
++
+ bool isUsed();
+
+ tmgr_trace_event_t p_powerEvent;
++
++ xbt_dynar_t p_powerPeakList; /*< List of supported CPU capacities */
++ int m_pstate; /*< Current pstate (index in the power_peak_list)*/
++ energy_cpu_cas01_t p_energy; /*< Structure with energy-consumption data */
+};
+
+/**********
+ * Action *
+ **********/
+class CpuCas01ActionLmm: public CpuActionLmm {
+public:
+ CpuCas01ActionLmm() {};
+ CpuCas01ActionLmm(ModelPtr model, double cost, bool failed): Action(model, cost, failed), CpuActionLmm(model, cost, failed) {};
++ void updateEnergy();
+
+};
--- /dev/null
- XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_ti, surf,
+#include "cpu_ti.hpp"
+#include "trace_mgr_private.h"
+#include "xbt/heap.h"
+
+#ifndef SURF_MODEL_CPUTI_H_
+#define SURF_MODEL_CPUTI_H_
+
+extern "C" {
- ("a %lf ind %d integral %lf ind + 1 %lf ind %lf time +1 %lf time %lf",
++XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_ti, surf_cpu,
+ "Logging specific to the SURF CPU TRACE INTEGRATION module");
+}
+
+static xbt_swag_t cpu_ti_running_action_set_that_does_not_need_being_checked;
+static xbt_swag_t cpu_ti_modified_cpu;
+static xbt_heap_t cpu_ti_action_heap;
+
+static void cpu_ti_action_update_index_heap(void *action, int i);
+
+/*********
+ * Trace *
+ *********/
+
+CpuTiTrace::CpuTiTrace(tmgr_trace_t power_trace)
+{
+ s_tmgr_event_t val;
+ unsigned int cpt;
+ double integral = 0;
+ double time = 0;
+ int i = 0;
+ p_timePoints = (double*) xbt_malloc0(sizeof(double) *
+ (xbt_dynar_length(power_trace->s_list.event_list) + 1));
+ p_integral = (double*) xbt_malloc0(sizeof(double) *
+ (xbt_dynar_length(power_trace->s_list.event_list) + 1));
+ m_nbPoints = xbt_dynar_length(power_trace->s_list.event_list);
+ xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) {
+ p_timePoints[i] = time;
+ p_integral[i] = integral;
+ integral += val.delta * val.value;
+ time += val.delta;
+ i++;
+ }
+ p_timePoints[i] = time;
+ p_integral[i] = integral;
+}
+
+CpuTiTrace::~CpuTiTrace()
+{
+ xbt_free(p_timePoints);
+ xbt_free(p_integral);
+}
+
+CpuTiTgmr::~CpuTiTgmr()
+{
+ if (p_trace)
+ delete p_trace;
+}
+
+/**
+* \brief Integrate trace
+*
+* Wrapper around surf_cpu_integrate_trace_simple() to get
+* the cyclic effect.
+*
+* \param trace Trace structure.
+* \param a Begin of interval
+* \param b End of interval
+* \return the integrate value. -1 if an error occurs.
+*/
+double CpuTiTgmr::integrate(double a, double b)
+{
+ double first_chunk;
+ double middle_chunk;
+ double last_chunk;
+ int a_index, b_index;
+
+ if ((a < 0.0) || (a > b)) {
+ XBT_CRITICAL
+ ("Error, invalid integration interval [%.2f,%.2f]. You probably have a task executing with negative computation amount. Check your code.",
+ a, b);
+ xbt_abort();
+ }
+ if (a == b)
+ return 0.0;
+
+ if (m_type == TRACE_FIXED) {
+ return ((b - a) * m_value);
+ }
+
+ if (ceil(a / m_lastTime) == a / m_lastTime)
+ a_index = 1 + (int) (ceil(a / m_lastTime));
+ else
+ a_index = (int) (ceil(a / m_lastTime));
+
+ b_index = (int) (floor(b / m_lastTime));
+
+ if (a_index > b_index) { /* Same chunk */
+ return p_trace->integrateSimple(a - (a_index -
+ 1) * m_lastTime,
+ b -
+ (b_index) *
+ m_lastTime);
+ }
+
+ first_chunk = p_trace->integrateSimple(a - (a_index -
+ 1) *
+ m_lastTime,
+ m_lastTime);
+ middle_chunk = (b_index - a_index) * m_total;
+ last_chunk = p_trace->integrateSimple(0.0,
+ b -
+ (b_index) *
+ m_lastTime);
+
+ XBT_DEBUG("first_chunk=%.2f middle_chunk=%.2f last_chunk=%.2f\n",
+ first_chunk, middle_chunk, last_chunk);
+
+ return (first_chunk + middle_chunk + last_chunk);
+}
+
+/**
+ * \brief Auxiliary function to calculate the integral between a and b.
+ * It simply calculates the integral at point a and b and returns the difference
+ * between them.
+ * \param trace Trace structure
+ * \param a Initial point
+ * \param b Final point
+ * \return Integral
+*/
+double CpuTiTrace::integrateSimple(double a, double b)
+{
+ return integrateSimplePoint(b) - integrateSimplePoint(a);
+}
+
+/**
+ * \brief Auxiliary function to calculate the integral at point a.
+ * \param trace Trace structure
+ * \param a point
+ * \return Integral
+*/
+double CpuTiTrace::integrateSimplePoint(double a)
+{
+ double integral = 0;
+ int ind;
+ double a_aux = a;
+ ind = binarySearch(p_timePoints, a, 0, m_nbPoints - 1);
+ integral += p_integral[ind];
+ XBT_DEBUG
- XBT_DEBUG("Integral a %lf = %lf", a, integral);
++ ("a %f ind %d integral %f ind + 1 %f ind %f time +1 %f time %f",
+ a, ind, integral, p_integral[ind + 1], p_integral[ind],
+ p_timePoints[ind + 1], p_timePoints[ind]);
+ double_update(&a_aux, p_timePoints[ind]);
+ if (a_aux > 0)
+ integral +=
+ ((p_integral[ind + 1] -
+ p_integral[ind]) / (p_timePoints[ind + 1] -
+ p_timePoints[ind])) * (a - p_timePoints[ind]);
- XBT_DEBUG("amount %lf total %lf", amount, m_total);
++ XBT_DEBUG("Integral a %f = %f", a, integral);
+
+ return integral;
+}
+
+/**
+* \brief Calculate the time needed to execute "amount" on cpu.
+*
+* Here, amount can span multiple trace periods
+*
+* \param trace CPU trace structure
+* \param a Initial time
+* \param amount Amount to be executed
+* \return End time
+*/
+double CpuTiTgmr::solve(double a, double amount)
+{
+ int quotient;
+ double reduced_b;
+ double reduced_amount;
+ double reduced_a;
+ double b;
+
+/* Fix very small negative numbers */
+ if ((a < 0.0) && (a > -EPSILON)) {
+ a = 0.0;
+ }
+ if ((amount < 0.0) && (amount > -EPSILON)) {
+ amount = 0.0;
+ }
+
+/* Sanity checks */
+ if ((a < 0.0) || (amount < 0.0)) {
+ XBT_CRITICAL
+ ("Error, invalid parameters [a = %.2f, amount = %.2f]. You probably have a task executing with negative computation amount. Check your code.",
+ a, amount);
+ xbt_abort();
+ }
+
+/* At this point, a and amount are positive */
+
+ if (amount < EPSILON)
+ return a;
+
+/* Is the trace fixed ? */
+ if (m_type == TRACE_FIXED) {
+ return (a + (amount / m_value));
+ }
+
- XBT_DEBUG("Quotient: %d reduced_amount: %lf reduced_a: %lf", quotient,
++ XBT_DEBUG("amount %f total %f", amount, m_total);
+/* Reduce the problem to one where amount <= trace_total */
+ quotient = (int) (floor(amount / m_total));
+ reduced_amount = (m_total) * ((amount / m_total) -
+ floor(amount / m_total));
+ reduced_a = a - (m_lastTime) * (int) (floor(a / m_lastTime));
+
- XBT_DEBUG("No availabily trace. Constant value = %lf", value);
++ XBT_DEBUG("Quotient: %d reduced_amount: %f reduced_a: %f", quotient,
+ reduced_amount, reduced_a);
+
+/* Now solve for new_amount which is <= trace_total */
+/*
+ fprintf(stderr,"reduced_a = %.2f\n",reduced_a);
+ fprintf(stderr,"reduced_amount = %.2f\n",reduced_amount);
+ */
+ reduced_b = solveSomewhatSimple(reduced_a, reduced_amount);
+
+/* Re-map to the original b and amount */
+ b = (m_lastTime) * (int) (floor(a / m_lastTime)) +
+ (quotient * m_lastTime) + reduced_b;
+ return b;
+}
+
+/**
+* \brief Auxiliary function to solve integral
+*
+* Here, amount is <= trace->total
+* and a <=trace->last_time
+*
+*/
+double CpuTiTgmr::solveSomewhatSimple(double a, double amount)
+{
+ double amount_till_end;
+ double b;
+
+ XBT_DEBUG("Solve integral: [%.2f, amount=%.2f]", a, amount);
+ amount_till_end = integrate(a, m_lastTime);
+/*
+ fprintf(stderr,"amount_till_end=%.2f\n",amount_till_end);
+ */
+
+ if (amount_till_end > amount) {
+ b = p_trace->solveSimple(a, amount);
+ } else {
+ b = m_lastTime + p_trace->solveSimple(0.0, amount - amount_till_end);
+ }
+ return b;
+}
+
+/**
+ * \brief Auxiliary function to solve integral.
+ * It returns the date when the requested amount of flops is available
+ * \param trace Trace structure
+ * \param a Initial point
+ * \param amount Amount of flops
+ * \return The date when amount is available.
+*/
+double CpuTiTrace::solveSimple(double a, double amount)
+{
+ double integral_a;
+ int ind;
+ double time;
+ integral_a = integrateSimplePoint(a);
+ ind = binarySearch(p_integral, integral_a + amount, 0, m_nbPoints - 1);
+ time = p_timePoints[ind];
+ time +=
+ (integral_a + amount -
+ p_integral[ind]) / ((p_integral[ind + 1] -
+ p_integral[ind]) /
+ (p_timePoints[ind + 1] -
+ p_timePoints[ind]));
+
+ return time;
+}
+
+/**
+* \brief Auxiliary function to update the CPU power scale.
+*
+* This function uses the trace structure to return the power scale at the determined time a.
+* \param trace Trace structure to search the updated power scale
+* \param a Time
+* \return CPU power scale
+*/
+double CpuTiTgmr::getPowerScale(double a)
+{
+ double reduced_a;
+ int point;
+ s_tmgr_event_t val;
+
+ reduced_a = a - floor(a / m_lastTime) * m_lastTime;
+ point = p_trace->binarySearch(p_trace->p_timePoints, reduced_a, 0,
+ p_trace->m_nbPoints - 1);
+ xbt_dynar_get_cpy(p_powerTrace->s_list.event_list, point, &val);
+ return val.value;
+}
+
+/**
+* \brief Creates a new integration trace from a tmgr_trace_t
+*
+* \param power_trace CPU availability trace
+* \param value Percentage of CPU power available (useful to fixed tracing)
+* \param spacing Initial spacing
+* \return Integration trace structure
+*/
+CpuTiTgmr::CpuTiTgmr(tmgr_trace_t power_trace, double value)
+{
+ double total_time = 0.0;
+ s_tmgr_event_t val;
+ unsigned int cpt;
+ p_trace = 0;
+
+/* no availability file, fixed trace */
+ if (!power_trace) {
+ m_type = TRACE_FIXED;
+ m_value = value;
- XBT_DEBUG("a %lf low %d high %d mid %d value %lf", a, low, high, mid,
++ XBT_DEBUG("No availability trace. Constant value = %lf", value);
+ return;
+ }
+
+ /* only one point available, fixed trace */
+ if (xbt_dynar_length(power_trace->s_list.event_list) == 1) {
+ xbt_dynar_get_cpy(power_trace->s_list.event_list, 0, &val);
+ m_type = TRACE_FIXED;
+ m_value = val.value;
+ return;
+ }
+
+ m_type = TRACE_DYNAMIC;
+ p_powerTrace = power_trace;
+
+ /* count the total time of trace file */
+ xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) {
+ total_time += val.delta;
+ }
+ p_trace = new CpuTiTrace(power_trace);
+ m_lastTime = total_time;
+ m_total = p_trace->integrateSimple(0, total_time);
+
+ XBT_DEBUG("Total integral %lf, last_time %lf ",
+ m_total, m_lastTime);
+}
+
+/**
+ * \brief Binary search in array.
+ * It returns the first point of the interval in which "a" is.
+ * \param array Array
+ * \param a Value to search
+ * \param low Low bound to search in array
+ * \param high Upper bound to search in array
+ * \return Index of point
+*/
+int CpuTiTrace::binarySearch(double *array, double a, int low, int high)
+{
+ xbt_assert(low < high, "Wrong parameters: low (%d) should be smaller than"
+ " high (%d)", low, high);
+
+ int mid;
+ do {
+ mid = low + (high - low) / 2;
- double powerPeak,
++ XBT_DEBUG("a %f low %d high %d mid %d value %f", a, low, high, mid,
+ array[mid]);
+
+ if (array[mid] > a)
+ high = mid;
+ else
+ low = mid;
+ }
+ while (low < high - 1);
+
+ return low;
+}
+
+/*************
+ * CallBacks *
+ *************/
+
+static void parse_cpu_ti_init(sg_platf_host_cbarg_t host){
+ ((CpuTiModelPtr)surf_cpu_model)->parseInit(host);
+}
+
+static void add_traces_cpu_ti(){
+ surf_cpu_model->addTraces();
+}
+
+static void cpu_ti_define_callbacks()
+{
+ sg_platf_host_add_cb(parse_cpu_ti_init);
+ sg_platf_postparse_add_cb(add_traces_cpu_ti);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_cpu_model_init_ti()
+{
+ xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen.");
+ surf_cpu_model = new CpuTiModel();
+ cpu_ti_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_cpu_model);
+ xbt_dynar_push(model_list, &model);
+}
+
+CpuTiModel::CpuTiModel() : CpuModel("cpu_ti")
+{
+ xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen.");
+ ActionPtr 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);
+}
+
+CpuTiModel::~CpuTiModel()
+{
+ void **cpu;
+ xbt_lib_cursor_t cursor;
+ char *key;
+
+ xbt_lib_foreach(host_lib, cursor, key, cpu){
+ if(cpu[SURF_CPU_LEVEL])
+ {
+ CpuTiPtr CPU = dynamic_cast<CpuTiPtr>(static_cast<ResourcePtr>(cpu[SURF_CPU_LEVEL]));
+ xbt_swag_free(CPU->p_actionSet);
+ delete CPU->p_availTrace;
+ }
+ }
+
+ surf_cpu_model = NULL;
+
+ xbt_swag_free
+ (cpu_ti_running_action_set_that_does_not_need_being_checked);
+ xbt_swag_free(cpu_ti_modified_cpu);
+ cpu_ti_running_action_set_that_does_not_need_being_checked = NULL;
+ xbt_heap_free(cpu_ti_action_heap);
+}
+
+void CpuTiModel::parseInit(sg_platf_host_cbarg_t host)
+{
+ createResource(host->id,
+ host->power_peak,
++ host->pstate,
+ host->power_scale,
+ host->power_trace,
+ host->core_amount,
+ host->initial_state,
+ host->state_trace,
+ host->properties);
+}
+
+CpuTiPtr CpuTiModel::createResource(const char *name,
- CpuTiPtr cpu = new CpuTi(this, name, powerPeak, powerScale, powerTrace,
++ xbt_dynar_t powerPeak,
++ int pstate,
+ double powerScale,
+ tmgr_trace_t powerTrace,
+ int core,
+ e_surf_resource_state_t stateInitial,
+ tmgr_trace_t stateTrace,
+ xbt_dict_t cpuProperties)
+{
+ tmgr_trace_t empty_trace;
+ s_tmgr_event_t val;
+ CpuTiActionPtr cpuAction;
+ xbt_assert(core==1,"Multi-core not handled with this model yet");
+ xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)),
+ "Host '%s' declared several times in the platform file",
+ name);
- XBT_DEBUG("Share resources, min next event date: %lf", min_action_duration);
++ CpuTiPtr cpu = new CpuTi(this, name, powerPeak, pstate, powerScale, powerTrace,
+ core, stateInitial, stateTrace, cpuProperties);
+ xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
+ return (CpuTiPtr) xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+CpuTiActionPtr CpuTiModel::createAction(double cost, bool failed)
+{
+ return NULL;//new CpuTiAction(this, cost, failed);
+}
+
+double CpuTiModel::shareResources(double now)
+{
+ void *_cpu, *_cpu_next;
+ double min_action_duration = -1;
+
+/* iterates over modified cpus to update share resources */
+ xbt_swag_foreach_safe(_cpu, _cpu_next, cpu_ti_modified_cpu) {
+ static_cast<CpuTiPtr>(_cpu)->updateActionFinishDate(now);
+ }
+/* get the min next event if heap not empty */
+ if (xbt_heap_size(cpu_ti_action_heap) > 0)
+ min_action_duration = xbt_heap_maxkey(cpu_ti_action_heap) - now;
+
- /* update remaining amout of all actions */
++ XBT_DEBUG("Share resources, min next event date: %f", min_action_duration);
+
+ return min_action_duration;
+}
+
+void CpuTiModel::updateActionsState(double now, double delta)
+{
+ while ((xbt_heap_size(cpu_ti_action_heap) > 0)
+ && (xbt_heap_maxkey(cpu_ti_action_heap) <= now)) {
+ CpuTiActionPtr action = (CpuTiActionPtr) xbt_heap_pop(cpu_ti_action_heap);
+ XBT_DEBUG("Action %p: finish", action);
+ action->m_finish = surf_get_clock();
+ /* set the remains to 0 due to precision problems when updating the remaining amount */
+ action->m_remains = 0;
+ action->setState(SURF_ACTION_DONE);
- CpuTi::CpuTi(CpuTiModelPtr model, const char *name, double powerPeak,
- double powerScale, tmgr_trace_t powerTrace, int core,
++ /* update remaining amount of all actions */
+ action->p_cpu->updateRemainingAmount(surf_get_clock());
+ }
+}
+
+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 = static_cast<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, static_cast<ResourcePtr>(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 = dynamic_cast<CpuTiPtr>(static_cast<ResourcePtr>(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, static_cast<ResourcePtr>(cpu));
+ }
+ }
+ }
+}
+
+/************
+ * Resource *
+ ************/
- m_powerPeak = powerPeak;
++CpuTi::CpuTi(CpuTiModelPtr model, const char *name, xbt_dynar_t powerPeak,
++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+ e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+ xbt_dict_t properties) :
+ Resource(model, name, properties), Cpu(model, name, properties) {
+ p_stateCurrent = stateInitial;
- p_powerEvent =
+ 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");
+ XBT_DEBUG("power scale %lf", powerScale);
+ p_availTrace = new CpuTiTgmr(powerTrace, powerScale);
+
+ CpuTiActionPtr action;
+ p_actionSet = xbt_swag_new(xbt_swag_offset(*action, p_cpuListHookup));
+
++ xbt_dynar_get_cpy(powerPeak, 0, &m_powerPeak);
++ xbt_dynar_free(&powerPeak); /* kill memory leak */
++ m_pstate = pstate;
++ XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate);
++
+ p_modifiedCpuHookup.prev = 0;
+ p_modifiedCpuHookup.next = 0;
+
+ if (stateTrace)
+ p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, static_cast<ResourcePtr>(this));
+ if (powerTrace && xbt_dynar_length(powerTrace->s_list.event_list) > 1) {
+ // add a fake trace event if periodicity == 0
+ xbt_dynar_get_cpy(powerTrace->s_list.event_list,
+ xbt_dynar_length(powerTrace->s_list.event_list) - 1, &val);
+ if (val.delta == 0) {
+ empty_trace = tmgr_empty_trace_new();
- surf_watched_hosts();
-
++ p_powerEvent =
+ tmgr_history_add_trace(history, empty_trace,
+ p_availTrace->m_lastTime, 0, static_cast<ResourcePtr>(this));
+ }
+ }
+};
+
+void CpuTi::updateState(tmgr_trace_event_t event_type,
+ double value, double date)
+{
+ void *_action;
+ CpuTiActionPtr action;
+
- XBT_DEBUG("Finish trace date: %lf value %lf date %lf", surf_get_clock(),
+ if (event_type == p_powerEvent) {
+ tmgr_trace_t power_trace;
+ CpuTiTgmrPtr trace;
+ s_tmgr_event_t val;
+
- XBT_DEBUG("value %lf", val.value);
++ XBT_DEBUG("Finish trace date: %f value %lf date %f", surf_get_clock(),
+ value, date);
+ /* update remaining of actions and put in modified cpu swag */
+ updateRemainingAmount(date);
+ xbt_swag_insert(this, cpu_ti_modified_cpu);
+
+ power_trace = p_availTrace->p_powerTrace;
+ xbt_dynar_get_cpy(power_trace->s_list.event_list,
+ xbt_dynar_length(power_trace->s_list.event_list) - 1, &val);
+ /* free old trace */
+ delete p_availTrace;
+ m_powerScale = val.value;
+
+ trace = new CpuTiTgmr(TRACE_FIXED, val.value);
- if (value > 0)
++ XBT_DEBUG("value %f", val.value);
+
+ p_availTrace = trace;
+
+ if (tmgr_trace_event_free(event_type))
+ p_powerEvent = NULL;
+
+ } else if (event_type == p_stateEvent) {
- else {
++ if (value > 0) {
++ if(p_stateCurrent == SURF_RESOURCE_OFF)
++ xbt_dynar_push_as(host_that_restart, char*, (char *)m_name);
+ p_stateCurrent = SURF_RESOURCE_ON;
- ("Update finish time: Cpu(%s) Action: %p, Start Time: %lf Finish Time: %lf Max duration %lf",
++ } else {
+ p_stateCurrent = SURF_RESOURCE_OFF;
+
+ /* put all action running on cpu to failed */
+ xbt_swag_foreach(_action, p_actionSet) {
+ action = static_cast<CpuTiActionPtr>(_action);
+ 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 (action->m_indexHeap >= 0) {
+ CpuTiActionPtr heap_act = (CpuTiActionPtr)
+ xbt_heap_remove(cpu_ti_action_heap, action->m_indexHeap);
+ if (heap_act != action)
+ DIE_IMPOSSIBLE;
+ }
+ }
+ }
+ }
+ if (tmgr_trace_event_free(event_type))
+ p_stateEvent = NULL;
+ } else {
+ XBT_CRITICAL("Unknown event ! \n");
+ xbt_abort();
+ }
+
+ return;
+}
+
+void CpuTi::updateActionFinishDate(double now)
+{
+ void *_action;
+ CpuTiActionPtr action;
+ double sum_priority = 0.0, total_area, min_finish = -1;
+
+/* update remaning amount of actions */
+updateRemainingAmount(now);
+
+ xbt_swag_foreach(_action, p_actionSet) {
+ action = static_cast<CpuTiActionPtr>(_action);
+ /* action not running, skip it */
+ if (action->p_stateSet !=
+ surf_cpu_model->p_runningActionSet)
+ continue;
+
+ /* bogus priority, skip it */
+ if (action->m_priority <= 0)
+ continue;
+
+ /* action suspended, skip it */
+ if (action->m_suspended != 0)
+ continue;
+
+ sum_priority += 1.0 / action->m_priority;
+ }
+ m_sumPriority = sum_priority;
+
+ xbt_swag_foreach(_action, p_actionSet) {
+ action = static_cast<CpuTiActionPtr>(_action);
+ min_finish = -1;
+ /* action not running, skip it */
+ if (action->p_stateSet !=
+ surf_cpu_model->p_runningActionSet)
+ continue;
+
+ /* verify if the action is really running on cpu */
+ if (action->m_suspended == 0 && action->m_priority > 0) {
+ /* total area needed to finish the action. Used in trace integration */
+ total_area =
+ (action->m_remains) * sum_priority *
+ action->m_priority;
+
+ total_area /= m_powerPeak;
+
+ action->m_finish = p_availTrace->solve(now, total_area);
+ /* verify which event will happen before (max_duration or finish time) */
+ if (action->m_maxDuration != NO_MAX_DURATION &&
+ action->m_start + action->m_maxDuration < action->m_finish)
+ min_finish = action->m_start + action->m_maxDuration;
+ else
+ min_finish = action->m_finish;
+ } else {
+ /* put the max duration time on heap */
+ if (action->m_maxDuration != NO_MAX_DURATION)
+ min_finish = action->m_start + action->m_maxDuration;
+ }
+ /* add in action heap */
+ XBT_DEBUG("action(%p) index %d", action, action->m_indexHeap);
+ if (action->m_indexHeap >= 0) {
+ CpuTiActionPtr heap_act = (CpuTiActionPtr)
+ xbt_heap_remove(cpu_ti_action_heap, action->m_indexHeap);
+ if (heap_act != action)
+ DIE_IMPOSSIBLE;
+ }
+ if (min_finish != NO_MAX_DURATION)
+ xbt_heap_push(cpu_ti_action_heap, action, min_finish);
+
+ XBT_DEBUG
- XBT_DEBUG("Flops total: %lf, Last update %lf", area_total,
++ ("Update finish time: Cpu(%s) Action: %p, Start Time: %f Finish Time: %f Max duration %f",
+ m_name, action, action->m_start,
+ action->m_finish,
+ action->m_maxDuration);
+ }
+/* remove from modified cpu */
+ xbt_swag_remove(this, cpu_ti_modified_cpu);
+}
+
+bool CpuTi::isUsed()
+{
+ return xbt_swag_size(p_actionSet);
+}
+
+
+
+double CpuTi::getAvailableSpeed()
+{
+ m_powerScale = p_availTrace->getPowerScale(surf_get_clock());
+ return Cpu::getAvailableSpeed();
+}
+
+/**
+* \brief Update the remaining amount of actions
+*
+* \param now Current time
+*/
+void CpuTi::updateRemainingAmount(double now)
+{
+ double area_total;
+ void* _action;
+ CpuTiActionPtr action;
+
+ /* already updated */
+ if (m_lastUpdate >= now)
+ return;
+
+/* calcule the surface */
+ area_total = p_availTrace->integrate(m_lastUpdate, now) * m_powerPeak;
- XBT_DEBUG("Update remaining action(%p) remaining %lf", action,
++ XBT_DEBUG("Flops total: %f, Last update %f", area_total,
+ m_lastUpdate);
+
+ xbt_swag_foreach(_action, p_actionSet) {
+ action = static_cast<CpuTiActionPtr>(_action);
+ /* action not running, skip it */
+ if (action->p_stateSet !=
+ getModel()->p_runningActionSet)
+ continue;
+
+ /* bogus priority, skip it */
+ if (action->m_priority <= 0)
+ continue;
+
+ /* action suspended, skip it */
+ if (action->m_suspended != 0)
+ continue;
+
+ /* action don't need update */
+ if (action->m_start >= now)
+ continue;
+
+ /* skip action that are finishing now */
+ if (action->m_finish >= 0
+ && action->m_finish <= now)
+ continue;
+
+ /* update remaining */
+ double_update(&(action->m_remains),
+ area_total / (m_sumPriority *
+ action->m_priority));
++ XBT_DEBUG("Update remaining action(%p) remaining %f", action,
+ action->m_remains);
+ }
+ m_lastUpdate = now;
+}
+
+CpuActionPtr CpuTi::execute(double size)
+{
+ return _execute(size);
+}
+
+CpuTiActionPtr CpuTi::_execute(double size)
+{
+ XBT_IN("(%s,%g)", m_name, size);
+ CpuTiActionPtr action = new CpuTiAction(static_cast<CpuTiModelPtr>(p_model), size, p_stateCurrent != SURF_RESOURCE_ON);
+
+ action->p_cpu = this;
+ action->m_indexHeap = -1;
+
+ xbt_swag_insert(this, cpu_ti_modified_cpu);
+
+ xbt_swag_insert(action, p_actionSet);
+
+ action->m_suspended = 0; /* Should be useless because of the
+ » calloc but it seems to help valgrind... */
+
+ XBT_OUT();
+ return action;
+}
+
+
+CpuActionPtr CpuTi::sleep(double duration)
+{
+ if (duration > 0)
+ duration = MAX(duration, MAXMIN_PRECISION);
+
+ XBT_IN("(%s,%g)", m_name, duration);
+ CpuTiActionPtr action = _execute(1.0);
+ 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(static_cast<ActionPtr>(action), action->p_stateSet);
+ action->p_stateSet = cpu_ti_running_action_set_that_does_not_need_being_checked;
+ xbt_swag_insert(static_cast<ActionPtr>(action), action->p_stateSet);
+ }
+ XBT_OUT();
+ return action;
+}
+
+void CpuTi::printCpuTiModel()
+{
+ std::cout << getModel()->getName() << "<<plop"<< std::endl;
+};
+
+/**********
+ * Action *
+ **********/
+static void cpu_ti_action_update_index_heap(void *action, int i)
+{
+ ((CpuTiActionPtr)action)->updateIndexHeap(i);
+}
+void CpuTiAction::updateIndexHeap(int i)
+{
+ m_indexHeap = i;
+}
+
+void CpuTiAction::setState(e_surf_action_state_t state)
+{
+ Action::setState(state);
+ xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+}
+
+int CpuTiAction::unref()
+{
+ m_refcount--;
+ if (!m_refcount) {
+ xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+ /* remove from action_set */
+ xbt_swag_remove(this, p_cpu->p_actionSet);
+ /* remove from heap */
+ xbt_heap_remove(cpu_ti_action_heap, this->m_indexHeap);
+ xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+ delete this;
+ return 1;
+ }
+ return 0;
+}
+
+void CpuTiAction::cancel()
+{
+ this->setState(SURF_ACTION_FAILED);
+ xbt_heap_remove(cpu_ti_action_heap, this->m_indexHeap);
+ xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+ return;
+}
+
+void CpuTiAction::recycle()
+{
+ DIE_IMPOSSIBLE;
+}
+
+void CpuTiAction::suspend()
+{
+ XBT_IN("(%p)", this);
+ if (m_suspended != 2) {
+ m_suspended = 1;
+ xbt_heap_remove(cpu_ti_action_heap, m_indexHeap);
+ xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+ }
+ XBT_OUT();
+}
+
+void CpuTiAction::resume()
+{
+ XBT_IN("(%p)", this);
+ if (m_suspended != 2) {
+ m_suspended = 0;
+ xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+ }
+ XBT_OUT();
+}
+
+bool CpuTiAction::isSuspended()
+{
+ return m_suspended == 1;
+}
+
+void CpuTiAction::setMaxDuration(double duration)
+{
+ double min_finish;
+
+ XBT_IN("(%p,%g)", this, duration);
+
+ m_maxDuration = duration;
+
+ if (duration >= 0)
+ min_finish = (m_start + m_maxDuration) < m_finish ?
+ (m_start + m_maxDuration) : m_finish;
+ else
+ min_finish = m_finish;
+
+/* add in action heap */
+ if (m_indexHeap >= 0) {
+ CpuTiActionPtr heap_act = (CpuTiActionPtr)
+ xbt_heap_remove(cpu_ti_action_heap, m_indexHeap);
+ if (heap_act != this)
+ DIE_IMPOSSIBLE;
+ }
+ xbt_heap_push(cpu_ti_action_heap, this, min_finish);
+
+ XBT_OUT();
+}
+
+void CpuTiAction::setPriority(double priority)
+{
+ XBT_IN("(%p,%g)", this, priority);
+ m_priority = priority;
+ xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+ XBT_OUT();
+}
+
+double CpuTiAction::getRemains()
+{
+ XBT_IN("(%p)", this);
+ p_cpu->updateRemainingAmount(surf_get_clock());
+ XBT_OUT();
+ return m_remains;
+}
+
+static void check() {
+ CpuTiActionPtr cupAction = new CpuTiAction(NULL, 0, true);
+}
+
+#endif /* SURF_MODEL_CPUTI_H_ */
+
--- /dev/null
- CpuTiPtr createResource(const char *name, double power_peak, double power_scale,
+#include "cpu.hpp"
+#include "trace_mgr_private.h"
+#include "surf/surf_routing.h"
+
+/* Epsilon */
+#define EPSILON 0.000000001
+
+/***********
+ * Classes *
+ ***********/
+class CpuTiTrace;
+typedef CpuTiTrace *CpuTiTracePtr;
+
+class CpuTiTgmr;
+typedef CpuTiTgmr *CpuTiTgmrPtr;
+
+class CpuTiModel;
+typedef CpuTiModel *CpuTiModelPtr;
+
+class CpuTi;
+typedef CpuTi *CpuTiPtr;
+
+class CpuTiAction;
+typedef CpuTiAction *CpuTiActionPtr;
+
+/*********
+ * Trace *
+ *********/
+class CpuTiTrace {
+public:
+ CpuTiTrace(tmgr_trace_t powerTrace);
+ ~CpuTiTrace();
+
+ double integrateSimple(double a, double b);
+ double integrateSimplePoint(double a);
+ double solveSimple(double a, double amount);
+
+ double *p_timePoints;
+ double *p_integral;
+ int m_nbPoints;
+ int binarySearch(double *array, double a, int low, int high);
+
+private:
+};
+
+enum trace_type {
+
+ TRACE_FIXED, /*< Trace fixed, no availability file */
+ TRACE_DYNAMIC /*< Dynamic, availability file disponible */
+};
+
+class CpuTiTgmr {
+public:
+ CpuTiTgmr(trace_type type, double value): m_type(type), m_value(value){};
+ CpuTiTgmr(tmgr_trace_t power_trace, double value);
+ ~CpuTiTgmr();
+
+ double integrate(double a, double b);
+ double solve(double a, double amount);
+ double solveSomewhatSimple(double a, double amount);
+ double getPowerScale(double a);
+
+ trace_type m_type;
+ double m_value; /*< Percentage of cpu power disponible. Value fixed between 0 and 1 */
+
+ /* Dynamic */
+ double m_lastTime; /*< Integral interval last point (discret time) */
+ double m_total; /*< Integral total between 0 and last_pointn */
+
+ CpuTiTracePtr p_trace;
+ tmgr_trace_t p_powerTrace;
+};
+
+
+/*********
+ * Model *
+ *********/
+class CpuTiModel : public CpuModel {
+public:
+ CpuTiModel();
+ ~CpuTiModel();
+
+ void parseInit(sg_platf_host_cbarg_t host);
- CpuTi(CpuTiModelPtr model, const char *name, double powerPeak,
- double powerScale, tmgr_trace_t powerTrace, int core,
++ CpuTiPtr createResource(const char *name, xbt_dynar_t powerPeak,
++ int pstate, 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);
+ CpuTiActionPtr createAction(double cost, bool failed);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+ void addTraces();
+
+protected:
+ void NotifyResourceTurnedOn(ResourcePtr r){};
+ void NotifyResourceTurnedOff(ResourcePtr r){};
+
+ void NotifyActionCancel(ActionPtr a){};
+ void NotifyActionResume(ActionPtr a){};
+ void NotifyActionSuspend(ActionPtr a){};
+};
+
+/************
+ * Resource *
+ ************/
+class CpuTi : public Cpu {
+public:
+ CpuTi() {};
- tmgr_trace_event_t p_powerEvent; /*< trace file with availabitly events */
++ CpuTi(CpuTiModelPtr model, const char *name, xbt_dynar_t powerPeak,
++ int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+ e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+ xbt_dict_t properties) ;
+ ~CpuTi() {};
+
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+ void updateActionFinishDate(double now);
+ bool isUsed();
+ void printCpuTiModel();
+ CpuActionPtr execute(double size);
+ CpuTiActionPtr _execute(double size);
+ CpuActionPtr sleep(double duration);
+ double getAvailableSpeed();
+
++ xbt_dynar_t getWattsRangeList() {};
++ double getCurrentWattsValue(double cpu_load) {};
++ void updateEnergy(double cpu_load) {};
++
++ double getCurrentPowerPeak() {};
++ double getPowerPeakAt(int pstate_index) {};
++ int getNbPstates() {};
++ void setPowerPeakAt(int pstate_index) {};
++ double getConsumedEnergy() {};
++
+ CpuTiTgmrPtr p_availTrace; /*< Structure with data needed to integrate trace file */
+ tmgr_trace_event_t p_stateEvent; /*< trace file with states events (ON or OFF) */
- s_xbt_swag_hookup_t p_modifiedCpuHookup; /*< hookup to swag that indicacates whether share resources must be recalculated or not */
++ tmgr_trace_event_t p_powerEvent; /*< trace file with availability events */
+ xbt_swag_t p_actionSet; /*< set with all actions running on cpu */
++ s_xbt_swag_hookup_t p_modifiedCpuHookup; /*< hookup to swag that indicates whether share resources must be recalculated or not */
+ double m_sumPriority; /*< the sum of actions' priority that are running on cpu */
+ double m_lastUpdate; /*< last update of actions' remaining amount done */
++
++ int m_pstate; /*< Current pstate (index in the power_peak_list)*/
++ double current_frequency;
++
+ void updateRemainingAmount(double now);
+};
+
+/**********
+ * Action *
+ **********/
+
+class CpuTiAction: public CpuAction {
+public:
+ CpuTiAction() {};
+ CpuTiAction(CpuTiModelPtr model, double cost, bool failed)
+ : Action(model, cost, failed), CpuAction(model, cost, failed) {
+ p_cpuListHookup.next = 0;
+ p_cpuListHookup.prev = 0;
+ };
+
+ void setState(e_surf_action_state_t state);
+ int unref();
+ void cancel();
+ void recycle();
+ void updateIndexHeap(int i);
+ void suspend();
+ void resume();
+ bool isSuspended();
+ void setMaxDuration(double duration);
+ void setPriority(double priority);
+ double getRemains();
+ CpuTiPtr p_cpu;
+ int m_indexHeap;
+ s_xbt_swag_hookup_t p_cpuListHookup;
+ int m_suspended;
+private:
+};
--- /dev/null
- /* printf("[" "%lg" "] Asking to update network card \"%s\" with value " */
- /* "%lg" " for event %p\n", surf_get_clock(), nw_link->name, */
+#include "network.hpp"
+#include "maxmin_private.h"
+#include "simgrid/sg_config.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
+ "Logging specific to the SURF network module");
+}
+
+NetworkCm02ModelPtr surf_network_model = NULL;
+
+double sg_sender_gap = 0.0;
+double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */
+double sg_bandwidth_factor = 1.0; /* default value; can be set by model or from command line */
+double sg_weight_S_parameter = 0.0; /* default value; can be set by model or from command line */
+
+double sg_tcp_gamma = 0.0;
+int sg_network_crosstraffic = 0;
+
+/*************
+ * CallBacks *
+ *************/
+
+static void net_parse_link_init(sg_platf_link_cbarg_t link){
+ if (link->policy == SURF_LINK_FULLDUPLEX) {
+ char *link_id;
+ link_id = bprintf("%s_UP", link->id);
+ surf_network_model->createResource(link_id,
+ link->bandwidth,
+ link->bandwidth_trace,
+ link->latency,
+ link->latency_trace,
+ link->state,
+ link->state_trace, link->policy, link->properties);
+ xbt_free(link_id);
+ link_id = bprintf("%s_DOWN", link->id);
+ surf_network_model->createResource(link_id,
+ link->bandwidth,
+ link->bandwidth_trace,
+ link->latency,
+ link->latency_trace,
+ link->state,
+ link->state_trace, link->policy, link->properties);
+ xbt_free(link_id);
+ } else {
+ surf_network_model->createResource(link->id,
+ link->bandwidth,
+ link->bandwidth_trace,
+ link->latency,
+ link->latency_trace,
+ link->state,
+ link->state_trace, link->policy, link->properties);
+ }
+}
+
+static void net_add_traces(void){
+ xbt_dict_cursor_t cursor = NULL;
+ char *trace_name, *elm;
+
+ static int called = 0;
+ if (called)
+ return;
+ called = 1;
+
+ /* connect all traces relative to network */
+ xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ NetworkCm02LinkLmmPtr link = dynamic_cast<NetworkCm02LinkLmmPtr>(
+ static_cast<ResourcePtr>(
+ xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+ xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
+ trace_name, elm);
+ xbt_assert(trace,
+ "Cannot connect trace %s to link %s: trace undefined",
+ trace_name, elm);
+
+ link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+ }
+
+ xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ NetworkCm02LinkLmmPtr link = dynamic_cast<NetworkCm02LinkLmmPtr>(
+ static_cast<ResourcePtr>(
+ xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+ xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
+ trace_name, elm);
+ xbt_assert(trace,
+ "Cannot connect trace %s to link %s: trace undefined",
+ trace_name, elm);
+
+ link->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+ }
+
+ xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ NetworkCm02LinkLmmPtr link = dynamic_cast<NetworkCm02LinkLmmPtr>(
+ static_cast<ResourcePtr>(
+ xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+ xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
+ trace_name, elm);
+ xbt_assert(trace,
+ "Cannot connect trace %s to link %s: trace undefined",
+ trace_name, elm);
+
+ link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+ }
+}
+
+void net_define_callbacks(void)
+{
+ /* Figuring out the network links */
+ sg_platf_link_add_cb(net_parse_link_init);
+ sg_platf_postparse_add_cb(net_add_traces);
+}
+
+/*********
+ * Model *
+ *********/
+
+/************************************************************************/
+/* New model based on optimizations discussed during Pedro Velho's thesis*/
+/************************************************************************/
+/* @techreport{VELHO:2011:HAL-00646896:1, */
+/* url = {http://hal.inria.fr/hal-00646896/en/}, */
+/* title = {{Flow-level network models: have we reached the limits?}}, */
+/* author = {Velho, Pedro and Schnorr, Lucas and Casanova, Henri and Legrand, Arnaud}, */
+/* type = {Rapport de recherche}, */
+/* institution = {INRIA}, */
+/* number = {RR-7821}, */
+/* year = {2011}, */
+/* month = Nov, */
+/* pdf = {http://hal.inria.fr/hal-00646896/PDF/rr-validity.pdf}, */
+/* } */
+void surf_network_model_init_LegrandVelho(void)
+{
+ if (surf_network_model)
+ return;
+
+ surf_network_model = new NetworkCm02Model();
+ net_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+ xbt_dynar_push(model_list, &model);
+
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor",
+ 13.01);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+ 0.97);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 20537);
+}
+
+/***************************************************************************/
+/* The nice TCP sharing model designed by Loris Marchal and Henri Casanova */
+/***************************************************************************/
+/* @TechReport{ rr-lip2002-40, */
+/* author = {Henri Casanova and Loris Marchal}, */
+/* institution = {LIP}, */
+/* title = {A Network Model for Simulation of Grid Application}, */
+/* number = {2002-40}, */
+/* month = {oct}, */
+/* year = {2002} */
+/* } */
+void surf_network_model_init_CM02(void)
+{
+
+ if (surf_network_model)
+ return;
+
+ surf_network_model = new NetworkCm02Model();
+ net_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+ xbt_dynar_push(model_list, &model);
+
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+ 1.0);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 0.0);
+}
+
+/***************************************************************************/
+/* The models from Steven H. Low */
+/***************************************************************************/
+/* @article{Low03, */
+/* author={Steven H. Low}, */
+/* title={A Duality Model of {TCP} and Queue Management Algorithms}, */
+/* year={2003}, */
+/* journal={{IEEE/ACM} Transactions on Networking}, */
+/* volume={11}, number={4}, */
+/* } */
+void surf_network_model_init_Reno(void)
+{
+ if (surf_network_model)
+ return;
+
+ surf_network_model = new NetworkCm02Model();
+ net_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+ xbt_dynar_push(model_list, &model);
+ lmm_set_default_protocol_function(func_reno_f, func_reno_fp,
+ func_reno_fpi);
+ surf_network_model->f_networkSolve = lagrange_solve;
+
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+ 0.92);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
+}
+
+
+void surf_network_model_init_Reno2(void)
+{
+ if (surf_network_model)
+ return;
+
+ surf_network_model = new NetworkCm02Model();
+ net_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+ xbt_dynar_push(model_list, &model);
+ lmm_set_default_protocol_function(func_reno2_f, func_reno2_fp,
+ func_reno2_fpi);
+ surf_network_model->f_networkSolve = lagrange_solve;
+
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+ 0.92);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S_parameter",
+ 8775);
+}
+
+void surf_network_model_init_Vegas(void)
+{
+ if (surf_network_model)
+ return;
+
+ surf_network_model = new NetworkCm02Model();
+ net_define_callbacks();
+ ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+ xbt_dynar_push(model_list, &model);
+ lmm_set_default_protocol_function(func_vegas_f, func_vegas_fp,
+ func_vegas_fpi);
+ surf_network_model->f_networkSolve = lagrange_solve;
+
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+ 0.92);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
+}
+
+NetworkCm02Model::NetworkCm02Model() : NetworkCm02Model("network"){
+}
+
+NetworkCm02Model::NetworkCm02Model(string name) : Model(name){
+ ActionLmmPtr comm;
+
+ char *optim = xbt_cfg_get_string(_sg_cfg_set, "network/optim");
+ int select =
+ xbt_cfg_get_boolean(_sg_cfg_set, "network/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, "network/maxmin_selective_update")),
+ "Disabling selective update while using the lazy update mechanism is dumb!");
+ } else {
+ xbt_die("Unsupported optimization (%s) for this model", optim);
+ }
+
+ if (!p_maxminSystem)
+ p_maxminSystem = lmm_system_new(m_selectiveUpdate);
+
+ routing_model_create(static_cast<ResourcePtr>(createResource("__loopback__",
+ 498000000, NULL, 0.000015, NULL,
+ SURF_RESOURCE_ON, NULL,
+ SURF_LINK_FATPIPE, NULL)));
+
+ 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(*comm, p_actionListHookup));
+ p_maxminSystem->keep_track = p_modifiedSet;
+ }
+}
+
+NetworkCm02LinkLmmPtr NetworkCm02Model::createResource(const char *name,
+ double bw_initial,
+ tmgr_trace_t bw_trace,
+ double lat_initial,
+ tmgr_trace_t lat_trace,
+ e_surf_resource_state_t state_initial,
+ tmgr_trace_t state_trace,
+ e_surf_link_sharing_policy_t policy,
+ xbt_dict_t properties)
+{
+ xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
+ "Link '%s' declared several times in the platform file.",
+ name);
+
+ NetworkCm02LinkLmmPtr nw_link =
+ new NetworkCm02LinkLmm(this, name, properties, p_maxminSystem, sg_bandwidth_factor * bw_initial, history,
+ state_initial, state_trace, bw_initial, bw_trace, lat_initial, lat_trace, policy);
+
+
+ xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast<ResourcePtr>(nw_link));
+ XBT_DEBUG("Create link '%s'",name);
+
+ return nw_link;
+}
+
+void NetworkCm02Model::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 = static_cast<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);
+
+ action->gapRemove();
+ }
+ }
+ return;
+}
+
+xbt_dynar_t NetworkCm02Model::getRoute(RoutingEdgePtr src, RoutingEdgePtr dst)
+{
+ xbt_dynar_t route = NULL;
+ routing_platf->getRouteAndLatency(src, dst, &route, NULL);
+ return route;
+}
+
+ActionPtr NetworkCm02Model::communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+ double size, double rate)
+{
+ unsigned int i;
+ void *_link;
+ NetworkCm02LinkLmmPtr link;
+ int failed = 0;
+ NetworkCm02ActionLmmPtr action = NULL;
+ double bandwidth_bound;
+ double latency = 0.0;
+ xbt_dynar_t back_route = NULL;
+ int constraints_per_variable = 0;
+
+ xbt_dynar_t route = xbt_dynar_new(sizeof(RoutingEdgePtr), NULL);
+
+ XBT_IN("(%s,%s,%g,%g)", src->p_name, dst->p_name, size, rate);
+
+ routing_platf->getRouteAndLatency(src, dst, &route, &latency);
+ xbt_assert(!xbt_dynar_is_empty(route) || latency,
+ "You're trying to send data from %s to %s but there is no connection at all between these two hosts.",
+ src->p_name, dst->p_name);
+
+ xbt_dynar_foreach(route, i, _link) {
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+ if (link->p_stateCurrent == SURF_RESOURCE_OFF) {
+ failed = 1;
+ break;
+ }
+ }
+ if (sg_network_crosstraffic == 1) {
+ routing_platf->getRouteAndLatency(dst, src, &back_route, NULL);
+ xbt_dynar_foreach(back_route, i, _link) {
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+ if (link->p_stateCurrent == SURF_RESOURCE_OFF) {
+ failed = 1;
+ break;
+ }
+ }
+ }
+
+ action = new NetworkCm02ActionLmm(this, size, failed);
+
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+ action->m_latencyLimited = 0;
+#endif
+ action->m_weight = action->m_latency = latency;
+
+ //FIXME:REMOVxbt_swag_insert(action, action->p_stateSet);
+ action->m_rate = rate;
+ if (p_updateMechanism == UM_LAZY) {
+ action->m_indexHeap = -1;
+ action->m_lastUpdate = surf_get_clock();
+ }
+
+ bandwidth_bound = -1.0;
+ if (sg_weight_S_parameter > 0) {
+ xbt_dynar_foreach(route, i, _link) {
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+ action->m_weight +=
+ sg_weight_S_parameter /
+ (link->p_power.peak * link->p_power.scale);
+ }
+ }
+ xbt_dynar_foreach(route, i, _link) {
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+ double bb = bandwidthFactor(size) * (link->p_power.peak * link->p_power.scale);
+ bandwidth_bound =
+ (bandwidth_bound < 0.0) ? bb : min(bandwidth_bound, bb);
+ }
+
+ action->m_latCurrent = action->m_latency;
+ action->m_latency *= latencyFactor(size);
+ action->m_rate = bandwidthConstraint(action->m_rate, bandwidth_bound, size);
+ if (m_haveGap) {
+ xbt_assert(!xbt_dynar_is_empty(route),
+ "Using a model with a gap (e.g., SMPI) with a platform without links (e.g. vivaldi)!!!");
+
+ //link = *(NetworkCm02LinkLmmPtr *) xbt_dynar_get_ptr(route, 0);
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(*static_cast<ResourcePtr *>(xbt_dynar_get_ptr(route, 0)));
+ gapAppend(size, link, action);
+ XBT_DEBUG("Comm %p: %s -> %s gap=%f (lat=%f)",
+ action, src->p_name, dst->p_name, action->m_senderGap,
+ action->m_latency);
+ }
+
+ constraints_per_variable = xbt_dynar_length(route);
+ if (back_route != NULL)
+ constraints_per_variable += xbt_dynar_length(back_route);
+
+ if (action->m_latency > 0) {
+ action->p_variable = lmm_variable_new(p_maxminSystem, action, 0.0, -1.0,
+ constraints_per_variable);
+ if (p_updateMechanism == UM_LAZY) {
+ // add to the heap the event when the latency is payed
+ XBT_DEBUG("Added action (%p) one latency event at date %f", action,
+ action->m_latency + action->m_lastUpdate);
+ action->heapInsert(p_actionHeap, action->m_latency + action->m_lastUpdate, xbt_dynar_is_empty(route) ? NORMAL : LATENCY);
+ }
+ } else
+ action->p_variable = lmm_variable_new(p_maxminSystem, action, 1.0, -1.0, constraints_per_variable);
+
+ if (action->m_rate < 0) {
+ lmm_update_variable_bound(p_maxminSystem, action->p_variable, (action->m_latCurrent > 0) ? sg_tcp_gamma / (2.0 * action->m_latCurrent) : -1.0);
+ } else {
+ lmm_update_variable_bound(p_maxminSystem, action->p_variable, (action->m_latCurrent > 0) ? min(action->m_rate, sg_tcp_gamma / (2.0 * action->m_latCurrent)) : action->m_rate);
+ }
+
+ xbt_dynar_foreach(route, i, _link) {
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+ lmm_expand(p_maxminSystem, link->p_constraint, action->p_variable, 1.0);
+ }
+
+ if (sg_network_crosstraffic == 1) {
+ XBT_DEBUG("Fullduplex active adding backward flow using 5%%");
+ xbt_dynar_foreach(back_route, i, _link) {
+ link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+ lmm_expand(p_maxminSystem, link->p_constraint, action->p_variable, .05);
+ }
+ }
+
+ xbt_dynar_free(&route);
+ XBT_OUT();
+
+ return action;
+}
+
+double NetworkCm02Model::latencyFactor(double size) {
+ return sg_latency_factor;
+}
+
+double NetworkCm02Model::bandwidthFactor(double size) {
+ return sg_bandwidth_factor;
+}
+
+double NetworkCm02Model::bandwidthConstraint(double rate, double bound, double size) {
+ return rate;
+}
+
+/************
+ * Resource *
+ ************/
+NetworkCm02LinkLmm::NetworkCm02LinkLmm(NetworkCm02ModelPtr model, const char *name, xbt_dict_t props,
+ lmm_system_t system,
+ double constraint_value,
+ tmgr_history_t history,
+ e_surf_resource_state_t state_init,
+ tmgr_trace_t state_trace,
+ double metric_peak,
+ tmgr_trace_t metric_trace,
+ double lat_initial,
+ tmgr_trace_t lat_trace,
+ e_surf_link_sharing_policy_t policy)
+: Resource(model, name, props),
+ ResourceLmm(model, name, props, system, constraint_value, history, state_init, state_trace, metric_peak, metric_trace),
+ NetworkCm02Link(model, name, props)
+{
+ m_latCurrent = lat_initial;
+ if (lat_trace)
+ p_latEvent = tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast<ResourcePtr>(this));
+
+ if (policy == SURF_LINK_FATPIPE)
+ lmm_constraint_shared(p_constraint);
+}
+
+bool NetworkCm02LinkLmm::isUsed()
+{
+ return lmm_constraint_used(p_model->p_maxminSystem, p_constraint);
+}
+
+double NetworkCm02Link::getLatency()
+{
+ return m_latCurrent;
+}
+
+double NetworkCm02LinkLmm::getBandwidth()
+{
+ return p_power.peak * p_power.scale;
+}
+
+bool NetworkCm02LinkLmm::isShared()
+{
+ return lmm_constraint_is_shared(p_constraint);
+}
+
+void NetworkCm02LinkLmm::updateState(tmgr_trace_event_t event_type,
+ double value, double date)
+{
++ /* printf("[" "%g" "] Asking to update network card \"%s\" with value " */
++ /* "%g" " for event %p\n", surf_get_clock(), nw_link->name, */
+ /* value, event_type); */
+
+ if (event_type == p_power.event) {
+ double delta =
+ sg_weight_S_parameter / value - sg_weight_S_parameter /
+ (p_power.peak * p_power.scale);
+ lmm_variable_t var = NULL;
+ lmm_element_t elem = NULL;
+ NetworkCm02ActionLmmPtr action = NULL;
+
+ p_power.peak = value;
+ lmm_update_constraint_bound(p_model->p_maxminSystem,
+ p_constraint,
+ sg_bandwidth_factor *
+ (p_power.peak * p_power.scale));
+#ifdef HAVE_TRACING
+ TRACE_surf_link_set_bandwidth(date, m_name, sg_bandwidth_factor * p_power.peak * p_power.scale);
+#endif
+ if (sg_weight_S_parameter > 0) {
+ while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, p_constraint, &elem))) {
+ action = (NetworkCm02ActionLmmPtr) lmm_variable_id(var);
+ action->m_weight += delta;
+ if (!action->m_suspended)
+ lmm_update_variable_weight(p_model->p_maxminSystem, action->p_variable, action->m_weight);
+ }
+ }
+ if (tmgr_trace_event_free(event_type))
+ p_power.event = NULL;
+ } else if (event_type == p_latEvent) {
+ double delta = value - m_latCurrent;
+ lmm_variable_t var = NULL;
+ lmm_element_t elem = NULL;
+ NetworkCm02ActionLmmPtr action = NULL;
+
+ m_latCurrent = value;
+ while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, p_constraint, &elem))) {
+ action = (NetworkCm02ActionLmmPtr) lmm_variable_id(var);
+ action->m_latCurrent += delta;
+ action->m_weight += delta;
+ if (action->m_rate < 0)
+ lmm_update_variable_bound(p_model->p_maxminSystem, action->p_variable, sg_tcp_gamma / (2.0 * action->m_latCurrent));
+ else {
+ lmm_update_variable_bound(p_model->p_maxminSystem, action->p_variable,
+ min(action->m_rate, sg_tcp_gamma / (2.0 * action->m_latCurrent)));
+
+ if (action->m_rate < sg_tcp_gamma / (2.0 * action->m_latCurrent)) {
+ XBT_INFO("Flow is limited BYBANDWIDTH");
+ } else {
+ XBT_INFO("Flow is limited BYLATENCY, latency of flow is %f",
+ action->m_latCurrent);
+ }
+ }
+ if (!action->m_suspended)
+ lmm_update_variable_weight(p_model->p_maxminSystem, action->p_variable, action->m_weight);
+
+ }
+ if (tmgr_trace_event_free(event_type))
+ p_latEvent = NULL;
+ } else if (event_type == p_stateEvent) {
+ if (value > 0)
+ p_stateCurrent = SURF_RESOURCE_ON;
+ else {
+ lmm_constraint_t cnst = p_constraint;
+ lmm_variable_t var = NULL;
+ lmm_element_t elem = NULL;
+
+ p_stateCurrent = SURF_RESOURCE_OFF;
+ while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, cnst, &elem))) {
+ ActionPtr action = (ActionPtr) lmm_variable_id(var);
+
+ if (action->getState() == SURF_ACTION_RUNNING ||
+ action->getState() == SURF_ACTION_READY) {
+ 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();
+ }
+
+ XBT_DEBUG
+ ("There were a resource state event, need to update actions related to the constraint (%p)",
+ p_constraint);
+ return;
+}
+
+/**********
+ * 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);
+}
+void NetworkCm02ActionLmm::recycle()
+{
+ return;
+}
+
--- /dev/null
- static random_data_t random_latency = NULL;
+#include "network_constant.hpp"
+#include "surf/random_mgr.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
- if (!random_latency)
- random_latency = random_new(RAND, 100, 0.0, 1.0, .125, .034);
-
+static int host_number_int = 0;
+
+static void netcste_count_hosts(sg_platf_host_cbarg_t h) {
+ host_number_int++;
+}
+
+/*********
+ * Model *
+ *********/
+void surf_network_model_init_Constant()
+{
+ xbt_assert(surf_network_model == NULL);
+ surf_network_model = new NetworkConstantModel();
+
+ sg_platf_host_add_cb(netcste_count_hosts);
+
+ ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+ xbt_dynar_push(model_list, &model);
+
+ routing_model_create(NULL);
+}
+
+double NetworkConstantModel::shareResources(double now)
+{
+ void *_action = NULL;
+ NetworkConstantActionLmmPtr action = NULL;
+ double min = -1.0;
+
+ xbt_swag_foreach(_action, p_runningActionSet) {
+ action = dynamic_cast<NetworkConstantActionLmmPtr>(static_cast<ActionPtr>(_action));
+ if (action->m_latency > 0) {
+ if (min < 0)
+ min = action->m_latency;
+ else if (action->m_latency < min)
+ min = action->m_latency;
+ }
+ }
+
+ return min;
+}
+
+void NetworkConstantModel::updateActionsState(double now, double delta)
+{
+ void *_action, *_next_action;
+ NetworkConstantActionLmmPtr action = NULL;
+
+ xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+ action = dynamic_cast<NetworkConstantActionLmmPtr>(static_cast<ActionPtr>(_action));
+ if (action->m_latency > 0) {
+ if (action->m_latency > delta) {
+ double_update(&(action->m_latency), delta);
+ } else {
+ action->m_latency = 0.0;
+ }
+ }
+ double_update(&(action->m_remains),
+ action->m_cost * delta / action->m_latInit);
+ if (action->m_maxDuration != NO_MAX_DURATION)
+ double_update(&(action->m_maxDuration), delta);
+
+ if (action->m_remains <= 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);
+ }
+ }
+}
+
+ActionPtr NetworkConstantModel::communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+ double size, double rate)
+{
+ char *src_name = src->p_name;
+ char *dst_name = dst->p_name;
+
+ XBT_IN("(%s,%s,%g,%g)", src_name, dst_name, size, rate);
+ NetworkConstantActionLmmPtr action = new NetworkConstantActionLmm(this, sg_latency_factor);
+ XBT_OUT();
+
+ return action;
+}
+
+/************
+ * Resource *
+ ************/
+bool NetworkConstantLinkLmm::isUsed()
+{
+ return 0;
+}
+
+void NetworkConstantLinkLmm::updateState(tmgr_trace_event_t event_type,
+ double value, double time)
+{
+ DIE_IMPOSSIBLE;
+}
+
+double NetworkConstantLinkLmm::getBandwidth()
+{
+ DIE_IMPOSSIBLE;
+ return -1.0; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */
+}
+
+double NetworkConstantLinkLmm::getLatency()
+{
+ DIE_IMPOSSIBLE;
+ return -1.0; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */
+}
+
+bool NetworkConstantLinkLmm::isShared()
+{
+ DIE_IMPOSSIBLE;
+ return -1; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */
+}
+
+/**********
+ * Action *
+ **********/
+
+int NetworkConstantActionLmm::unref()
+{
+ m_refcount--;
+ if (!m_refcount) {
+ xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+ delete this;
+ return 1;
+ }
+ return 0;
+}
+
+void NetworkConstantActionLmm::cancel()
+{
+ return;
+}
+
+#ifdef HAVE_TRACING
+void NetworkConstantActionLmm::setCategory(const char *category)
+{
+ //ignore completely the categories in constant model, they are not traced
+}
+#endif
+
+void NetworkConstantActionLmm::suspend()
+{
+ m_suspended = true;
+}
+
+void NetworkConstantActionLmm::resume()
+{
+ if (m_suspended)
+ m_suspended = false;
+}
+
+void NetworkConstantActionLmm::recycle()
+{
+ return;
+}
+
+bool NetworkConstantActionLmm::isSuspended()
+{
+ return m_suspended;
+}
+
--- /dev/null
- gap_lookup = xbt_dict_new();
+#include "network_smpi.hpp"
+#include "simgrid/sg_config.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
+
+xbt_dynar_t smpi_bw_factor = NULL;
+xbt_dynar_t smpi_lat_factor = NULL;
+
+typedef struct s_smpi_factor *smpi_factor_t;
+typedef struct s_smpi_factor {
+ long factor;
+ double value;
+} s_smpi_factor_t;
+
+xbt_dict_t gap_lookup = NULL;
+
+static int factor_cmp(const void *pa, const void *pb)
+{
+ return (((s_smpi_factor_t*)pa)->factor > ((s_smpi_factor_t*)pb)->factor);
+}
+
+
+static xbt_dynar_t parse_factor(const char *smpi_coef_string)
+{
+ char *value = NULL;
+ unsigned int iter = 0;
+ s_smpi_factor_t fact;
+ xbt_dynar_t smpi_factor, radical_elements, radical_elements2 = NULL;
+
+ smpi_factor = xbt_dynar_new(sizeof(s_smpi_factor_t), NULL);
+ radical_elements = xbt_str_split(smpi_coef_string, ";");
+ xbt_dynar_foreach(radical_elements, iter, value) {
+
+ radical_elements2 = xbt_str_split(value, ":");
+ if (xbt_dynar_length(radical_elements2) != 2)
+ xbt_die("Malformed radical for smpi factor!");
+ fact.factor = atol(xbt_dynar_get_as(radical_elements2, 0, char *));
+ fact.value = atof(xbt_dynar_get_as(radical_elements2, 1, char *));
+ xbt_dynar_push_as(smpi_factor, s_smpi_factor_t, fact);
+ XBT_DEBUG("smpi_factor:\t%ld : %f", fact.factor, fact.value);
+ xbt_dynar_free(&radical_elements2);
+ }
+ xbt_dynar_free(&radical_elements);
+ iter=0;
+ xbt_dynar_sort(smpi_factor, &factor_cmp);
+ xbt_dynar_foreach(smpi_factor, iter, fact) {
+ XBT_DEBUG("ordered smpi_factor:\t%ld : %f", fact.factor, fact.value);
+
+ }
+ return smpi_factor;
+}
+
+/*********
+ * Model *
+ *********/
+
+/************************************************************************/
+/* New model based on LV08 and experimental results of MPI ping-pongs */
+/************************************************************************/
+/* @Inproceedings{smpi_ipdps, */
+/* author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and Martin Quinson}, */
+/* title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */
+/* booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */
+/* address={Anchorage (Alaska) USA}, */
+/* month=may, */
+/* year={2011} */
+/* } */
+void surf_network_model_init_SMPI(void)
+{
+
+ if (surf_network_model)
+ return;
+ surf_network_model = new NetworkSmpiModel();
+ net_define_callbacks();
+ xbt_dynar_push(model_list, &surf_network_model);
+ //network_solve = lmm_solve;
+
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/sender_gap", 10e-6);
+ xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
+}
+
+void NetworkSmpiModel::gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action)
+{
+ const char *src = link->m_name;
+ xbt_fifo_t fifo;
+ //surf_action_network_CM02_t last_action;
+ //double bw;
+
+ if (sg_sender_gap > 0.0) {
+ if (!gap_lookup) {
- XBT_DEBUG("%lf <= %ld return %f", size, fact.factor, current);
++ gap_lookup = xbt_dict_new_homogeneous(NULL);
+ }
+ fifo = (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, src);
+ action->m_senderGap = 0.0;
+ if (fifo && xbt_fifo_size(fifo) > 0) {
+ /* Compute gap from last send */
+ /*last_action =
+ (surf_action_network_CM02_t)
+ xbt_fifo_get_item_content(xbt_fifo_get_last_item(fifo));*/
+ // bw = net_get_link_bandwidth(link);
+ action->m_senderGap = sg_sender_gap;
+ /* max(sg_sender_gap,last_action->sender.size / bw);*/
+ action->m_latency += action->m_senderGap;
+ }
+ /* Append action as last send */
+ /*action->sender.link_name = link->lmm_resource.generic_resource.name;
+ fifo =
+ (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup,
+ action->sender.link_name);
+ if (!fifo) {
+ fifo = xbt_fifo_new();
+ xbt_dict_set(gap_lookup, action->sender.link_name, fifo, NULL);
+ }
+ action->sender.fifo_item = xbt_fifo_push(fifo, action);*/
+ action->m_senderSize = size;
+ }
+}
+
+void NetworkSmpiModel::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);
+ }
+ }
+ }
+}
+
+double NetworkSmpiModel::bandwidthFactor(double size)
+{
+ if (!smpi_bw_factor)
+ smpi_bw_factor =
+ parse_factor(sg_cfg_get_string("smpi/bw_factor"));
+
+ unsigned int iter = 0;
+ s_smpi_factor_t fact;
+ double current=1.0;
+ xbt_dynar_foreach(smpi_bw_factor, iter, fact) {
+ if (size <= fact.factor) {
- XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current);
++ XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
+ return current;
+ }else
+ current=fact.value;
+ }
- XBT_DEBUG("%lf <= %ld return %f", size, fact.factor, current);
++ XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
+
+ return current;
+}
+double NetworkSmpiModel::latencyFactor(double size)
+{
+ if (!smpi_lat_factor)
+ smpi_lat_factor =
+ parse_factor(sg_cfg_get_string("smpi/lat_factor"));
+
+ unsigned int iter = 0;
+ s_smpi_factor_t fact;
+ double current=1.0;
+ xbt_dynar_foreach(smpi_lat_factor, iter, fact) {
+ if (size <= fact.factor) {
- XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current);
++ XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
+ return current;
+ }else
+ current=fact.value;
+ }
++ XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
+
+ return current;
+}
+
+double NetworkSmpiModel::bandwidthConstraint(double rate, double bound, double size)
+{
+ return rate < 0 ? bound : min(bound, rate * bandwidthFactor(size));
+}
+
+/************
+ * Resource *
+ ************/
+
+
+
+/**********
+ * Action *
+ **********/
--- /dev/null
- StoragePtr storage = (StoragePtr) r;
+#include "storage.hpp"
+#include "surf_private.h"
+
++#define __STDC_FORMAT_MACROS
++#include <inttypes.h>
++
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_storage, surf,
+ "Logging specific to the SURF storage module");
+}
+
+xbt_lib_t storage_lib;
+int ROUTING_STORAGE_LEVEL; //Routing for storagelevel
+int ROUTING_STORAGE_HOST_LEVEL;
+int SURF_STORAGE_LEVEL;
+xbt_lib_t storage_type_lib;
+int ROUTING_STORAGE_TYPE_LEVEL; //Routing for storage_type level
+
+static xbt_dynar_t storage_list;
+
+xbt_dynar_t mount_list = NULL; /* temporary store of current mount storage */
+StorageModelPtr surf_storage_model = NULL;
+
+static int storage_selective_update = 0;
+static xbt_swag_t storage_running_action_set_that_does_not_need_being_checked = NULL;
+
+/*************
+ * CallBacks *
+ *************/
+
+static XBT_INLINE void routing_storage_type_free(void *r)
+{
+ storage_type_t stype = (storage_type_t) r;
+ free(stype->model);
+ free(stype->type_id);
+ free(stype->content);
+ xbt_dict_free(&(stype->properties));
++ xbt_dict_free(&(stype->properties));
+ free(stype);
+}
+
+static XBT_INLINE void surf_storage_resource_free(void *r)
+{
+ // specific to storage
- XBT_DEBUG("For disk '%s' content is empty, use the content of storage type '%s'",storage->id,((storage_type_t) stype)->type_id);
++ StoragePtr storage = dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(r));
+ xbt_dict_free(&storage->p_content);
+ xbt_dynar_free(&storage->p_writeActions);
++ free(storage->p_typeId);
++ free(storage->p_contentType);
+ // generic resource
+ delete storage;
+}
+
+static XBT_INLINE void routing_storage_host_free(void *r)
+{
+ xbt_dynar_t dyn = (xbt_dynar_t) r;
+ xbt_dynar_free(&dyn);
+}
+
+static void parse_storage_init(sg_platf_storage_cbarg_t storage)
+{
+ void* stype = xbt_lib_get_or_null(storage_type_lib,
+ storage->type_id,
+ ROUTING_STORAGE_TYPE_LEVEL);
+ if(!stype) xbt_die("No storage type '%s'",storage->type_id);
+
+ // if storage content is not specified use the content of storage_type if exist
+ if(!strcmp(storage->content,"") && strcmp(((storage_type_t) stype)->content,"")){
+ storage->content = ((storage_type_t) stype)->content;
- XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' \n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tproperties '%p'\n",
++ storage->content_type = ((storage_type_t) stype)->content_type;
++ XBT_DEBUG("For disk '%s' content is empty, inherit the content (of type %s) from storage type '%s' ",
++ storage->id,((storage_type_t) stype)->content_type,
++ ((storage_type_t) stype)->type_id);
+ }
+
- storage->content);
++ XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' "
++ "\n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tcontent_type '%s' "
++ "\n\t\tproperties '%p'\n",
+ storage->id,
+ ((storage_type_t) stype)->model,
+ ((storage_type_t) stype)->type_id,
+ storage->content,
++ storage->content_type,
+ ((storage_type_t) stype)->properties);
+
+ surf_storage_model->createResource(storage->id, ((storage_type_t) stype)->model,
+ ((storage_type_t) stype)->type_id,
- static xbt_dict_t parse_storage_content(char *filename, size_t *used_size)
++ storage->content,
++ storage->content_type,
++ storage->properties);
+}
+
+static void parse_mstorage_init(sg_platf_mstorage_cbarg_t mstorage)
+{
+ XBT_DEBUG("parse_mstorage_init");
+}
+
+static void parse_storage_type_init(sg_platf_storage_type_cbarg_t storagetype_)
+{
+ XBT_DEBUG("parse_storage_type_init");
+}
+
+static void parse_mount_init(sg_platf_mount_cbarg_t mount)
+{
+ XBT_DEBUG("parse_mount_init");
+}
+
+static void storage_parse_storage(sg_platf_storage_cbarg_t storage)
+{
+ xbt_assert(!xbt_lib_get_or_null(storage_lib, storage->id,ROUTING_STORAGE_LEVEL),
+ "Reading a storage, processing unit \"%s\" already exists", storage->id);
+
+ // Verification of an existing type_id
+#ifndef NDEBUG
+ void* storage_type = xbt_lib_get_or_null(storage_type_lib, storage->type_id,ROUTING_STORAGE_TYPE_LEVEL);
+#endif
+ xbt_assert(storage_type,"Reading a storage, type id \"%s\" does not exists", storage->type_id);
+
+ XBT_DEBUG("ROUTING Create a storage name '%s' with type_id '%s' and content '%s'",
+ storage->id,
+ storage->type_id,
+ storage->content);
+
+ xbt_lib_set(storage_lib,
+ storage->id,
+ ROUTING_STORAGE_LEVEL,
+ (void *) xbt_strdup(storage->type_id));
+}
+
- xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL);
++static xbt_dict_t parse_storage_content(char *filename, sg_storage_size_t *used_size)
+{
+ *used_size = 0;
+ if ((!filename) || (strcmp(filename, "") == 0))
+ return NULL;
+
- size_t size;
++ xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free);
+ FILE *file = NULL;
+
+ file = surf_fopen(filename, "r");
+ xbt_assert(file != NULL, "Cannot open file '%s' (path=%s)", filename,
+ xbt_str_join(surf_path, ":"));
+
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read;
+ char path[1024];
- if(sscanf(line,"%s %zu",path, &size)==2) {
++ sg_storage_size_t size;
+
+
+ while ((read = xbt_getline(&line, &len, file)) != -1) {
+ if (read){
- xbt_dict_set(parse_content,path,(void*) size,NULL);
++ if(sscanf(line,"%s %" SCNu64, path, &size) == 2) {
+ *used_size += size;
- stype->size = storage_type->size * 1000000000; /* storage_type->size is in Gbytes and stype->sizeis in bytes */
++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
++ *psize = size;
++ xbt_dict_set(parse_content,path,psize,NULL);
+ } else {
+ xbt_die("Be sure of passing a good format for content file.\n");
+ }
+ }
+ }
+ free(line);
+ fclose(file);
+ return parse_content;
+}
+
+static void storage_parse_storage_type(sg_platf_storage_type_cbarg_t storage_type)
+{
+ xbt_assert(!xbt_lib_get_or_null(storage_type_lib, storage_type->id,ROUTING_STORAGE_TYPE_LEVEL),
+ "Reading a storage type, processing unit \"%s\" already exists", storage_type->id);
+
+ storage_type_t stype = xbt_new0(s_storage_type_t, 1);
+ stype->model = xbt_strdup(storage_type->model);
+ stype->properties = storage_type->properties;
+ stype->content = xbt_strdup(storage_type->content);
++ stype->content_type = xbt_strdup(storage_type->content_type);
+ stype->type_id = xbt_strdup(storage_type->id);
- XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s' content '%s'",
++ stype->size = storage_type->size;
+
- storage_type->content);
++ XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s', "
++ "content '%s', and content_type '%s'",
+ stype->type_id,
+ stype->model,
- void* storage = xbt_lib_get_or_null(storage_lib, mount->id,ROUTING_STORAGE_LEVEL);
++ storage_type->content,
++ storage_type->content_type);
+
+ xbt_lib_set(storage_type_lib,
+ stype->type_id,
+ ROUTING_STORAGE_TYPE_LEVEL,
+ (void *) stype);
+}
+static void storage_parse_mstorage(sg_platf_mstorage_cbarg_t mstorage)
+{
+ THROW_UNIMPLEMENTED;
+// mount_t mnt = xbt_new0(s_mount_t, 1);
+// mnt->id = xbt_strdup(mstorage->type_id);
+// mnt->name = xbt_strdup(mstorage->name);
+//
+// if(!mount_list){
+// XBT_DEBUG("Creata a Mount list for %s",A_surfxml_host_id);
+// mount_list = xbt_dynar_new(sizeof(char *), NULL);
+// }
+// xbt_dynar_push(mount_list,(void *) mnt);
+// free(mnt->id);
+// free(mnt->name);
+// xbt_free(mnt);
+// XBT_DEBUG("ROUTING Mount a storage name '%s' with type_id '%s'",mstorage->name, mstorage->id);
+}
+
+static void mount_free(void *p)
+{
+ mount_t mnt = (mount_t) p;
+ xbt_free(mnt->name);
+}
+
+static void storage_parse_mount(sg_platf_mount_cbarg_t mount)
+{
+ // Verification of an existing storage
+#ifndef NDEBUG
- xbt_assert(storage,"Disk id \"%s\" does not exists", mount->id);
++ void* storage = xbt_lib_get_or_null(storage_lib, mount->storageId, ROUTING_STORAGE_LEVEL);
+#endif
- XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->id, mount->name);
++ xbt_assert(storage,"Disk id \"%s\" does not exists", mount->storageId);
+
- mnt.id = surf_storage_resource_priv(surf_storage_resource_by_name(mount->id));
++ XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->storageId, mount->name);
+
+ s_mount_t mnt;
- StoragePtr StorageModel::createResource(const char* id, const char* model, const char* type_id, const char* content_name)
++ mnt.storage = surf_storage_resource_priv(surf_storage_resource_by_name(mount->storageId));
+ mnt.name = xbt_strdup(mount->name);
+
+ if(!mount_list){
+ //FIXME:XBT_DEBUG("Create a Mount list for %s",A_surfxml_host_id);
+ mount_list = xbt_dynar_new(sizeof(s_mount_t), mount_free);
+ }
+ xbt_dynar_push(mount_list,&mnt);
+}
+
+static void storage_define_callbacks()
+{
+ sg_platf_storage_add_cb(parse_storage_init);
+ sg_platf_storage_type_add_cb(parse_storage_type_init);
+ sg_platf_mstorage_add_cb(parse_mstorage_init);
+ sg_platf_mount_add_cb(parse_mount_init);
+}
+
+void storage_register_callbacks() {
+
+ ROUTING_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,xbt_free);
+ ROUTING_STORAGE_HOST_LEVEL = xbt_lib_add_level(storage_lib, routing_storage_host_free);
+ ROUTING_STORAGE_TYPE_LEVEL = xbt_lib_add_level(storage_type_lib, routing_storage_type_free);
+ SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib, surf_storage_resource_free);
+
+ sg_platf_storage_add_cb(storage_parse_storage);
+ sg_platf_mstorage_add_cb(storage_parse_mstorage);
+ sg_platf_storage_type_add_cb(storage_parse_storage_type);
+ sg_platf_mount_add_cb(storage_parse_mount);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_storage_model_init_default(void)
+{
+ surf_storage_model = new StorageModel();
+ storage_define_callbacks();
+ xbt_dynar_push(model_list, &surf_storage_model);
+}
+
+StorageModel::StorageModel() : Model("Storage") {
+ StorageActionLmm action;
+
+ XBT_DEBUG("surf_storage_model_init_internal");
+
+ storage_running_action_set_that_does_not_need_being_checked =
+ xbt_swag_new(xbt_swag_offset(action, p_stateHookup));
+
+ if (!p_maxminSystem) {
+ p_maxminSystem = lmm_system_new(storage_selective_update);
+ }
+}
+
+
+StorageModel::~StorageModel(){
+ lmm_system_free(p_maxminSystem);
+
+ surf_storage_model = NULL;
+
+ xbt_dynar_free(&storage_list);
+
+ xbt_swag_free(storage_running_action_set_that_does_not_need_being_checked);
+ storage_running_action_set_that_does_not_need_being_checked = NULL;
+}
+
- double Bread = atof((char*)xbt_dict_get(storage_type->properties, "Bread"));
- double Bwrite = atof((char*)xbt_dict_get(storage_type->properties, "Bwrite"));
- double Bconnection = atof((char*)xbt_dict_get(storage_type->properties, "Bconnection"));
++StoragePtr StorageModel::createResource(const char* id, const char* model, const char* type_id,
++ const char* content_name, const char* content_type, xbt_dict_t properties)
+{
+
+ xbt_assert(!surf_storage_resource_priv(surf_storage_resource_by_name(id)),
+ "Storage '%s' declared several times in the platform file",
+ id);
+
+ storage_type_t storage_type = (storage_type_t) xbt_lib_get_or_null(storage_type_lib, type_id,ROUTING_STORAGE_TYPE_LEVEL);
+
- StoragePtr storage = new StorageLmm(this, NULL, NULL, p_maxminSystem,
- Bread, Bwrite, Bconnection, (char *)content_name, storage_type->size);
++ double Bread = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bread"));
++ double Bwrite = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bwrite"));
++ double Bconnection = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bconnection"));
+
- xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, storage);
++ StoragePtr storage = new StorageLmm(this, id, properties, p_maxminSystem,
++ Bread, Bwrite, Bconnection,
++ type_id, (char *)content_name, xbt_strdup(content_type), storage_type->size);
+
- if(!storage_list) storage_list=xbt_dynar_new(sizeof(char *),NULL);
++ xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, static_cast<ResourcePtr>(storage));
+
+ XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' \n\t\tmodel '%s' \n\t\tproperties '%p'\n\t\tBread '%f'\n",
+ id,
+ model,
+ type_id,
+ storage_type->properties,
+ Bread);
+
- // Update the disk usage
- // Update the file size
- // For each action of type write
++ if(!storage_list)
++ storage_list = xbt_dynar_new(sizeof(char *),NULL);
+ xbt_dynar_push(storage_list, &storage);
+
+ return storage;
+}
+
+double StorageModel::shareResources(double now)
+{
+ XBT_DEBUG("storage_share_resources %f", now);
+ unsigned int i, j;
+ StoragePtr storage;
+ StorageActionLmmPtr write_action;
+
+ double min_completion = shareResourcesMaxMin(p_runningActionSet,
+ p_maxminSystem, lmm_solve);
+
+ double rate;
+ // Foreach disk
+ xbt_dynar_foreach(storage_list,i,storage)
+ {
+ rate = 0;
+ // Foreach write action on disk
+ xbt_dynar_foreach(storage->p_writeActions, j, write_action)
+ {
+ rate += lmm_variable_getvalue(write_action->p_variable);
+ }
+ if(rate > 0)
+ min_completion = MIN(min_completion, (storage->m_size-storage->m_usedSize)/rate);
+ }
+
+ return min_completion;
+}
+
+void StorageModel::updateActionsState(double now, double delta)
+{
+ void *_action, *_next_action;
+ StorageActionLmmPtr action = NULL;
+
- * (note that the next sizes are of type size_t). */
+ xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+ action = dynamic_cast<StorageActionLmmPtr>(static_cast<ActionPtr>(_action));
+ if(action->m_type == WRITE)
+ {
++ // Update the disk usage
++ // Update the file size
++ // For each action of type write
+ double rate = lmm_variable_getvalue(action->p_variable);
+ /* Hack to avoid rounding differences between x86 and x86_64
- }
- }
++ * (note that the next sizes are of type sg_storage_size_t). */
+ long incr = delta * rate + MAXMIN_PRECISION;
+ action->p_storage->m_usedSize += incr; // disk usage
+ action->p_file->size += incr; // file size
- xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
- action = dynamic_cast<StorageActionLmmPtr>(static_cast<ActionPtr>(_action));
+
- xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL);
++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t,1);
++ *psize = action->p_file->size;
++
++ xbt_dict_t content_dict = action->p_storage->p_content;
++ xbt_dict_set(content_dict, action->p_file->name, psize, NULL);
++ }
+
+ 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->p_storage->m_usedSize == action->p_storage->m_size)
+ {
+ action->m_finish = surf_get_clock();
+ action->setState(SURF_ACTION_FAILED);
+ } else 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;
+}
+
+xbt_dict_t Storage::parseContent(char *filename)
+{
+ m_usedSize = 0;
+ if ((!filename) || (strcmp(filename, "") == 0))
+ return NULL;
+
- size_t size;
++ xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free);
+ FILE *file = NULL;
+
+ file = surf_fopen(filename, "r");
+ xbt_assert(file != NULL, "Cannot open file '%s' (path=%s)", filename,
+ xbt_str_join(surf_path, ":"));
+
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read;
+ char path[1024];
- if(sscanf(line,"%s %zu",path, &size)==2) {
++ sg_storage_size_t size;
+
+
+ while ((read = xbt_getline(&line, &len, file)) != -1) {
+ if (read){
- xbt_dict_set(parse_content,path,(void*) size,NULL);
++ if(sscanf(line,"%s %" SCNu64, path, &size) == 2) {
+ m_usedSize += size;
- char *content_name, size_t size)
++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
++ *psize = size;
++ xbt_dict_set(parse_content,path,psize,NULL);
+ } else {
+ xbt_die("Be sure of passing a good format for content file.\n");
+ }
+ }
+ }
+ free(line);
+ fclose(file);
+ return parse_content;
+}
+
+/************
+ * Resource *
+ ************/
+
+Storage::Storage(StorageModelPtr model, const char* name, xbt_dict_t properties)
+: Resource(model, name, properties)
+{
+ p_writeActions = xbt_dynar_new(sizeof(char *),NULL);
+}
+
+StorageLmm::StorageLmm(StorageModelPtr model, const char* name, xbt_dict_t properties,
+ lmm_system_t maxminSystem, double bread, double bwrite, double bconnection,
- xbt_dict_t ls_dict = xbt_dict_new();
++ const char* type_id, char *content_name, char *content_type, size_t size)
+ : Resource(model, name, properties), ResourceLmm(), Storage(model, name, properties) {
+ XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%lu'", bconnection, bread, bwrite, ((unsigned long)size));
+
+ p_stateCurrent = SURF_RESOURCE_ON;
+ m_usedSize = 0;
+ m_size = 0;
+
+ p_content = parseContent(content_name);
++ p_contentType = content_type;
+ p_constraint = lmm_constraint_new(maxminSystem, this, bconnection);
+ p_constraintRead = lmm_constraint_new(maxminSystem, this, bread);
+ p_constraintWrite = lmm_constraint_new(maxminSystem, this, bwrite);
+ m_size = size;
++ p_typeId = xbt_strdup(type_id);
+}
+
+bool Storage::isUsed()
+{
+ THROW_UNIMPLEMENTED;
+ return false;
+}
+
+void Storage::updateState(tmgr_trace_event_t event_type, double value, double date)
+{
+ THROW_UNIMPLEMENTED;
+}
+
+StorageActionPtr StorageLmm::ls(const char* path)
+{
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, LS);
+
+ action->p_lsDict = NULL;
- size_t size = 0;
++ xbt_dict_t ls_dict = xbt_dict_new_homogeneous(xbt_free);
+
+ char* key;
- xbt_dict_set(ls_dict,file,&size,NULL);
++ sg_storage_size_t size = 0;
+ xbt_dict_cursor_t cursor = NULL;
+
+ xbt_dynar_t dyn = NULL;
+ char* file = NULL;
+
+ // for each file in the storage content
+ xbt_dict_foreach(p_content,cursor,key,size){
+ // Search if file start with the prefix 'path'
+ if(xbt_str_start_with(key,path)){
+ file = &key[strlen(path)];
+
+ // Split file with '/'
+ dyn = xbt_str_split(file,"/");
+ file = xbt_dynar_get_as(dyn,0,char*);
+
+ // file
+ if(xbt_dynar_length(dyn) == 1){
- size_t size = (size_t) xbt_dict_get_or_null(p_content, path);
++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
++ *psize=size;
++ xbt_dict_set(ls_dict, file, psize, NULL);
+ }
+ // Directory
+ else
+ {
+ // if directory does not exist yet in the dictionary
+ if(!xbt_dict_get_or_null(ls_dict,file))
+ xbt_dict_set(ls_dict,file,NULL,NULL);
+ }
+ xbt_dynar_free(&dyn);
+ }
+ }
+
+ action->p_lsDict = ls_dict;
+ return action;
+}
+
+StorageActionPtr StorageLmm::open(const char* mount, const char* path)
+{
+ XBT_DEBUG("\tOpen file '%s'",path);
- if(!size){
- xbt_dict_set(p_content, path, &size, NULL);
++ sg_storage_size_t size, *psize;
++ psize = (sg_storage_size_t*) xbt_dict_get_or_null(p_content, path);
+ // if file does not exist create an empty file
- file->storage = xbt_strdup(mount);
++ if(psize)
++ size = *psize;
++ else {
++ psize = xbt_new(sg_storage_size_t,1);
++ size = 0;
++ *psize = size;
++ xbt_dict_set(p_content, path, psize, NULL);
+ XBT_DEBUG("File '%s' was not found, file created.",path);
+ }
+ surf_file_t file = xbt_new0(s_surf_file_t,1);
+ file->name = xbt_strdup(path);
+ file->size = size;
- XBT_DEBUG("\tClose file '%s' size '%zu'", filename, fd->size);
++ file->mount = xbt_strdup(mount);
+
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, OPEN);
+ action->p_file = file;
+ return action;
+}
+
+StorageActionPtr StorageLmm::close(surf_file_t fd)
+{
+ char *filename = fd->name;
- free(fd->storage);
++ XBT_DEBUG("\tClose file '%s' size '%" PRIu64 "'", filename, fd->size);
+ // unref write actions from storage
+ StorageActionLmmPtr write_action;
+ unsigned int i;
+ xbt_dynar_foreach(p_writeActions, i, write_action) {
+ if ((write_action->p_file) == fd) {
+ xbt_dynar_cursor_rm(p_writeActions, &i);
+ write_action->unref();
+ }
+ }
+ free(fd->name);
- StorageActionPtr StorageLmm::read(void* ptr, size_t size, surf_file_t fd)
++ free(fd->mount);
+ xbt_free(fd);
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, CLOSE);
+ return action;
+}
+
- StorageActionPtr StorageLmm::write(const void* ptr, size_t size, surf_file_t fd)
++StorageActionPtr StorageLmm::read(surf_file_t fd, sg_storage_size_t size)
+{
+ if(size > fd->size)
+ size = fd->size;
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, size, p_stateCurrent != SURF_RESOURCE_ON, this, READ);
+ return action;
+}
+
- XBT_DEBUG("\tWrite file '%s' size '%zu/%zu'",filename,size,fd->size);
++StorageActionPtr StorageLmm::write(surf_file_t fd, sg_storage_size_t size)
+{
+ char *filename = fd->name;
- XBT_IN("(%s,%zu", storage->m_name, cost);
++ XBT_DEBUG("\tWrite file '%s' size '%" PRIu64 "/%" PRIu64 "'",filename,size,fd->size);
+
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, size, p_stateCurrent != SURF_RESOURCE_ON, this, WRITE);
+ action->p_file = fd;
+
+ // If the storage is full
+ if(m_usedSize==m_size) {
+ action->setState(SURF_ACTION_FAILED);
+ }
+ return action;
+}
+
++xbt_dict_t StorageLmm::getContent()
++{
++ /* For the moment this action has no cost, but in the future we could take in account access latency of the disk */
++ /*surf_action_t action = storage_action_execute(storage,0, LS);*/
++
++ xbt_dict_t content_dict = xbt_dict_new_homogeneous(NULL);
++ xbt_dict_cursor_t cursor = NULL;
++ char *file;
++ sg_storage_size_t *psize;
++
++ xbt_dict_foreach(p_content, cursor, file, psize){
++ xbt_dict_set(content_dict,file,psize,NULL);
++ }
++ return content_dict;
++}
++
++sg_storage_size_t StorageLmm::getSize(){
++ return m_size;
++}
++
+/**********
+ * Action *
+ **********/
+
+StorageActionLmm::StorageActionLmm(ModelPtr model, double cost, bool failed, StorageLmmPtr storage, e_surf_action_storage_type_t type)
+ : Action(model, cost, failed), ActionLmm(model, cost, failed), StorageAction(model, cost, failed, storage, type) {
++ XBT_IN("(%s,%" PRIu64, storage->m_name, cost);
+ p_variable = lmm_variable_new(p_model->p_maxminSystem, this, 1.0, -1.0 , 3);
+
+ // Must be less than the max bandwidth for all actions
+ lmm_expand(p_model->p_maxminSystem, storage->p_constraint, p_variable, 1.0);
+ switch(type) {
+ case OPEN:
+ case CLOSE:
+ case STAT:
+ case LS:
+ break;
+ case READ:
+ lmm_expand(p_model->p_maxminSystem, storage->p_constraintRead,
+ p_variable, 1.0);
+ break;
+ case WRITE:
+ lmm_expand(p_model->p_maxminSystem, storage->p_constraintWrite,
+ p_variable, 1.0);
+ xbt_dynar_push(storage->p_writeActions, static_cast<ActionPtr>(this));
+ break;
+ }
+ XBT_OUT();
+}
+
+int StorageActionLmm::unref()
+{
+ m_refcount--;
+ if (!m_refcount) {
+ xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+ if (p_variable)
+ lmm_variable_free(p_model->p_maxminSystem, p_variable);
+#ifdef HAVE_TRACING
+ xbt_free(p_category);
+#endif
+ delete this;
+ return 1;
+ }
+ return 0;
+}
+
+void StorageActionLmm::cancel()
+{
+ setState(SURF_ACTION_FAILED);
+ return;
+}
+
+void StorageActionLmm::suspend()
+{
+ XBT_IN("(%p)", this);
+ if (m_suspended != 2) {
+ lmm_update_variable_weight(p_model->p_maxminSystem,
+ p_variable,
+ 0.0);
+ m_suspended = 1;
+ }
+ XBT_OUT();
+}
+
+void StorageActionLmm::resume()
+{
+ THROW_UNIMPLEMENTED;
+}
+
+bool StorageActionLmm::isSuspended()
+{
+ return m_suspended == 1;
+}
+
+void StorageActionLmm::setMaxDuration(double duration)
+{
+ THROW_UNIMPLEMENTED;
+}
+
+void StorageActionLmm::setPriority(double priority)
+{
+ THROW_UNIMPLEMENTED;
+}
+
--- /dev/null
- StoragePtr createResource(const char* id, const char* model, const char* type_id, const char* content_name);
+#include "surf.hpp"
+
+#ifndef STORAGE_HPP_
+#define STORAGE_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class StorageModel;
+typedef StorageModel *StorageModelPtr;
+
+class Storage;
+typedef Storage *StoragePtr;
+
+class StorageLmm;
+typedef StorageLmm *StorageLmmPtr;
+
+class StorageAction;
+typedef StorageAction *StorageActionPtr;
+
+class StorageActionLmm;
+typedef StorageActionLmm *StorageActionLmmPtr;
+
+
+/*********
+ * Model *
+ *********/
+class StorageModel : public Model {
+public:
+ StorageModel();
+ ~StorageModel();
- xbt_dict_t p_content; /* char * -> s_surf_file_t */
++ StoragePtr createResource(const char* id, const char* model, const char* type_id,
++ const char* content_name, const char* content_type, xbt_dict_t properties);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+
+};
+
+/************
+ * Resource *
+ ************/
+
+class Storage : virtual public Resource {
+public:
+ Storage(StorageModelPtr model, const char* name, xbt_dict_t properties);
+
+ bool isUsed();
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+
- //virtual size_t getSize(surf_file_t fd);
- virtual StorageActionPtr read(void* ptr, size_t size, surf_file_t fd)=0;//FIXME:why we have a useless param ptr ??
- virtual StorageActionPtr write(const void* ptr, size_t size, surf_file_t fd)=0;//FIXME:why we have a useless param ptr ??
++ xbt_dict_t p_content;
++ char* p_contentType;
++ sg_storage_size_t m_size;
++ sg_storage_size_t m_usedSize;
++ char * p_typeId;
+
+ virtual StorageActionPtr open(const char* mount, const char* path)=0;
+ virtual StorageActionPtr close(surf_file_t fd)=0;
+ //virtual StorageActionPtr unlink(surf_file_t fd)=0;
+ virtual StorageActionPtr ls(const char *path)=0;
- size_t m_size;
- size_t m_usedSize;
++ virtual StorageActionPtr read(surf_file_t fd, sg_storage_size_t size)=0;
++ virtual StorageActionPtr write(surf_file_t fd, sg_storage_size_t size)=0;
++ virtual xbt_dict_t getContent()=0;
++ virtual sg_storage_size_t getSize()=0;
++
+ xbt_dict_t parseContent(char *filename);
+
- char *content_name, size_t size);
+ xbt_dynar_t p_writeActions;
+};
+
+class StorageLmm : public ResourceLmm, public Storage {
+public:
+ StorageLmm(StorageModelPtr model, const char* name, xbt_dict_t properties,
+ lmm_system_t maxminSystem, double bread, double bwrite, double bconnection,
- //size_t getSize(surf_file_t fd);
- StorageActionPtr read(void* ptr, size_t size, surf_file_t fd);//FIXME:why we have a useless param ptr ??
- StorageActionPtr write(const void* ptr, size_t size, surf_file_t fd);//FIXME:why we have a useless param ptr ??
++ const char* type_id, char *content_name, char *content_type, size_t size);
+
+ StorageActionPtr open(const char* mount, const char* path);
+ StorageActionPtr close(surf_file_t fd);
+ //StorageActionPtr unlink(surf_file_t fd);
+ StorageActionPtr ls(const char *path);
- size_t size;
++ xbt_dict_t getContent();
++ sg_storage_size_t getSize();
++ StorageActionPtr read(surf_file_t fd, sg_storage_size_t size);//FIXME:why we have a useless param ptr ??
++ StorageActionPtr write(surf_file_t fd, sg_storage_size_t size);//FIXME:why we have a useless param ptr ??
+
+ lmm_constraint_t p_constraintWrite; /* Constraint for maximum write bandwidth*/
+ lmm_constraint_t p_constraintRead; /* Constraint for maximum write bandwidth*/
+};
+
+/**********
+ * Action *
+ **********/
+
+typedef enum {
+ READ=0, WRITE, STAT, OPEN, CLOSE, LS
+} e_surf_action_storage_type_t;
+
+
+class StorageAction : virtual public Action {
+public:
+ StorageAction(){};
+ StorageAction(ModelPtr model, double cost, bool failed, StoragePtr storage, e_surf_action_storage_type_t type)
+ : p_storage(storage), m_type(type) {};
+
+
+
+ e_surf_action_storage_type_t m_type;
+ StoragePtr p_storage;
+ surf_file_t p_file;
+ xbt_dict_t p_lsDict;
+};
+
+class StorageActionLmm : public ActionLmm, public StorageAction {
+public:
+ StorageActionLmm(){};
+ StorageActionLmm(ModelPtr model, double cost, bool failed, StorageLmmPtr storage, e_surf_action_storage_type_t type);
+ void suspend();
+ int unref();
+ void cancel();
+ //FIXME:??void recycle();
+ void resume();
+ bool isSuspended();
+ void setMaxDuration(double duration);
+ void setPriority(double priority);
+
+};
+
+
+typedef struct s_storage_type {
+ char *model;
+ char *content;
++ char *content_type;
+ char *type_id;
+ xbt_dict_t properties;
- void *id;
++ sg_storage_size_t size;
+} s_storage_type_t, *storage_type_t;
+
+typedef struct s_mount {
- char *storage;
- size_t size;
++ void *storage;
+ char *name;
+} s_mount_t, *mount_t;
+
+typedef struct surf_file {
+ char *name;
++ char *mount;
++ sg_storage_size_t size;
+} s_surf_file_t;
+
+
+#endif /* STORAGE_HPP_ */
typedef struct surf_file {
char *name;
- char *storage;
- size_t size;
+ char *mount;
+ sg_storage_size_t size;
} s_surf_file_t;
++<<<<<<< HEAD
+typedef struct storage {
+ //FIXME:s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */
++||||||| merged common ancestors
++typedef struct storage {
++ s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */
++=======
+ typedef struct surf_storage {
+ s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */
++>>>>>>> 045db1657e870c721be490b411868f4181a12ced
e_surf_resource_state_t state_current; /*< STORAGE current state (ON or OFF) */
lmm_constraint_t constraint; /* Constraint for maximum bandwidth from connection */
lmm_constraint_t constraint_write; /* Constraint for maximum write bandwidth*/
--- /dev/null
- void surf_watched_hosts(void)
+#include "surf_private.h"
+#include "surf.hpp"
+#include "network.hpp"
+#include "cpu.hpp"
+#include "workstation.hpp"
+#include "simix/smx_host_private.h"
+#include "surf_routing.hpp"
+#include "simgrid/sg_config.h"
+#include "mc/mc.h"
+
+extern "C" {
+XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
+ "Logging specific to SURF (kernel)");
+}
+
+/*********
+ * Utils *
+ *********/
+
+/* This function is a pimple that we ought to fix. But it won't be easy.
+ *
+ * The surf_solve() function does properly return the set of actions that changed.
+ * Instead, each model change a global data, and then the caller of surf_solve must
+ * pick into these sets of action_failed and action_done.
+ *
+ * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
+ * We worked by putting sentinel actions on every resources we are interested in,
+ * so that surf informs us if/when the corresponding resource fails.
+ *
+ * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
+ * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
+ * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
+ * that was turned back up in the meanwhile. This is UGLY and slow.
+ *
+ * The proper solution would be to not rely on globals for the action_failed and action_done swags.
+ * They must be passed as parameter by the caller (the handling of these actions in simix may let you
+ * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
+ * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
+ * cleanup to do).
+ *
+ * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
+ * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
+ * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
+ * sees it and react accordingly. This would kill that need for surf to call simix.
+ *
+ */
+
+static void remove_watched_host(void *key)
+{
+ xbt_dict_remove(watched_hosts_lib, *(char**)key);
+}
+
- }
++/*void surf_watched_hosts(void)
+{
+ char *key;
+ void *host;
+ xbt_dict_cursor_t cursor;
+ xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
+
+ XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
+ xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
+ {
+ if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
+ XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
+ SIMIX_host_autorestart((smx_host_t)host);
+ xbt_dynar_push_as(hosts, char*, key);
+ }
+ else
+ XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
+ }
+ xbt_dynar_map(hosts, remove_watched_host);
+ xbt_dynar_free(&hosts);
- /*TODO: keepit void surf_watched_hosts(void)
- {
- char *key;
- void *_host;
- smx_host_t host;
- xbt_dict_cursor_t cursor;
- xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
-
- XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
- xbt_dict_foreach(watched_hosts_lib,cursor,key,_host)
- {
- host = (smx_host_t) host;
- if(SIMIX_host_get_state(host) == SURF_RESOURCE_ON){
- XBT_INFO("Restart processes on host: %s",SIMIX_host_get_name(host));
- SIMIX_host_autorestart(host);
- xbt_dynar_push_as(hosts, char*, key);
- }
- else
- XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
- }
- xbt_dynar_map(hosts, remove_watched_host);
- xbt_dynar_free(&hosts);
- }*/
-
++}*/
+
+
+xbt_dynar_t model_list = NULL;
+tmgr_history_t history = NULL;
+lmm_system_t maxmin_system = NULL;
+xbt_dynar_t surf_path = NULL;
++xbt_dynar_t host_that_restart = NULL;
++xbt_dict_t watched_hosts_lib;
+
+/* Don't forget to update the option description in smx_config when you change this */
+s_surf_model_description_t surf_network_model_description[] = {
+ {"LV08",
+ "Realistic network analytic model (slow-start modeled by multiplying latency by 10.4, bandwidth by .92; bottleneck sharing uses a payload of S=8775 for evaluating RTT). ",
+ surf_network_model_init_LegrandVelho},
+ {"Constant",
+ "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
+ surf_network_model_init_Constant},
+ {"SMPI",
+ "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
+ surf_network_model_init_SMPI},
+ {"CM02",
+ "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
+ surf_network_model_init_CM02},
+#ifdef HAVE_GTNETS
+ {"GTNets",
+ "Network pseudo-model using the GTNets simulator instead of an analytic model",
+ surf_network_model_init_GTNETS},
+#endif
+#ifdef HAVE_NS3
+ {"NS3",
+ "Network pseudo-model using the NS3 tcp model instead of an analytic model",
+ surf_network_model_init_NS3},
+#endif
+ {"Reno",
+ "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
+ surf_network_model_init_Reno},
+ {"Reno2",
+ "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
+ surf_network_model_init_Reno2},
+ {"Vegas",
+ "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
+ surf_network_model_init_Vegas},
+ {NULL, NULL, NULL} /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_cpu_model_description[] = {
+ {"Cas01",
+ "Simplistic CPU model (time=size/power).",
+ surf_cpu_model_init_Cas01},
+ {NULL, NULL, NULL} /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_workstation_model_description[] = {
+ {"default",
+ "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
+ surf_workstation_model_init_current_default},
+ {"compound",
+ "Workstation model that is automatically chosen if you change the network and CPU models",
+ surf_workstation_model_init_compound},
+ {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
+ surf_workstation_model_init_ptask_L07},
+ {NULL, NULL, NULL} /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_optimization_mode_description[] = {
+ {"Lazy",
+ "Lazy action management (partial invalidation in lmm + heap in action remaining).",
+ NULL},
+ {"TI",
+ "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
+ NULL},
+ {"Full",
+ "Full update of remaining and variables. Slow but may be useful when debugging.",
+ NULL},
+ {NULL, NULL, NULL} /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_storage_model_description[] = {
+ {"default",
+ "Simplistic storage model.",
+ surf_storage_model_init_default},
+ {NULL, NULL, NULL} /* this array must be NULL terminated */
+};
+
+#ifdef CONTEXT_THREADS
+static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
+#endif
+
+static double *surf_mins = NULL; /* return value of share_resources for each model */
+static int surf_min_index; /* current index in surf_mins */
+static double min; /* duration determined by surf_solve */
+
+double NOW = 0;
+
+double surf_get_clock(void)
+{
+ return NOW;
+}
+
- watched_hosts_lib = xbt_dict_new();
+#ifdef _XBT_WIN32
+# define FILE_DELIM "\\"
+#else
+# define FILE_DELIM "/" /* FIXME: move to better location */
+#endif
+
+FILE *surf_fopen(const char *name, const char *mode)
+{
+ unsigned int cpt;
+ char *path_elm = NULL;
+ char *buff;
+ FILE *file = NULL;
+
+ xbt_assert(name);
+
+ if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
+ return fopen(name, mode);
+
+ /* search relative files in the path */
+ xbt_dynar_foreach(surf_path, cpt, path_elm) {
+ buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
+ file = fopen(buff, mode);
+ free(buff);
+
+ if (file)
+ return file;
+ }
+ return NULL;
+}
+
+/*
+ * Returns the initial path. On Windows the initial path is
+ * the current directory for the current process in the other
+ * case the function returns "./" that represents the current
+ * directory on Unix/Linux platforms.
+ */
+
+const char *__surf_get_initial_path(void)
+{
+
+#ifdef _XBT_WIN32
+ unsigned i;
+ char current_directory[MAX_PATH + 1] = { 0 };
+ unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
+ char root[4] = { 0 };
+
+ if (!len)
+ return NULL;
+
+ strncpy(root, current_directory, 3);
+
+ for (i = 0; i < MAX_DRIVE; i++) {
+ if (toupper(root[0]) == disk_drives_letter_table[i][0])
+ return disk_drives_letter_table[i];
+ }
+
+ return NULL;
+#else
+ return "./";
+#endif
+}
+
+/* The __surf_is_absolute_file_path() returns 1 if
+ * file_path is a absolute file path, in the other
+ * case the function returns 0.
+ */
+int __surf_is_absolute_file_path(const char *file_path)
+{
+#ifdef _XBT_WIN32
+ WIN32_FIND_DATA wfd = { 0 };
+ HANDLE hFile = FindFirstFile(file_path, &wfd);
+
+ if (INVALID_HANDLE_VALUE == hFile)
+ return 0;
+
+ FindClose(hFile);
+ return 1;
+#else
+ return (file_path[0] == '/');
+#endif
+}
+
+/** Displays the long description of all registered models, and quit */
+void model_help(const char *category, s_surf_model_description_t * table)
+{
+ int i;
+ printf("Long description of the %s models accepted by this simulator:\n",
+ category);
+ for (i = 0; table[i].name; i++)
+ printf(" %s: %s\n", table[i].name, table[i].description);
+}
+
+int find_model_description(s_surf_model_description_t * table,
+ const char *name)
+{
+ int i;
+ char *name_list = NULL;
+
+ for (i = 0; table[i].name; i++)
+ if (!strcmp(name, table[i].name)) {
+ return i;
+ }
+ name_list = strdup(table[0].name);
+ for (i = 1; table[i].name; i++) {
+ name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
+ strcat(name_list, ", ");
+ strcat(name_list, table[i].name);
+ }
+ xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
+ return -1;
+}
+
+static XBT_INLINE void routing_asr_host_free(void *p)
+{
+ delete ((RoutingEdgePtr) p);
+}
+
+static XBT_INLINE void routing_asr_prop_free(void *p)
+{
+ xbt_dict_t elm = (xbt_dict_t) p;
+ xbt_dict_free(&elm);
+}
+
+static XBT_INLINE void surf_cpu_free(void *r)
+{
+ delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
+}
+
+static XBT_INLINE void surf_link_free(void *r)
+{
+ delete dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(r));
+}
+
+static XBT_INLINE void surf_workstation_free(void *r)
+{
+ delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
+}
+
+
+void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
+ *ver_major = SIMGRID_VERSION_MAJOR;
+ *ver_minor = SIMGRID_VERSION_MINOR;
+ *ver_patch = SIMGRID_VERSION_PATCH;
+}
+
+void surf_init(int *argc, char **argv)
+{
+ XBT_DEBUG("Create all Libs");
+ host_lib = xbt_lib_new();
+ link_lib = xbt_lib_new();
+ as_router_lib = xbt_lib_new();
+ storage_lib = xbt_lib_new();
+ storage_type_lib = xbt_lib_new();
-
++ watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
+
+ XBT_DEBUG("Add routing levels");
+ ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
+ ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
+ ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
+
+ XBT_DEBUG("Add SURF levels");
+ SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
+ SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
+ SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
+
+ xbt_init(argc, argv);
+ if (!model_list)
+ model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
+ if (!history)
+ history = tmgr_history_new();
+
+#ifdef HAVE_TRACING
+ TRACE_add_start_function(TRACE_surf_alloc);
+ TRACE_add_end_function(TRACE_surf_release);
+#endif
+
+ sg_config_init(argc, argv);
+
+ surf_action_init();
+ if (MC_is_active())
+ MC_memory_init();
+}
+
+void surf_exit(void)
+{
+ unsigned int iter;
+ ModelPtr model = NULL;
+
++#ifdef HAVE_TRACING
++ TRACE_end(); /* Just in case it was not called by the upper
++ * layer (or there is no upper layer) */
++#endif
++
+ sg_config_finalize();
+
+ xbt_dynar_foreach(model_list, iter, model)
+ delete model;
+ xbt_dynar_free(&model_list);
+ routing_exit();
+
+ if (maxmin_system) {
+ lmm_system_free(maxmin_system);
+ maxmin_system = NULL;
+ }
+ if (history) {
+ tmgr_history_free(history);
+ history = NULL;
+ }
+ surf_action_exit();
+
+#ifdef CONTEXT_THREADS
+ xbt_parmap_destroy(surf_parmap);
+ xbt_free(surf_mins);
+ surf_mins = NULL;
+#endif
- XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate);
++ xbt_dynar_free(&host_that_restart);
+ xbt_dynar_free(&surf_path);
+
+ xbt_lib_free(&host_lib);
+ xbt_lib_free(&link_lib);
+ xbt_lib_free(&as_router_lib);
+ xbt_lib_free(&storage_lib);
+ xbt_lib_free(&storage_type_lib);
+
+ xbt_dict_free(&watched_hosts_lib);
+
+ tmgr_finalize();
+ surf_parse_lex_destroy();
+ surf_parse_free_callbacks();
+
+ NOW = 0; /* Just in case the user plans to restart the simulation afterward */
+}
+/*********
+ * Model *
+ *********/
+
+Model::Model(string name)
+ : m_name(name), m_resOnCB(0), m_resOffCB(0),
+ m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
+ p_maxminSystem(0)
+{
+ ActionPtr action;
+ p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+ p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+ p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+ p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+
+ p_modifiedSet = NULL;
+ p_actionHeap = NULL;
+ p_updateMechanism = UM_UNDEFINED;
+ m_selectiveUpdate = 0;
+}
+
+Model::~Model(){
+xbt_swag_free(p_readyActionSet);
+xbt_swag_free(p_runningActionSet);
+xbt_swag_free(p_failedActionSet);
+xbt_swag_free(p_doneActionSet);
+}
+
+double Model::shareResources(double now)
+{
+ //FIXME: set the good function once and for all
+ if (p_updateMechanism == UM_LAZY)
+ return shareResourcesLazy(now);
+ else if (p_updateMechanism == UM_FULL)
+ return shareResourcesFull(now);
+ else
+ xbt_die("Invalid cpu update mechanism!");
+}
+
+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 = static_cast<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(double now) {
+ THROW_UNIMPLEMENTED;
+}
+
+
+double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
+ lmm_system_t sys,
+ void (*solve) (lmm_system_t))
+{
+ void *_action = NULL;
+ ActionLmmPtr action = NULL;
+ double min = -1;
+ double value = -1;
+
+ solve(sys);
+
+ xbt_swag_foreach(_action, running_actions) {
+ action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
+ value = lmm_variable_getvalue(action->p_variable);
+ 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 = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
+ _action;
+ _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
+ action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
+ value = lmm_variable_getvalue(action->p_variable);
+ 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);
+
+ return min;
+}
+
+void Model::updateActionsState(double now, double delta)
+{
+ if (p_updateMechanism == UM_FULL)
+ updateActionsStateFull(now, delta);
+ else if (p_updateMechanism == UM_LAZY)
+ updateActionsStateLazy(now, delta);
+ else
+ xbt_die("Invalid cpu update mechanism!");
+}
+
+void Model::updateActionsStateLazy(double now, double delta)
+{
+
+}
+
+void Model::updateActionsStateFull(double now, double delta)
+{
+
+}
+
+
+void Model::addTurnedOnCallback(ResourceCallback rc)
+{
+ m_resOnCB = rc;
+}
+
+void Model::notifyResourceTurnedOn(ResourcePtr r)
+{
+ m_resOnCB(r);
+}
+
+void Model::addTurnedOffCallback(ResourceCallback rc)
+{
+ m_resOffCB = rc;
+}
+
+void Model::notifyResourceTurnedOff(ResourcePtr r)
+{
+ m_resOffCB(r);
+}
+
+void Model::addActionCancelCallback(ActionCallback ac)
+{
+ m_actCancelCB = ac;
+}
+
+void Model::notifyActionCancel(ActionPtr a)
+{
+ m_actCancelCB(a);
+}
+
+void Model::addActionResumeCallback(ActionCallback ac)
+{
+ m_actResumeCB = ac;
+}
+
+void Model::notifyActionResume(ActionPtr a)
+{
+ m_actResumeCB(a);
+}
+
+void Model::addActionSuspendCallback(ActionCallback ac)
+{
+ m_actSuspendCB = ac;
+}
+
+void Model::notifyActionSuspend(ActionPtr a)
+{
+ m_actSuspendCB(a);
+}
+
+
+/************
+ * Resource *
+ ************/
+
+Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
+ : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
+{}
+
+Resource::Resource(){
+ //FIXME:free(m_name);
+ //FIXME:xbt_dict_free(&m_properties);
+}
+
+const char *Resource::getName()
+{
+ return m_name;
+}
+
+xbt_dict_t Resource::getProperties()
+{
+ return m_properties;
+}
+
+e_surf_resource_state_t Resource::getState()
+{
+ return p_stateCurrent;
+}
+
+bool Resource::isOn()
+{
+ return m_running;
+}
+
+void Resource::turnOn()
+{
+ if (!m_running) {
+ m_running = true;
+ p_model->notifyResourceTurnedOn(this);
+ }
+}
+
+void Resource::turnOff()
+{
+ if (m_running) {
+ m_running = false;
+ p_model->notifyResourceTurnedOff(this);
+ }
+}
+
+ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
+ lmm_system_t system,
+ double constraint_value,
+ tmgr_history_t history,
+ e_surf_resource_state_t state_init,
+ tmgr_trace_t state_trace,
+ double metric_peak,
+ tmgr_trace_t metric_trace)
+ : Resource(model, name, props)
+{
+ p_constraint = lmm_constraint_new(system, this, constraint_value);
+ p_stateCurrent = state_init;
+ if (state_trace)
+ p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
+ p_power.scale = 1.0;
+ p_power.peak = metric_peak;
+ if (metric_trace)
+ p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
+}
+
+/**********
+ * Action *
+ **********/
+
+const char *surf_action_state_names[6] = {
+ "SURF_ACTION_READY",
+ "SURF_ACTION_RUNNING",
+ "SURF_ACTION_FAILED",
+ "SURF_ACTION_DONE",
+ "SURF_ACTION_TO_FREE",
+ "SURF_ACTION_NOT_IN_THE_SYSTEM"
+};
+
+/**
+ * \brief Initializes the action module of Surf.
+ */
+void surf_action_init(void) {
+
+ /* the action mallocator will always provide actions of the following size,
+ * so this size should be set to the maximum size of the surf action structures
+ */
+ /*FIXME:action_mallocator_allocated_size = sizeof(s_surf_action_network_CM02_t);
+ action_mallocator = xbt_mallocator_new(65536, surf_action_mallocator_new_f,
+ surf_action_mallocator_free_f, surf_action_mallocator_reset_f);*/
+}
+
+/**
+ * \brief Uninitializes the action module of Surf.
+ */
+void surf_action_exit(void) {
+ //FIXME:xbt_mallocator_free(action_mallocator);
+}
+
+Action::Action(){}
+
+Action::Action(ModelPtr model, double cost, bool failed):
+ m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
+ m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
+ m_start(surf_get_clock()), m_finish(-1.0)
+{
+ #ifdef HAVE_TRACING
+ p_category = NULL;
+ #endif
+ p_stateHookup.prev = 0;
+ p_stateHookup.next = 0;
+ if (failed)
+ p_stateSet = p_model->p_failedActionSet;
+ else
+ p_stateSet = p_model->p_runningActionSet;
+
+ xbt_swag_insert(this, p_stateSet);
+}
+
+Action::~Action() {}
+
+int Action::unref(){
+ DIE_IMPOSSIBLE;
+}
+
+void Action::cancel(){
+ DIE_IMPOSSIBLE;
+}
+
+void Action::recycle(){
+ DIE_IMPOSSIBLE;
+}
+
+e_surf_action_state_t Action::getState()
+{
+ if (p_stateSet == p_model->p_readyActionSet)
+ return SURF_ACTION_READY;
+ if (p_stateSet == p_model->p_runningActionSet)
+ return SURF_ACTION_RUNNING;
+ if (p_stateSet == p_model->p_failedActionSet)
+ return SURF_ACTION_FAILED;
+ if (p_stateSet == p_model->p_doneActionSet)
+ return SURF_ACTION_DONE;
+ return SURF_ACTION_NOT_IN_THE_SYSTEM;
+}
+
+void Action::setState(e_surf_action_state_t state)
+{
+ //surf_action_state_t action_state = &(action->model_type->states);
+ XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
+ xbt_swag_remove(this, p_stateSet);
+
+ if (state == SURF_ACTION_READY)
+ p_stateSet = p_model->p_readyActionSet;
+ else if (state == SURF_ACTION_RUNNING)
+ p_stateSet = p_model->p_runningActionSet;
+ else if (state == SURF_ACTION_FAILED)
+ p_stateSet = p_model->p_failedActionSet;
+ else if (state == SURF_ACTION_DONE)
+ p_stateSet = p_model->p_doneActionSet;
+ else
+ p_stateSet = NULL;
+
+ if (p_stateSet)
+ xbt_swag_insert(this, p_stateSet);
+ XBT_OUT();
+}
+
+double Action::getStartTime()
+{
+ return m_start;
+}
+
+double Action::getFinishTime()
+{
+ /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
+ return m_remains == 0 ? m_finish : -1;
+}
+
+double Action::getRemains()
+{
+ XBT_IN("(%p)", this);
+ XBT_OUT();
+ return m_remains;
+}
+
+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
+
+void Action::ref(){
+ m_refcount++;
+}
+
+void ActionLmm::setMaxDuration(double duration)
+{
+ XBT_IN("(%p,%g)", this, duration);
+ m_maxDuration = duration;
+ if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
+ heapRemove(p_model->p_actionHeap);
+ XBT_OUT();
+}
+
+void ActionLmm::gapRemove() {}
+
+void ActionLmm::setPriority(double priority)
+{
+ XBT_IN("(%p,%g)", this, priority);
+ m_priority = priority;
+ lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
+
+ if (p_model->p_updateMechanism == UM_LAZY)
+ heapRemove(p_model->p_actionHeap);
+ XBT_OUT();
+}
+
+void ActionLmm::cancel(){
+ setState(SURF_ACTION_FAILED);
+ if (p_model->p_updateMechanism == UM_LAZY) {
+ xbt_swag_remove(this, p_model->p_modifiedSet);
+ heapRemove(p_model->p_actionHeap);
+ }
+}
+
+int ActionLmm::unref(){
+ m_refcount--;
+ if (!m_refcount) {
+ xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+ if (p_variable)
+ lmm_variable_free(p_model->p_maxminSystem, p_variable);
+ if (p_model->p_updateMechanism == UM_LAZY) {
+ /* remove from heap */
+ heapRemove(p_model->p_actionHeap);
+ xbt_swag_remove(this, p_model->p_modifiedSet);
+ }
+#ifdef HAVE_TRACING
+ xbt_free(p_category);
+#endif
+ delete this;
+ return 1;
+ }
+ return 0;
+}
+
+void ActionLmm::suspend()
+{
+ XBT_IN("(%p)", this);
+ if (m_suspended != 2) {
+ lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
+ m_suspended = 1;
+ if (p_model->p_updateMechanism == UM_LAZY)
+ heapRemove(p_model->p_actionHeap);
+ }
+ XBT_OUT();
+}
+
+void ActionLmm::resume()
+{
+ XBT_IN("(%p)", this);
+ if (m_suspended != 2) {
+ lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
+ m_suspended = 0;
+ if (p_model->p_updateMechanism == UM_LAZY)
+ heapRemove(p_model->p_actionHeap);
+ }
+ XBT_OUT();
+}
+
+bool ActionLmm::isSuspended()
+{
+ return m_suspended == 1;
+}
+/* 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);
+ }
+}
+
+/* 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;
+}
+
+double ActionLmm::getRemains()
+{
+ XBT_IN("(%p)", this);
+ /* update remains before return it */
+ if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
+ updateRemainingLazy(surf_get_clock());
+ XBT_OUT();
+ return m_remains;
+}
+
+//FIXME split code in the right places
+void ActionLmm::updateRemainingLazy(double now)
+{
+ double delta = 0.0;
+
+ if(p_model == static_cast<ModelPtr>(surf_network_model))
+ {
+ if (m_suspended != 0)
+ return;
+ }
+ else
+ {
+ 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 is now %lf", this, m_remains);
++ XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
+ double_update(&m_remains, m_lastValue * delta);
+
+#ifdef HAVE_TRACING
+ if (p_model == static_cast<ModelPtr>(surf_cpu_model) && TRACE_is_enabled()) {
+ ResourcePtr cpu = static_cast<ResourcePtr>(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 %f", this, m_remains);
+ }
+
+ if(p_model == static_cast<ModelPtr>(surf_network_model))
+ {
+ if (m_maxDuration != NO_MAX_DURATION)
+ double_update(&m_maxDuration, delta);
+
+ //FIXME: duplicated code
+ 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);
+}
+
+/*void Action::cancel()
+{
+ p_model->notifyActionCancel(this);
+}
+
+void Action::suspend()
+{
+ p_model->notifyActionSuspend(this);
+}
+
+void Action::resume()
+{
+ p_model->notifyActionResume(this);
+}
+
+bool Action::isSuspended()
+{
+ return false;
+}*/
+
--- /dev/null
- XBT_PUBLIC(void) surf_watched_hosts(void);
+//using namespace generic;
+
+#ifndef SURF_MODEL_H_
+#define SURF_MODEL_H_
+
+#include <xbt.h>
+#include <string>
+#include <vector>
+#include <memory>
+#include <boost/smart_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/functional/factory.hpp>
+#include <boost/bind.hpp>
+#include "surf/trace_mgr.h"
+#include "xbt/lib.h"
+#include "surf/surf_routing.h"
+#include "simgrid/platf_interface.h"
+#include "surf/surf.h"
+#include "surf/surf_private.h"
+
+extern tmgr_history_t history;
+#define NO_MAX_DURATION -1.0
+
+using namespace std;
+
+/** \ingroup SURF_simulation
+ * \brief Return the current time
+ *
+ * Return the current time in millisecond.
+ */
+
+/*********
+ * Utils *
+ *********/
+
+/* user-visible parameters */
+extern double sg_tcp_gamma;
+extern double sg_sender_gap;
+extern double sg_latency_factor;
+extern double sg_bandwidth_factor;
+extern double sg_weight_S_parameter;
+extern int sg_network_crosstraffic;
+#ifdef HAVE_GTNETS
+extern double sg_gtnets_jitter;
+extern int sg_gtnets_jitter_seed;
+#endif
+extern xbt_dynar_t surf_path;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XBT_PUBLIC(double) surf_get_clock(void);
+#ifdef __cplusplus
+}
+#endif
+
+extern double sg_sender_gap;
+XBT_PUBLIC(int) SURF_CPU_LEVEL; //Surf cpu level
+
+int __surf_is_absolute_file_path(const char *file_path);
+
+/***********
+ * Classes *
+ ***********/
+//class Model;
+typedef Model* ModelPtr;
+
+//class Resource;
+typedef Resource* ResourcePtr;
+typedef boost::function<void (ResourcePtr r)> ResourceCallback;
+
+//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
+};
+
+/*********
+ * Trace *
+ *********/
+/* For the trace and trace:connect tag (store their content till the end of the parsing) */
+XBT_PUBLIC_DATA(xbt_dict_t) traces_set_list;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_host_avail;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_power;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_link_avail;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_bandwidth;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_latency;
+
+
+/*********
+ * Model *
+ *********/
+XBT_PUBLIC_DATA(xbt_dynar_t) model_list;
+
+class Model {
+public:
+ Model(string name);
+ virtual ~Model();
+
+ ResourcePtr createResource(string name);
+ ActionPtr createAction(double _cost, bool _failed);
+ virtual double shareResources(double now);
+ virtual double shareResourcesLazy(double now);
+ virtual double shareResourcesFull(double now);
+ double shareResourcesMaxMin(xbt_swag_t running_actions,
+ lmm_system_t sys,
+ void (*solve) (lmm_system_t));
+ virtual void updateActionsState(double now, double delta);
+ virtual void updateActionsStateLazy(double now, double delta);
+ virtual void updateActionsStateFull(double now, double delta);
+
+ string getName() {return m_name;};
+
+ void addTurnedOnCallback(ResourceCallback rc);
+ void notifyResourceTurnedOn(ResourcePtr r);
+
+ void addTurnedOffCallback(ResourceCallback rc);
+ void notifyResourceTurnedOff(ResourcePtr r);
+
+ void addActionCancelCallback(ActionCallback ac);
+ void notifyActionCancel(ActionPtr a);
+ void addActionResumeCallback(ActionCallback ac);
+ void notifyActionResume(ActionPtr a);
+ 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 */
+ xbt_swag_t p_doneActionSet; /**< Actions in state SURF_ACTION_DONE */
+ string m_name;
+
+protected:
+ std::vector<ActionPtr> m_failedActions, m_runningActions;
+
+private:
+ ResourceCallback m_resOnCB, m_resOffCB;
+ ActionCallback m_actCancelCB, m_actSuspendCB, m_actResumeCB;
+};
+
+/************
+ * 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);
+ virtual ~Resource() {};
+
+ virtual void updateState(tmgr_trace_event_t event_type, double value, double date)=0;
+
+ //private
+ virtual bool isUsed()=0;
+ //FIXME:updateActionState();
+ //FIXME:updateResourceState();
+ //FIXME:finilize();
+
+ bool isOn();
+ void turnOn();
+ void turnOff();
+ void setName(string name);
+ const char *getName();
+ virtual xbt_dict_t getProperties();
+
+ ModelPtr getModel() {return p_model;};
+ virtual e_surf_resource_state_t getState();
+ void printModel() { std::cout << p_model->getName() << "<<plop"<<std::endl;};
+ void *p_resource;
+ const char *m_name;
+ xbt_dict_t m_properties;
+ ModelPtr p_model;
+ e_surf_resource_state_t p_stateCurrent;
+
+protected:
+
+private:
+ bool m_running;
+};
+
+class ResourceLmm: virtual public Resource {
+public:
+ ResourceLmm() {};
+ ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
+ lmm_system_t system,
+ double constraint_value,
+ tmgr_history_t history,
+ e_surf_resource_state_t state_init,
+ tmgr_trace_t state_trace,
+ double metric_peak,
+ tmgr_trace_t metric_trace);
+ lmm_constraint_t p_constraint;
+ tmgr_trace_event_t p_stateEvent;
+ s_surf_metric_t p_power;
+};
+
+/**********
+ * Action *
+ **********/
+
+class Action {
+public:
+ Action();
+ Action(ModelPtr model, double cost, bool failed);
+ virtual ~Action();
+
+ s_xbt_swag_hookup_t p_stateHookup;
+
+ e_surf_action_state_t getState(); /**< get the state*/
+ virtual void setState(e_surf_action_state_t state); /**< Change state*/
+ double getStartTime(); /**< Return the start time of an action */
+ double getFinishTime(); /**< Return the finish time of an action */
+ void setData(void* data);
+
+ void ref();
+ virtual int unref(); /**< Specify that we don't use that action anymore. Returns true if the action was destroyed and false if someone still has references on it. */
+ virtual void cancel(); /**< Cancel a running action */
+ virtual void recycle(); /**< Recycle an action */
+
+ virtual void suspend()=0; /**< Suspend an action */
+ virtual void resume()=0; /**< Resume a suspended action */
+ virtual bool isSuspended()=0; /**< Return whether an action is suspended */
+ virtual void setMaxDuration(double duration)=0; /**< Set the max duration of an action*/
+ virtual void setPriority(double priority)=0; /**< Set the priority of an action */
+#ifdef HAVE_TRACING
+ void setCategory(const char *category); /**< Set the category of an action */
+#endif
+ virtual double getRemains(); /**< Get the remains of an action */
+#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) */
+ bool m_failed;
+ double m_start; /**< start time */
+ double m_finish; /**< finish time : this is modified during the run and fluctuates until the task is completed */
+ double m_remains; /**< How much of that cost remains to be done in the currently running task */
+ #ifdef HAVE_LATENCY_BOUND_TRACKING
+ 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 */
+ int m_cost;
+ void *p_data; /**< for your convenience */
+protected:
+ ModelPtr p_model;
+ int m_refcount;
+#ifdef HAVE_TRACING
+#endif
+ e_UM_t p_updateMechanism;
+
+private:
+ int resourceUsed(void *resource_id);
+ /* Share the resources to the actions and return in how much time
+ the next action may terminate */
+ double shareResources(double now);
+ /* Update the actions' state */
+ void updateActionsState(double now, double delta);
+ void updateResourceState(void *id, tmgr_trace_event_t event_type,
+ double value, double time);
+
+ xbt_swag_t p_modifiedSet;
+ xbt_heap_t p_actionHeap;
+ int m_selectiveUpdate;
+};
+
+//FIXME:REMOVE
+void surf_action_lmm_update_index_heap(void *action, int i);
+
+class ActionLmm: virtual public Action {
+public:
+ ActionLmm() : m_suspended(false) {
+ p_actionListHookup.prev = 0;
+ p_actionListHookup.next = 0;
+ };
+ ActionLmm(ModelPtr model, double cost, bool failed) : m_suspended(false) {
+ p_actionListHookup.prev = 0;
+ p_actionListHookup.next = 0;
+ };
+
+ virtual void updateRemainingLazy(double now);
+ 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);
+
+ virtual int unref();
+ void cancel();
+ void suspend();
+ void resume();
+ bool isSuspended();
+ void setMaxDuration(double duration);
+ void setPriority(double priority);
+ void gapRemove();
+
+ lmm_variable_t p_variable;
+ s_xbt_swag_hookup_t p_actionListHookup;
+ int m_indexHeap;
+ double m_lastUpdate;
+ double m_lastValue;
+ enum heap_action_type m_hat;
+ int m_suspended;
+};
+
+#endif /* SURF_MODEL_H_ */
--- /dev/null
- if (resource->isUsed()) {
+#include "surf.hpp"
+#include "workstation.hpp"
+#include "network.hpp"
+#include "surf_routing_cluster.hpp"
+#include "instr/instr_private.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
+
+/*********
+ * TOOLS *
+ *********/
+extern double NOW;
+
+static CpuPtr get_casted_cpu(surf_resource_t resource){
+ return dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(surf_cpu_resource_priv(resource)));
+}
+
+static WorkstationCLM03Ptr get_casted_workstation(surf_resource_t resource){
+ return dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(surf_workstation_resource_priv(resource)));
+}
+
+char *surf_routing_edge_name(sg_routing_edge_t edge){
+ return edge->p_name;
+}
+
+#ifdef CONTEXT_THREADS
+static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
+#endif
+
+static double *surf_mins = NULL; /* return value of share_resources for each model */
+static int surf_min_index; /* current index in surf_mins */
+static double surf_min; /* duration determined by surf_solve */
+
+void surf_presolve(void)
+{
+ double next_event_date = -1.0;
+ tmgr_trace_event_t event = NULL;
+ double value = -1.0;
+ ResourcePtr resource = NULL;
+ ModelPtr model = NULL;
+ unsigned int iter;
+
+ XBT_DEBUG
+ ("First Run! Let's \"purge\" events and put models in the right state");
+ while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
+ if (next_event_date > NOW)
+ break;
+ while ((event =
+ tmgr_history_get_next_event_leq(history, next_event_date,
+ &value,
+ (void **) &resource))) {
+ if (value >= 0){
+ resource->updateState(event, value, NOW);
+ }
+ }
+ }
+ xbt_dynar_foreach(model_list, iter, model)
+ model->updateActionsState(NOW, 0.0);
+}
+
+static void surf_share_resources(surf_model_t model)
+{
+ double next_action_end = -1.0;
+ int i = __sync_fetch_and_add(&surf_min_index, 1);
+ if (strcmp(model->m_name.c_str(), "network NS3")) {
+ XBT_DEBUG("Running for Resource [%s]", model->m_name.c_str());
+ next_action_end = model->shareResources(NOW);
+ XBT_DEBUG("Resource [%s] : next action end = %f",
+ model->m_name.c_str(), next_action_end);
+ }
+ surf_mins[i] = next_action_end;
+}
+
+static void surf_update_actions_state(surf_model_t model)
+{
+ model->updateActionsState(NOW, surf_min);
+}
+
+double surf_solve(double max_date)
+{
+ surf_min = -1.0; /* duration */
+ double next_event_date = -1.0;
+ double model_next_action_end = -1.0;
+ double value = -1.0;
+ ResourcePtr resource = NULL;
+ ModelPtr model = NULL;
+ tmgr_trace_event_t event = NULL;
+ unsigned int iter;
+
++ if(!host_that_restart)
++ host_that_restart = xbt_dynar_new(sizeof(char*), NULL);
++
+ if (max_date != -1.0 && max_date != NOW) {
+ surf_min = max_date - NOW;
+ }
+
+ XBT_DEBUG("Looking for next action end for all models except NS3");
+
+ if (surf_mins == NULL) {
+ surf_mins = xbt_new(double, xbt_dynar_length(model_list));
+ }
+ surf_min_index = 0;
+
+ /* sequential version */
+ xbt_dynar_foreach(model_list, iter, model) {
+ surf_share_resources(static_cast<ModelPtr>(model));
+ }
+
+ unsigned i;
+ for (i = 0; i < xbt_dynar_length(model_list); i++) {
+ if ((surf_min < 0.0 || surf_mins[i] < surf_min)
+ && surf_mins[i] >= 0.0) {
+ surf_min = surf_mins[i];
+ }
+ }
+
+ XBT_DEBUG("Min for resources (remember that NS3 don't update that value) : %f", surf_min);
+
+ XBT_DEBUG("Looking for next trace event");
+
+ do {
+ XBT_DEBUG("Next TRACE event : %f", next_event_date);
+
+ next_event_date = tmgr_history_next_date(history);
+
+ if(!strcmp(surf_network_model->m_name.c_str(), "network NS3")){//FIXME: add surf_network_model->m_name &&
+ if(next_event_date!=-1.0 && surf_min!=-1.0) {
+ surf_min = MIN(next_event_date - NOW, surf_min);
+ } else{
+ surf_min = MAX(next_event_date - NOW, surf_min);
+ }
+
+ XBT_DEBUG("Run for network at most %f", surf_min);
+ // run until min or next flow
+ model_next_action_end = surf_network_model->shareResources(surf_min);
+
+ XBT_DEBUG("Min for network : %f", model_next_action_end);
+ if(model_next_action_end>=0.0)
+ surf_min = model_next_action_end;
+ }
+
+ if (next_event_date < 0.0) {
+ XBT_DEBUG("no next TRACE event. Stop searching for it");
+ break;
+ }
+
+ if ((surf_min == -1.0) || (next_event_date > NOW + surf_min)) break;
+
+ XBT_DEBUG("Updating models (min = %g, NOW = %g, next_event_date = %g)", surf_min, NOW, next_event_date);
+ while ((event =
+ tmgr_history_get_next_event_leq(history, next_event_date,
+ &value,
+ (void **) &resource))) {
- resource->p_model->m_name.c_str(), surf_min);
++ if (resource->isUsed() || xbt_dict_get_or_null(watched_hosts_lib, resource->m_name)) {
+ surf_min = next_event_date - NOW;
+ XBT_DEBUG
+ ("This event will modify model state. Next event set to %f",
+ surf_min);
+ }
+ /* update state of model_obj according to new value. Does not touch lmm.
+ It will be modified if needed when updating actions */
+ XBT_DEBUG("Calling update_resource_state for resource %s with min %lf",
- surf_action_t surf_workstation_read(surf_resource_t resource, void *ptr, size_t size, surf_file_t fd){
- return get_casted_workstation(resource)->read(ptr, size, fd);
++ resource->m_name, surf_min);
+ resource->updateState(event, value, next_event_date);
+ }
+ } while (1);
+
+ /* FIXME: Moved this test to here to avoid stopping simulation if there are actions running on cpus and all cpus are with availability = 0.
+ * This may cause an infinite loop if one cpu has a trace with periodicity = 0 and the other a trace with periodicity > 0.
+ * The options are: all traces with same periodicity(0 or >0) or we need to change the way how the events are managed */
+ if (surf_min == -1.0) {
+ XBT_DEBUG("No next event at all. Bail out now.");
+ return -1.0;
+ }
+
+ XBT_DEBUG("Duration set to %f", surf_min);
+
+ NOW = NOW + surf_min;
+
+ /* sequential version */
+ xbt_dynar_foreach(model_list, iter, model) {
+ surf_update_actions_state(model);
+ }
+
+#ifdef HAVE_TRACING
+ TRACE_paje_dump_buffer (0);
+#endif
+
+ return surf_min;
+}
+
+XBT_INLINE double surf_get_clock(void)
+{
+ return NOW;
+}
+
+void routing_get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
+ xbt_dynar_t * route, double *latency){
+ routing_platf->getRouteAndLatency(src, dst, route, latency);
+}
+
+/*********
+ * MODEL *
+ *********/
+
+void *surf_as_cluster_get_backbone(AS_t as){
+ return static_cast<AsClusterPtr>(as)->p_backbone;
+}
+
+void surf_as_cluster_set_backbone(AS_t as, void* backbone){
+ static_cast<AsClusterPtr>(as)->p_backbone = dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(backbone));
+}
+
+const char *surf_model_name(surf_model_t model){
+ return model->m_name.c_str();
+}
+
+xbt_swag_t surf_model_done_action_set(surf_model_t model){
+ return model->p_doneActionSet;
+}
+
+xbt_swag_t surf_model_failed_action_set(surf_model_t model){
+ return model->p_failedActionSet;
+}
+
+xbt_swag_t surf_model_ready_action_set(surf_model_t model){
+ return model->p_readyActionSet;
+}
+
+xbt_swag_t surf_model_running_action_set(surf_model_t model){
+ return model->p_runningActionSet;
+}
+
+surf_action_t surf_workstation_model_execute_parallel_task(surf_workstation_model_t model,
+ int workstation_nb,
+ void **workstation_list,
+ double *computation_amount,
+ double *communication_amount,
+ double rate){
+ return static_cast<ActionPtr>(model->executeParallelTask(workstation_nb, workstation_list, computation_amount, communication_amount, rate));
+}
+
+surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst, double size, double rate){
+ return model->communicate(get_casted_workstation(src), get_casted_workstation(dst), size, rate);
+}
+
+xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model,
+ surf_resource_t src, surf_resource_t dst){
+ return model->getRoute(get_casted_workstation(src), get_casted_workstation(dst));
+}
+
+surf_action_t surf_network_model_communicate(surf_network_model_t model, sg_routing_edge_t src, sg_routing_edge_t dst, double size, double rate){
+ return model->communicate(src, dst, size, rate);
+}
+
+const char *surf_resource_name(surf_cpp_resource_t resource){
+ return resource->m_name;
+}
+
+xbt_dict_t surf_resource_get_properties(surf_cpp_resource_t resource){
+ return resource->getProperties();
+}
+
+e_surf_resource_state_t surf_resource_get_state(surf_cpp_resource_t resource){
+ return resource->getState();
+}
+
+surf_action_t surf_workstation_sleep(surf_resource_t resource, double duration){
+ return get_casted_workstation(resource)->sleep(duration);
+}
+
+double surf_workstation_get_speed(surf_resource_t resource, double load){
+ return get_casted_workstation(resource)->getSpeed(load);
+}
+
+double surf_workstation_get_available_speed(surf_resource_t resource){
+ return get_casted_workstation(resource)->getAvailableSpeed();
+}
+
+int surf_workstation_get_core(surf_resource_t resource){
+ return get_casted_workstation(resource)->getCore();
+}
+
+surf_action_t surf_workstation_execute(surf_resource_t resource, double size){
+ return get_casted_workstation(resource)->execute(size);
+}
+
++double surf_workstation_get_current_power_peak(surf_resource_t resource){
++ return get_casted_workstation(resource)->getCurrentPowerPeak();
++}
++
++double surf_workstation_get_power_peak_at(surf_resource_t resource, int pstate_index){
++ return get_casted_workstation(resource)->getPowerPeakAt(pstate_index);
++}
++
++int surf_workstation_get_nb_pstates(surf_resource_t resource){
++ return get_casted_workstation(resource)->getNbPstates();
++}
++
++void surf_workstation_set_power_peak_at(surf_resource_t resource, int pstate_index){
++ return get_casted_workstation(resource)->setPowerPeakAt(pstate_index);
++}
++
++double surf_workstation_get_consumed_energy(surf_resource_t resource){
++ return get_casted_workstation(resource)->getConsumedEnergy();
++}
++
++xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation){
++ return get_casted_workstation(workstation)->getStorageList();
++}
+surf_action_t surf_workstation_open(surf_resource_t workstation, const char* mount, const char* path){
+ return get_casted_workstation(workstation)->open(mount, path);
+}
+
+surf_action_t surf_workstation_close(surf_resource_t workstation, surf_file_t fd){
+ return get_casted_workstation(workstation)->close(fd);
+}
+
+int surf_workstation_unlink(surf_resource_t workstation, surf_file_t fd){
+ return get_casted_workstation(workstation)->unlink(fd);
+}
+
+surf_action_t surf_workstation_ls(surf_resource_t workstation, const char* mount, const char *path){
+ return get_casted_workstation(workstation)->ls(mount, path);
+}
+
+size_t surf_workstation_get_size(surf_resource_t workstation, surf_file_t fd){
+ return get_casted_workstation(workstation)->getSize(fd);
+}
+
- surf_action_t surf_workstation_write(surf_resource_t resource, const void *ptr, size_t size, surf_file_t fd){
- return get_casted_workstation(resource)->write(ptr, size, fd);
++surf_action_t surf_workstation_read(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size){
++ return get_casted_workstation(resource)->read(fd, size);
++}
++
++surf_action_t surf_workstation_write(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size){
++ return get_casted_workstation(resource)->write(fd, size);
++}
++
++xbt_dynar_t surf_workstation_get_info(surf_resource_t resource, surf_file_t fd){
++ return get_casted_workstation(resource)->getInfo(fd);
+}
+
++sg_storage_size_t surf_workstation_get_free_size(surf_resource_t resource, const char* name){
++ return get_casted_workstation(resource)->getFreeSize(name);
++}
++sg_storage_size_t surf_workstation_get_used_size(surf_resource_t resource, const char* name){
++ return get_casted_workstation(resource)->getUsedSize(name);
+}
+
+int surf_network_link_is_shared(surf_cpp_resource_t link){
+ return dynamic_cast<NetworkCm02LinkPtr>(link)->isShared();
+}
+
+double surf_network_link_get_bandwidth(surf_cpp_resource_t link){
+ return dynamic_cast<NetworkCm02LinkPtr>(link)->getBandwidth();
+}
+
+double surf_network_link_get_latency(surf_cpp_resource_t link){
+ return dynamic_cast<NetworkCm02LinkPtr>(link)->getLatency();
+}
+
++xbt_dict_t surf_storage_get_content(surf_resource_t resource){
++ return dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(surf_storage_resource_priv(resource)))->getContent();
++}
++
++sg_storage_size_t surf_storage_get_size(surf_resource_t resource){
++ return dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(surf_storage_resource_priv(resource)))->getSize();
++}
++
+surf_action_t surf_cpu_execute(surf_resource_t cpu, double size){
+ return get_casted_cpu(cpu)->execute(size);
+}
+
+surf_action_t surf_cpu_sleep(surf_resource_t cpu, double duration){
+ return get_casted_cpu(cpu)->sleep(duration);
+}
+
+double surf_action_get_start_time(surf_action_t action){
+ return action->m_start;
+}
+
+double surf_action_get_finish_time(surf_action_t action){
+ return action->m_finish;
+}
+
+double surf_action_get_remains(surf_action_t action){
+ return action->getRemains();
+}
+
+void surf_action_unref(surf_action_t action){
+ action->unref();
+}
+
+void surf_action_suspend(surf_action_t action){
+ action->suspend();
+}
+
+void surf_action_resume(surf_action_t action){
+ action->resume();
+}
+
+void surf_action_cancel(surf_action_t action){
+ action->cancel();
+}
+
+void surf_action_set_priority(surf_action_t action, double priority){
+ action->setPriority(priority);
+}
+
+void surf_action_set_category(surf_action_t action, const char *category){
+ action->setCategory(category);
+}
+
+void *surf_action_get_data(surf_action_t action){
+ return action->p_data;
+}
+
+void surf_action_set_data(surf_action_t action, void *data){
+ action->p_data = data;
+}
+
+e_surf_action_state_t surf_action_get_state(surf_action_t action){
+ return action->getState();
+}
+
+int surf_action_get_cost(surf_action_t action){
+ return action->m_cost;
+}
+
+surf_file_t surf_storage_action_get_file(surf_action_t action){
+ return dynamic_cast<StorageActionPtr>(action)->p_file;
+}
+
+xbt_dict_t surf_storage_action_get_ls_dict(surf_action_t action){
+ return dynamic_cast<StorageActionPtr>(action)->p_lsDict;
+}
-/* Copyright (c) 2009-2013. The SimGrid Team.
++/* Copyright (c) 2009, 2010, 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 "surf_routing.hpp"
+#include "surf_routing_private.hpp"
++
+ #include "simgrid/platf_interface.h" // platform creation API internal interface
+ #include "simgrid/sg_config.h"
+
-#include "surf_routing_private.h"
-#include "surf/surf_routing.h"
#include "surf/surfxml_parse_values.h"
- #include "surf/random_mgr.h"
/**
* @ingroup SURF_build_api
XBT_DEBUG(" ");
host_id = HOST_PEER(peer->id);
link_id = LINK_PEER(peer->id);
- current_routing->link_up_down_list
- = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
+ router_id = ROUTER_PEER(peer->id);
+
+ XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", peer->id);
+ s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+ AS.id = peer->id;
+ AS.routing = A_surfxml_AS_routing_Cluster;
+ sg_platf_new_AS_begin(&AS);
+
++ current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->power);
s_sg_platf_host_cbarg_t host;
host_link.link_down= link_down;
sg_platf_new_host_link(&host_link);
- ((as_cluster_t)current_routing)->router = xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL);
+ XBT_DEBUG("<router id=\"%s\"/>", router_id);
+ s_sg_platf_router_cbarg_t router;
+ memset(&router, 0, sizeof(router));
+ router.id = router_id;
+ router.coord = peer->coord;
+ sg_platf_new_router(&router);
++ static_cast<AsClusterPtr>(current_routing)->p_router = static_cast<RoutingEdgePtr>(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL));
+
+ XBT_DEBUG("</AS>");
+ sg_platf_new_AS_end();
XBT_DEBUG(" ");
//xbt_dynar_free(&tab_elements_num);
+ /* Copyright (c) 2009-2013. 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 "surf_routing_private.h"
+#include "surf_routing_floyd.hpp"
+#include "network.hpp"
-/* Global vars */
-extern routing_platf_t routing_platf;
-
+extern "C" {
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_floyd, surf, "Routing part of surf");
+}
-#define TO_FLOYD_COST(i,j) (as->cost_table)[(i)+(j)*table_size]
-#define TO_FLOYD_PRED(i,j) (as->predecessor_table)[(i)+(j)*table_size]
-#define TO_FLOYD_LINK(i,j) (as->link_table)[(i)+(j)*table_size]
+#define TO_FLOYD_COST(i,j) (p_costTable)[(i)+(j)*table_size]
+#define TO_FLOYD_PRED(i,j) (p_predecessorTable)[(i)+(j)*table_size]
+#define TO_FLOYD_LINK(i,j) (p_linkTable)[(i)+(j)*table_size]
-/* Routing model structure */
+AS_t model_floyd_create(void)
+{
+ return new AsFloyd();
+}
-typedef struct {
- s_as_t generic_routing;
- /* vars for calculate the floyd algorithm. */
- int *predecessor_table;
- double *cost_table;
- sg_platf_route_cbarg_t *link_table;
-} s_as_floyd_t, *as_floyd_t;
+void model_floyd_end(AS_t current_routing)
+{
+ static_cast<AsFloydPtr>(current_routing)->end();
+}
-static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_routing_edge_t dst,
- sg_platf_route_cbarg_t res, double *lat);
+AsFloyd::AsFloyd(): AsGeneric() {
+}
+
+AsFloyd::~AsFloyd(){
+ int i, j;
+ size_t table_size;
+ table_size = xbt_dynar_length(p_indexNetworkElm);
+ /* Delete link_table */
+ for (i = 0; i < table_size; i++)
+ for (j = 0; j < table_size; j++)
+ generic_free_route(TO_FLOYD_LINK(i, j));
+ xbt_free(p_linkTable);
+ /* Delete bypass dict */
+ xbt_dict_free(&p_bypassRoutes);
+ /* Delete predecessor and cost table */
+ xbt_free(p_predecessorTable);
+ xbt_free(p_costTable);
+}
/* Business methods */
-static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
+xbt_dynar_t AsFloyd::getOneLinkRoutes()
{
xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+ /* Copyright (c) 2009-2013. 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 "surf_routing_private.h"
+#include "surf_routing_full.hpp"
+#include "network.hpp"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf");
+}
/* Global vars */
extern routing_platf_t routing_platf;
--- /dev/null
- xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes"));
+#include "workstation.hpp"
+#include "simgrid/sg_config.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
+ "Logging specific to the SURF workstation module");
+}
+
+WorkstationModelPtr surf_workstation_model = NULL;
+
+//FIXME:Faire hériter ou composer de cup et network
+
+/*************
+ * CallBacks *
+ *************/
+
+static void workstation_new(sg_platf_host_cbarg_t host){
+ surf_workstation_model->createResource(host->id);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_workstation_model_init_current_default(void)
+{
+ surf_workstation_model = new WorkstationModel();
- StoragePtr WorkstationCLM03::findStorageOnMountList(const char* storage)
++ xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "yes");
+ surf_cpu_model_init_Cas01();
+ surf_network_model_init_LegrandVelho();
+
+ ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
+ xbt_dynar_push(model_list, &model);
+ sg_platf_host_add_cb(workstation_new);
+}
+
+void surf_workstation_model_init_compound()
+{
+
+ xbt_assert(surf_cpu_model, "No CPU model defined yet!");
+ xbt_assert(surf_network_model, "No network model defined yet!");
+ surf_workstation_model = new WorkstationModel();
+
+ ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
+ xbt_dynar_push(model_list, &model);
+ sg_platf_host_add_cb(workstation_new);
+}
+
+WorkstationModel::WorkstationModel() : Model("Workstation") {
+}
+
+WorkstationModel::~WorkstationModel() {
+}
+
+void WorkstationModel::parseInit(sg_platf_host_cbarg_t host){
+ createResource(host->id);
+}
+
+WorkstationCLM03Ptr WorkstationModel::createResource(string name){
+
+ WorkstationCLM03Ptr workstation = new WorkstationCLM03(surf_workstation_model, name.c_str(), NULL,
+ (xbt_dynar_t)xbt_lib_get_or_null(storage_lib, name.c_str(), ROUTING_STORAGE_HOST_LEVEL),
+ (RoutingEdgePtr)xbt_lib_get_or_null(host_lib, name.c_str(), ROUTING_HOST_LEVEL),
+ dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(host_lib, name.c_str(), SURF_CPU_LEVEL))));
+ XBT_DEBUG("Create workstation %s with %ld mounted disks", name.c_str(), xbt_dynar_length(workstation->p_storage));
+ xbt_lib_set(host_lib, name.c_str(), SURF_WKS_LEVEL, static_cast<ResourcePtr>(workstation));
+ return workstation;
+}
+
+double WorkstationModel::shareResources(double now){
+ return -1.0;
+}
+
+void WorkstationModel::updateActionsState(double now, double delta){
+ return;
+}
+
+ActionPtr WorkstationModel::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;
+}
+
+/* returns an array of network_link_CM02_t */
+xbt_dynar_t WorkstationModel::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst)
+{
+ XBT_DEBUG("ws_get_route");
+ return surf_network_model->getRoute(src->p_netElm, dst->p_netElm);
+}
+
+ActionPtr WorkstationModel::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate){
+ return surf_network_model->communicate(src->p_netElm, dst->p_netElm, size, rate);
+}
+
+
+
+/************
+ * Resource *
+ ************/
+WorkstationCLM03::WorkstationCLM03(WorkstationModelPtr model, const char* name, xbt_dict_t properties, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu)
+ : Resource(model, name, properties), p_storage(storage), p_netElm(netElm), p_cpu(cpu) {}
+
+bool WorkstationCLM03::isUsed(){
+ THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */
+ return -1;
+}
+
+void WorkstationCLM03::updateState(tmgr_trace_event_t event_type, double value, double date){
+ THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */
+}
+
+ActionPtr WorkstationCLM03::execute(double size) {
+ return p_cpu->execute(size);
+}
+
+ActionPtr WorkstationCLM03::sleep(double duration) {
+ return p_cpu->sleep(duration);
+}
+
+e_surf_resource_state_t WorkstationCLM03::getState() {
+ return p_cpu->getState();
+}
+
+int WorkstationCLM03::getCore(){
+ return p_cpu->getCore();
+}
+
+double WorkstationCLM03::getSpeed(double load){
+ return p_cpu->getSpeed(load);
+}
+
+double WorkstationCLM03::getAvailableSpeed(){
+ return p_cpu->getAvailableSpeed();
+}
+
++double WorkstationCLM03::getCurrentPowerPeak()
++{
++ return p_cpu->getCurrentPowerPeak();
++}
++
++double WorkstationCLM03::getPowerPeakAt(int pstate_index)
++{
++ return p_cpu->getPowerPeakAt(pstate_index);
++}
++
++int WorkstationCLM03::getNbPstates()
++{
++ return p_cpu->getNbPstates();
++}
++
++void WorkstationCLM03::setPowerPeakAt(int pstate_index)
++{
++ p_cpu->setPowerPeakAt(pstate_index);
++}
++
++double WorkstationCLM03::getConsumedEnergy()
++{
++ return p_cpu->getConsumedEnergy();
++}
++
++
+xbt_dict_t WorkstationCLM03::getProperties()
+{
+ return p_cpu->m_properties;
+}
+
+
- XBT_DEBUG("Search for storage name '%s' on '%s'",storage,m_name);
++StoragePtr WorkstationCLM03::findStorageOnMountList(const char* mount)
+{
+ StoragePtr st = NULL;
+ s_mount_t mnt;
+ unsigned int cursor;
+
- if(!strcmp(storage,mnt.name)){
- st = (StoragePtr)mnt.id;
++ XBT_DEBUG("Search for storage name '%s' on '%s'", mount, m_name);
+ xbt_dynar_foreach(p_storage,cursor,mnt)
+ {
+ XBT_DEBUG("See '%s'",mnt.name);
- if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,m_name);
++ if(!strcmp(mount,mnt.name)){
++ st = dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(mnt.storage));
+ break;
+ }
+ }
- StoragePtr st = findStorageOnMountList(fd->storage);
++ if(!st) xbt_die("Can't find mount '%s' for '%s'", mount, m_name);
+ return st;
+}
+
++xbt_dict_t WorkstationCLM03::getStorageList()
++{
++ s_mount_t mnt;
++ unsigned int i;
++ xbt_dict_t storage_list = xbt_dict_new_homogeneous(NULL);
++ char *storage_name = NULL;
++
++ xbt_dynar_foreach(p_storage,i,mnt){
++ storage_name = (char *)dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(mnt.storage))->m_name;
++ xbt_dict_set(storage_list,mnt.name,storage_name,NULL);
++ }
++ return storage_list;
++}
++
+ActionPtr WorkstationCLM03::open(const char* mount, const char* path) {
+ StoragePtr st = findStorageOnMountList(mount);
+ XBT_DEBUG("OPEN on disk '%s'", st->m_name);
+ return st->open(mount, path);
+}
+
+ActionPtr WorkstationCLM03::close(surf_file_t fd) {
- ActionPtr WorkstationCLM03::read(void* ptr, size_t size, surf_file_t fd) {
- StoragePtr st = findStorageOnMountList(fd->storage);
++ StoragePtr st = findStorageOnMountList(fd->mount);
+ XBT_DEBUG("CLOSE on disk '%s'",st->m_name);
+ return st->close(fd);
+}
+
- return st->read(ptr, size, fd);
++ActionPtr WorkstationCLM03::read(surf_file_t fd, sg_storage_size_t size) {
++ StoragePtr st = findStorageOnMountList(fd->mount);
+ XBT_DEBUG("READ on disk '%s'",st->m_name);
- ActionPtr WorkstationCLM03::write(const void* ptr, size_t size, surf_file_t fd) {
- StoragePtr st = findStorageOnMountList(fd->storage);
++ return st->read(fd, size);
+}
+
- return st->write(ptr, size, fd);
++ActionPtr WorkstationCLM03::write(surf_file_t fd, sg_storage_size_t size) {
++ StoragePtr st = findStorageOnMountList(fd->mount);
+ XBT_DEBUG("WRITE on disk '%s'",st->m_name);
- StoragePtr st = findStorageOnMountList(fd->storage);
++ return st->write(fd, size);
+}
+
+int WorkstationCLM03::unlink(surf_file_t fd) {
+ if (!fd){
+ XBT_WARN("No such file descriptor. Impossible to unlink");
+ return 0;
+ } else {
+// XBT_INFO("%s %zu", fd->storage, fd->size);
- free(fd->storage);
++ StoragePtr st = findStorageOnMountList(fd->mount);
+ /* Check if the file is on this storage */
+ if (!xbt_dict_get_or_null(st->p_content, fd->name)){
+ XBT_WARN("File %s is not on disk %s. Impossible to unlink", fd->name,
+ st->m_name);
+ return 0;
+ } else {
+ XBT_DEBUG("UNLINK on disk '%s'",st->m_name);
+ st->m_usedSize -= fd->size;
+
+ // Remove the file from storage
+ xbt_dict_remove(st->p_content, fd->name);
+
+ free(fd->name);
- size_t WorkstationCLM03::getSize(surf_file_t fd){
++ free(fd->mount);
+ xbt_free(fd);
+ return 1;
+ }
+ }
+}
+
+ActionPtr WorkstationCLM03::ls(const char* mount, const char *path){
+ XBT_DEBUG("LS on mount '%s' and file '%s'", mount, path);
+ StoragePtr st = findStorageOnMountList(mount);
+ return st->ls(path);
+}
+
++sg_storage_size_t WorkstationCLM03::getSize(surf_file_t fd){
+ return fd->size;
+}
+
++xbt_dynar_t WorkstationCLM03::getInfo( surf_file_t fd)
++{
++ StoragePtr st = findStorageOnMountList(fd->mount);
++ sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
++ *psize = fd->size;
++ xbt_dynar_t info = xbt_dynar_new(sizeof(void*), NULL);
++ xbt_dynar_push_as(info, sg_storage_size_t *, psize);
++ xbt_dynar_push_as(info, void *, fd->mount);
++ xbt_dynar_push_as(info, void *, (void *)st->m_name);
++ xbt_dynar_push_as(info, void *, st->p_typeId);
++ xbt_dynar_push_as(info, void *, st->p_contentType);
++
++ return info;
++}
++
++sg_storage_size_t WorkstationCLM03::getFreeSize(const char* name)
++{
++ StoragePtr st = findStorageOnMountList(name);
++ return st->m_size - st->m_usedSize;
++}
++
++sg_storage_size_t WorkstationCLM03::getUsedSize(const char* name)
++{
++ StoragePtr st = findStorageOnMountList(name);
++ return st->m_usedSize;
++}
++
+e_surf_resource_state_t WorkstationCLM03Lmm::getState() {
+ return WorkstationCLM03::getState();
+}
+/**********
+ * Action *
+ **********/
--- /dev/null
- size_t getSize(surf_file_t fd);
- ActionPtr read(void* ptr, size_t size, surf_file_t fd);
- ActionPtr write(const void* ptr, size_t size, surf_file_t fd);
+#include "surf.hpp"
+#include "storage.hpp"
+#include "cpu.hpp"
+#include "network.hpp"
+
+#ifndef WORKSTATION_HPP_
+#define WORKSTATION_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class WorkstationModel;
+typedef WorkstationModel *WorkstationModelPtr;
+
+class WorkstationCLM03;
+typedef WorkstationCLM03 *WorkstationCLM03Ptr;
+
+class WorkstationCLM03Lmm;
+typedef WorkstationCLM03Lmm *WorkstationCLM03LmmPtr;
+
+class WorkstationAction;
+typedef WorkstationAction *WorkstationActionPtr;
+
+/*FIXME:class WorkstationActionLmm;
+typedef WorkstationActionLmm *WorkstationActionLmmPtr;*/
+
+/*********
+ * Tools *
+ *********/
+extern WorkstationModelPtr surf_workstation_model;
+
+/*********
+ * Model *
+ *********/
+class WorkstationModel : public Model {
+public:
+ WorkstationModel(string name): Model(name) {};
+ WorkstationModel();
+ ~WorkstationModel();
+ virtual void parseInit(sg_platf_host_cbarg_t host);
+ WorkstationCLM03Ptr createResource(string name);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+
+ virtual ActionPtr executeParallelTask(int workstation_nb,
+ void **workstation_list,
+ double *computation_amount,
+ double *communication_amount,
+ double rate);
+ virtual xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst);
+ virtual ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate);
+};
+
+/************
+ * Resource *
+ ************/
+
+class WorkstationCLM03 : virtual public Resource {
+public:
+ WorkstationCLM03(WorkstationModelPtr model, const char* name, xbt_dict_t properties, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu);
+
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+
+ virtual ActionPtr execute(double size);
+ virtual ActionPtr sleep(double duration);
+ e_surf_resource_state_t getState();
+
+ virtual int getCore();
+ virtual double getSpeed(double load);
+ virtual double getAvailableSpeed();
++ virtual double getCurrentPowerPeak();
++ virtual double getPowerPeakAt(int pstate_index);
++ virtual int getNbPstates();
++ virtual void setPowerPeakAt(int pstate_index);
++ virtual double getConsumedEnergy();
+
+ xbt_dict_t getProperties();
+
+ StoragePtr findStorageOnMountList(const char* storage);
++ xbt_dict_t getStorageList();
+ ActionPtr open(const char* mount, const char* path);
+ ActionPtr close(surf_file_t fd);
+ int unlink(surf_file_t fd);
+ ActionPtr ls(const char* mount, const char *path);
++ sg_storage_size_t getSize(surf_file_t fd);
++ ActionPtr read(surf_file_t fd, sg_storage_size_t size);
++ ActionPtr write(surf_file_t fd, sg_storage_size_t size);
++ xbt_dynar_t getInfo( surf_file_t fd);
++ sg_storage_size_t getFreeSize(const char* name);
++ sg_storage_size_t getUsedSize(const char* name);
++
+ bool isUsed();
+ //bool isShared();
+ xbt_dynar_t p_storage;
+ RoutingEdgePtr p_netElm;
+ CpuPtr p_cpu;
+ NetworkCm02LinkPtr p_network;
+};
+
+class WorkstationCLM03Lmm : public WorkstationCLM03, public ResourceLmm {
+public:
+ WorkstationCLM03Lmm(WorkstationModelPtr model, const char* name, xbt_dict_t props, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu):
+ WorkstationCLM03(model, name, props, storage, netElm, cpu){};
+ e_surf_resource_state_t getState();
+};
+
+/**********
+ * Action *
+ **********/
+class WorkstationAction : virtual public Action {
+public:
+ WorkstationAction(ModelPtr model, double cost, bool failed): Action(model, cost, failed) {};
+};
+
+class WorkstationActionLmm : public ActionLmm, public WorkstationAction {
+public:
+ WorkstationActionLmm(ModelPtr model, double cost, bool failed): ActionLmm(model, cost, failed), WorkstationAction(model, cost, failed) {};
+};
+
+
+#endif /* WORKSTATION_HPP_ */
--- /dev/null
- host->power_peak,
+/* Copyright (c) 2007, 2008, 2009, 2010. 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 "workstation_ptask_L07.hpp"
+#include "cpu.hpp"
+#include "surf_routing.hpp"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_workstation);
+
+static int ptask_host_count = 0;
+static xbt_dict_t ptask_parallel_task_link_set = NULL;
+lmm_system_t ptask_maxmin_system = NULL;
+
+WorkstationL07Model::WorkstationL07Model() : WorkstationModel("Workstation ptask_L07") {
+ if (!ptask_maxmin_system)
+ ptask_maxmin_system = lmm_system_new(1);
+ surf_workstation_model = NULL;
+ surf_network_model = new NetworkL07Model();
+ surf_cpu_model = new CpuL07Model();
+ routing_model_create(p_networkModel->createResource("__loopback__",
+ 498000000, NULL,
+ 0.000015, NULL,
+ SURF_RESOURCE_ON, NULL,
+ SURF_LINK_FATPIPE, NULL));
+}
+
+WorkstationL07Model::~WorkstationL07Model() {
+ xbt_dict_free(&ptask_parallel_task_link_set);
+
+ delete surf_cpu_model;
+ delete surf_network_model;
+ ptask_host_count = 0;
+
+ if (ptask_maxmin_system) {
+ lmm_system_free(ptask_maxmin_system);
+ ptask_maxmin_system = NULL;
+ }
+}
+
+double WorkstationL07Model::shareResources(double now)
+{
+ void *_action;
+ WorkstationL07ActionLmmPtr action;
+
+ xbt_swag_t running_actions = this->p_runningActionSet;
+ double min = this->shareResourcesMaxMin(running_actions,
+ ptask_maxmin_system,
+ bottleneck_solve);
+
+ xbt_swag_foreach(_action, running_actions) {
+ action = dynamic_cast<WorkstationL07ActionLmmPtr>(static_cast<ActionPtr>(_action));
+ if (action->m_latency > 0) {
+ if (min < 0) {
+ min = action->m_latency;
+ XBT_DEBUG("Updating min (value) with %p (start %f): %f", action,
+ action->m_start, min);
+ } else if (action->m_latency < min) {
+ min = action->m_latency;
+ XBT_DEBUG("Updating min (latency) with %p (start %f): %f", action,
+ action->m_start, min);
+ }
+ }
+ }
+
+ XBT_DEBUG("min value : %f", min);
+
+ return min;
+}
+
+void WorkstationL07Model::updateActionsState(double now, double delta)
+{
+ double deltap = 0.0;
+ void *_action, *_next_action;
+ WorkstationL07ActionLmmPtr action;
+
+ xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+ action = dynamic_cast<WorkstationL07ActionLmmPtr>(static_cast<ActionPtr>(_action));
+
+ deltap = delta;
+ if (action->m_latency > 0) {
+ if (action->m_latency > deltap) {
+ double_update(&(action->m_latency), deltap);
+ deltap = 0.0;
+ } else {
+ double_update(&(deltap), action->m_latency);
+ action->m_latency = 0.0;
+ }
+ if ((action->m_latency == 0.0) && (action->m_suspended == 0)) {
+ action->updateBound();
+ lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 1.0);
+ }
+ }
+ XBT_DEBUG("Action (%p) : remains (%g) updated by %g.",
+ action, action->m_remains, lmm_variable_getvalue(action->p_variable) * delta);
+ 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);
+
+ XBT_DEBUG("Action (%p) : remains (%g).",
+ action, action->m_remains);
+ 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);
+ } else {
+ /* Need to check that none of the model has failed */
+ lmm_constraint_t cnst = NULL;
+ int i = 0;
+ void *constraint_id = NULL;
+
+ while ((cnst = lmm_get_cnst_from_var(ptask_maxmin_system, action->p_variable,
+ i++))) {
+ constraint_id = lmm_constraint_id(cnst);
+
+ if (static_cast<WorkstationCLM03LmmPtr>(constraint_id)->p_stateCurrent == SURF_RESOURCE_OFF) {
+ XBT_DEBUG("Action (%p) Failed!!", action);
+ action->m_finish = surf_get_clock();
+ action->setState(SURF_ACTION_FAILED);
+ break;
+ }
+ }
+ }
+ }
+ return;
+}
+
+ActionPtr WorkstationL07Model::executeParallelTask(int workstation_nb,
+ void **workstation_list,
+ double
+ *computation_amount, double
+ *communication_amount,
+ double rate)
+{
+ WorkstationL07ActionLmmPtr action;
+ int i, j;
+ unsigned int cpt;
+ int nb_link = 0;
+ int nb_host = 0;
+ double latency = 0.0;
+
+ if (ptask_parallel_task_link_set == NULL)
+ ptask_parallel_task_link_set = xbt_dict_new_homogeneous(NULL);
+
+ xbt_dict_reset(ptask_parallel_task_link_set);
+
+ /* Compute the number of affected resources... */
+ for (i = 0; i < workstation_nb; i++) {
+ for (j = 0; j < workstation_nb; j++) {
+ xbt_dynar_t route=NULL;
+
+ if (communication_amount[i * workstation_nb + j] > 0) {
+ double lat=0.0;
+ unsigned int cpt;
+ void *_link;
+ LinkL07Ptr link;
+
+ routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(
+ workstation_list[i]))->p_netElm,
+ dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(
+ workstation_list[j]))->p_netElm,
+ &route,
+ &lat);
+ latency = MAX(latency, lat);
+
+ xbt_dynar_foreach(route, cpt, _link) {
+ link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(_link));
+ xbt_dict_set(ptask_parallel_task_link_set, link->m_name, link, NULL);
+ }
+ }
+ }
+ }
+
+ nb_link = xbt_dict_length(ptask_parallel_task_link_set);
+ xbt_dict_reset(ptask_parallel_task_link_set);
+
+ for (i = 0; i < workstation_nb; i++)
+ if (computation_amount[i] > 0)
+ nb_host++;
+
+ action = new WorkstationL07ActionLmm(this, 1, 0);
+ XBT_DEBUG("Creating a parallel task (%p) with %d cpus and %d links.",
+ action, workstation_nb, nb_link);
+ action->m_suspended = 0; /* Should be useless because of the
+ calloc but it seems to help valgrind... */
+ action->m_workstationNb = workstation_nb;
+ action->p_workstationList = (WorkstationCLM03Ptr *) workstation_list;
+ action->p_computationAmount = computation_amount;
+ action->p_communicationAmount = communication_amount;
+ action->m_latency = latency;
+ action->m_rate = rate;
+
+ action->p_variable = lmm_variable_new(ptask_maxmin_system, action, 1.0,
+ (action->m_rate > 0) ? action->m_rate : -1.0,
+ workstation_nb + nb_link);
+
+ if (action->m_latency > 0)
+ lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0);
+
+ for (i = 0; i < workstation_nb; i++)
+ lmm_expand(ptask_maxmin_system,
+ static_cast<CpuLmmPtr>(dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(workstation_list[i]))->p_cpu)->p_constraint,
+ action->p_variable, computation_amount[i]);
+
+ for (i = 0; i < workstation_nb; i++) {
+ for (j = 0; j < workstation_nb; j++) {
+ void *_link;
+ LinkL07Ptr link;
+
+ xbt_dynar_t route=NULL;
+ if (communication_amount[i * workstation_nb + j] == 0.0)
+ continue;
+
+ routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(workstation_list[i]))->p_netElm,
+ dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(workstation_list[j]))->p_netElm,
+ &route, NULL);
+
+ xbt_dynar_foreach(route, cpt, _link) {
+ link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(_link));
+ lmm_expand_add(ptask_maxmin_system, link->p_constraint,
+ action->p_variable,
+ communication_amount[i * workstation_nb + j]);
+ }
+ }
+ }
+
+ if (nb_link + nb_host == 0) {
+ action->m_cost = 1.0;
+ action->m_remains = 0.0;
+ }
+
+ return static_cast<ActionPtr>(action);
+}
+
+ResourcePtr WorkstationL07Model::createResource(const char *name, double power_scale,
+ double power_initial,
+ tmgr_trace_t power_trace,
+ e_surf_resource_state_t state_initial,
+ tmgr_trace_t state_trace,
+ xbt_dict_t cpu_properties)
+{
+ WorkstationL07Ptr wk = NULL;
+ xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
+ "Host '%s' declared several times in the platform file.",
+ name);
+
+ wk = new WorkstationL07(this, name, cpu_properties,
+ static_cast<RoutingEdgePtr>(xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL)),
+ dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(host_lib, name, SURF_CPU_LEVEL))));
+
+ xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, static_cast<ResourcePtr>(wk));
+
+ return wk;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+ActionPtr WorkstationL07Model::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst,
+ double size, double rate)
+{
+ void **workstation_list = xbt_new0(void *, 2);
+ double *computation_amount = xbt_new0(double, 2);
+ double *communication_amount = xbt_new0(double, 4);
+ ActionPtr res = NULL;
+
+ workstation_list[0] = static_cast<ResourcePtr>(src);
+ workstation_list[1] = static_cast<ResourcePtr>(dst);
+ communication_amount[1] = size;
+
+ res = executeParallelTask(2, workstation_list,
+ computation_amount,
+ communication_amount, rate);
+
+ return res;
+}
+
+xbt_dynar_t WorkstationL07Model::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst)
+{
+ xbt_dynar_t route=NULL;
+ routing_platf->getRouteAndLatency(src->p_netElm, dst->p_netElm, &route, NULL);
+ return route;
+}
+
+ResourcePtr CpuL07Model::createResource(const char *name, double power_scale,
+ double power_initial,
+ tmgr_trace_t power_trace,
+ e_surf_resource_state_t state_initial,
+ tmgr_trace_t state_trace,
+ xbt_dict_t cpu_properties)
+{
+ CpuL07Ptr cpu = NULL;
+ xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
+ "Host '%s' declared several times in the platform file.",
+ name);
+
+ cpu = new CpuL07(this, name, cpu_properties);
+
+ cpu->p_power.scale = power_scale;
+ xbt_assert(cpu->p_power.scale > 0, "Power has to be >0");
+
+ cpu->m_powerCurrent = power_initial;
+ if (power_trace)
+ cpu->p_power.event =
+ tmgr_history_add_trace(history, power_trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
+
+ cpu->p_stateCurrent = state_initial;
+ if (state_trace)
+ cpu->p_stateEvent =
+ tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
+
+ cpu->p_constraint =
+ lmm_constraint_new(ptask_maxmin_system, cpu,
+ cpu->m_powerCurrent * cpu->p_power.scale);
+
+ xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
+
+ return cpu;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+ResourcePtr NetworkL07Model::createResource(const char *name,
+ double bw_initial,
+ tmgr_trace_t bw_trace,
+ double lat_initial,
+ tmgr_trace_t lat_trace,
+ e_surf_resource_state_t
+ state_initial,
+ tmgr_trace_t state_trace,
+ e_surf_link_sharing_policy_t
+ policy, xbt_dict_t properties)
+{
+ LinkL07Ptr nw_link = new LinkL07(this, xbt_strdup(name), properties);
+ xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
+ "Link '%s' declared several times in the platform file.",
+ name);
+
+ nw_link->m_bwCurrent = bw_initial;
+ if (bw_trace)
+ nw_link->p_bwEvent =
+ tmgr_history_add_trace(history, bw_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
+ nw_link->p_stateCurrent = state_initial;
+ nw_link->m_latCurrent = lat_initial;
+ if (lat_trace)
+ nw_link->p_latEvent =
+ tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
+ if (state_trace)
+ nw_link->p_stateEvent =
+ tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
+
+ nw_link->p_constraint =
+ lmm_constraint_new(ptask_maxmin_system, nw_link,
+ nw_link->m_bwCurrent);
+
+ if (policy == SURF_LINK_FATPIPE)
+ lmm_constraint_shared(nw_link->p_constraint);
+
+ xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast<ResourcePtr>(nw_link));
+ return nw_link;
+}
+
+void WorkstationL07Model::addTraces()
+{
+ xbt_dict_cursor_t cursor = NULL;
+ char *trace_name, *elm;
+
+ if (!trace_connect_list_host_avail)
+ return;
+
+ /* Connect traces relative to cpu */
+ 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);
+ CpuL07Ptr host = dynamic_cast<CpuL07Ptr>(
+ static_cast<ResourcePtr>(
+ surf_cpu_resource_priv(
+ 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, static_cast<ResourcePtr>(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);
+ CpuL07Ptr host = dynamic_cast<CpuL07Ptr>(
+ static_cast<ResourcePtr>(
+ surf_cpu_resource_priv(
+ surf_cpu_resource_by_name(elm))));
+
+ xbt_assert(host, "Host %s undefined", elm);
+ xbt_assert(trace, "Trace %s undefined", trace_name);
+
+ host->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
+ }
+
+ /* Connect traces relative to network */
+ xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ LinkL07Ptr link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+ xbt_assert(link, "Link %s undefined", elm);
+ xbt_assert(trace, "Trace %s undefined", trace_name);
+
+ link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+ }
+
+ xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ LinkL07Ptr link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+ xbt_assert(link, "Link %s undefined", elm);
+ xbt_assert(trace, "Trace %s undefined", trace_name);
+
+ link->p_bwEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+ }
+
+ xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ LinkL07Ptr link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+ xbt_assert(link, "Link %s undefined", elm);
+ xbt_assert(trace, "Trace %s undefined", trace_name);
+
+ link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+ }
+}
+
+/************
+ * Resource *
+ ************/
+
+WorkstationL07::WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu)
+ : Resource(model, name, props), WorkstationCLM03Lmm(model, name, props, NULL, netElm, cpu)
+{
+}
+
++double WorkstationL07::getPowerPeakAt(int pstate_index)
++{
++ XBT_DEBUG("[ws_get_power_peak_at] Not implemented for workstation_ptask_L07");
++ return 0.0;
++}
++
++int WorkstationL07::getNbPstates()
++{
++ XBT_DEBUG("[ws_get_nb_pstates] Not implemented for workstation_ptask_L07");
++ return 0.0;
++}
++
++void WorkstationL07::setPowerPeakAt(int pstate_index)
++{
++ XBT_DEBUG("[ws_set_power_peak_at] Not implemented for workstation_ptask_L07");
++}
++
++double WorkstationL07::getConsumedEnergy()
++{
++ XBT_DEBUG("[ws_get_consumed_energy] Not implemented for workstation_ptask_L07");
++ return 0.0;
++}
++
+CpuL07::CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t props)
+ : Resource(model, name, props), CpuLmm(model, name, props) {
+
+}
+
+LinkL07::LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props)
+ : Resource(model, name, props), NetworkCm02LinkLmm(model, name, props) {
+
+}
+
+bool CpuL07::isUsed(){
+ return lmm_constraint_used(ptask_maxmin_system, p_constraint);
+}
+
+bool LinkL07::isUsed(){
+ return lmm_constraint_used(ptask_maxmin_system, p_constraint);
+}
+
+void CpuL07::updateState(tmgr_trace_event_t event_type, double value, double date){
+ XBT_DEBUG("Updating cpu %s (%p) with value %g", m_name, this, value);
+ if (event_type == p_power.event) {
+ m_powerCurrent = value;
+ lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_powerCurrent * p_power.scale);
+ if (tmgr_trace_event_free(event_type))
+ p_power.event = NULL;
+ } else if (event_type == p_stateEvent) {
+ if (value > 0)
+ p_stateCurrent = SURF_RESOURCE_ON;
+ else
+ p_stateCurrent = SURF_RESOURCE_OFF;
+ if (tmgr_trace_event_free(event_type))
+ p_stateEvent = NULL;
+ } else {
+ XBT_CRITICAL("Unknown event ! \n");
+ xbt_abort();
+ }
+ return;
+}
+
+void LinkL07::updateState(tmgr_trace_event_t event_type, double value, double date){
+ XBT_DEBUG("Updating link %s (%p) with value=%f for date=%g", m_name, this, value, date);
+ if (event_type == p_bwEvent) {
+ m_bwCurrent = value;
+ lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_bwCurrent);
+ if (tmgr_trace_event_free(event_type))
+ p_bwEvent = NULL;
+ } else if (event_type == p_latEvent) {
+ lmm_variable_t var = NULL;
+ WorkstationL07ActionLmmPtr action;
+ lmm_element_t elem = NULL;
+
+ m_latCurrent = value;
+ while ((var = lmm_get_var_from_cnst(ptask_maxmin_system, p_constraint, &elem))) {
+ action = (WorkstationL07ActionLmmPtr) lmm_variable_id(var);
+ action->updateBound();
+ }
+ if (tmgr_trace_event_free(event_type))
+ p_latEvent = NULL;
+ } else if (event_type == p_stateEvent) {
+ if (value > 0)
+ p_stateCurrent = SURF_RESOURCE_ON;
+ else
+ p_stateCurrent = SURF_RESOURCE_OFF;
+ if (tmgr_trace_event_free(event_type))
+ p_stateEvent = NULL;
+ } else {
+ XBT_CRITICAL("Unknown event ! \n");
+ xbt_abort();
+ }
+ return;
+}
+
+e_surf_resource_state_t WorkstationL07::getState()
+{
+ return p_cpu->p_stateCurrent;
+}
+
+e_surf_resource_state_t CpuL07::getState()
+{
+ return p_stateCurrent;
+}
+
+double CpuL07::getSpeed(double load)
+{
+ return load * p_power.scale;
+}
+
+double CpuL07::getAvailableSpeed()
+{
+ return m_powerCurrent;
+}
+
+ActionPtr WorkstationL07::execute(double size)
+{
+ void **workstation_list = xbt_new0(void *, 1);
+ double *computation_amount = xbt_new0(double, 1);
+ double *communication_amount = xbt_new0(double, 1);
+
+ workstation_list[0] = static_cast<ResourcePtr>(this);
+ communication_amount[0] = 0.0;
+ computation_amount[0] = size;
+
+ return static_cast<WorkstationL07ModelPtr>(p_model)->executeParallelTask(1, workstation_list,
+ computation_amount,
+ communication_amount, -1);
+}
+
+ActionPtr WorkstationL07::sleep(double duration)
+{
+ WorkstationL07ActionLmmPtr action = NULL;
+
+ XBT_IN("(%s,%g)", m_name, duration);
+
+ action = dynamic_cast<WorkstationL07ActionLmmPtr>(execute(1.0));
+ action->m_maxDuration = duration;
+ action->m_suspended = 2;
+ lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0);
+
+ XBT_OUT();
+ return action;
+}
+
+double LinkL07::getBandwidth()
+{
+ return m_bwCurrent;
+}
+
+double LinkL07::getLatency()
+{
+ return m_latCurrent;
+}
+
+bool LinkL07::isShared()
+{
+ return lmm_constraint_is_shared(p_constraint);
+}
+
+/**********
+ * Action *
+ **********/
+
+WorkstationL07ActionLmm::~WorkstationL07ActionLmm(){
+ free(p_workstationList);
+ free(p_communicationAmount);
+ free(p_computationAmount);
+#ifdef HAVE_TRACING
+ xbt_free(p_category);
+#endif
+}
+
+void WorkstationL07ActionLmm::updateBound()
+{
+ double lat_current = 0.0;
+ double lat_bound = -1.0;
+ int i, j;
+
+ for (i = 0; i < m_workstationNb; i++) {
+ for (j = 0; j < m_workstationNb; j++) {
+ xbt_dynar_t route=NULL;
+
+ if (p_communicationAmount[i * m_workstationNb + j] > 0) {
+ double lat = 0.0;
+ routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(((void**)p_workstationList)[i]))->p_netElm,
+ dynamic_cast<WorkstationL07Ptr>(
+ static_cast<ResourcePtr>(((void**)p_workstationList)[j]))->p_netElm,
+ &route, &lat);
+
+ lat_current = MAX(lat_current, lat * p_communicationAmount[i * m_workstationNb + j]);
+ }
+ }
+ }
+ lat_bound = sg_tcp_gamma / (2.0 * lat_current);
+ XBT_DEBUG("action (%p) : lat_bound = %g", this, lat_bound);
+ if ((m_latency == 0.0) && (m_suspended == 0)) {
+ if (m_rate < 0)
+ lmm_update_variable_bound(ptask_maxmin_system, p_variable, lat_bound);
+ else
+ lmm_update_variable_bound(ptask_maxmin_system, p_variable, min(m_rate, lat_bound));
+ }
+}
+
+int WorkstationL07ActionLmm::unref()
+{
+ m_refcount--;
+ if (!m_refcount) {
+ xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+ if (p_variable)
+ lmm_variable_free(ptask_maxmin_system, p_variable);
+ delete this;
+ return 1;
+ }
+ return 0;
+}
+
+void WorkstationL07ActionLmm::cancel()
+{
+ setState(SURF_ACTION_FAILED);
+ return;
+}
+
+void WorkstationL07ActionLmm::suspend()
+{
+ XBT_IN("(%p))", this);
+ if (m_suspended != 2) {
+ m_suspended = 1;
+ lmm_update_variable_weight(ptask_maxmin_system, p_variable, 0.0);
+ }
+ XBT_OUT();
+}
+
+void WorkstationL07ActionLmm::resume()
+{
+ XBT_IN("(%p)", this);
+ if (m_suspended != 2) {
+ lmm_update_variable_weight(ptask_maxmin_system, p_variable, 1.0);
+ m_suspended = 0;
+ }
+ XBT_OUT();
+}
+
+bool WorkstationL07ActionLmm::isSuspended()
+{
+ return m_suspended == 1;
+}
+
+void WorkstationL07ActionLmm::setMaxDuration(double duration)
+{ /* FIXME: should inherit */
+ XBT_IN("(%p,%g)", this, duration);
+ m_maxDuration = duration;
+ XBT_OUT();
+}
+
+void WorkstationL07ActionLmm::setPriority(double priority)
+{ /* FIXME: should inherit */
+ XBT_IN("(%p,%g)", this, priority);
+ m_priority = priority;
+ XBT_OUT();
+}
+
+double WorkstationL07ActionLmm::getRemains()
+{
+ XBT_IN("(%p)", this);
+ XBT_OUT();
+ return m_remains;
+}
+
+
+
+
+
+
+
+
+
+static void ptask_finalize(void)
+{
+ xbt_dict_free(&ptask_parallel_task_link_set);
+
+ delete surf_workstation_model;
+ surf_workstation_model = NULL;
+ delete surf_network_model;
+ surf_network_model = NULL;
+
+ ptask_host_count = 0;
+
+ if (ptask_maxmin_system) {
+ lmm_system_free(ptask_maxmin_system);
+ ptask_maxmin_system = NULL;
+ }
+}
+
+/**************************************/
+/******* Resource Private **********/
+/**************************************/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************/
+/*** Resource Creation & Destruction **/
+/**************************************/
+
+static void ptask_parse_workstation_init(sg_platf_host_cbarg_t host)
+{
++ double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double);
++ //cpu->power_peak = power_peak;
++ xbt_dynar_free(&(host->power_peak)); /* kill memory leak */
+ static_cast<WorkstationL07ModelPtr>(surf_workstation_model)->createResource(
+ host->id,
- static_cast<CpuL07ModelPtr>(surf_cpu_model)->createResource(
++ power_peak,
+ host->power_scale,
+ host->power_trace,
+ host->initial_state,
+ host->state_trace,
+ host->properties);
+}
+
+static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host)
+{
- host->power_peak,
++ double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double);
++ static_cast<CpuL07ModelPtr>(surf_cpu_model)->createResource(
+ host->id,
++ power_peak,
+ host->power_scale,
+ host->power_trace,
+ host->initial_state,
+ host->state_trace,
+ host->properties);
+}
+
+
+
+static void ptask_parse_link_init(sg_platf_link_cbarg_t link)
+{
+ if (link->policy == SURF_LINK_FULLDUPLEX) {
+ char *link_id;
+ link_id = bprintf("%s_UP", link->id);
+ static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link_id,
+ link->bandwidth,
+ link->bandwidth_trace,
+ link->latency,
+ link->latency_trace,
+ link->state,
+ link->state_trace,
+ link->policy,
+ link->properties);
+ xbt_free(link_id);
+ link_id = bprintf("%s_DOWN", link->id);
+ static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link_id,
+ link->bandwidth,
+ link->bandwidth_trace,
+ link->latency,
+ link->latency_trace,
+ link->state,
+ link->state_trace,
+ link->policy,
+ NULL); /* FIXME: We need to deep copy the
+ * properties or we won't be able to free
+ * it */
+ xbt_free(link_id);
+ } else {
+ static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link->id,
+ link->bandwidth,
+ link->bandwidth_trace,
+ link->latency,
+ link->latency_trace,
+ link->state,
+ link->state_trace,
+ link->policy,
+ link->properties);
+ }
+
+ current_property_set = NULL;
+}
+
+static void ptask_add_traces(){
+ static_cast<WorkstationL07ModelPtr>(surf_workstation_model)->addTraces();
+}
+
+static void ptask_define_callbacks()
+{
+ sg_platf_host_add_cb(ptask_parse_cpu_init);
+ sg_platf_host_add_cb(ptask_parse_workstation_init);
+ sg_platf_link_add_cb(ptask_parse_link_init);
+ sg_platf_postparse_add_cb(ptask_add_traces);
+}
+
+/**************************************/
+/*************** Generic **************/
+/**************************************/
+void surf_workstation_model_init_ptask_L07(void)
+{
+ XBT_INFO("surf_workstation_model_init_ptask_L07");
+ xbt_assert(!surf_cpu_model, "CPU model type already defined");
+ xbt_assert(!surf_network_model, "network model type already defined");
+ ptask_define_callbacks();
+ surf_workstation_model = new WorkstationL07Model();
+ ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
+ xbt_dynar_push(model_list, &model);
+}
--- /dev/null
+#include "workstation.hpp"
+
+#ifndef WORKSTATION_L07_HPP_
+#define WORKSTATION_L07_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class WorkstationL07Model;
+typedef WorkstationL07Model *WorkstationL07ModelPtr;
+
+class CpuL07Model;
+typedef CpuL07Model *CpuL07ModelPtr;
+
+class NetworkL07Model;
+typedef NetworkL07Model *NetworkL07ModelPtr;
+
+class WorkstationL07;
+typedef WorkstationL07 *WorkstationL07Ptr;
+
+class CpuL07;
+typedef CpuL07 *CpuL07Ptr;
+
+class LinkL07;
+typedef LinkL07 *LinkL07Ptr;
+
+class WorkstationL07ActionLmm;
+typedef WorkstationL07ActionLmm *WorkstationL07ActionLmmPtr;
+
+/*FIXME:class WorkstationActionLmm;
+typedef WorkstationActionLmm *WorkstationActionLmmPtr;*/
+
+/*********
+ * Tools *
+ *********/
+
+/*********
+ * Model *
+ *********/
+class WorkstationL07Model : public WorkstationModel {
+public:
+ WorkstationL07Model();
+ ~WorkstationL07Model();
+
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+ ResourcePtr createResource(const char *name, double power_scale,
+ double power_initial,
+ tmgr_trace_t power_trace,
+ e_surf_resource_state_t state_initial,
+ tmgr_trace_t state_trace,
+ xbt_dict_t cpu_properties);
+ ActionPtr executeParallelTask(int workstation_nb,
+ void **workstation_list,
+ double *computation_amount,
+ double *communication_amount,
+ double rate);
+ xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst);
+ ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate);
+ void addTraces();
+ CpuL07ModelPtr p_cpuModel;
+ NetworkL07ModelPtr p_networkModel;
+};
+
+class CpuL07Model : public CpuModel {
+public:
+ CpuL07Model() : CpuModel("cpuL07") {};
+ ~CpuL07Model() {surf_cpu_model = NULL;};
+ ResourcePtr createResource(const char *name, double power_scale,
+ double power_initial,
+ tmgr_trace_t power_trace,
+ e_surf_resource_state_t state_initial,
+ tmgr_trace_t state_trace,
+ xbt_dict_t cpu_properties);
+ void addTraces() {DIE_IMPOSSIBLE;};
+ WorkstationL07ModelPtr p_workstationModel;
+};
+
+class NetworkL07Model : public NetworkCm02Model {
+public:
+ NetworkL07Model() : NetworkCm02Model(0) {};
+ ~NetworkL07Model() {surf_network_model = NULL;};
+ ResourcePtr createResource(const char *name,
+ double bw_initial,
+ tmgr_trace_t bw_trace,
+ double lat_initial,
+ tmgr_trace_t lat_trace,
+ e_surf_resource_state_t
+ state_initial,
+ tmgr_trace_t state_trace,
+ e_surf_link_sharing_policy_t
+ policy, xbt_dict_t properties);
+
+ xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst) {DIE_IMPOSSIBLE;};
+ ActionPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst, double size, double rate) {DIE_IMPOSSIBLE;};
+ void addTraces() {DIE_IMPOSSIBLE;};
+ WorkstationL07ModelPtr p_workstationModel;
+};
+
+/************
+ * Resource *
+ ************/
+
+class WorkstationL07 : public WorkstationCLM03Lmm {
+public:
+ WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu);
+ //bool isUsed();
+ bool isUsed() {DIE_IMPOSSIBLE;};
+ void updateState(tmgr_trace_event_t event_type, double value, double date) {DIE_IMPOSSIBLE;};
+ ActionPtr execute(double size);
+ ActionPtr sleep(double duration);
+ e_surf_resource_state_t getState();
++ double getPowerPeakAt(int pstate_index);
++ int getNbPstates();
++ void setPowerPeakAt(int pstate_index);
++ double getConsumedEnergy();
+};
+
+class CpuL07 : public CpuLmm {
+public:
+ CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t properties);
+ bool isUsed();
+ //bool isUsed() {DIE_IMPOSSIBLE;};
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+ e_surf_resource_state_t getState();
+ double getSpeed(double load);
+ double getAvailableSpeed();
+ ActionPtr execute(double size) {DIE_IMPOSSIBLE;};
+ ActionPtr sleep(double duration) {DIE_IMPOSSIBLE;};
++
++ double getCurrentPowerPeak() {};
++ double getPowerPeakAt(int pstate_index) {};
++ int getNbPstates() {};
++ void setPowerPeakAt(int pstate_index) {};
++ double getConsumedEnergy() {};
++
+ double m_powerCurrent;
+};
+
+class LinkL07 : public NetworkCm02LinkLmm {
+public:
+ LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props);
+ bool isUsed();
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+ double getBandwidth();
+ double getLatency();
+ bool isShared();
+
+ double m_latCurrent;
+ tmgr_trace_event_t p_latEvent;
+ double m_bwCurrent;
+ tmgr_trace_event_t p_bwEvent;
+};
+
+/**********
+ * Action *
+ **********/
+class WorkstationL07ActionLmm : public WorkstationActionLmm {
+public:
+ WorkstationL07ActionLmm(ModelPtr model, double cost, bool failed)
+ : Action(model, cost, failed), WorkstationActionLmm(model, cost, failed) {};
+ ~WorkstationL07ActionLmm();
+
+ void updateBound();
+
+ int unref();
+ void cancel();
+ void suspend();
+ void resume();
+ bool isSuspended();
+ void setMaxDuration(double duration);
+ void setPriority(double priority);
+ double getRemains();
+
+ int m_workstationNb;
+ WorkstationCLM03Ptr *p_workstationList;
+ double *p_computationAmount;
+ double *p_communicationAmount;
+ double m_latency;
+ double m_rate;
+};
+
+#endif /* WORKSTATION_L07_HPP_ */