src/surf/gtnets/gtnets_interface.h
src/surf/gtnets/gtnets_simulator.h
src/surf/gtnets/gtnets_topology.h
- src/surf/solver.hpp
- src/surf/solver.h
+ #src/surf/solver.hpp
+ #src/surf/solver.h
src/surf/maxmin_private.h
- src/surf/maxmin_private_.h
+ #src/surf/maxmin_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_constant.hpp
src/surf/ns3/my-point-to-point-helper.h
src/surf/ns3/ns3_interface.h
src/surf/ns3/ns3_simulator.h
src/surf/cpu.cpp
src/surf/cpu_ti.cpp
src/surf/cpu_cas01.cpp
- src/surf/cpu_cas01.c
- src/surf/cpu_ti.c
- src/surf/fair_bottleneck.cpp
+ src/surf/fair_bottleneck.c
src/surf/instr_routing.c
src/surf/instr_surf.c
- src/surf/lagrange.cpp
- src/surf/solver.cpp
- src/surf/solver_c.cpp
+ src/surf/lagrange.c
+ src/surf/maxmin.c
src/surf/network.cpp
- src/surf/network.c
- src/surf/network_constant.c
+ src/surf/network_smpi.cpp
+ src/surf/network_constant.cpp
src/surf/platf_generator.c
src/surf/random_mgr.c
src/surf/sg_platf.c
- src/surf/storage.c
- src/surf/surf.c
+ src/surf/storage.cpp
src/surf/surf.cpp
- src/surf/surf_action.c
- src/surf/surf_model.c
- src/surf/surf_routing.c
- src/surf/surf_routing_cluster.c
- src/surf/surf_routing_dijkstra.c
- src/surf/surf_routing_floyd.c
- src/surf/surf_routing_full.c
- src/surf/surf_routing_generic.c
- src/surf/surf_routing_none.c
- src/surf/surf_routing_vivaldi.c
+ src/surf/surf_interface.cpp
+ src/surf/surf_routing.cpp
+ src/surf/surf_routing_cluster.cpp
+ src/surf/surf_routing_dijkstra.cpp
+ src/surf/surf_routing_floyd.cpp
+ src/surf/surf_routing_full.cpp
+ src/surf/surf_routing_generic.cpp
+ src/surf/surf_routing_none.cpp
+ src/surf/surf_routing_vivaldi.cpp
src/surf/surfxml_parse.c
src/surf/surfxml_parseplatf.c
src/surf/trace_mgr.c
- src/surf/workstation.c
- src/surf/workstation_ptask_L07.c
+ src/surf/workstation.cpp
+ src/surf/workstation_ptask_L07.cpp
src/xbt/xbt_sg_stubs.c
)
typedef struct s_smx_rvpoint *msg_mailbox_t;
/* ******************************** Environment ************************************ */
-typedef struct s_as *msg_as_t;
+typedef struct As *msg_as_t;
/* ******************************** Host ************************************ */
#include <xbt.h>
typedef void *sg_routing_link_t; /* The actual type is model-dependent so use void* instead*/
-typedef struct s_routing_edge *sg_routing_edge_t;
+typedef struct RoutingEdge *sg_routing_edge_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
XBT_PUBLIC(sg_routing_edge_t) sg_routing_edge_by_name_or_null(const char *name);
+#ifdef __cplusplus
+}
+#endif
/** Defines whether a given resource is working or not */
typedef enum {
/** opaque structure defining a event generator for availability based on a probability distribution */
typedef struct probabilist_event_generator *probabilist_event_generator_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_file(const char *filename);
XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_string(const char *id,
const char *input,
XBT_PUBLIC(probabilist_event_generator_t) tmgr_event_generator_new_weibull(const char* id,
double scale,
double shape);
+#ifdef __cplusplus
+}
+#endif
+
typedef xbt_dictelm_t sg_host_t;
static inline char* sg_host_name(sg_host_t host) {
return host->key;
/* ***************************************** */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
XBT_PUBLIC(void) sg_platf_begin(void); // Start a new platform
XBT_PUBLIC(void) sg_platf_end(void); // Finish the creation of the platform
typedef void (*sg_platf_process_cb_t)(sg_platf_process_cbarg_t);
XBT_PUBLIC(void) sg_platf_process_add_cb(sg_platf_process_cb_t fct);
+#ifdef __cplusplus
+}
+#endif
#endif /* SG_PLATF_H */
#include "xbt/lib.h"
#include "simgrid/platf_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
XBT_PUBLIC(xbt_lib_t) host_lib;
XBT_PUBLIC(int) ROUTING_HOST_LEVEL; //Routing level
XBT_PUBLIC(int) SURF_CPU_LEVEL; //Surf cpu level
void routing_cluster_add_backbone(void* bb);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _SURF_SURF_H */
typedef struct xbt_automaton* xbt_automaton_t;
typedef struct xbt_automaton_exp_label{
- enum{or=0, and=1, not=2, predicat=3, one=4} type;
+ enum{AUT_OR=0, AUT_AND=1, AUT_NOT=2, AUT_PREDICAT=3, AUT_ONE=4} type;
union{
struct{
struct xbt_automaton_exp_label* left_exp;
#include <xbt/misc.h> /* XBT_PUBLIC */
+#ifdef __cplusplus
+extern "C" {
+#endif
XBT_PUBLIC(void) xbt_init(int *argc, char **argv);
XBT_PUBLIC(void) xbt_exit(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _XBT_MODULE_H */
#include "xbt.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
XBT_PUBLIC(int) TRACE_start (void);
XBT_PUBLIC(int) TRACE_end (void);
XBT_PUBLIC(void) TRACE_global_init(int *argc, char **argv);
XBT_PUBLIC(void) TRACE_surf_resource_utilization_release(void);
XBT_PUBLIC(void) TRACE_add_start_function(void (*func)(void));
XBT_PUBLIC(void) TRACE_add_end_function(void (*func)(void));
+
+#ifdef __cplusplus
+}
+#endif
/* ***************************************** */
/* TUTORIAL: New TAG */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef void (*sg_platf_gpu_cb_t)(sg_platf_gpu_cbarg_t);
XBT_PUBLIC(void) sg_platf_gpu_add_cb(sg_platf_gpu_cb_t);
/* ***************************************** */
XBT_PUBLIC(void) sg_platf_storage_type_add_cb(sg_platf_storage_type_cb_t fct);
XBT_PUBLIC(void) sg_platf_mount_add_cb(sg_platf_mount_cb_t fct);
+#ifdef __cplusplus
+}
+#endif
/** \brief Pick the right models for CPU, net and workstation, and call their model_init_preparse
*
* Must be called within parsing/creating the environment (after the <config>s, if any, and before <AS> or friends such as <cluster>)
/*******************************************/
/*** Config Globals **************************/
/*******************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
XBT_PUBLIC_DATA(xbt_cfg_t) _sg_cfg_set;
XBT_PUBLIC(int) sg_cfg_get_int(const char* name);
XBT_PUBLIC(double) sg_cfg_get_double(const char* name);
void sg_config_init(int *argc, char **argv);
void sg_config_finalize(void);
+
+#ifdef __cplusplus
+}
+#endif
* Generic data structure for a model. The workstations,
* the CPUs and the network links are examples of models.
*/
-typedef struct surf_model *surf_model_t;
+//FIXME: typedef struct surf_model *surf_model_t;
/** \ingroup SURF_actions
* \brief Action datatype
* 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_stat *surf_stat_t;
+typedef struct lmm_element *lmm_element_t;
+typedef struct lmm_variable *lmm_variable_t;
+typedef struct lmm_constraint *lmm_constraint_t;
+typedef struct lmm_constraint_light *lmm_constraint_light_t;
+typedef struct lmm_system *lmm_system_t;
+
typedef struct tmgr_history *tmgr_history_t;
typedef struct tmgr_trace_event *tmgr_trace_event_t;
--- /dev/null
+/* Copyright (c) 2004, 2005, 2006, 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. */
+
+#ifndef _SURF_MAXMIN_H
+#define _SURF_MAXMIN_H
+
+#include "portable.h"
+#include "xbt/misc.h"
+#include "surf/datatypes.h"
+#include <math.h>
+
+extern double sg_maxmin_precision;
+#define MAXMIN_PRECISION sg_maxmin_precision
+static XBT_INLINE void double_update(double *variable, double value)
+{
+ *variable -= value;
+ if (*variable < MAXMIN_PRECISION)
+ *variable = 0.0;
+}
+
+static XBT_INLINE int double_positive(double value)
+{
+ return (value > MAXMIN_PRECISION);
+}
+
+static XBT_INLINE int double_equals(double value1, double value2)
+{
+ return (fabs(value1 - value2) < MAXMIN_PRECISION);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XBT_PUBLIC(lmm_system_t) lmm_system_new(int selective_update);
+XBT_PUBLIC(void) lmm_system_free(lmm_system_t sys);
+void lmm_variable_disable(lmm_system_t sys, lmm_variable_t var);
+
+XBT_PUBLIC(lmm_constraint_t) lmm_constraint_new(lmm_system_t sys, void *id,
+ double bound_value);
+void lmm_constraint_shared(lmm_constraint_t cnst);
+int lmm_constraint_is_shared(lmm_constraint_t cnst);
+
+void lmm_constraint_free(lmm_system_t sys, lmm_constraint_t cnst);
+
+XBT_PUBLIC(lmm_variable_t) lmm_variable_new(lmm_system_t sys, void *id,
+ double weight_value,
+ double bound,
+ int number_of_constraints);
+XBT_PUBLIC(void) lmm_variable_free(lmm_system_t sys, lmm_variable_t var);
+XBT_PUBLIC(double) lmm_variable_getvalue(lmm_variable_t var);
+XBT_PUBLIC(double) lmm_variable_getbound(lmm_variable_t var);
+
+XBT_PUBLIC(void) lmm_expand(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value);
+void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value);
+void lmm_elem_set_value(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value);
+
+lmm_constraint_t lmm_get_cnst_from_var(lmm_system_t sys,
+ lmm_variable_t var, int num);
+double lmm_get_cnst_weight_from_var(lmm_system_t sys, lmm_variable_t var,
+ int num);
+int lmm_get_number_of_cnst_from_var(lmm_system_t sys, lmm_variable_t var);
+lmm_variable_t lmm_get_var_from_cnst(lmm_system_t sys,
+ lmm_constraint_t cnst,
+ lmm_element_t * elem);
+
+lmm_constraint_t lmm_get_first_active_constraint(lmm_system_t sys);
+lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t sys,
+ lmm_constraint_t cnst);
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+XBT_PUBLIC(int) lmm_is_variable_limited_by_latency(lmm_variable_t var);
+#endif
+
+void *lmm_constraint_id(lmm_constraint_t cnst);
+void *lmm_variable_id(lmm_variable_t var);
+
+void lmm_update(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value);
+void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var,
+ double bound);
+
+
+XBT_PUBLIC(void) lmm_update_variable_weight(lmm_system_t sys,
+ lmm_variable_t var,
+ double weight);
+double lmm_get_variable_weight(lmm_variable_t var);
+
+XBT_PUBLIC(void) lmm_update_constraint_bound(lmm_system_t sys,
+ lmm_constraint_t cnst,
+ double bound);
+
+int lmm_constraint_used(lmm_system_t sys, lmm_constraint_t cnst);
+
+
+XBT_PUBLIC(void) lmm_solve(lmm_system_t sys);
+
+XBT_PUBLIC(void) lagrange_solve(lmm_system_t sys);
+XBT_PUBLIC(void) bottleneck_solve(lmm_system_t sys);
+
+/**
+ * Default functions associated to the chosen protocol. When
+ * using the lagrangian approach.
+ */
+
+XBT_PUBLIC(void) lmm_set_default_protocol_function(double (*func_f)
+ (lmm_variable_t var,
+ double x),
+ double (*func_fp)
+ (lmm_variable_t var,
+ double x),
+ double (*func_fpi)
+ (lmm_variable_t var,
+ double x));
+
+XBT_PUBLIC(double func_reno_f) (lmm_variable_t var, double x);
+XBT_PUBLIC(double func_reno_fp) (lmm_variable_t var, double x);
+XBT_PUBLIC(double func_reno_fpi) (lmm_variable_t var, double x);
+
+XBT_PUBLIC(double func_reno2_f) (lmm_variable_t var, double x);
+XBT_PUBLIC(double func_reno2_fp) (lmm_variable_t var, double x);
+XBT_PUBLIC(double func_reno2_fpi) (lmm_variable_t var, double x);
+
+XBT_PUBLIC(double func_vegas_f) (lmm_variable_t var, double x);
+XBT_PUBLIC(double func_vegas_fp) (lmm_variable_t var, double x);
+XBT_PUBLIC(double func_vegas_fpi) (lmm_variable_t var, double x);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SURF_MAXMIN_H */
#include "xbt/config.h"
#include "surf/datatypes.h"
#include "xbt/lib.h"
-#include "surf/solver.h"
#include "surf/surf_routing.h"
#include "simgrid/platf_interface.h"
#endif
extern xbt_dynar_t surf_path;
-
typedef enum {
SURF_NETWORK_ELEMENT_NULL = 0, /* NULL */
SURF_NETWORK_ELEMENT_HOST, /* host type */
SURF_NETWORK_ELEMENT_AS /* AS type */
} e_surf_network_element_type_t;
+#ifdef __cplusplus
+class Model;
+class CpuModel;
+class WorkstationModel;
+class NetworkCm02Model;
+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 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 Resource *surf_resource_t;
+typedef ResourceLmm *surf_resource_lmm_t;
+typedef WorkstationCLM03 *surf_workstation_CLM03_t;
+typedef xbt_dictelm_t surf_workstation_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);
XBT_PUBLIC(void) model_help(const char *category,
s_surf_model_description_t * table);
-enum heap_action_type{
- LATENCY = 100,
- MAX_DURATION,
- NORMAL,
- NOTSET
-};
-
-/** \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 struct surf_action {
- s_xbt_swag_hookup_t state_hookup;
- xbt_swag_t state_set;
- double cost; /**< cost */
- double priority; /**< priority (1.0 by default) */
- double max_duration; /**< max_duration (may fluctuate until
- the task is completed) */
- double remains; /**< How much of that cost remains to
- * be done in the currently running task */
-#ifdef HAVE_LATENCY_BOUND_TRACKING
- int latency_limited; /**< Set to 1 if is limited by latency, 0 otherwise */
-#endif
- double start; /**< start time */
- double finish; /**< finish time : this is modified during the run
- * and fluctuates until the task is completed */
- void *data; /**< for your convenience */
- int refcount;
- surf_model_t model_type;
-#ifdef HAVE_TRACING
- char *category; /**< tracing category for categorized resource utilization monitoring */
-#endif
- surf_file_t file; /**< surf_file_t for storage model */
- xbt_dict_t ls_dict;
-} s_surf_action_t;
-
-typedef struct surf_action_lmm {
- s_surf_action_t generic_action;
- lmm_variable_t variable;
- int suspended;
- s_xbt_swag_hookup_t action_list_hookup;
- int index_heap;
- double last_update;
- double last_value;
- enum heap_action_type hat;
-} s_surf_action_lmm_t, *surf_action_lmm_t;
/** \ingroup SURF_actions
* \brief Action states
*
* \see surf_action_t, surf_action_state_t
*/
+
typedef enum {
SURF_ACTION_READY = 0, /**< Ready */
SURF_ACTION_RUNNING, /**< Running */
/**< Not in the system anymore. Why did you ask ? */
} e_surf_action_state_t;
-/** \ingroup SURF_actions
- * \brief Action state sets
- *
- * This structure contains some sets of actions.
- * It provides a fast access to the actions in each state.
- *
- * \see surf_action_t, e_surf_action_state_t
- */
-typedef struct surf_action_state {
- xbt_swag_t ready_action_set;
- /**< Actions in state SURF_ACTION_READY */
- xbt_swag_t running_action_set;
- /**< Actions in state SURF_ACTION_RUNNING */
- xbt_swag_t failed_action_set;
- /**< Actions in state SURF_ACTION_FAILED */
- xbt_swag_t done_action_set;
- /**< Actions in state SURF_ACTION_DONE */
-} s_surf_action_state_t, *surf_action_state_t;
-
/***************************/
/* Generic model object */
/***************************/
-typedef struct s_routing_platf s_routing_platf_t, *routing_platf_t;
+//FIXME:REMOVE typedef struct s_routing_platf s_routing_platf_t, *routing_platf_t;
XBT_PUBLIC_DATA(routing_platf_t) routing_platf;
/*******************************************
} s_surf_model_extension_network_t;
/* Storage model */
-
+//
/** \ingroup SURF_models
* \brief Storage model extension public
*
} 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 xbt_lib_get_level((void *)host, SURF_STORAGE_LEVEL);
+ return (void*)xbt_lib_get_level((xbt_dictelm_t)host, 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;
-} 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
+
+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_workstation_CLM03_t src, surf_workstation_CLM03_t dst, double size, double rate);
+xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model, surf_workstation_t src, surf_workstation_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_resource_t resource);
+xbt_dict_t surf_resource_get_properties(surf_resource_t resource);
+e_surf_resource_state_t surf_resource_get_state(surf_resource_t resource);
+double surf_workstation_get_speed(surf_workstation_t resource, double load);
+double surf_workstation_get_available_speed(surf_workstation_t resource);
+int surf_workstation_get_core(surf_workstation_t resource);
+surf_action_t surf_workstation_execute(surf_workstation_t resource, double size);
+surf_action_t surf_workstation_sleep(surf_workstation_t resource, double duration);
+surf_action_t surf_workstation_communicate(surf_workstation_t workstation_src, surf_workstation_t workstation_dst, double size, double rate);
+surf_action_t surf_workstation_open(surf_workstation_t workstation, const char* mount, const char* path);
+surf_action_t surf_workstation_close(surf_workstation_t workstation, surf_file_t fd);
+surf_action_t surf_cpu_execute(surf_cpu_t cpu, double size);
+surf_action_t surf_cpu_sleep(surf_cpu_t cpu, double duration);
+int surf_workstation_unlink(surf_workstation_t workstation, surf_file_t fd);
+surf_action_t surf_workstation_ls(surf_workstation_t workstation, const char* mount, const char *path);
+size_t surf_workstation_get_size(surf_workstation_t workstation, surf_file_t fd);
+surf_action_t surf_workstation_read(surf_workstation_t resource, void *ptr, size_t size, surf_file_t fd);
+surf_action_t surf_workstation_write(surf_workstation_t resource, const void *ptr, size_t size, surf_file_t fd);
+int surf_network_link_is_shared(surf_network_link_t link);
+double surf_network_link_get_bandwidth(surf_network_link_t link);
+double surf_network_link_get_latency(surf_network_link_t link);
+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_storage_action_lmm_t action);
+xbt_dict_t surf_storage_action_get_ls_dict(surf_storage_action_lmm_t action);
+
+#ifdef __cplusplus
+}
+#endif
/**************************************/
/* Implementations of model object */
/** \ingroup SURF_models
* \brief The CPU model
*/
-XBT_PUBLIC_DATA(surf_model_t) surf_cpu_model;
+XBT_PUBLIC_DATA(surf_cpu_model_t) surf_cpu_model;
/** \ingroup SURF_models
* \brief Initializes the CPU model with the model Cas01
* model should be accessed because depending on the platform model,
* the network model can be NULL.
*/
-XBT_PUBLIC_DATA(surf_model_t) surf_network_model;
+XBT_PUBLIC_DATA(surf_network_model_t) surf_network_model;
/** \ingroup SURF_models
* \brief Same as network model 'LagrangeVelho', only with different correction factors.
* because depending on the platform model, the network model and the CPU model
* may not exist.
*/
-XBT_PUBLIC_DATA(surf_model_t) surf_workstation_model;
+XBT_PUBLIC_DATA(surf_workstation_model_t) surf_workstation_model;
/** \ingroup SURF_models
* \brief Initializes the platform with a compound workstation model
* TUTORIAL: New model
*/
XBT_PUBLIC(void) surf_new_model_init_default(void);
+
XBT_PUBLIC_DATA(s_surf_model_description_t) surf_new_model_description[];
+
/*******************************************/
/** \ingroup SURF_models
/*******************************************/
/*** SURF Platform *************************/
/*******************************************/
-typedef struct s_as *AS_t;
-
+#ifdef __cplusplus
+extern "C" {
+#endif
XBT_PUBLIC_DATA(AS_t) surf_AS_get_routing_root(void);
XBT_PUBLIC_DATA(const char *) surf_AS_get_name(AS_t as);
XBT_PUBLIC_DATA(xbt_dict_t) surf_AS_get_routing_sons(AS_t as);
XBT_PUBLIC_DATA(const char *) surf_AS_get_model(AS_t as);
XBT_PUBLIC_DATA(xbt_dynar_t) surf_AS_get_hosts(AS_t as);
+XBT_PUBLIC_DATA(void) surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+XBT_PUBLIC_DATA(AS_t) surf_platf_get_root(routing_platf_t platf);
+XBT_PUBLIC_DATA(e_surf_network_element_type_t) surf_routing_edge_get_rc_type(sg_routing_edge_t edge);
+#ifdef __cplusplus
+}
+#endif
/*******************************************/
/*** SURF Globals **************************/
void instr_new_variable_type (const char *new_typename, const char *color);
void instr_new_user_variable_type (const char *father_type, const char *new_typename, const char *color);
void instr_new_user_state_type (const char *father_type, const char *new_typename);
-void instr_new_value_for_user_state_type (const char *typename, const char *value, const char *color);
+void instr_new_value_for_user_state_type (const char *_typename, const char *value, const char *color);
int instr_platform_traced (void);
xbt_graph_t instr_routing_platform_graph (void);
void instr_routing_platform_graph_export_graphviz (xbt_graph_t g, const char *filename);
#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)
static XBT_INLINE xbt_dict_t surf_resource_properties(const void *resource)
{
return ((surf_resource_t) resource)->properties;
-}
+}*/
#endif /* SURF_RESOURCE_H */
#include "xbt/heap.h"
#include "xbt/dynar.h"
-#include "surf/solver.h"
+#include "surf/maxmin.h"
#include "surf/datatypes.h"
#include "simgrid/platf_interface.h"
#ifdef HAVE_TRACING
#include "instr/instr_private.h"
-#include "surf/network_private.h"
+#include "surf/surf.h"
+#include "surf/surf_private.h"
+
+//FIXME:#include "surf/network_private.h"
typedef enum {
INSTR_US_DECLARE,
unsigned int i;
void *link;
xbt_dynar_foreach (route, i, link) {
- char *link_name = ((link_CM02_t)link)->lmm_resource.generic_resource.name;
+ char *link_name = (char*)surf_resource_name(link);
instr_user_variable (time, link_name, variable, father_type, value, what, NULL, user_link_variables);
}
}
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);
XBT_PUBLIC(val_t) PJ_value_get (const char *name, const type_t father);
void PJ_value_free (val_t value);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* HAVE_TRACING */
#ifdef HAVE_JEDULE
#include "msg/msg.h"
#include "simgrid/simix.h"
-#include "surf/solver.h"
#include "surf/surf.h"
#include "xbt/fifo.h"
#include "xbt/dynar.h"
#include "xbt/fifo.h"
#include "simdag/simdag.h"
#include "simdag/datatypes.h"
-#include "surf/solver.h"
#include "surf/surf.h"
#include "xbt/swag.h"
#include "xbt/mallocator.h"
/* let's see which tasks are done */
xbt_dynar_foreach(model_list, iter, model) {
- while ((action = xbt_swag_extract(model->states.done_action_set))) {
- task = action->data;
- task->start_time =
- surf_workstation_model->
- action_get_start_time(task->surf_action);
+ while ((action = xbt_swag_extract(surf_model_done_action_set(model)))) {
+ task = surf_action_get_data(action);
+ task->start_time = surf_action_get_start_time(task->surf_action);
+
task->finish_time = surf_get_clock();
XBT_VERB("Task '%s' done", SD_task_get_name(task));
XBT_DEBUG("Calling __SD_task_just_done");
}
/* let's see which tasks have just failed */
- while ((action = xbt_swag_extract(model->states.failed_action_set))) {
- task = action->data;
- task->start_time =
- surf_workstation_model->
- action_get_start_time(task->surf_action);
+ while ((action = xbt_swag_extract(surf_model_failed_action_set(model)))) {
+ task = surf_action_get_data(action);
+ task->start_time = surf_action_get_start_time(task->surf_action);
task->finish_time = surf_get_clock();
XBT_VERB("Task '%s' failed", SD_task_get_name(task));
__SD_task_set_state(task, SD_FAILED);
- surf_workstation_model->action_unref(action);
+ surf_action_unref(action);
task->surf_action = NULL;
xbt_swag_insert(task,sd_global->return_set);
link = xbt_new(s_SD_link_t, 1);
link->surf_link = surf_link;
link->data = data; /* user data */
- if (surf_workstation_model->extension.workstation.link_shared(surf_link))
+ if (surf_network_link_is_shared(surf_link))
link->sharing_policy = SD_LINK_SHARED;
else
link->sharing_policy = SD_LINK_FATPIPE;
*/
double SD_link_get_current_bandwidth(SD_link_t link)
{
- return surf_workstation_model->extension.workstation.
- get_link_bandwidth(link->surf_link);
+ return surf_network_link_get_bandwidth(link->surf_link);
}
/**
*/
double SD_link_get_current_latency(SD_link_t link)
{
- return surf_workstation_model->extension.workstation.
- get_link_latency(link->surf_link);
+ return surf_network_link_get_latency(link->surf_link);
}
/**
xbt_free(task->name);
if (task->surf_action != NULL)
- surf_workstation_model->action_unref(task->surf_action);
+ surf_action_unref(task->surf_action);
xbt_free(task->workstation_list);
xbt_free(task->communication_amount);
break;
case SD_RUNNING:
task->state_set = sd_global->running_task_set;
- task->start_time =
- surf_workstation_model->action_get_start_time(task->surf_action);
+ task->start_time = surf_action_get_start_time(task->surf_action);
break;
case SD_DONE:
task->state_set = sd_global->done_task_set;
- task->finish_time =
- surf_workstation_model->action_get_finish_time(task->surf_action);
+ task->finish_time = surf_action_get_finish_time(task->surf_action);
task->remains = 0;
#ifdef HAVE_JEDULE
jedule_log_sd_event(task);
double SD_task_get_remaining_amount(SD_task_t task)
{
if (task->surf_action)
- return surf_workstation_model->get_remains(task->surf_action);
+ return surf_action_get_remains(task->surf_action);
else
return task->remains;
}
}
if (__SD_task_is_running(task)) /* the task should become SD_FAILED */
- surf_workstation_model->action_cancel(task->surf_action);
+ surf_action_cancel(task->surf_action);
else {
if (task->unsatisfied_dependencies == 0)
__SD_task_set_state(task, SD_SCHEDULABLE);
memcpy(communication_amount, task->communication_amount,
sizeof(double) * workstation_nb * workstation_nb);
- task->surf_action =
- surf_workstation_model->extension.
- workstation.execute_parallel_task(workstation_nb,
- surf_workstations,
- computation_amount,
- communication_amount,
- task->rate);
+ task->surf_action = surf_workstation_model_execute_parallel_task((surf_workstation_model_t)surf_workstation_model,
+ workstation_nb,
+ surf_workstations,
+ computation_amount,
+ communication_amount,
+ task->rate);
- surf_workstation_model->action_data_set(task->surf_action, task);
+ surf_action_set_data(task->surf_action, task);
XBT_DEBUG("surf_action = %p", task->surf_action);
candidates = xbt_new(SD_task_t, 8);
__SD_task_set_state(task, SD_DONE);
- surf_workstation_model->action_unref(task->surf_action);
+ surf_action_unref(task->surf_action);
task->surf_action = NULL;
XBT_DEBUG("Looking for candidates");
double SD_task_get_start_time(SD_task_t task)
{
if (task->surf_action)
- return surf_workstation_model->
- action_get_start_time(task->surf_action);
+ return surf_action_get_start_time(task->surf_action);
else
return task->start_time;
}
double SD_task_get_finish_time(SD_task_t task)
{
if (task->surf_action) /* should never happen as actions are destroyed right after their completion */
- return surf_workstation_model->
- action_get_finish_time(task->surf_action);
+ return surf_action_get_finish_time(task->surf_action);
else
return task->finish_time;
}
#include "surf/surf.h"
#include "surf/surf_resource.h"
-
-
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_workstation, sd,
"Logging specific to SimDag (workstation)");
*/
xbt_dict_t SD_workstation_get_properties(SD_workstation_t workstation)
{
- return surf_workstation_model->extension.
- workstation.get_properties(surf_workstation_resource_priv(workstation));
+ return surf_resource_get_properties(surf_workstation_resource_priv(workstation));
}
surf_src = src;
surf_dst = dst;
- surf_route =
- surf_workstation_model->extension.workstation.get_route(surf_src,
- surf_dst);
+
+ surf_route = surf_workstation_model_get_route((surf_workstation_model_t)surf_workstation_model,
+ surf_src, surf_dst);
xbt_dynar_foreach(surf_route, cpt, surf_link) {
link_name = surf_resource_name(surf_link);
*/
int SD_route_get_size(SD_workstation_t src, SD_workstation_t dst)
{
- return xbt_dynar_length(surf_workstation_model->extension.
- workstation.get_route(src, dst));
+ return xbt_dynar_length(surf_workstation_model_get_route(
+ (surf_workstation_model_t)surf_workstation_model, src, dst));
}
/**
*/
double SD_workstation_get_power(SD_workstation_t workstation)
{
- return surf_workstation_model->extension.workstation.
- get_speed(workstation, 1.0);
+ return surf_workstation_get_speed(workstation, 1.0);
}
/**
*/
double SD_workstation_get_available_power(SD_workstation_t workstation)
{
- return surf_workstation_model->extension.
- workstation.get_available_speed(workstation);
+ return surf_workstation_get_available_speed(workstation);
}
/**
#include "xbt/str.h"
#include "xbt/lib.h"
#include "xbt/sysdep.h"
-#include "surf/solver.h"
#include "surf/surf.h"
-#include "surf/solver.h"
+#include "surf/maxmin.h"
#include "instr/instr_interface.h"
#include "simgrid/simix.h"
#include "simgrid/sg_config.h"
((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));
}
/* Clean processes to destroy */
xbt_dict_t SIMIX_host_get_properties(smx_host_t host){
xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
- return surf_workstation_model->extension.workstation.get_properties(host);
+ return surf_resource_get_properties(surf_workstation_resource_priv(host));
}
double SIMIX_pre_host_get_speed(smx_simcall_t simcall, smx_host_t host){
}
double SIMIX_host_get_speed(smx_host_t host){
xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
-
- return surf_workstation_model->extension.workstation.
- get_speed(host, 1.0);
+ return surf_workstation_get_speed(host, 1.0);
}
int SIMIX_pre_host_get_core(smx_simcall_t simcall, smx_host_t host){
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);
}
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);
}
int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){
int SIMIX_host_get_state(smx_host_t host){
xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
- return surf_workstation_model->extension.workstation.
- get_state(host);
+ return surf_resource_get_state(surf_workstation_resource_priv(host));
}
void* SIMIX_pre_host_self_get_data(smx_simcall_t simcall){
/* set surf's action */
if (!MC_is_active()) {
action->execution.surf_exec =
- surf_workstation_model->extension.workstation.execute(host,
- computation_amount);
- surf_workstation_model->action_data_set(action->execution.surf_exec, action);
- surf_workstation_model->set_priority(action->execution.surf_exec, priority);
+ surf_workstation_execute(host, computation_amount);
+ surf_action_set_data(action->execution.surf_exec, action);
+ surf_action_set_priority(action->execution.surf_exec, priority);
}
XBT_DEBUG("Create execute action %p", action);
/* set surf's action */
if (!MC_is_active()) {
action->execution.surf_exec =
- surf_workstation_model->extension.workstation.
- execute_parallel_task(host_nb, workstation_list, computation_amount,
- communication_amount, rate);
+ surf_workstation_model_execute_parallel_task((surf_workstation_model_t)surf_workstation_model,
+ host_nb, workstation_list, computation_amount, communication_amount, rate);
- surf_workstation_model->action_data_set(action->execution.surf_exec, action);
+ surf_action_set_data(action->execution.surf_exec, action);
}
XBT_DEBUG("Create parallel execute action %p", action);
XBT_DEBUG("Destroy action %p", action);
if (action->execution.surf_exec) {
- surf_workstation_model->action_unref(action->execution.surf_exec);
+ surf_action_unref(action->execution.surf_exec);
action->execution.surf_exec = NULL;
}
xbt_free(action->name);
XBT_DEBUG("Cancel action %p", action);
if (action->execution.surf_exec)
- surf_workstation_model->action_cancel(action->execution.surf_exec);
+ surf_action_cancel(action->execution.surf_exec);
}
double SIMIX_pre_host_execution_get_remains(smx_simcall_t simcall, smx_action_t action){
double result = 0.0;
if (action->state == SIMIX_RUNNING)
- result = surf_workstation_model->get_remains(action->execution.surf_exec);
+ result = surf_action_get_remains(action->execution.surf_exec);
return result;
}
}
void SIMIX_host_execution_set_priority(smx_action_t action, double priority){
if(action->execution.surf_exec)
- surf_workstation_model->set_priority(action->execution.surf_exec, priority);
+ surf_action_set_priority(action->execution.surf_exec, priority);
}
void SIMIX_pre_host_execution_wait(smx_simcall_t simcall, smx_action_t action){
void SIMIX_host_execution_suspend(smx_action_t action)
{
if(action->execution.surf_exec)
- surf_workstation_model->suspend(action->execution.surf_exec);
+ surf_action_suspend(action->execution.surf_exec);
}
void SIMIX_host_execution_resume(smx_action_t action)
{
if(action->execution.surf_exec)
- surf_workstation_model->resume(action->execution.surf_exec);
+ surf_action_resume(action->execution.surf_exec);
}
void SIMIX_execution_finish(smx_action_t action)
(int)action->state);
}
/* check if the host is down */
- if (surf_workstation_model->extension.
- workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+
+ if (surf_resource_get_state((surf_resource_t)surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
simcall->issuer->context->iwannadie = 1;
}
{
if (action->type == SIMIX_ACTION_EXECUTE && /* FIMXE: handle resource failure
* for parallel tasks too */
- surf_workstation_model->extension.workstation.get_state(action->execution.host) == SURF_RESOURCE_OFF) {
+ surf_resource_get_state((surf_resource_t)surf_workstation_resource_priv(action->execution.host)) == SURF_RESOURCE_OFF) {
/* If the host running the action failed, notice it so that the asking
* process can be killed if it runs on that host itself */
action->state = SIMIX_FAILED;
- } else if (surf_workstation_model->action_state_get(action->execution.surf_exec) == SURF_ACTION_FAILED) {
+ } else if (surf_action_get_state(action->execution.surf_exec) == SURF_ACTION_FAILED) {
/* If the host running the action didn't fail, then the action was
* canceled */
action->state = SIMIX_CANCELED;
}
if (action->execution.surf_exec) {
- surf_workstation_model->action_unref(action->execution.surf_exec);
+ surf_action_unref(action->execution.surf_exec);
action->execution.surf_exec = NULL;
}
{
if (action->state != SIMIX_RUNNING) return;
if (action->type == SIMIX_ACTION_EXECUTE){
- surf_workstation_model->set_category(action->execution.surf_exec, category);
+ surf_action_set_category(action->execution.surf_exec, category);
}else if (action->type == SIMIX_ACTION_COMMUNICATE){
- surf_workstation_model->set_category(action->comm.surf_comm, category);
+ surf_action_set_category(action->comm.surf_comm, category);
}
}
#endif
return (smx_host_priv_t) xbt_lib_get_level(host, SIMIX_HOST_LEVEL);
}
-
+#ifdef __cplusplus
+extern "C" {
+#endif
smx_host_t SIMIX_host_create(const char *name, void *workstation, void *data);
void SIMIX_host_destroy(void *host);
void SIMIX_set_category(smx_action_t action, const char *category);
#endif
+#ifdef __cplusplus
+}
+#endif
+
#endif
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
#endif
action->io.host = host;
- action->io.surf_io =
- surf_workstation_model->extension.workstation.read(host, ptr, size,
- fd->surf_file);
+ action->io.surf_io = surf_workstation_read(host, ptr, size, fd->surf_file);
- 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;
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
#endif
action->io.host = host;
- action->io.surf_io =
- surf_workstation_model->extension.workstation.write(host, ptr, size,
- fd->surf_file);
+ action->io.surf_io = surf_workstation_write(host, ptr, size, fd->surf_file);
- 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;
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
#endif
action->io.host = host;
- action->io.surf_io =
- surf_workstation_model->extension.workstation.open(host, mount, path);
+ action->io.surf_io = surf_workstation_open(host, mount, path);
- 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;
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
#endif
action->io.host = host;
- action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fd->surf_file);
+ action->io.surf_io = surf_workstation_close(host, fd->surf_file);
- 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;
{
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
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;
return 1;
} else
smx_action_t action;
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
#endif
action->io.host = host;
- action->io.surf_io = surf_workstation_model->extension.workstation.ls(host,mount,path);
+ action->io.surf_io = surf_workstation_ls(host,mount,path);
- 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;
}
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);
}
switch (simcall->call) {
case SIMCALL_FILE_OPEN:;
smx_file_t tmp = xbt_new(s_smx_file_t,1);
- tmp->surf_file = (action->io.surf_io)->file;
+ tmp->surf_file = surf_storage_action_get_file((surf_storage_action_lmm_t)action->io.surf_io);
simcall_file_open__set__result(simcall, tmp);
break;
xbt_free(simcall_file_close__get__fd(simcall));
simcall_file_close__set__result(simcall, 0);
break;
-
case SIMCALL_FILE_WRITE:
- simcall_file_write__set__result(simcall, (action->io.surf_io)->cost);
+ simcall_file_write__set__result(simcall, surf_action_get_cost(action->io.surf_io));
break;
case SIMCALL_FILE_READ:
- simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
+ simcall_file_read__set__result(simcall, surf_action_get_cost(action->io.surf_io));
break;
case SIMCALL_FILE_LS:
// xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
// }
// }
- simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
+ simcall_file_ls__set__result(simcall, surf_storage_action_get_ls_dict((surf_storage_action_lmm_t)action->io.surf_io));
break;
default:
break;
}
}
- switch (surf_workstation_model->action_state_get(action->io.surf_io)) {
+ switch (surf_action_get_state(action->io.surf_io)) {
case SURF_ACTION_FAILED:
action->state = SIMIX_FAILED;
{
XBT_DEBUG("Destroy action %p", action);
if (action->io.surf_io)
- action->io.surf_io->model_type->action_unref(action->io.surf_io);
+ surf_action_unref(action->io.surf_io);
xbt_mallocator_release(simix_global->action_mallocator, action);
}
(int)action->state);
}
- if (surf_workstation_model->extension.
- workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
simcall->issuer->context->iwannadie = 1;
}
#ifdef HAVE_LATENCY_BOUND_TRACKING
action->latency_limited = SIMIX_comm_is_latency_bounded(action);
#endif
- action->comm.surf_comm->model_type->action_unref(action->comm.surf_comm);
+ surf_action_unref(action->comm.surf_comm);
action->comm.surf_comm = NULL;
}
if (action->comm.src_timeout){
- action->comm.src_timeout->model_type->action_unref(action->comm.src_timeout);
+ surf_action_unref(action->comm.src_timeout);
action->comm.src_timeout = NULL;
}
if (action->comm.dst_timeout){
- action->comm.dst_timeout->model_type->action_unref(action->comm.dst_timeout);
+ surf_action_unref(action->comm.dst_timeout);
action->comm.dst_timeout = NULL;
}
}
if (action->state != SIMIX_WAITING && action->state != SIMIX_RUNNING) {
SIMIX_comm_finish(action);
} else { /* if (timeout >= 0) { we need a surf sleep action even when there is no timeout, otherwise surf won't tell us when the host fails */
- sleep = surf_workstation_model->extension.workstation.sleep(simcall->issuer->smx_host, timeout);
- surf_workstation_model->action_data_set(sleep, action);
+ sleep = surf_workstation_sleep(surf_workstation_resource_priv(simcall->issuer->smx_host), timeout);
+ surf_action_set_data(sleep, action);
if (simcall->issuer == action->comm.src_proc)
action->comm.src_timeout = sleep;
XBT_DEBUG("Starting communication %p from '%s' to '%s'", action,
SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
- action->comm.surf_comm = surf_workstation_model->extension.workstation.
- communicate(sender, receiver, action->comm.task_size, action->comm.rate);
+ action->comm.surf_comm = surf_workstation_communicate(sender, receiver, action->comm.task_size, action->comm.rate);
- surf_workstation_model->action_data_set(action->comm.surf_comm, action);
+ surf_action_set_data(action->comm.surf_comm, action);
action->state = SIMIX_RUNNING;
/* If a link is failed, detect it immediately */
- if (surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+ if (surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
XBT_DEBUG("Communication from '%s' to '%s' failed to start because of a link failure",
SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
action->state = SIMIX_LINK_FAILURE;
XBT_DEBUG("The communication is suspended on startup because dst (%s:%s) were suspended since it initiated the communication",
SIMIX_host_get_name(action->comm.dst_proc->smx_host), action->comm.dst_proc->name);
- surf_workstation_model->suspend(action->comm.surf_comm);
+ surf_action_suspend(action->comm.surf_comm);
}
}
}
}
- if (surf_workstation_model->extension.
- workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
simcall->issuer->context->iwannadie = 1;
}
{
/* Update action state */
if (action->comm.src_timeout &&
- surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_DONE)
+ surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_DONE)
action->state = SIMIX_SRC_TIMEOUT;
else if (action->comm.dst_timeout &&
- surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_DONE)
+ surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_DONE)
action->state = SIMIX_DST_TIMEOUT;
else if (action->comm.src_timeout &&
- surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_FAILED)
+ surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_FAILED)
action->state = SIMIX_SRC_HOST_FAILURE;
else if (action->comm.dst_timeout &&
- surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_FAILED)
+ surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_FAILED)
action->state = SIMIX_DST_HOST_FAILURE;
else if (action->comm.surf_comm &&
- surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+ surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
XBT_DEBUG("Puta madre. Surf says that the link broke");
action->state = SIMIX_LINK_FAILURE;
} else
else if (!MC_is_active() /* when running the MC there are no surf actions */
&& (action->state == SIMIX_READY || action->state == SIMIX_RUNNING)) {
- surf_workstation_model->action_cancel(action->comm.surf_comm);
+ surf_action_cancel(action->comm.surf_comm);
}
}
{
/*FIXME: shall we suspend also the timeout actions? */
if (action->comm.surf_comm)
- surf_workstation_model->suspend(action->comm.surf_comm);
+ surf_action_suspend(action->comm.surf_comm);
/* in the other case, the action will be suspended on creation, in SIMIX_comm_start() */
}
{
/*FIXME: check what happen with the timeouts */
if (action->comm.surf_comm)
- surf_workstation_model->resume(action->comm.surf_comm);
+ surf_action_resume(action->comm.surf_comm);
/* in the other case, the action were not really suspended yet, see SIMIX_comm_suspend() and SIMIX_comm_start() */
}
switch (action->state) {
case SIMIX_RUNNING:
- remains = surf_workstation_model->get_remains(action->comm.surf_comm);
+ remains = surf_action_get_remains(action->comm.surf_comm);
break;
case SIMIX_WAITING:
}
}
- switch (surf_workstation_model->action_state_get(action->new_api.surf_new_api)) {
+ switch (surf_action_get_state(action->new_api.surf_new_api)) {
case SURF_ACTION_FAILED:
action->state = SIMIX_FAILED;
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
#endif
// Called the function from the new model
- action->new_api.surf_new_api = surf_workstation_model->extension.new_model.fct();
+ //FIXME:CHECK WHAT TO DO action->new_api.surf_new_api = surf_workstation_model->extension.new_model.fct();
- surf_workstation_model->action_data_set(action->new_api.surf_new_api, action);
+ surf_action_set_data(action->new_api.surf_new_api, action);
XBT_DEBUG("Create NEW MODEL action %p", action);
return action;
{
XBT_DEBUG("Destroy action %p", action);
if (action->new_api.surf_new_api)
- action->new_api.surf_new_api->model_type->action_unref(action->new_api.surf_new_api);
+ surf_action_unref(action->new_api.surf_new_api);
xbt_mallocator_release(simix_global->action_mallocator, action);
}
(int)action->state);
}
- if (surf_workstation_model->extension.
- workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
simcall->issuer->context->iwannadie = 1;
}
#define _SIMIX_PRIVATE_H
#include "simgrid/simix.h"
-#include "surf/solver.h"
#include "surf/surf.h"
#include "xbt/fifo.h"
#include "xbt/swag.h"
smx_host_t host = process->smx_host;
/* check if the host is active */
- if (surf_workstation_model->extension.
- workstation.get_state(host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
THROWF(host_error, 0, "Host %s failed, you cannot call this function",
sg_host_name(host));
}
action->sleep.host = host;
action->sleep.surf_sleep =
- surf_workstation_model->extension.workstation.sleep(host, duration);
+ surf_workstation_sleep(host, duration);
- surf_workstation_model->action_data_set(action->sleep.surf_sleep, action);
+ surf_action_set_data(action->sleep.surf_sleep, action);
XBT_DEBUG("Create sleep action %p", action);
return action;
while ((simcall = xbt_fifo_shift(action->simcalls))) {
- switch(surf_workstation_model->action_state_get(action->sleep.surf_sleep)){
+ switch(surf_action_get_state(action->sleep.surf_sleep)){
case SURF_ACTION_FAILED:
simcall->issuer->context->iwannadie = 1;
//SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
THROW_IMPOSSIBLE;
break;
}
- if (surf_workstation_model->extension.
- workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+ if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
simcall->issuer->context->iwannadie = 1;
}
simcall_process_sleep__set__result(simcall, state);
{
XBT_DEBUG("Destroy action %p", action);
if (action->sleep.surf_sleep)
- action->sleep.surf_sleep->model_type->action_unref(action->sleep.surf_sleep);
+ surf_action_unref(action->sleep.surf_sleep);
xbt_mallocator_release(simix_global->action_mallocator, action);
}
void SIMIX_process_sleep_suspend(smx_action_t action)
{
- surf_workstation_model->suspend(action->sleep.surf_sleep);
+ surf_action_suspend(action->sleep.surf_sleep);
}
void SIMIX_process_sleep_resume(smx_action_t action)
{
- surf_workstation_model->resume(action->sleep.surf_sleep);
+ surf_action_resume(action->sleep.surf_sleep);
}
/**
(name, type, __VA_ARGS__)
#define SIMCALL_FUNC_SIMCALL(res) SIMCALL_FUNC_SIMCALL_ res
-#define SIMCALL_WITH_FUNC_RETURN(name, type, field, cast) return self->simcall.result.field;
+#define SIMCALL_WITH_FUNC_RETURN(name, type, field, ...) return self->simcall.result.field;
#define SIMCALL_WITHOUT_FUNC_RETURN(name, type, field)
#define SIMCALL_FUNC_RETURN_(name, type, ...)\
- MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_FUNC_RETURN, SIMCALL_WITHOUT_FUNC_RETURN, SIMCALL_WITHOUT_FUNC_RETURN)\
+ MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_FUNC_RETURN, SIMCALL_WITH_FUNC_RETURN, SIMCALL_WITHOUT_FUNC_RETURN)\
(name, type, __VA_ARGS__)
#define SIMCALL_FUNC_RETURN(res) SIMCALL_FUNC_RETURN_ res
action->type = SIMIX_ACTION_SYNCHRO;
action->name = xbt_strdup("synchro");
action->synchro.sleep =
- surf_workstation_model->extension.workstation.sleep(smx_host, timeout);
+ surf_workstation_sleep(smx_host, timeout);
- surf_workstation_model->action_data_set(action->synchro.sleep, action);
+ surf_action_set_data(action->synchro.sleep, action);
XBT_OUT();
return action;
}
{
XBT_IN("(%p)",action);
XBT_DEBUG("Destroying synchro %p", action);
- action->synchro.sleep->model_type->action_unref(action->synchro.sleep);
+ surf_action_unref(action->synchro.sleep);
xbt_free(action->name);
xbt_mallocator_release(simix_global->action_mallocator, action);
XBT_OUT();
void SIMIX_post_synchro(smx_action_t action)
{
XBT_IN("(%p)",action);
- if (surf_workstation_model->action_state_get(action->synchro.sleep) == SURF_ACTION_FAILED)
+ if (surf_action_get_state(action->synchro.sleep) == SURF_ACTION_FAILED)
action->state = SIMIX_FAILED;
- else if(surf_workstation_model->action_state_get(action->synchro.sleep) == SURF_ACTION_DONE)
+ else if(surf_action_get_state(action->synchro.sleep) == SURF_ACTION_DONE)
action->state = SIMIX_SRC_TIMEOUT;
SIMIX_synchro_finish(action);
#include "cpu.hpp"
-//TODO: resolve dependencies
-static int TRACE_is_enabled(void) {return 0;}
-static void TRACE_surf_host_set_utilization(const char *resource,
- const char *category,
- double value,
- double now,
- double delta){}
-static double TRACE_last_timestamp_to_dump = 0;
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_cpu, surfpp,
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf,
"Logging specific to the SURF cpu module");
+}
+CpuModelPtr surf_cpu_model;
/*********
* Model *
public:
Cpu(){};
Cpu(CpuModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {};
- CpuActionPtr execute(double size);
- CpuActionPtr sleep(double duration);
- e_surf_resource_state_t getState();
+ virtual CpuActionPtr execute(double size)=0;
+ virtual CpuActionPtr sleep(double duration)=0;
int getCore();
double getSpeed(double load);
double getAvailableSpeed();
void addTraces(void);
-
double m_powerPeak; /*< CPU power peak */
double m_powerScale; /*< Percentage of CPU disponible */
protected:
surf_action_lmm_update_index_heap);
surf_cpu_model->model_private->modified_set =
xbt_swag_new(xbt_swag_offset(comp, generic_lmm_action.action_list_hookup));
- //TOREPAIR: cpu_model->model_private->maxmin_system->m_keepTrack = cpu_model->model_private->modified_set;
+ surf_cpu_model->model_private->maxmin_system->keep_track = surf_cpu_model->model_private->modified_set;
}
}
#include "maxmin_private.h"
#include "simgrid/sg_config.h"
-//TODO: resolve dependencies
-static void TRACE_surf_host_set_power(double date, const char *resource, double power) {}
-
-
-static ModelPtr surf_cpu_model = NULL;
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_cpu_cas, surfpp,
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf,
"Logging specific to the SURF CPU IMPROVED module");
+}
static xbt_swag_t
cpu_running_action_set_that_does_not_need_being_checked = NULL;
double CpuCas01Model::shareResourcesFull(double now)
{
CpuCas01ActionLmm action;
- Model::shareResourcesFull(p_runningActionSet,
+ Model::shareResourcesMaxMin(p_runningActionSet,
xbt_swag_offset(action, p_variable),
p_maxminSystem, lmm_solve);
return 0;
#include "cpu_ti.hpp"
-//#include "solver.hpp"
#include "trace_mgr_private.h"
#include "xbt/heap.h"
#ifndef SURF_MODEL_CPUTI_H_
#define SURF_MODEL_CPUTI_H_
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_cpu_tii, surfpp,
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_ti, surf,
"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 CpuTiModelPtr surf_cpu_model = NULL;
-
static void cpu_ti_action_update_index_heap(void *action, int i);
/*********
}
CpuActionPtr CpuTi::execute(double size)
+{
+ return execute(size);
+}
+
+CpuTiActionPtr CpuTi::_execute(double size)
{
XBT_IN("(%s,%g)", m_name, size);
- CpuTiActionPtr action = new CpuTiAction(surf_cpu_model, size, p_stateCurrent != SURF_RESOURCE_ON);
+ CpuTiActionPtr action = new CpuTiAction((CpuTiModelPtr) p_model, size, p_stateCurrent != SURF_RESOURCE_ON);
action->p_cpu = this;
action->m_indexHeap = -1;
duration = MAX(duration, MAXMIN_PRECISION);
XBT_IN("(%s,%g)", m_name, duration);
- CpuActionPtr action = execute(1.0);
+ CpuTiActionPtr action = _execute(1.0);
action->m_maxDuration = duration;
action->m_suspended = 2;
if (duration == NO_MAX_DURATION) {
void updateState(tmgr_trace_event_t event_type, double value, double date);
void updateActionFinishDate(double now);
- bool isUsed();
+ bool isUsed();
void printCpuTiModel();
CpuTiModelPtr getModel();
CpuActionPtr execute(double size);
+ CpuTiActionPtr _execute(double size);
CpuActionPtr sleep(double duration);
double getAvailableSpeed();
double getRemains();
CpuTiPtr p_cpu;
int m_indexHeap;
-
+ int m_suspended;
private:
};
--- /dev/null
+/* 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 "xbt/sysdep.h"
+#include "xbt/log.h"
+#include "maxmin_private.h"
+#include <stdlib.h>
+#include <math.h>
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_maxmin);
+#define SHOW_EXPR_G(expr) XBT_DEBUG(#expr " = %g",expr);
+#define SHOW_EXPR_D(expr) XBT_DEBUG(#expr " = %d",expr);
+#define SHOW_EXPR_P(expr) XBT_DEBUG(#expr " = %p",expr);
+
+void bottleneck_solve(lmm_system_t sys)
+{
+ lmm_variable_t var = NULL;
+ lmm_variable_t var_next = NULL;
+ lmm_constraint_t cnst = NULL;
+ s_lmm_constraint_t s_cnst;
+ lmm_constraint_t cnst_next = NULL;
+ lmm_element_t elem = NULL;
+ xbt_swag_t cnst_list = NULL;
+ xbt_swag_t var_list = NULL;
+ xbt_swag_t elem_list = NULL;
+ int i;
+
+ static s_xbt_swag_t cnst_to_update;
+
+ if (!(sys->modified))
+ return;
+
+ /* Init */
+ xbt_swag_init(&(cnst_to_update),
+ xbt_swag_offset(s_cnst, saturated_constraint_set_hookup));
+
+ var_list = &(sys->variable_set);
+ XBT_DEBUG("Variable set : %d", xbt_swag_size(var_list));
+ xbt_swag_foreach(var, var_list) {
+ int nb = 0;
+ var->value = 0.0;
+ XBT_DEBUG("Handling variable %p", var);
+ xbt_swag_insert(var, &(sys->saturated_variable_set));
+ for (i = 0; i < var->cnsts_number; i++) {
+ if (var->cnsts[i].value == 0.0)
+ nb++;
+ }
+ if ((nb == var->cnsts_number) && (var->weight > 0.0)) {
+ XBT_DEBUG("Err, finally, there is no need to take care of variable %p",
+ var);
+ xbt_swag_remove(var, &(sys->saturated_variable_set));
+ var->value = 1.0;
+ }
+ if (var->weight <= 0.0) {
+ XBT_DEBUG("Err, finally, there is no need to take care of variable %p",
+ var);
+ xbt_swag_remove(var, &(sys->saturated_variable_set));
+ }
+ }
+ var_list = &(sys->saturated_variable_set);
+
+ cnst_list = &(sys->active_constraint_set);
+ XBT_DEBUG("Active constraints : %d", xbt_swag_size(cnst_list));
+ xbt_swag_foreach(cnst, cnst_list) {
+ xbt_swag_insert(cnst, &(sys->saturated_constraint_set));
+ }
+ cnst_list = &(sys->saturated_constraint_set);
+ xbt_swag_foreach(cnst, cnst_list) {
+ cnst->remaining = cnst->bound;
+ cnst->usage = 0.0;
+ }
+
+ XBT_DEBUG("Fair bottleneck Initialized");
+
+ /*
+ * Compute Usage and store the variables that reach the maximum.
+ */
+ do {
+ if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+ XBT_DEBUG("Fair bottleneck done");
+ lmm_print(sys);
+ }
+ XBT_DEBUG("******* Constraints to process: %d *******",
+ xbt_swag_size(cnst_list));
+ xbt_swag_foreach_safe(cnst, cnst_next, cnst_list) {
+ int nb = 0;
+ XBT_DEBUG("Processing cnst %p ", cnst);
+ elem_list = &(cnst->element_set);
+ cnst->usage = 0.0;
+ xbt_swag_foreach(elem, elem_list) {
+ if (elem->variable->weight <= 0)
+ break;
+ if ((elem->value > 0)
+ && xbt_swag_belongs(elem->variable, var_list))
+ nb++;
+ }
+ XBT_DEBUG("\tThere are %d variables", nb);
+ if (nb > 0 && !cnst->shared)
+ nb = 1;
+ if (!nb) {
+ cnst->remaining = 0.0;
+ cnst->usage = cnst->remaining;
+ xbt_swag_remove(cnst, cnst_list);
+ continue;
+ }
+ cnst->usage = cnst->remaining / nb;
+ XBT_DEBUG("\tConstraint Usage %p : %f with %d variables", cnst,
+ cnst->usage, nb);
+ }
+
+ xbt_swag_foreach_safe(var, var_next, var_list) {
+ double min_inc =
+ var->cnsts[0].constraint->usage / var->cnsts[0].value;
+ for (i = 1; i < var->cnsts_number; i++) {
+ lmm_element_t elm = &var->cnsts[i];
+ min_inc = MIN(min_inc, elm->constraint->usage / elm->value);
+ }
+ if (var->bound > 0)
+ min_inc = MIN(min_inc, var->bound - var->value);
+ var->mu = min_inc;
+ XBT_DEBUG("Updating variable %p maximum increment: %g", var, var->mu);
+ var->value += var->mu;
+ if (var->value == var->bound) {
+ xbt_swag_remove(var, var_list);
+ }
+ }
+
+ xbt_swag_foreach_safe(cnst, cnst_next, cnst_list) {
+ XBT_DEBUG("Updating cnst %p ", cnst);
+ elem_list = &(cnst->element_set);
+ xbt_swag_foreach(elem, elem_list) {
+ if (elem->variable->weight <= 0)
+ break;
+ if (cnst->shared) {
+ XBT_DEBUG("\tUpdate constraint %p (%g) with variable %p by %g",
+ cnst, cnst->remaining, elem->variable,
+ elem->variable->mu);
+ double_update(&(cnst->remaining),
+ elem->value * elem->variable->mu);
+ } else {
+ XBT_DEBUG
+ ("\tNon-Shared variable. Update constraint usage of %p (%g) with variable %p by %g",
+ cnst, cnst->usage, elem->variable, elem->variable->mu);
+ cnst->usage = MIN(cnst->usage, elem->value * elem->variable->mu);
+ }
+ }
+ if (!cnst->shared) {
+ XBT_DEBUG("\tUpdate constraint %p (%g) by %g",
+ cnst, cnst->remaining, cnst->usage);
+
+ double_update(&(cnst->remaining), cnst->usage);
+ }
+
+ XBT_DEBUG("\tRemaining for %p : %g", cnst, cnst->remaining);
+ if (cnst->remaining == 0.0) {
+ XBT_DEBUG("\tGet rid of constraint %p", cnst);
+
+ xbt_swag_remove(cnst, cnst_list);
+ xbt_swag_foreach(elem, elem_list) {
+ if (elem->variable->weight <= 0)
+ break;
+ if (elem->value > 0) {
+ XBT_DEBUG("\t\tGet rid of variable %p", elem->variable);
+ xbt_swag_remove(elem->variable, var_list);
+ }
+ }
+ }
+ }
+ } while (xbt_swag_size(var_list));
+
+ xbt_swag_reset(cnst_list);
+ sys->modified = 0;
+ if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+ XBT_DEBUG("Fair bottleneck done");
+ lmm_print(sys);
+ }
+}
#ifdef HAVE_TRACING
#include "surf/surf_private.h"
-#include "surf/network_private.h"
+//FIXME:#include "surf/network_private.h"
#include "xbt/graph.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_routing, instr, "Tracing platform hierarchy");
XBT_DEBUG("Graph extraction disabled by user.");
return;
}
- XBT_DEBUG ("Graph extraction for routing_component = %s", rc->name);
- if (!xbt_dict_is_empty(rc->routing_sons)){
+ XBT_DEBUG ("Graph extraction for routing_component = %s", surf_AS_get_name(rc));
+ if (!xbt_dict_is_empty(surf_AS_get_routing_sons(rc))){
xbt_dict_cursor_t cursor = NULL;
AS_t rc_son;
char *child_name;
//bottom-up recursion
- xbt_dict_foreach(rc->routing_sons, cursor, child_name, rc_son) {
- container_t child_container = xbt_dict_get (container->children, rc_son->name);
+ xbt_dict_foreach(surf_AS_get_routing_sons(rc), cursor, child_name, rc_son) {
+ container_t child_container = xbt_dict_get (container->children, surf_AS_get_name(rc_son));
recursiveGraphExtraction (rc_son, child_container, filter);
}
}
xbt_dict_cursor_t cursor = NULL;
char *edge_name;
- rc->get_graph(graph,nodes,edges,rc);
+ surf_AS_get_graph(rc, graph, nodes, edges);
xbt_dict_foreach(edges,cursor,edge_name,edge) {
linkContainers(PJ_container_get(edge->src->data), PJ_container_get(edge->dst->data), filter);
}
currentContainer = NULL;
xbt_dict_t filter = xbt_dict_new_homogeneous(xbt_free);
XBT_DEBUG ("Starting graph extraction.");
- recursiveGraphExtraction (routing_platf->root, PJ_container_get_root(), filter);
+ recursiveGraphExtraction (surf_platf_get_root(routing_platf), PJ_container_get_root(), filter);
XBT_DEBUG ("Graph extraction finished.");
xbt_dict_free(&filter);
platform_created = 1;
static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges,
AS_t rc, container_t container)
{
- if (!xbt_dict_is_empty(rc->routing_sons)){
+ if (!xbt_dict_is_empty(surf_AS_get_routing_sons(rc))){
xbt_dict_cursor_t cursor = NULL;
AS_t rc_son;
char *child_name;
//bottom-up recursion
- xbt_dict_foreach(rc->routing_sons, cursor, child_name, rc_son) {
- container_t child_container = xbt_dict_get (container->children, rc_son->name);
+ xbt_dict_foreach(surf_AS_get_routing_sons(rc), cursor, child_name, rc_son) {
+ container_t child_container = xbt_dict_get (container->children, surf_AS_get_name(rc_son));
recursiveXBTGraphExtraction (graph, nodes, edges, rc_son, child_container);
}
}
- rc->get_graph(graph,nodes,edges,rc);
+ surf_AS_get_graph(rc, graph, nodes, edges);
}
xbt_graph_t instr_routing_platform_graph (void)
xbt_graph_t ret = xbt_graph_new_graph (0, NULL);
xbt_dict_t nodes = xbt_dict_new_homogeneous(NULL);
xbt_dict_t edges = xbt_dict_new_homogeneous(NULL);
- recursiveXBTGraphExtraction (ret, nodes, edges, routing_platf->root, PJ_container_get_root());
+ recursiveXBTGraphExtraction (ret, nodes, edges, surf_platf_get_root(routing_platf), PJ_container_get_root());
xbt_dict_free (&nodes);
xbt_dict_free (&edges);
return ret;
#include "instr/instr_private.h"
#include "surf/surf_private.h"
-#include "surf/network_gtnets_private.h"
+//FIXME:#include "surf/network_gtnets_private.h"
#ifdef HAVE_TRACING
/* to trace gtnets */
void TRACE_surf_gtnets_communicate(void *action, void *src, void *dst)
{
- surf_action_network_GTNETS_t gtnets_action = (surf_action_network_GTNETS_t)action;
+ /*FIXME:surf_action_network_GTNETS_t gtnets_action = (surf_action_network_GTNETS_t)action;
gtnets_action->src = src;
- gtnets_action->dst = dst;
+ gtnets_action->dst = dst;*/
}
void TRACE_surf_action(surf_action_t surf_action, const char *category)
if (!category)
return;
- surf_action->category = xbt_strdup(category);
+ surf_action_set_category(surf_action, xbt_strdup(category));
}
#endif /* HAVE_TRACING */
--- /dev/null
+/* 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. */
+
+/*
+ * Modelling the proportional fairness using the Lagrange Optimization
+ * Approach. For a detailed description see:
+ * "ssh://username@scm.gforge.inria.fr/svn/memo/people/pvelho/lagrange/ppf.ps".
+ */
+#include "xbt/log.h"
+#include "xbt/sysdep.h"
+#include "maxmin_private.h"
+
+#include <stdlib.h>
+#ifndef MATH
+#include <math.h>
+#endif
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_lagrange, surf,
+ "Logging specific to SURF (lagrange)");
+XBT_LOG_NEW_SUBCATEGORY(surf_lagrange_dichotomy, surf_lagrange,
+ "Logging specific to SURF (lagrange dichotomy)");
+
+#define SHOW_EXPR(expr) XBT_CDEBUG(surf_lagrange,#expr " = %g",expr);
+
+double (*func_f_def) (lmm_variable_t, double);
+double (*func_fp_def) (lmm_variable_t, double);
+double (*func_fpi_def) (lmm_variable_t, double);
+
+/*
+ * Local prototypes to implement the lagrangian optimization with optimal step, also called dichotomy.
+ */
+//solves the proportional fairness using a lagrange optimizition with dichotomy step
+void lagrange_solve(lmm_system_t sys);
+//computes the value of the dichotomy using a initial values, init, with a specific variable or constraint
+static double dichotomy(double init, double diff(double, void *),
+ void *var_cnst, double min_error);
+//computes the value of the differential of constraint param_cnst applied to lambda
+static double partial_diff_lambda(double lambda, void *param_cnst);
+
+static int __check_feasible(xbt_swag_t cnst_list, xbt_swag_t var_list,
+ int warn)
+{
+ xbt_swag_t elem_list = NULL;
+ lmm_element_t elem = NULL;
+ lmm_constraint_t cnst = NULL;
+ lmm_variable_t var = NULL;
+
+ double tmp;
+
+ xbt_swag_foreach(cnst, cnst_list) {
+ tmp = 0;
+ elem_list = &(cnst->element_set);
+ xbt_swag_foreach(elem, elem_list) {
+ var = elem->variable;
+ if (var->weight <= 0)
+ continue;
+ tmp += var->value;
+ }
+
+ if (double_positive(tmp - cnst->bound)) {
+ if (warn)
+ XBT_WARN
+ ("The link (%p) is over-used. Expected less than %f and got %f",
+ cnst, cnst->bound, tmp);
+ return 0;
+ }
+ XBT_DEBUG
+ ("Checking feasability for constraint (%p): sat = %f, lambda = %f ",
+ cnst, tmp - cnst->bound, cnst->lambda);
+ }
+
+ xbt_swag_foreach(var, var_list) {
+ if (!var->weight)
+ break;
+ if (var->bound < 0)
+ continue;
+ XBT_DEBUG("Checking feasability for variable (%p): sat = %f mu = %f", var,
+ var->value - var->bound, var->mu);
+
+ if (double_positive(var->value - var->bound)) {
+ if (warn)
+ XBT_WARN
+ ("The variable (%p) is too large. Expected less than %f and got %f",
+ var, var->bound, var->value);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static double new_value(lmm_variable_t var)
+{
+ double tmp = 0;
+ int i;
+
+ for (i = 0; i < var->cnsts_number; i++) {
+ tmp += (var->cnsts[i].constraint)->lambda;
+ }
+ if (var->bound > 0)
+ tmp += var->mu;
+ XBT_DEBUG("\t Working on var (%p). cost = %e; Weight = %e", var, tmp,
+ var->weight);
+ //uses the partial differential inverse function
+ return var->func_fpi(var, tmp);
+}
+
+static double new_mu(lmm_variable_t var)
+{
+ double mu_i = 0.0;
+ double sigma_i = 0.0;
+ int j;
+
+ for (j = 0; j < var->cnsts_number; j++) {
+ sigma_i += (var->cnsts[j].constraint)->lambda;
+ }
+ mu_i = var->func_fp(var, var->bound) - sigma_i;
+ if (mu_i < 0.0)
+ return 0.0;
+ return mu_i;
+}
+
+static double dual_objective(xbt_swag_t var_list, xbt_swag_t cnst_list)
+{
+ lmm_constraint_t cnst = NULL;
+ lmm_variable_t var = NULL;
+
+ double obj = 0.0;
+
+ xbt_swag_foreach(var, var_list) {
+ double sigma_i = 0.0;
+ int j;
+
+ if (!var->weight)
+ break;
+
+ for (j = 0; j < var->cnsts_number; j++)
+ sigma_i += (var->cnsts[j].constraint)->lambda;
+
+ if (var->bound > 0)
+ sigma_i += var->mu;
+
+ XBT_DEBUG("var %p : sigma_i = %1.20f", var, sigma_i);
+
+ obj += var->func_f(var, var->func_fpi(var, sigma_i)) -
+ sigma_i * var->func_fpi(var, sigma_i);
+
+ if (var->bound > 0)
+ obj += var->mu * var->bound;
+ }
+
+ xbt_swag_foreach(cnst, cnst_list)
+ obj += cnst->lambda * cnst->bound;
+
+ return obj;
+}
+
+void lagrange_solve(lmm_system_t sys)
+{
+ /*
+ * Lagrange Variables.
+ */
+ int max_iterations = 100;
+ double epsilon_min_error = MAXMIN_PRECISION;
+ double dichotomy_min_error = 1e-14;
+ double overall_modification = 1;
+
+ /*
+ * Variables to manipulate the data structure proposed to model the maxmin
+ * fairness. See docummentation for more details.
+ */
+ xbt_swag_t cnst_list = NULL;
+ lmm_constraint_t cnst = NULL;
+
+ xbt_swag_t var_list = NULL;
+ lmm_variable_t var = NULL;
+
+ /*
+ * Auxiliar variables.
+ */
+ int iteration = 0;
+ double tmp = 0;
+ int i;
+ double obj, new_obj;
+
+ XBT_DEBUG("Iterative method configuration snapshot =====>");
+ XBT_DEBUG("#### Maximum number of iterations : %d", max_iterations);
+ XBT_DEBUG("#### Minimum error tolerated : %e",
+ epsilon_min_error);
+ XBT_DEBUG("#### Minimum error tolerated (dichotomy) : %e",
+ dichotomy_min_error);
+
+ if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
+ lmm_print(sys);
+ }
+
+ if (!(sys->modified))
+ return;
+
+
+ /*
+ * Initialize lambda.
+ */
+ cnst_list = &(sys->active_constraint_set);
+ xbt_swag_foreach(cnst, cnst_list) {
+ cnst->lambda = 1.0;
+ cnst->new_lambda = 2.0;
+ XBT_DEBUG("#### cnst(%p)->lambda : %e", cnst, cnst->lambda);
+ }
+
+ /*
+ * Initialize the var list variable with only the active variables.
+ * Associate an index in the swag variables. Initialize mu.
+ */
+ var_list = &(sys->variable_set);
+ i = 0;
+ xbt_swag_foreach(var, var_list) {
+ if (!var->weight)
+ var->value = 0.0;
+ else {
+ int nb = 0;
+ if (var->bound < 0.0) {
+ XBT_DEBUG("#### NOTE var(%d) is a boundless variable", i);
+ var->mu = -1.0;
+ var->value = new_value(var);
+ } else {
+ var->mu = 1.0;
+ var->new_mu = 2.0;
+ var->value = new_value(var);
+ }
+ XBT_DEBUG("#### var(%p) ->weight : %e", var, var->weight);
+ XBT_DEBUG("#### var(%p) ->mu : %e", var, var->mu);
+ XBT_DEBUG("#### var(%p) ->weight: %e", var, var->weight);
+ XBT_DEBUG("#### var(%p) ->bound: %e", var, var->bound);
+ for (i = 0; i < var->cnsts_number; i++) {
+ if (var->cnsts[i].value == 0.0)
+ nb++;
+ }
+ if (nb == var->cnsts_number)
+ var->value = 1.0;
+ }
+ }
+
+ /*
+ * Compute dual objective.
+ */
+ obj = dual_objective(var_list, cnst_list);
+
+ /*
+ * While doesn't reach a minimun error or a number maximum of iterations.
+ */
+ while (overall_modification > epsilon_min_error
+ && iteration < max_iterations) {
+/* int dual_updated=0; */
+
+ iteration++;
+ XBT_DEBUG("************** ITERATION %d **************", iteration);
+ XBT_DEBUG("-------------- Gradient Descent ----------");
+
+ /*
+ * Improve the value of mu_i
+ */
+ xbt_swag_foreach(var, var_list) {
+ if (!var->weight)
+ break;
+ if (var->bound >= 0) {
+ XBT_DEBUG("Working on var (%p)", var);
+ var->new_mu = new_mu(var);
+/* dual_updated += (fabs(var->new_mu-var->mu)>dichotomy_min_error); */
+/* XBT_DEBUG("dual_updated (%d) : %1.20f",dual_updated,fabs(var->new_mu-var->mu)); */
+ XBT_DEBUG("Updating mu : var->mu (%p) : %1.20f -> %1.20f", var,
+ var->mu, var->new_mu);
+ var->mu = var->new_mu;
+
+ new_obj = dual_objective(var_list, cnst_list);
+ XBT_DEBUG("Improvement for Objective (%g -> %g) : %g", obj, new_obj,
+ obj - new_obj);
+ xbt_assert(obj - new_obj >= -epsilon_min_error,
+ "Our gradient sucks! (%1.20f)", obj - new_obj);
+ obj = new_obj;
+ }
+ }
+
+ /*
+ * Improve the value of lambda_i
+ */
+ xbt_swag_foreach(cnst, cnst_list) {
+ XBT_DEBUG("Working on cnst (%p)", cnst);
+ cnst->new_lambda =
+ dichotomy(cnst->lambda, partial_diff_lambda, cnst,
+ dichotomy_min_error);
+/* dual_updated += (fabs(cnst->new_lambda-cnst->lambda)>dichotomy_min_error); */
+/* XBT_DEBUG("dual_updated (%d) : %1.20f",dual_updated,fabs(cnst->new_lambda-cnst->lambda)); */
+ XBT_DEBUG("Updating lambda : cnst->lambda (%p) : %1.20f -> %1.20f",
+ cnst, cnst->lambda, cnst->new_lambda);
+ cnst->lambda = cnst->new_lambda;
+
+ new_obj = dual_objective(var_list, cnst_list);
+ XBT_DEBUG("Improvement for Objective (%g -> %g) : %g", obj, new_obj,
+ obj - new_obj);
+ xbt_assert(obj - new_obj >= -epsilon_min_error,
+ "Our gradient sucks! (%1.20f)", obj - new_obj);
+ obj = new_obj;
+ }
+
+ /*
+ * Now computes the values of each variable (\rho) based on
+ * the values of \lambda and \mu.
+ */
+ XBT_DEBUG("-------------- Check convergence ----------");
+ overall_modification = 0;
+ xbt_swag_foreach(var, var_list) {
+ if (var->weight <= 0)
+ var->value = 0.0;
+ else {
+ tmp = new_value(var);
+
+ overall_modification =
+ MAX(overall_modification, fabs(var->value - tmp));
+
+ var->value = tmp;
+ XBT_DEBUG("New value of var (%p) = %e, overall_modification = %e",
+ var, var->value, overall_modification);
+ }
+ }
+
+ XBT_DEBUG("-------------- Check feasability ----------");
+ if (!__check_feasible(cnst_list, var_list, 0))
+ overall_modification = 1.0;
+ XBT_DEBUG("Iteration %d: overall_modification : %f", iteration,
+ overall_modification);
+/* if(!dual_updated) { */
+/* XBT_WARN("Could not improve the convergence at iteration %d. Drop it!",iteration); */
+/* break; */
+/* } */
+ }
+
+ __check_feasible(cnst_list, var_list, 1);
+
+ if (overall_modification <= epsilon_min_error) {
+ XBT_DEBUG("The method converges in %d iterations.", iteration);
+ }
+ if (iteration >= max_iterations) {
+ XBT_DEBUG
+ ("Method reach %d iterations, which is the maximum number of iterations allowed.",
+ iteration);
+ }
+/* XBT_INFO("Method converged after %d iterations", iteration); */
+
+ if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
+ lmm_print(sys);
+ }
+}
+
+/*
+ * Returns a double value corresponding to the result of a dichotomy proccess with
+ * respect to a given variable/constraint (\mu in the case of a variable or \lambda in
+ * case of a constraint) and a initial value init.
+ *
+ * @param init initial value for \mu or \lambda
+ * @param diff a function that computes the differential of with respect a \mu or \lambda
+ * @param var_cnst a pointer to a variable or constraint
+ * @param min_erro a minimun error tolerated
+ *
+ * @return a double correponding to the result of the dichotomyal process
+ */
+static double dichotomy(double init, double diff(double, void *),
+ void *var_cnst, double min_error)
+{
+ double min, max;
+ double overall_error;
+ double middle;
+ double min_diff, max_diff, middle_diff;
+ double diff_0 = 0.0;
+ min = max = init;
+
+ XBT_IN();
+
+ if (init == 0.0) {
+ min = max = 0.5;
+ }
+
+ min_diff = max_diff = middle_diff = 0.0;
+ overall_error = 1;
+
+ if ((diff_0 = diff(1e-16, var_cnst)) >= 0) {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "returning 0.0 (diff = %e)", diff_0);
+ XBT_OUT();
+ return 0.0;
+ }
+
+ min_diff = diff(min, var_cnst);
+ max_diff = diff(max, var_cnst);
+
+ while (overall_error > min_error) {
+ XBT_CDEBUG(surf_lagrange_dichotomy,
+ "[min, max] = [%1.20f, %1.20f] || diffmin, diffmax = %1.20f, %1.20f",
+ min, max, min_diff, max_diff);
+
+ if (min_diff > 0 && max_diff > 0) {
+ if (min == max) {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing min");
+ min = min / 2.0;
+ min_diff = diff(min, var_cnst);
+ } else {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
+ max = min;
+ max_diff = min_diff;
+ }
+ } else if (min_diff < 0 && max_diff < 0) {
+ if (min == max) {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing max");
+ max = max * 2.0;
+ max_diff = diff(max, var_cnst);
+ } else {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
+ min = max;
+ min_diff = max_diff;
+ }
+ } else if (min_diff < 0 && max_diff > 0) {
+ middle = (max + min) / 2.0;
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Trying (max+min)/2 : %1.20f",
+ middle);
+
+ if ((min == middle) || (max == middle)) {
+ XBT_CWARN(surf_lagrange_dichotomy,
+ "Cannot improve the convergence! min=max=middle=%1.20f, diff = %1.20f."
+ " Reaching the 'double' limits. Maybe scaling your function would help ([%1.20f,%1.20f]).",
+ min, max - min, min_diff, max_diff);
+ break;
+ }
+ middle_diff = diff(middle, var_cnst);
+
+ if (middle_diff < 0) {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
+ min = middle;
+ overall_error = max_diff - middle_diff;
+ min_diff = middle_diff;
+/* SHOW_EXPR(overall_error); */
+ } else if (middle_diff > 0) {
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
+ max = middle;
+ overall_error = max_diff - middle_diff;
+ max_diff = middle_diff;
+/* SHOW_EXPR(overall_error); */
+ } else {
+ overall_error = 0;
+/* SHOW_EXPR(overall_error); */
+ }
+ } else if (min_diff == 0) {
+ max = min;
+ overall_error = 0;
+/* SHOW_EXPR(overall_error); */
+ } else if (max_diff == 0) {
+ min = max;
+ overall_error = 0;
+/* SHOW_EXPR(overall_error); */
+ } else if (min_diff > 0 && max_diff < 0) {
+ XBT_CWARN(surf_lagrange_dichotomy,
+ "The impossible happened, partial_diff(min) > 0 && partial_diff(max) < 0");
+ xbt_abort();
+ } else {
+ XBT_CWARN(surf_lagrange_dichotomy,
+ "diffmin (%1.20f) or diffmax (%1.20f) are something I don't know, taking no action.",
+ min_diff, max_diff);
+ xbt_abort();
+ }
+ }
+
+ XBT_CDEBUG(surf_lagrange_dichotomy, "returning %e", (min + max) / 2.0);
+ XBT_OUT();
+ return ((min + max) / 2.0);
+}
+
+static double partial_diff_lambda(double lambda, void *param_cnst)
+{
+
+ int j;
+ xbt_swag_t elem_list = NULL;
+ lmm_element_t elem = NULL;
+ lmm_variable_t var = NULL;
+ lmm_constraint_t cnst = (lmm_constraint_t) param_cnst;
+ double diff = 0.0;
+ double sigma_i = 0.0;
+
+ XBT_IN();
+ elem_list = &(cnst->element_set);
+
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Computing diff of cnst (%p)", cnst);
+
+ xbt_swag_foreach(elem, elem_list) {
+ var = elem->variable;
+ if (var->weight <= 0)
+ continue;
+
+ XBT_CDEBUG(surf_lagrange_dichotomy, "Computing sigma_i for var (%p)",
+ var);
+ // Initialize the summation variable
+ sigma_i = 0.0;
+
+ // Compute sigma_i
+ for (j = 0; j < var->cnsts_number; j++) {
+ sigma_i += (var->cnsts[j].constraint)->lambda;
+ }
+
+ //add mu_i if this flow has a RTT constraint associated
+ if (var->bound > 0)
+ sigma_i += var->mu;
+
+ //replace value of cnst->lambda by the value of parameter lambda
+ sigma_i = (sigma_i - cnst->lambda) + lambda;
+
+ diff += -var->func_fpi(var, sigma_i);
+ }
+
+
+ diff += cnst->bound;
+
+ XBT_CDEBUG(surf_lagrange_dichotomy,
+ "d D/d lambda for cnst (%p) at %1.20f = %1.20f", cnst, lambda,
+ diff);
+ XBT_OUT();
+ return diff;
+}
+
+/** \brief Attribute the value bound to var->bound.
+ *
+ * \param func_fpi inverse of the partial differential of f (f prime inverse, (f')^{-1})
+ *
+ * Set default functions to the ones passed as parameters. This is a polimorfism in C pure, enjoy the roots of programming.
+ *
+ */
+void lmm_set_default_protocol_function(double (*func_f)
+
+
+
+
+
+
+ (lmm_variable_t var, double x),
+ double (*func_fp) (lmm_variable_t
+ var, double x),
+ double (*func_fpi) (lmm_variable_t
+ var, double x))
+{
+ func_f_def = func_f;
+ func_fp_def = func_fp;
+ func_fpi_def = func_fpi;
+}
+
+
+/**************** Vegas and Reno functions *************************/
+/*
+ * NOTE for Reno: all functions consider the network
+ * coeficient (alpha) equal to 1.
+ */
+
+/*
+ * For Vegas: $f(x) = \alpha D_f\ln(x)$
+ * Therefore: $fp(x) = \frac{\alpha D_f}{x}$
+ * Therefore: $fpi(x) = \frac{\alpha D_f}{x}$
+ */
+#define VEGAS_SCALING 1000.0
+
+double func_vegas_f(lmm_variable_t var, double x)
+{
+ xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
+ return VEGAS_SCALING * var->weight * log(x);
+}
+
+double func_vegas_fp(lmm_variable_t var, double x)
+{
+ xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
+ return VEGAS_SCALING * var->weight / x;
+}
+
+double func_vegas_fpi(lmm_variable_t var, double x)
+{
+ xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
+ return var->weight / (x / VEGAS_SCALING);
+}
+
+/*
+ * For Reno: $f(x) = \frac{\sqrt{3/2}}{D_f} atan(\sqrt{3/2}D_f x)$
+ * Therefore: $fp(x) = \frac{3}{3 D_f^2 x^2+2}$
+ * Therefore: $fpi(x) = \sqrt{\frac{1}{{D_f}^2 x} - \frac{2}{3{D_f}^2}}$
+ */
+#define RENO_SCALING 1.0
+double func_reno_f(lmm_variable_t var, double x)
+{
+ xbt_assert(var->weight > 0.0, "Don't call me with stupid values!");
+
+ return RENO_SCALING * sqrt(3.0 / 2.0) / var->weight *
+ atan(sqrt(3.0 / 2.0) * var->weight * x);
+}
+
+double func_reno_fp(lmm_variable_t var, double x)
+{
+ return RENO_SCALING * 3.0 / (3.0 * var->weight * var->weight * x * x +
+ 2.0);
+}
+
+double func_reno_fpi(lmm_variable_t var, double x)
+{
+ double res_fpi;
+
+ xbt_assert(var->weight > 0.0, "Don't call me with stupid values!");
+ xbt_assert(x > 0.0, "Don't call me with stupid values!");
+
+ res_fpi =
+ 1.0 / (var->weight * var->weight * (x / RENO_SCALING)) -
+ 2.0 / (3.0 * var->weight * var->weight);
+ if (res_fpi <= 0.0)
+ return 0.0;
+/* xbt_assert(res_fpi>0.0,"Don't call me with stupid values!"); */
+ return sqrt(res_fpi);
+}
+
+
+/* Implementing new Reno-2
+ * For Reno-2: $f(x) = U_f(x_f) = \frac{{2}{D_f}}*ln(2+x*D_f)$
+ * Therefore: $fp(x) = 2/(Weight*x + 2)
+ * Therefore: $fpi(x) = (2*Weight)/x - 4
+ */
+#define RENO2_SCALING 1.0
+double func_reno2_f(lmm_variable_t var, double x)
+{
+ xbt_assert(var->weight > 0.0, "Don't call me with stupid values!");
+ return RENO2_SCALING * (1.0 / var->weight) * log((x * var->weight) /
+ (2.0 * x * var->weight +
+ 3.0));
+}
+
+double func_reno2_fp(lmm_variable_t var, double x)
+{
+ return RENO2_SCALING * 3.0 / (var->weight * x *
+ (2.0 * var->weight * x + 3.0));
+}
+
+double func_reno2_fpi(lmm_variable_t var, double x)
+{
+ double res_fpi;
+ double tmp;
+
+ xbt_assert(x > 0.0, "Don't call me with stupid values!");
+ tmp = x * var->weight * var->weight;
+ res_fpi = tmp * (9.0 * x + 24.0);
+
+ if (res_fpi <= 0.0)
+ return 0.0;
+
+ res_fpi = RENO2_SCALING * (-3.0 * tmp + sqrt(res_fpi)) / (4.0 * tmp);
+ return res_fpi;
+}
--- /dev/null
+/* Copyright (c) 2004-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 "xbt/sysdep.h"
+#include "xbt/log.h"
+#include "xbt/mallocator.h"
+#include "maxmin_private.h"
+#include <stdlib.h>
+#include <stdio.h> /* sprintf */
+#include <math.h>
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_maxmin, surf,
+ "Logging specific to SURF (maxmin)");
+
+typedef struct s_dyn_light {
+ int *data;
+ int pos;
+ int size;
+} s_dyn_light_t, *dyn_light_t;
+
+XBT_EXPORT_NO_IMPORT(double) sg_maxmin_precision = 0.00001;
+
+static void *lmm_variable_mallocator_new_f(void);
+static void lmm_variable_mallocator_free_f(void *var);
+#define lmm_variable_mallocator_reset_f ((void_f_pvoid_t)NULL)
+static void lmm_update_modified_set(lmm_system_t sys,
+ lmm_constraint_t cnst);
+static void lmm_remove_all_modified_set(lmm_system_t sys);
+static int Global_debug_id = 1;
+static int Global_const_debug_id = 1;
+
+static void lmm_var_free(lmm_system_t sys, lmm_variable_t var);
+static XBT_INLINE void lmm_cnst_free(lmm_system_t sys,
+ lmm_constraint_t cnst);
+
+lmm_system_t lmm_system_new(int selective_update)
+{
+ lmm_system_t l = NULL;
+ s_lmm_variable_t var;
+ s_lmm_constraint_t cnst;
+
+ l = xbt_new0(s_lmm_system_t, 1);
+
+ l->modified = 0;
+ l->selective_update_active = selective_update;
+ l->visited_counter = 1;
+
+ XBT_DEBUG("Setting selective_update_active flag to %d\n",
+ l->selective_update_active);
+
+ xbt_swag_init(&(l->variable_set),
+ xbt_swag_offset(var, variable_set_hookup));
+ xbt_swag_init(&(l->constraint_set),
+ xbt_swag_offset(cnst, constraint_set_hookup));
+
+ xbt_swag_init(&(l->active_constraint_set),
+ xbt_swag_offset(cnst, active_constraint_set_hookup));
+
+ xbt_swag_init(&(l->modified_constraint_set),
+ xbt_swag_offset(cnst, modified_constraint_set_hookup));
+ xbt_swag_init(&(l->saturated_variable_set),
+ xbt_swag_offset(var, saturated_variable_set_hookup));
+ xbt_swag_init(&(l->saturated_constraint_set),
+ xbt_swag_offset(cnst, saturated_constraint_set_hookup));
+
+ l->variable_mallocator = xbt_mallocator_new(65536,
+ lmm_variable_mallocator_new_f,
+ lmm_variable_mallocator_free_f,
+ lmm_variable_mallocator_reset_f);
+
+ return l;
+}
+
+void lmm_system_free(lmm_system_t sys)
+{
+ lmm_variable_t var = NULL;
+ lmm_constraint_t cnst = NULL;
+
+ while ((var = extract_variable(sys))) {
+ XBT_WARN
+ ("Variable %p (%d) still in LMM system when freing it: this may be a bug",
+ var, var->id_int);
+ lmm_var_free(sys, var);
+ }
+
+ while ((cnst = extract_constraint(sys)))
+ lmm_cnst_free(sys, cnst);
+
+ xbt_mallocator_free(sys->variable_mallocator);
+ free(sys);
+}
+
+XBT_INLINE void lmm_variable_disable(lmm_system_t sys, lmm_variable_t var)
+{
+ int i;
+ int n;
+
+ lmm_element_t elem = NULL;
+
+ XBT_IN("(sys=%p, var=%p)", sys, var);
+ sys->modified = 1;
+
+ n = 0;
+ for (i = 0; i < var->cnsts_number; i++) {
+ elem = &var->cnsts[i];
+ xbt_swag_remove(elem, &(elem->constraint->element_set));
+ xbt_swag_remove(elem, &(elem->constraint->active_element_set));
+ if (!xbt_swag_size(&(elem->constraint->element_set)))
+ make_constraint_inactive(sys, elem->constraint);
+ else {
+ if (n < i)
+ var->cnsts[n].constraint = elem->constraint;
+ n++;
+ }
+ }
+ if (n) {
+ var->cnsts_number = n;
+ lmm_update_modified_set(sys, var->cnsts[0].constraint);
+ }
+
+ var->cnsts_number = 0;
+ XBT_OUT();
+}
+
+static void lmm_var_free(lmm_system_t sys, lmm_variable_t var)
+{
+
+ lmm_variable_disable(sys, var);
+ xbt_mallocator_release(sys->variable_mallocator, var);
+}
+
+static XBT_INLINE void lmm_cnst_free(lmm_system_t sys,
+ lmm_constraint_t cnst)
+{
+/* xbt_assert(xbt_swag_size(&(cnst->element_set)), */
+/* "This list should be empty!"); */
+ make_constraint_inactive(sys, cnst);
+ free(cnst);
+}
+
+lmm_constraint_t lmm_constraint_new(lmm_system_t sys, void *id,
+ double bound_value)
+{
+ lmm_constraint_t cnst = NULL;
+ s_lmm_element_t elem;
+
+ cnst = xbt_new0(s_lmm_constraint_t, 1);
+ cnst->id = id;
+ cnst->id_int = Global_const_debug_id++;
+ xbt_swag_init(&(cnst->element_set),
+ xbt_swag_offset(elem, element_set_hookup));
+ xbt_swag_init(&(cnst->active_element_set),
+ xbt_swag_offset(elem, active_element_set_hookup));
+
+ cnst->bound = bound_value;
+ cnst->usage = 0;
+ cnst->shared = 1;
+ insert_constraint(sys, cnst);
+
+ return cnst;
+}
+
+XBT_INLINE void lmm_constraint_shared(lmm_constraint_t cnst)
+{
+ cnst->shared = 0;
+}
+
+XBT_INLINE int lmm_constraint_is_shared(lmm_constraint_t cnst)
+{
+ return (cnst->shared);
+}
+
+XBT_INLINE void lmm_constraint_free(lmm_system_t sys,
+ lmm_constraint_t cnst)
+{
+ remove_constraint(sys, cnst);
+ lmm_cnst_free(sys, cnst);
+}
+
+static void *lmm_variable_mallocator_new_f(void)
+{
+ lmm_variable_t var = xbt_new(s_lmm_variable_t, 1);
+ var->cnsts = NULL; /* will be created by realloc */
+ return var;
+}
+
+static void lmm_variable_mallocator_free_f(void *var)
+{
+ xbt_free(((lmm_variable_t) var)->cnsts);
+ xbt_free(var);
+}
+
+lmm_variable_t lmm_variable_new(lmm_system_t sys, void *id,
+ double weight,
+ double bound, int number_of_constraints)
+{
+ lmm_variable_t var = NULL;
+ int i;
+
+ XBT_IN("(sys=%p, id=%p, weight=%f, bound=%f, num_cons =%d)",
+ sys, id, weight, bound, number_of_constraints);
+
+ var = xbt_mallocator_get(sys->variable_mallocator);
+ var->id = id;
+ var->id_int = Global_debug_id++;
+ var->cnsts = xbt_realloc(var->cnsts, number_of_constraints * sizeof(s_lmm_element_t));
+ for (i = 0; i < number_of_constraints; i++) {
+ var->cnsts[i].element_set_hookup.next = NULL;
+ var->cnsts[i].element_set_hookup.prev = NULL;
+ var->cnsts[i].active_element_set_hookup.next = NULL;
+ var->cnsts[i].active_element_set_hookup.prev = NULL;
+ var->cnsts[i].constraint = NULL;
+ var->cnsts[i].variable = NULL;
+ var->cnsts[i].value = 0.0;
+ }
+ var->cnsts_size = number_of_constraints;
+ var->cnsts_number = 0;
+ var->weight = weight;
+ var->bound = bound;
+ var->value = 0.0;
+ var->visited = sys->visited_counter - 1;
+ var->mu = 0.0;
+ var->new_mu = 0.0;
+ var->func_f = func_f_def;
+ var->func_fp = func_fp_def;
+ var->func_fpi = func_fpi_def;
+
+ var->variable_set_hookup.next = NULL;
+ var->variable_set_hookup.prev = NULL;
+ var->saturated_variable_set_hookup.next = NULL;
+ var->saturated_variable_set_hookup.prev = NULL;
+
+ if (weight)
+ xbt_swag_insert_at_head(var, &(sys->variable_set));
+ else
+ xbt_swag_insert_at_tail(var, &(sys->variable_set));
+
+ XBT_OUT(" returns %p", var);
+ return var;
+}
+
+void lmm_variable_free(lmm_system_t sys, lmm_variable_t var)
+{
+ remove_variable(sys, var);
+ lmm_var_free(sys, var);
+}
+
+XBT_INLINE double lmm_variable_getvalue(lmm_variable_t var)
+{
+ return (var->value);
+}
+
+XBT_INLINE double lmm_variable_getbound(lmm_variable_t var)
+{
+ return (var->bound);
+}
+
+void lmm_expand(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value)
+{
+ lmm_element_t elem = NULL;
+
+ sys->modified = 1;
+
+ xbt_assert(var->cnsts_number < var->cnsts_size, "Too much constraints");
+
+ elem = &(var->cnsts[var->cnsts_number++]);
+
+ elem->value = value;
+ elem->constraint = cnst;
+ elem->variable = var;
+
+ if (var->weight)
+ xbt_swag_insert_at_head(elem, &(elem->constraint->element_set));
+ else
+ xbt_swag_insert_at_tail(elem, &(elem->constraint->element_set));
+ if(!sys->selective_update_active) {
+ make_constraint_active(sys, cnst);
+ } else if(elem->value>0 || var->weight >0) {
+ make_constraint_active(sys, cnst);
+ lmm_update_modified_set(sys, cnst);
+ if (var->cnsts_number > 1)
+ lmm_update_modified_set(sys, var->cnsts[0].constraint);
+ }
+}
+
+void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value)
+{
+ int i;
+ sys->modified = 1;
+
+ for (i = 0; i < var->cnsts_number; i++)
+ if (var->cnsts[i].constraint == cnst)
+ break;
+
+ if (i < var->cnsts_number) {
+ if (cnst->shared)
+ var->cnsts[i].value += value;
+ else
+ var->cnsts[i].value = MAX(var->cnsts[i].value, value);
+ lmm_update_modified_set(sys, cnst);
+ } else
+ lmm_expand(sys, cnst, var, value);
+}
+
+void lmm_elem_set_value(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value)
+{
+ int i;
+
+ for (i = 0; i < var->cnsts_number; i++)
+ if (var->cnsts[i].constraint == cnst)
+ break;
+
+ if (i < var->cnsts_number) {
+ var->cnsts[i].value = value;
+ sys->modified = 1;
+ lmm_update_modified_set(sys, cnst);
+ } else
+ DIE_IMPOSSIBLE;
+}
+
+XBT_INLINE lmm_constraint_t lmm_get_cnst_from_var(lmm_system_t sys,
+ lmm_variable_t var,
+ int num)
+{
+ if (num < var->cnsts_number)
+ return (var->cnsts[num].constraint);
+ else
+ return NULL;
+}
+
+XBT_INLINE double lmm_get_cnst_weight_from_var(lmm_system_t sys,
+ lmm_variable_t var,
+ int num)
+{
+ if (num < var->cnsts_number)
+ return (var->cnsts[num].value);
+ else
+ return 0.0;
+}
+
+XBT_INLINE int lmm_get_number_of_cnst_from_var(lmm_system_t sys,
+ lmm_variable_t var)
+{
+ return (var->cnsts_number);
+}
+
+lmm_variable_t lmm_get_var_from_cnst(lmm_system_t sys,
+ lmm_constraint_t cnst,
+ lmm_element_t * elem)
+{
+ if (!(*elem))
+ *elem = xbt_swag_getFirst(&(cnst->element_set));
+ else
+ *elem = xbt_swag_getNext(*elem, cnst->element_set.offset);
+ if (*elem)
+ return (*elem)->variable;
+ else
+ return NULL;
+}
+
+XBT_INLINE void *lmm_constraint_id(lmm_constraint_t cnst)
+{
+ return cnst->id;
+}
+
+XBT_INLINE void *lmm_variable_id(lmm_variable_t var)
+{
+ return var->id;
+}
+
+static XBT_INLINE void saturated_constraint_set_update(double usage,
+ int cnst_light_num,
+ dyn_light_t saturated_constraint_set,
+ double *min_usage)
+{
+ xbt_assert(usage > 0,"Impossible");
+
+ if (*min_usage < 0 || *min_usage > usage) {
+ *min_usage = usage;
+ // XBT_HERE(" min_usage=%f (cnst->remaining / cnst->usage =%f)", *min_usage, usage);
+ saturated_constraint_set->data[0] = cnst_light_num;
+ saturated_constraint_set->pos = 1;
+ } else if (*min_usage == usage) {
+ if(saturated_constraint_set->pos == saturated_constraint_set->size) { // realloc the size
+ saturated_constraint_set->size *= 2;
+ saturated_constraint_set->data = xbt_realloc(saturated_constraint_set->data, (saturated_constraint_set->size) * sizeof(int));
+ }
+ saturated_constraint_set->data[saturated_constraint_set->pos] = cnst_light_num;
+ saturated_constraint_set->pos++;
+ }
+}
+
+static XBT_INLINE void saturated_variable_set_update(
+ s_lmm_constraint_light_t *cnst_light_tab,
+ dyn_light_t saturated_constraint_set,
+ lmm_system_t sys)
+{
+ lmm_constraint_light_t cnst = NULL;
+ lmm_element_t elem = NULL;
+ xbt_swag_t elem_list = NULL;
+ int i;
+ for(i = 0; i< saturated_constraint_set->pos; i++){
+ cnst = &cnst_light_tab[saturated_constraint_set->data[i]];
+ elem_list = &(cnst->cnst->active_element_set);
+ xbt_swag_foreach(elem, elem_list) {
+ if (elem->variable->weight <= 0)
+ break;
+ if ((elem->value > 0))
+ xbt_swag_insert(elem->variable, &(sys->saturated_variable_set));
+ }
+ }
+}
+
+void lmm_print(lmm_system_t sys)
+{
+ lmm_constraint_t cnst = NULL;
+ lmm_element_t elem = NULL;
+ lmm_variable_t var = NULL;
+ xbt_swag_t cnst_list = NULL;
+ xbt_swag_t var_list = NULL;
+ xbt_swag_t elem_list = NULL;
+ char print_buf[1024];
+ char *trace_buf = xbt_malloc0(sizeof(char));
+ double sum = 0.0;
+
+ /* Printing Objective */
+ var_list = &(sys->variable_set);
+ sprintf(print_buf, "MAX-MIN ( ");
+ trace_buf =
+ xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ xbt_swag_foreach(var, var_list) {
+ sprintf(print_buf, "'%d'(%f) ", var->id_int, var->weight);
+ trace_buf =
+ xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ }
+ sprintf(print_buf, ")");
+ trace_buf =
+ xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ XBT_DEBUG("%20s", trace_buf);
+ trace_buf[0] = '\000';
+
+ XBT_DEBUG("Constraints");
+ /* Printing Constraints */
+ cnst_list = &(sys->active_constraint_set);
+ xbt_swag_foreach(cnst, cnst_list) {
+ sum = 0.0;
+ elem_list = &(cnst->element_set);
+ sprintf(print_buf, "\t");
+ trace_buf =
+ xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ sprintf(print_buf, "%s(",(cnst->shared)?"":"max");
+ trace_buf =
+ xbt_realloc(trace_buf,
+ strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ xbt_swag_foreach(elem, elem_list) {
+ sprintf(print_buf, "%f.'%d'(%f) %s ", elem->value,
+ elem->variable->id_int, elem->variable->value,(cnst->shared)?"+":",");
+ trace_buf =
+ xbt_realloc(trace_buf,
+ strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ if(cnst->shared)
+ sum += elem->value * elem->variable->value;
+ else
+ sum = MAX(sum,elem->value * elem->variable->value);
+ }
+ sprintf(print_buf, "0) <= %f ('%d')", cnst->bound, cnst->id_int);
+ trace_buf =
+ xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+
+ if (!cnst->shared) {
+ sprintf(print_buf, " [MAX-Constraint]");
+ trace_buf =
+ xbt_realloc(trace_buf,
+ strlen(trace_buf) + strlen(print_buf) + 1);
+ strcat(trace_buf, print_buf);
+ }
+ XBT_DEBUG("%s", trace_buf);
+ trace_buf[0] = '\000';
+ xbt_assert(!double_positive(sum - cnst->bound),
+ "Incorrect value (%f is not smaller than %f): %g",
+ sum, cnst->bound, sum - cnst->bound);
+ }
+
+ XBT_DEBUG("Variables");
+ /* Printing Result */
+ xbt_swag_foreach(var, var_list) {
+ if (var->bound > 0) {
+ XBT_DEBUG("'%d'(%f) : %f (<=%f)", var->id_int, var->weight, var->value,
+ var->bound);
+ xbt_assert(!double_positive(var->value - var->bound),
+ "Incorrect value (%f is not smaller than %f",
+ var->value, var->bound);
+ } else {
+ XBT_DEBUG("'%d'(%f) : %f", var->id_int, var->weight, var->value);
+ }
+ }
+
+ free(trace_buf);
+}
+
+void lmm_solve(lmm_system_t sys)
+{
+ lmm_variable_t var = NULL;
+ lmm_constraint_t cnst = NULL;
+ lmm_constraint_t cnst_next = NULL;
+ lmm_element_t elem = NULL;
+ xbt_swag_t cnst_list = NULL;
+ xbt_swag_t var_list = NULL;
+ xbt_swag_t elem_list = NULL;
+ double min_usage = -1;
+ double min_bound = -1;
+
+ if (!(sys->modified))
+ return;
+
+ XBT_IN("(sys=%p)", sys);
+
+ /*
+ * Compute Usage and store the variables that reach the maximum.
+ */
+ cnst_list =
+ sys->
+ selective_update_active ? &(sys->modified_constraint_set) :
+ &(sys->active_constraint_set);
+
+ XBT_DEBUG("Active constraints : %d", xbt_swag_size(cnst_list));
+ /* Init: Only modified code portions */
+ xbt_swag_foreach(cnst, cnst_list) {
+ elem_list = &(cnst->element_set);
+ //XBT_DEBUG("Variable set : %d", xbt_swag_size(elem_list));
+ xbt_swag_foreach(elem, elem_list) {
+ var = elem->variable;
+ if (var->weight <= 0.0)
+ break;
+ var->value = 0.0;
+ }
+ }
+
+ s_lmm_constraint_light_t *cnst_light_tab = (s_lmm_constraint_light_t *)xbt_malloc0(xbt_swag_size(cnst_list)*sizeof(s_lmm_constraint_light_t));
+ int cnst_light_num = 0;
+ dyn_light_t saturated_constraint_set = xbt_new0(s_dyn_light_t,1);
+ saturated_constraint_set->size = 5;
+ saturated_constraint_set->data = xbt_new0(int, saturated_constraint_set->size);
+
+ xbt_swag_foreach_safe(cnst, cnst_next, cnst_list) {
+ /* INIT */
+ cnst->remaining = cnst->bound;
+ if (cnst->remaining == 0)
+ continue;
+ cnst->usage = 0;
+ elem_list = &(cnst->element_set);
+ xbt_swag_foreach(elem, elem_list) {
+ /* 0-weighted elements (ie, sleep actions) are at the end of the swag and we don't want to consider them */
+ if (elem->variable->weight <= 0)
+ break;
+ if ((elem->value > 0)) {
+ if (cnst->shared)
+ cnst->usage += elem->value / elem->variable->weight;
+ else if (cnst->usage < elem->value / elem->variable->weight)
+ cnst->usage = elem->value / elem->variable->weight;
+
+ make_elem_active(elem);
+ if (sys->keep_track)
+ xbt_swag_insert(elem->variable->id, sys->keep_track);
+ }
+ }
+ XBT_DEBUG("Constraint Usage '%d' : %f", cnst->id_int, cnst->usage);
+ /* Saturated constraints update */
+
+ if(cnst->usage > 0) {
+ cnst_light_tab[cnst_light_num].cnst = cnst;
+ cnst->cnst_light = &(cnst_light_tab[cnst_light_num]);
+ cnst_light_tab[cnst_light_num].remaining_over_usage = cnst->remaining / cnst->usage;
+ saturated_constraint_set_update(cnst_light_tab[cnst_light_num].remaining_over_usage,
+ cnst_light_num, saturated_constraint_set, &min_usage);
+ cnst_light_num++;
+ }
+ }
+
+ saturated_variable_set_update( cnst_light_tab,
+ saturated_constraint_set,
+ sys);
+
+ /* Saturated variables update */
+
+ do {
+ /* Fix the variables that have to be */
+ var_list = &(sys->saturated_variable_set);
+
+ xbt_swag_foreach(var, var_list) {
+ if (var->weight <= 0.0)
+ DIE_IMPOSSIBLE;
+ /* First check if some of these variables have reach their upper
+ bound and update min_usage accordingly. */
+ XBT_DEBUG
+ ("var=%d, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f",
+ var->id_int, var->bound, var->weight, min_usage,
+ var->bound * var->weight);
+ if ((var->bound > 0) && (var->bound * var->weight < min_usage)) {
+ if (min_bound < 0)
+ min_bound = var->bound;
+ else
+ min_bound = MIN(min_bound, var->bound);
+ XBT_DEBUG("Updated min_bound=%f", min_bound);
+ }
+ }
+
+
+ while ((var = xbt_swag_getFirst(var_list))) {
+ int i;
+
+ if (min_bound < 0) {
+ var->value = min_usage / var->weight;
+ } else {
+ if (min_bound == var->bound)
+ var->value = var->bound;
+ else {
+ xbt_swag_remove(var, var_list);
+ continue;
+ }
+ }
+ XBT_DEBUG("Min usage: %f, Var(%d)->weight: %f, Var(%d)->value: %f ",
+ min_usage, var->id_int, var->weight, var->id_int, var->value);
+
+
+ /* Update usage */
+
+ for (i = 0; i < var->cnsts_number; i++) {
+ elem = &var->cnsts[i];
+ cnst = elem->constraint;
+ if (cnst->shared) {
+ double_update(&(cnst->remaining), elem->value * var->value);
+ double_update(&(cnst->usage), elem->value / var->weight);
+ if(cnst->usage<=0 || cnst->remaining<=0) {
+ if (cnst->cnst_light) {
+ int index = (cnst->cnst_light-cnst_light_tab);
+ XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p \t cnst_light_tab: %p ",
+ index,cnst_light_num, cnst, cnst->cnst_light, cnst_light_tab);
+ cnst_light_tab[index]=cnst_light_tab[cnst_light_num-1];
+ cnst_light_tab[index].cnst->cnst_light = &cnst_light_tab[index];
+ cnst_light_num--;
+ cnst->cnst_light = NULL;
+ }
+ } else {
+ cnst->cnst_light->remaining_over_usage = cnst->remaining / cnst->usage;
+ }
+ make_elem_inactive(elem);
+ } else {
+ cnst->usage = 0.0;
+ make_elem_inactive(elem);
+ elem_list = &(cnst->element_set);
+ xbt_swag_foreach(elem, elem_list) {
+ if (elem->variable->weight <= 0 || elem->variable->value > 0)
+ break;
+ if (elem->value > 0)
+ cnst->usage = MAX(cnst->usage, elem->value / elem->variable->weight);
+ }
+ if (cnst->usage<=0 || cnst->remaining<=0) {
+ if(cnst->cnst_light) {
+ int index = (cnst->cnst_light-cnst_light_tab);
+ XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p \t cnst_light_tab: %p ",
+ index,cnst_light_num, cnst, cnst->cnst_light, cnst_light_tab);
+ cnst_light_tab[index]=cnst_light_tab[cnst_light_num-1];
+ cnst_light_tab[index].cnst->cnst_light = &cnst_light_tab[index];
+ cnst_light_num--;
+ cnst->cnst_light = NULL;
+ }
+ } else {
+ cnst->cnst_light->remaining_over_usage = cnst->remaining / cnst->usage;
+ }
+ }
+ }
+ xbt_swag_remove(var, var_list);
+ }
+
+ /* Find out which variables reach the maximum */
+ min_usage = -1;
+ min_bound = -1;
+ saturated_constraint_set->pos = 0;
+ int pos;
+ for(pos=0; pos<cnst_light_num; pos++)
+ saturated_constraint_set_update(
+ cnst_light_tab[pos].remaining_over_usage,
+ pos,
+ saturated_constraint_set,
+ &min_usage);
+
+ saturated_variable_set_update( cnst_light_tab,
+ saturated_constraint_set,
+ sys);
+
+ } while (cnst_light_num > 0);
+
+ sys->modified = 0;
+ if (sys->selective_update_active)
+ lmm_remove_all_modified_set(sys);
+
+ if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+ lmm_print(sys);
+ }
+
+ xbt_free(saturated_constraint_set->data);
+ xbt_free(saturated_constraint_set);
+ xbt_free(cnst_light_tab);
+ XBT_OUT();
+}
+
+/* Not a O(1) function */
+
+void lmm_update(lmm_system_t sys, lmm_constraint_t cnst,
+ lmm_variable_t var, double value)
+{
+ int i;
+
+ for (i = 0; i < var->cnsts_number; i++)
+ if (var->cnsts[i].constraint == cnst) {
+ var->cnsts[i].value = value;
+ sys->modified = 1;
+ lmm_update_modified_set(sys, cnst);
+ return;
+ }
+}
+
+/** \brief Attribute the value bound to var->bound.
+ *
+ * \param sys the lmm_system_t
+ * \param var the lmm_variable_t
+ * \param bound the new bound to associate with var
+ *
+ * Makes var->bound equal to bound. Whenever this function is called
+ * a change is signed in the system. To
+ * avoid false system changing detection it is a good idea to test
+ * (bound != 0) before calling it.
+ *
+ */
+void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var,
+ double bound)
+{
+ sys->modified = 1;
+ var->bound = bound;
+
+ if (var->cnsts_number)
+ lmm_update_modified_set(sys, var->cnsts[0].constraint);
+}
+
+
+void lmm_update_variable_weight(lmm_system_t sys, lmm_variable_t var,
+ double weight)
+{
+ int i;
+ lmm_element_t elem;
+
+ if (weight == var->weight)
+ return;
+ XBT_IN("(sys=%p, var=%p, weight=%f)", sys, var, weight);
+ sys->modified = 1;
+ var->weight = weight;
+ xbt_swag_remove(var, &(sys->variable_set));
+ if (weight)
+ xbt_swag_insert_at_head(var, &(sys->variable_set));
+ else
+ xbt_swag_insert_at_tail(var, &(sys->variable_set));
+
+ for (i = 0; i < var->cnsts_number; i++) {
+ elem = &var->cnsts[i];
+ xbt_swag_remove(elem, &(elem->constraint->element_set));
+ if (weight)
+ xbt_swag_insert_at_head(elem, &(elem->constraint->element_set));
+ else
+ xbt_swag_insert_at_tail(elem, &(elem->constraint->element_set));
+
+ if (i == 0)
+ lmm_update_modified_set(sys, elem->constraint);
+ }
+ if (!weight)
+ var->value = 0.0;
+
+ XBT_OUT();
+}
+
+XBT_INLINE double lmm_get_variable_weight(lmm_variable_t var)
+{
+ return var->weight;
+}
+
+XBT_INLINE void lmm_update_constraint_bound(lmm_system_t sys,
+ lmm_constraint_t cnst,
+ double bound)
+{
+ sys->modified = 1;
+ lmm_update_modified_set(sys, cnst);
+ cnst->bound = bound;
+}
+
+XBT_INLINE int lmm_constraint_used(lmm_system_t sys, lmm_constraint_t cnst)
+{
+ return xbt_swag_belongs(cnst, &(sys->active_constraint_set));
+}
+
+XBT_INLINE lmm_constraint_t lmm_get_first_active_constraint(lmm_system_t
+ sys)
+{
+ return xbt_swag_getFirst(&(sys->active_constraint_set));
+}
+
+XBT_INLINE lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t
+ sys,
+ lmm_constraint_t
+ cnst)
+{
+ return xbt_swag_getNext(cnst, (sys->active_constraint_set).offset);
+}
+
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+XBT_INLINE int lmm_is_variable_limited_by_latency(lmm_variable_t var)
+{
+ return (double_equals(var->bound, var->value));
+}
+#endif
+
+
+/** \brief Update the constraint set propagating recursively to
+ * other constraints so the system should not be entirely computed.
+ *
+ * \param sys the lmm_system_t
+ * \param cnst the lmm_constraint_t affected by the change
+ *
+ * A recursive algorithm to optimize the system recalculation selecting only
+ * constraints that have changed. Each constraint change is propagated
+ * to the list of constraints for each variable.
+ */
+static void lmm_update_modified_set_rec(lmm_system_t sys,
+ lmm_constraint_t cnst)
+{
+ lmm_element_t elem;
+
+ xbt_swag_foreach(elem, &cnst->element_set) {
+ lmm_variable_t var = elem->variable;
+ s_lmm_element_t *cnsts = var->cnsts;
+ int i;
+ for (i = 0; var->visited != sys->visited_counter
+ && i < var->cnsts_number ; i++) {
+ if (cnsts[i].constraint != cnst
+ && !xbt_swag_belongs(cnsts[i].constraint,
+ &sys->modified_constraint_set)) {
+ xbt_swag_insert(cnsts[i].constraint, &sys->modified_constraint_set);
+ lmm_update_modified_set_rec(sys, cnsts[i].constraint);
+ }
+ }
+ var->visited = sys->visited_counter;
+ }
+}
+
+static void lmm_update_modified_set(lmm_system_t sys,
+ lmm_constraint_t cnst)
+{
+ /* nothing to do if selective update isn't active */
+ if (sys->selective_update_active
+ && !xbt_swag_belongs(cnst, &sys->modified_constraint_set)) {
+ xbt_swag_insert(cnst, &sys->modified_constraint_set);
+ lmm_update_modified_set_rec(sys, cnst);
+ }
+}
+
+/** \brief Remove all constraints of the modified_constraint_set.
+ *
+ * \param sys the lmm_system_t
+ */
+static void lmm_remove_all_modified_set(lmm_system_t sys)
+{
+ if (++sys->visited_counter == 1) {
+ /* the counter wrapped around, reset each variable->visited */
+ lmm_variable_t var;
+ xbt_swag_foreach(var, &sys->variable_set)
+ var->visited = 0;
+ }
+ xbt_swag_reset(&sys->modified_constraint_set);
+}
#ifndef _SURF_MAXMIN_PRIVATE_H
#define _SURF_MAXMIN_PRIVATE_H
-//#include "surf/maxmin.h"
-#include "surf/solver.h"
+#include "surf/maxmin.h"
#include "xbt/swag.h"
#include "xbt/mallocator.h"
--- /dev/null
+/* Copyright (c) 2004, 2005, 2006, 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. */
+
+#ifndef _SURF_MAXMIN_PRIVATE_H
+#define _SURF_MAXMIN_PRIVATE_H
+
+#include "surf/maxmin_.h"
+#include "xbt/swag.h"
+#include "xbt/mallocator.h"
+
+
+
+typedef struct lmm_element {
+ /* hookup to constraint */
+ s_xbt_swag_hookup_t element_set_hookup;
+ s_xbt_swag_hookup_t active_element_set_hookup;
+
+ lmm_constraint_t constraint;
+ lmm_variable_t variable;
+ double value;
+} s_lmm_element_t;
+#define make_elem_active(elem) xbt_swag_insert_at_head(elem,&(elem->constraint->active_element_set))
+#define make_elem_inactive(elem) xbt_swag_remove(elem,&(elem->constraint->active_element_set))
+
+typedef struct lmm_constraint_light {
+ double remaining_over_usage;
+ lmm_constraint_t cnst;
+} s_lmm_constraint_light_t;
+
+typedef struct lmm_constraint {
+ /* hookup to system */
+ s_xbt_swag_hookup_t constraint_set_hookup;
+ s_xbt_swag_hookup_t active_constraint_set_hookup;
+ s_xbt_swag_hookup_t modified_constraint_set_hookup;
+ s_xbt_swag_hookup_t saturated_constraint_set_hookup;
+
+ s_xbt_swag_t element_set; /* a list of lmm_element_t */
+ s_xbt_swag_t active_element_set; /* a list of lmm_element_t */
+ double remaining;
+ double usage;
+ double bound;
+ int shared;
+ void *id;
+ int id_int;
+ double lambda;
+ double new_lambda;
+ lmm_constraint_light_t cnst_light;
+} s_lmm_constraint_t;
+
+typedef struct lmm_variable {
+ /* hookup to system */
+ s_xbt_swag_hookup_t variable_set_hookup;
+ s_xbt_swag_hookup_t saturated_variable_set_hookup;
+
+ s_lmm_element_t *cnsts;
+ int cnsts_size;
+ int cnsts_number;
+ double weight;
+ double bound;
+ double value;
+ void *id;
+ int id_int;
+ unsigned visited; /* used by lmm_update_modified_set */
+ /* \begin{For Lagrange only} */
+ double mu;
+ double new_mu;
+ double (*func_f) (struct lmm_variable * var, double x); /* (f) */
+ double (*func_fp) (struct lmm_variable * var, double x); /* (f') */
+ double (*func_fpi) (struct lmm_variable * var, double x); /* (f')^{-1} */
+ /* \end{For Lagrange only} */
+} s_lmm_variable_t;
+
+typedef struct lmm_system {
+ int modified;
+ int selective_update_active; /* flag to update partially the system only selecting changed portions */
+ unsigned visited_counter; /* used by lmm_update_modified_set */
+ s_xbt_swag_t variable_set; /* a list of lmm_variable_t */
+ s_xbt_swag_t constraint_set; /* a list of lmm_constraint_t */
+
+ s_xbt_swag_t active_constraint_set; /* a list of lmm_constraint_t */
+ s_xbt_swag_t modified_constraint_set; /* a list of modified lmm_constraint_t */
+
+ s_xbt_swag_t saturated_variable_set; /* a list of lmm_variable_t */
+ s_xbt_swag_t saturated_constraint_set; /* a list of lmm_constraint_t_t */
+
+ xbt_swag_t keep_track;
+
+ xbt_mallocator_t variable_mallocator;
+} s_lmm_system_t;
+
+#define extract_variable(sys) xbt_swag_extract(&(sys->variable_set))
+#define extract_constraint(sys) xbt_swag_extract(&(sys->constraint_set))
+#define insert_constraint(sys,cnst) xbt_swag_insert(cnst,&(sys->constraint_set))
+#define remove_variable(sys,var) do {xbt_swag_remove(var,&(sys->variable_set));\
+ xbt_swag_remove(var,&(sys->saturated_variable_set));} while(0)
+#define remove_constraint(sys,cnst) do {xbt_swag_remove(cnst,&(sys->constraint_set));\
+ xbt_swag_remove(cnst,&(sys->saturated_constraint_set));} while(0)
+#define make_constraint_active(sys,cnst) xbt_swag_insert(cnst,&(sys->active_constraint_set))
+#define make_constraint_inactive(sys,cnst) \
+ do { xbt_swag_remove(cnst, &sys->active_constraint_set); \
+ xbt_swag_remove(cnst, &sys->modified_constraint_set); } while (0)
+
+void lmm_print(lmm_system_t sys);
+
+extern double (*func_f_def) (lmm_variable_t, double);
+extern double (*func_fp_def) (lmm_variable_t, double);
+extern double (*func_fpi_def) (lmm_variable_t, double);
+
+#endif /* _SURF_MAXMIN_PRIVATE_H */
surf_action_lmm_update_index_heap);
surf_network_model->model_private->modified_set =
xbt_swag_new(xbt_swag_offset(comm, generic_lmm_action.action_list_hookup));
- //TOREPAIR: surf_network_model->model_private->maxmin_system->keep_track = surf_network_model->model_private->modified_set;
+ surf_network_model->model_private->maxmin_system->keep_track = surf_network_model->model_private->modified_set;
}
surf_network_model->gap_remove = NULL;
#include "network.hpp"
+#include "maxmin_private.h"
+#include "simgrid/sg_config.h"
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_network, surfpp,
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
"Logging specific to the SURF network module");
+}
-//TODO: resolve dependencies
-static int TRACE_is_enabled(void) {return 0;}
-static void TRACE_surf_host_set_utilization(const char *resource,
- const char *category,
- double value,
- double now,
- double delta){}
-static void TRACE_surf_link_set_utilization(const char *resource,
- const char *category,
- double value,
- double now,
- double delta){}
-static double TRACE_last_timestamp_to_dump = 0;
+NetworkCm02ModelPtr surf_network_model = NULL;
-/*********
- * Utils *
- *********/
+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 */
-static xbt_dict_t gap_lookup = NULL;//TODO: remove static
+double sg_tcp_gamma = 0.0;
+int sg_network_crosstraffic = 0;
/*********
* Model *
*********/
-void NetworkModel::updateActionsStateLazy(double now, double delta)
+/************************************************************************/
+/* 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();
+ xbt_dynar_push(model_list, &surf_network_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();
+ xbt_dynar_push(model_list, &surf_network_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();
+ xbt_dynar_push(model_list, &surf_network_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();
+ xbt_dynar_push(model_list, &surf_network_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();
+ xbt_dynar_push(model_list, &surf_network_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){
+ NetworkCm02ActionLmmPtr 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(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, 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)
action->setState(SURF_ACTION_DONE);
action->heapRemove(p_actionHeap);
- gapRemove(action);
+ action->gapRemove();
}
}
return;
}
-void NetworkModel::gapRemove(ActionLmmPtr lmm_action)
-{
- xbt_fifo_t fifo;
- size_t size;
- NetworkCm02ActionLmmPtr action = (NetworkCm02ActionLmmPtr)lmm_action;
-
- if (sg_sender_gap > 0.0 && action->p_senderLinkName
- && action->p_senderFifoItem) {
- fifo =
- (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup,
- action->p_senderLinkName);
- xbt_fifo_remove_item(fifo, action->p_senderFifoItem);
- size = xbt_fifo_size(fifo);
- if (size == 0) {
- xbt_fifo_free(fifo);
- xbt_dict_remove(gap_lookup, action->p_senderLinkName);
- size = xbt_dict_length(gap_lookup);
- if (size == 0) {
- xbt_dict_free(&gap_lookup);
+xbt_dynar_t NetworkCm02Model::getRoute(RoutingEdgePtr src, RoutingEdgePtr dst)
+{
+ xbt_dynar_t route = NULL;
+ routing_platf->getRouteAndLatency(src, dst, &route, NULL);
+ return route;
+}
+
+NetworkCm02ActionPtr NetworkCm02Model::communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+ double size, double rate)
+{
+ unsigned int i;
+ 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) {
+ 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) {
+ 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;
+
+ xbt_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) {
+ action->m_weight +=
+ sg_weight_S_parameter /
+ (link->p_power.peak * link->p_power.scale);
+ }
+ }
+ xbt_dynar_foreach(route, i, 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);
+ 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) {
+ 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) {
+ 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)
+: ResourceLmm(model, name, props, system, constraint_value, history, state_init, state_trace, metric_peak, metric_trace)
+{
+ m_latCurrent = lat_initial;
+ if (lat_trace)
+ p_latEvent = tmgr_history_add_trace(history, lat_trace, 0.0, 0, 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("[" "%lg" "] Asking to update network card \"%s\" with value " */
+ /* "%lg" " 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 *
m_lastUpdate = now;
m_lastValue = lmm_variable_getvalue(p_variable);
}
+void NetworkCm02ActionLmm::recycle()
+{
+ return;
+}
#include "surf.hpp"
#include "xbt/fifo.h"
+#include "xbt/graph.h"
+#include "surf_routing.hpp"
#ifndef SURF_MODEL_NETWORK_H_
#define SURF_MODEL_NETWORK_H_
/***********
* Classes *
***********/
-class NetworkModel;
-typedef NetworkModel *NetworkModelPtr;
+class NetworkCm02Model;
+typedef NetworkCm02Model *NetworkCm02ModelPtr;
class NetworkCm02Link;
typedef NetworkCm02Link *NetworkCm02LinkPtr;
+class NetworkCm02LinkLmm;
+typedef NetworkCm02LinkLmm *NetworkCm02LinkLmmPtr;
+
class NetworkCm02Action;
typedef NetworkCm02Action *NetworkCm02ActionPtr;
class NetworkCm02ActionLmm;
typedef NetworkCm02ActionLmm *NetworkCm02ActionLmmPtr;
+/*********
+ * Tools *
+ *********/
+extern NetworkCm02ModelPtr surf_network_model;
+
+
+
/*********
* Model *
*********/
-class NetworkModel : public Model {
+class NetworkCm02Model : public Model {
public:
- NetworkModel(string name) : Model(name) {};
- NetworkCm02LinkPtr createResource(string name);
+ NetworkCm02Model(string name);
+ NetworkCm02Model();
+ //FIXME:NetworkCm02LinkPtr createResource(string name);
+ NetworkCm02LinkLmmPtr 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);
void updateActionsStateLazy(double now, double delta);
- void updateActionsStateFull(double now, double delta);
- void gapRemove(ActionLmmPtr action);
-
- virtual void addTraces() =0;
+ void updateActionsStateFull(double now, double delta);
+ virtual void gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action) {};
+ NetworkCm02ActionPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+ double size, double rate);
+ xbt_dynar_t getRoute(RoutingEdgePtr src, RoutingEdgePtr dst); //FIXME: kill field? That is done by the routing nowadays
+ //FIXME: virtual void addTraces() =0;
+ void (*f_networkSolve)(lmm_system_t) = lmm_solve;
+ double latencyFactor(double size);
+ double bandwidthFactor(double size);
+ double bandwidthConstraint(double rate, double bound, double size);
+ bool m_haveGap = false;
};
/************
* Resource *
************/
-class NetworkCm02Link : public Resource {
-public:
- NetworkCm02Link(NetworkModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {};
+class NetworkCm02Link : virtual public Resource {
+public:
+ NetworkCm02Link(){};
+ NetworkCm02Link(NetworkCm02ModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {};
+ virtual double getBandwidth()=0;
+ double getLatency();
+ virtual bool isShared()=0;
/* Using this object with the public part of
model does not make sense */
- double lat_current;
- tmgr_trace_event_t lat_event;
+ double m_latCurrent;
+ tmgr_trace_event_t p_latEvent;
};
+class NetworkCm02LinkLmm : public ResourceLmm, public NetworkCm02Link {
+public:
+ 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);
+ bool isShared();
+ bool isUsed();
+ double getBandwidth();
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+};
+
+
/**********
* Action *
**********/
public:
NetworkCm02ActionLmm(ModelPtr model, double cost, bool failed): ActionLmm(model, cost, failed), NetworkCm02Action(model, cost, failed) {};
void updateRemainingLazy(double now);
+ void recycle();
};
#endif /* SURF_MODEL_NETWORK_H_ */
--- /dev/null
+#include "network_constant.hpp"
+#include "surf/random_mgr.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
+static random_data_t random_latency = NULL;
+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();
+
+ if (!random_latency)
+ random_latency = random_new(RAND, 100, 0.0, 1.0, .125, .034);
+
+ //FIXME:sg_platf_host_add_cb(netcste_count_hosts);
+
+ xbt_dynar_push(model_list, &surf_network_model);
+
+ //FIXME: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 = (NetworkConstantActionLmmPtr) _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 = (NetworkConstantActionLmmPtr) _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);
+ }
+ }
+}
+
+NetworkCm02ActionLmmPtr 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(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
+#include "network.hpp"
+
+#ifndef NETWORK_CONSTANT_HPP_
+#define NETWORK_CONSTANT_HPP_
+
+/***********
+ * Classes *
+ ***********/
+class NetworkConstantModel;
+typedef NetworkConstantModel *NetworkConstantModelPtr;
+
+class NetworkConstantLinkLmm;
+typedef NetworkConstantLinkLmm *NetworkConstantLinkLmmPtr;
+
+class NetworkConstantActionLmm;
+typedef NetworkConstantActionLmm *NetworkConstantActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class NetworkConstantModel : public NetworkCm02Model {
+public:
+ NetworkConstantModel() : NetworkCm02Model("constant time network") {};
+ NetworkCm02LinkLmmPtr createResource(string name);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+ NetworkCm02ActionLmmPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+ double size, double rate);
+ void gapRemove(ActionLmmPtr action);
+ //FIXME:virtual void addTraces() =0;
+};
+
+/************
+ * Resource *
+ ************/
+class NetworkConstantLinkLmm : public NetworkCm02LinkLmm {
+public:
+ NetworkConstantLinkLmm(NetworkCm02ModelPtr model, const char* name, xbt_dict_t properties);
+ bool isUsed();
+ void updateState(tmgr_trace_event_t event_type, double value, double date);
+ double getBandwidth();
+ double getLatency();
+ bool isShared();
+};
+
+/**********
+ * Action *
+ **********/
+class NetworkConstantActionLmm : public NetworkCm02ActionLmm {
+public:
+ NetworkConstantActionLmm(NetworkConstantModelPtr model, double latency):
+ NetworkCm02ActionLmm(model, 0, false), m_latInit(latency) {
+ m_latency = latency;
+ if (m_latency <= 0.0) {
+ p_stateSet = p_model->p_doneActionSet;
+ xbt_swag_insert(this, p_stateSet);
+ }
+ };
+ int unref();
+ void recycle();
+ void cancel();
+ void setCategory(const char *category);
+ void suspend();
+ void resume();
+ bool isSuspended();
+ double m_latInit;
+ int m_suspended;
+};
+
+#endif /* NETWORK_CONSTANT_HPP_ */
--- /dev/null
+#include "network_gtnets.hpp"
+
+static double time_to_next_flow_completion = -1;
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets, surf,
+ "Logging specific to the SURF network GTNetS module");
+
+extern routing_platf_t routing_platf;
+
+double sg_gtnets_jitter = 0.0;
+int sg_gtnets_jitter_seed = 10;
+
+/*********
+ * Model *
+ *********/
+
+void newRoute(int src_id, int dst_id,
+ xbt_dynar_t links, int nb_link)
+{
+ void *_link;
+ NetworkGTNetsLinkPtr link;
+ unsigned int cursor;
+ int i = 0;
+ int *gtnets_links;
+
+ XBT_IN("(src_id=%d, dst_id=%d, links=%p, nb_link=%d)",
+ src_id, dst_id, links, nb_link);
+
+ /* Build the list of gtnets link IDs */
+ gtnets_links = xbt_new0(int, nb_link);
+ i = 0;
+ xbt_dynar_foreach(links, cursor, _link) {
+ link = (NetworkGTNetsLinkPtr) _link;
+ gtnets_links[i++] = link->m_id;
+ }
+
+ if (gtnets_add_route(src_id, dst_id, gtnets_links, nb_link)) {
+ xbt_die("Cannot create GTNetS route");
+ }
+ XBT_OUT();
+}
+
+void newRouteOnehop(int src_id, int dst_id,
+ NetworkGTNetsLinkPtr link)
+{
+ if (gtnets_add_onehop_route(src_id, dst_id, link->m_id)) {
+ xbt_die("Cannot create GTNetS route");
+ }
+}
+
+int NetworkGTNetsModel::addLink(ind id, double bandwidth, double latency)
+{
+ double bw = bandwidth * 8; //Bandwidth in bits (used in GTNETS).
+
+ map<int,GTNETS_Link*>::iterator iter = p_links.find(id);
+ xbt_assert((iter == p_links.end()), "Link %d already exists", id);
+
+ if(iter == p_links.end()) {
+ GTNETS_Link* link= new GTNETS_Link(id);
+ p_links[id] = link;
+ }
+
+ XBT_DEBUG("Creating a new P2P, linkid %d, bandwidth %gl, latency %gl", id, bandwidth, latency);
+ p_gtnetsLinks_[id] = new Linkp2p(bw, latency);
+ if(jitter_ > 0){
+ XBT_DEBUG("Using jitter %f, and seed %u", jitter_, jitter_seed_);
+ double min = -1*jitter_*latency;
+ double max = jitter_*latency;
+ uniform_jitter_generator_[id] = new Uniform(min,max);
+ gtnets_links_[id]->Jitter((const Random &) *(uniform_jitter_generator_[id]));
+ }
+
+ return 0;
+}
+
+/************
+ * Resource *
+ ************/
+NetworkGTNetsLink::NetworkGTNetsLink(NetworkGTNetsModelPtr model, const char* name, double bw, double lat, xbt_dict_t properties)
+ :NetworkCm02Link(model, name, properties), m_bwCurrent(bw), m_latCurrent(lat)
+{
+
+ static int link_count = -1;
+
+ if (xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL)) {
+ return;
+ }
+
+ XBT_DEBUG("Scanning link name %s", name);
+
+ link_count++;
+
+ XBT_DEBUG("Adding new link, linkid %d, name %s, latency %g, bandwidth %g",
+ link_count, name, lat, bw);
+
+
+
+ if (gtnets_add_link(link_count, bw, lat)) {
+ xbt_die("Cannot create GTNetS link");
+ }
+ m_id = link_count;
+
+ xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, this);
+}
+
+/**********
+ * Action *
+ **********/
--- /dev/null
+#include "network.hpp"
+
+#ifndef NETWORK_GTNETS_HPP_
+#define NETWORK_GTNETS_HPP_
+
+#include "simulator.h" // Definitions for the Simulator Object
+#include "node.h" // Definitions for the Node Object
+#include "linkp2p.h" // Definitions for point-to-point link objects
+#include "ratetimeparse.h" // Definitions for Rate and Time objects
+#include "application-tcpserver.h" // Definitions for TCPServer application
+#include "application-tcpsend.h" // Definitions for TCP Sending application
+#include "tcp-tahoe.h" // Definitions for TCP Tahoe
+#include "tcp-reno.h"
+#include "tcp-newreno.h"
+#include "event.h"
+#include "routing-manual.h"
+#include "red.h"
+
+xbt_dict_t network_card_ids;
+
+/***********
+ * Classes *
+ ***********/
+class NetworkGTNetsModel;
+typedef NetworkGTNetsModel *NetworkGTNetsModelPtr;
+
+class NetworkGTNetsLink;
+typedef NetworkGTNetsLink *NetworkGTNetsLinkPtr;
+
+class NetworkGTNetsAction;
+typedef NetworkGTNetsAction *NetworkGTNetsActionPtr;
+
+class NetworkGTNetsActionLmm;
+typedef NetworkGTNetsActionLmm *NetworkGTNetsActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class NetworkGTNetsModel : public NetworkCm02Model {
+public:
+ NetworkGTNetsModel() : NetworkCm02Model("constant time network") {};
+ int addLink(int id, double bandwidth, double latency);
+ int addOnehop_route(int src, int dst, int link);
+ int addRoute(int src, int dst, int *links, int nlink);
+ int addRouter(int id);
+ int createFlow(int src, int dst, long datasize, void *metadata);
+ double getTimeToNextFlowCompletion();
+ int runUntilNextFlowCompletion(void ***metadata,
+ int *number_of_flows);
+ int run(double deltat);
+ // returns the total received by the TCPServer peer of the given action
+ double gtNetsGetFlowRx(void *metadata);
+ void createGTNetsTopology();
+ void printTopology();
+ void setJitter(double);
+ void setJitterSeed(int);
+private:
+ void addNodes();
+ void nodeConnect();
+
+ bool nodeInclude(int);
+ bool linkInclude(int);
+ Simulator *p_sim;
+ GTNETS_Topology *p_topo;
+ RoutingManual *p_rm;
+ REDQueue *p_redQueue;
+ int m_nnode;
+ int m_isTopology;
+ int m_nflow;
+ double m_jitter;
+ int m_jitterSeed;
+ map<int, Uniform*> p_uniformJitterGenerator;
+
+ map<int, TCPServer*> p_gtnetsServers;
+ map<int, TCPSend*> p_gtnetsClients;
+ map<int, Linkp2p*> p_gtnetsLinks_;
+ map<int, Node*> p_gtnetsNodes;
+ map<void*, int> p_gtnetsActionToFlow;
+
+ map <int, void*> p_gtnetsMetadata;
+
+ // From Topology
+ int m_nodeID;
+ map<int, GTNETS_Link*> p_links;
+ vector<GTNETS_Node*> p_nodes;
+ map<int, int> p_hosts; //hostid->nodeid
+ set<int > p_routers;
+};
+
+/************
+ * Resource *
+ ************/
+class NetworkGTNetsLink : public NetworkCm02Link {
+public:
+ NetworkGTNetsLink(NetworkGTNetsModelPtr model, const char* name, double bw, double lat, xbt_dict_t properties);
+ /* Using this object with the public part of
+ model does not make sense */
+ double m_bwCurrent;
+ double m_latCurrent;
+ int m_id;
+};
+
+/**********
+ * Action *
+ **********/
+class NetworkGTNetsAction : public NetworkCm02Action {
+public:
+ NetworkGTNetsAction(NetworkGTNetsModelPtr model, double latency){};
+
+ double m_latency;
+ double m_latCurrent;
+#ifdef HAVE_TRACING
+ int m_lastRemains;
+#endif
+ lmm_variable_t p_variable;
+ double m_rate;
+ int m_suspended;
+#ifdef HAVE_TRACING
+ RoutingEdgePtr src;
+ RoutingEdgePtr dst;
+#endif //HAVE_TRACING
+};
+
+#endif /* NETWORK_GTNETS_HPP_ */
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "surf_private.h"
-//#include "surf/maxmin.h"
-#include "surf/solver.h"
+#include "surf/maxmin.h"
#include "surf/ns3/ns3_interface.h"
#include "xbt/lib.h"
#include "surf/network_ns3_private.h"
--- /dev/null
+#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();
+
+ xbt_dynar_push(model_list, &surf_network_model);
+
+ 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) {
+ gap_lookup = xbt_dict_new();
+ }
+ 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::latencyFactor(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);
+ return current;
+ }else
+ current=fact.value;
+ }
+ XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current);
+
+ return current;
+}
+double NetworkSmpiModel::bandwidthFactor(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);
+ return current;
+ }else
+ current=fact.value;
+ }
+ XBT_DEBUG("%lf > %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
+#include "network.hpp"
+
+/***********
+ * Classes *
+ ***********/
+
+class NetworkSmpiModel;
+typedef NetworkSmpiModel *NetworkSmpiModelPtr;
+
+class NetworkSmpiLink;
+typedef NetworkSmpiLink *NetworkSmpiLinkPtr;
+
+class NetworkSmpiLinkLmm;
+typedef NetworkSmpiLinkLmm *NetworkSmpiLinkLmmPtr;
+
+class NetworkSmpiAction;
+typedef NetworkSmpiAction *NetworkSmpiActionPtr;
+
+class NetworkSmpiActionLmm;
+typedef NetworkSmpiActionLmm *NetworkSmpiActionLmmPtr;
+
+/*********
+ * Tools *
+ *********/
+
+/*********
+ * Model *
+ *********/
+
+class NetworkSmpiModel : public NetworkCm02Model {
+public:
+ NetworkSmpiModel(){};
+ void gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action);
+ void gapRemove(ActionLmmPtr action);
+ double latencyFactor(double size);
+ double bandwidthFactor(double size);
+ double bandwidthConstraint(double rate, double bound, double size);
+ void communicateCallBack() {};
+};
+
+
+/************
+ * Resource *
+ ************/
+
+class NetworkSmpiLinkLmm : public NetworkCm02LinkLmm {
+public:
+ NetworkSmpiLinkLmm(NetworkSmpiModelPtr 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);
+};
+
+
+/**********
+ * Action *
+ **********/
+
+class NetworkSmpiActionLmm : public NetworkCm02ActionLmm {
+public:
+ NetworkSmpiActionLmm(ModelPtr model, double cost, bool failed);
+};
+
+
surf_model_t surf_new_model = NULL;
lmm_system_t new_model_maxmin_system = NULL;
+/*FIXME:
static int new_model_selective_update = 0;
static xbt_swag_t
new_model_running_action_set_that_does_not_need_being_checked = NULL;
+*/
#define GENERIC_LMM_ACTION(action) action->generic_lmm_action
#define GENERIC_ACTION(action) GENERIC_LMM_ACTION(action).generic_action
+void surf_new_model_init_default(void){}
+
+//FIXME:UPDATE FOR SURF++
+#ifdef UPDATE_FOR_SURFPP
static void new_model_action_state_set(surf_action_t action, e_surf_action_state_t state);
static surf_action_t new_model_action_execute ()
xbt_dynar_push(model_list, &surf_new_model);
}
+
+#endif
--- /dev/null
+#include "storage.hpp"
+#include "surf_private.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;
+
+lmm_system_t storage_maxmin_system = NULL;
+static int storage_selective_update = 0;
+static xbt_swag_t storage_running_action_set_that_does_not_need_being_checked = NULL;
+
+void storage_register_callbacks() {
+
+ /*FIXME: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);*/
+}
+
+/***********
+ * PARSING *
+ ***********/
+
+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("For disk '%s' content is empty, use the content of storage type '%s'",storage->id,((storage_type_t) stype)->type_id);
+ }
+
+ 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->id,
+ ((storage_type_t) stype)->model,
+ ((storage_type_t) stype)->type_id,
+ storage->content,
+ ((storage_type_t) stype)->properties);
+
+ surf_storage_model->createResource(storage->id, ((storage_type_t) stype)->model,
+ ((storage_type_t) stype)->type_id,
+ storage->content);
+}
+
+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));
+}
+
+static xbt_dict_t parse_storage_content(char *filename, size_t *used_size)
+{
+ *used_size = 0;
+ if ((!filename) || (strcmp(filename, "") == 0))
+ return NULL;
+
+ xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL);
+ 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];
+ size_t size;
+
+
+ while ((read = xbt_getline(&line, &len, file)) != -1) {
+ if (read){
+ if(sscanf(line,"%s %zu",path, &size)==2) {
+ *used_size += size;
+ xbt_dict_set(parse_content,path,(void*) size,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->type_id = xbt_strdup(storage_type->id);
+ stype->size = storage_type->size * 1000000000; /* storage_type->size is in Gbytes and stype->sizeis in bytes */
+
+ XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s' content '%s'",
+ stype->type_id,
+ stype->model,
+ storage_type->content);
+
+ 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
+ void* storage = xbt_lib_get_or_null(storage_lib, mount->id,ROUTING_STORAGE_LEVEL);
+#endif
+ xbt_assert(storage,"Disk id \"%s\" does not exists", mount->id);
+
+ XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->id, mount->name);
+
+ s_mount_t mnt;
+ mnt.id = surf_storage_resource_priv(surf_storage_resource_by_name(mount->id));
+ 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 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));
+ free(stype);
+}
+
+static XBT_INLINE void surf_storage_resource_free(void *r)
+{
+ // specific to storage
+ StoragePtr storage = (StoragePtr) r;
+ xbt_dict_free(&storage->p_content);
+ xbt_dynar_free(&storage->p_writeActions);
+ // 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);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_storage_model_init_default(void)
+{
+ new StorageModel();
+}
+
+StorageModel::StorageModel() : Model("Storage"){
+ StorageActionLmm action;
+ storage_running_action_set_that_does_not_need_being_checked =
+ xbt_swag_new(xbt_swag_offset(action, p_stateHookup));
+
+ if (!storage_maxmin_system) {
+ storage_maxmin_system = lmm_system_new(storage_selective_update);
+ }
+ xbt_dynar_push(model_list, this);
+
+ 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);
+
+ 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);
+}
+
+
+StorageModel::~StorageModel(){
+ lmm_system_free(storage_maxmin_system);
+ storage_maxmin_system = NULL;
+
+ 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;
+}
+
+StoragePtr StorageModel::createResource(const char* id, const char* model, const char* type_id, const char* content_name)
+{
+
+ xbt_assert(!surf_storage_resource_priv(surf_storage_resource_by_name(id)),
+ "Storage '%s' declared several times in the platform file",
+ id);
+
+ StoragePtr storage ;//= new Storage();
+
+ storage_type_t storage_type = (storage_type_t) xbt_lib_get_or_null(storage_type_lib, type_id,ROUTING_STORAGE_TYPE_LEVEL);
+ 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"));
+ XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%lu'", Bconnection, Bread, Bwrite, (unsigned long)storage_type->size);
+ storage->p_constraint = lmm_constraint_new(storage_maxmin_system, storage, Bconnection);
+ /* TOREPAIR: storage->constraint = lmm_constraint_new(storage_maxmin_system, storage, Bconnection);
+ storage->constraint_read = lmm_constraint_new(storage_maxmin_system, storage, Bread);
+ storage->constraint_write = lmm_constraint_new(storage_maxmin_system, storage, Bwrite);*/
+ storage->p_content = parseContent((char*)content_name, &(storage->m_usedSize));
+ storage->m_size = storage_type->size;
+
+ xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, 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);
+
+ 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);
+ StorageActionLmm action;
+ unsigned int i, j;
+ StoragePtr storage;
+ StorageActionLmmPtr write_action;
+
+ double min_completion = shareResourcesMaxMin(p_runningActionSet,
+ xbt_swag_offset(action, p_variable),
+ storage_maxmin_system, 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;
+
+ // Update the disk usage
+ // Update the file size
+ // For each action of type write
+ xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+ action = (StorageActionLmmPtr) _action;
+ if(action->m_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 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 = (StorageActionLmmPtr) _action;
+
+ 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 StorageModel::parseContent(char *filename, size_t *used_size)
+{
+ *used_size = 0;
+ if ((!filename) || (strcmp(filename, "") == 0))
+ return NULL;
+
+ xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL);
+ 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];
+ size_t size;
+
+
+ while ((read = xbt_getline(&line, &len, file)) != -1) {
+ if (read){
+ if(sscanf(line,"%s %zu",path, &size)==2) {
+ *used_size += size;
+ xbt_dict_set(parse_content,path,(void*) size,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) {
+ p_writeActions = xbt_dynar_new(sizeof(char *),NULL);
+}
+
+bool Storage::isUsed()
+{
+ THROW_UNIMPLEMENTED;
+ return false;
+}
+
+void Storage::updateState(tmgr_trace_event_t event_type, double value, double date)
+{
+ THROW_UNIMPLEMENTED;
+}
+
+StorageActionLmmPtr Storage::ls(const char* path)
+{
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, m_stateCurrent != SURF_RESOURCE_ON, this, LS);
+
+ action->p_lsDict = NULL;
+ xbt_dict_t ls_dict = xbt_dict_new();
+
+ char* key;
+ 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){
+ xbt_dict_set(ls_dict,file,&size,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;
+}
+
+StorageActionLmmPtr Storage::open(const char* mount, const char* path)
+{
+ XBT_DEBUG("\tOpen file '%s'",path);
+ size_t size = (size_t) xbt_dict_get_or_null(p_content, path);
+ // if file does not exist create an empty file
+ if(!size){
+ xbt_dict_set(p_content, path, &size, 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;
+ file->storage = xbt_strdup(mount);
+
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, m_stateCurrent != SURF_RESOURCE_ON, this, OPEN);
+ action->p_file = file;
+ return action;
+}
+
+StorageActionLmmPtr Storage::close(surf_file_t fd)
+{
+ char *filename = fd->name;
+ XBT_DEBUG("\tClose file '%s' size '%zu'", 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);
+ free(fd->storage);
+ xbt_free(fd);
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, m_stateCurrent != SURF_RESOURCE_ON, this, CLOSE);
+ return action;
+}
+
+StorageActionLmmPtr Storage::read(void* ptr, size_t size, surf_file_t fd)
+{
+ if(size > fd->size)
+ size = fd->size;
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, m_stateCurrent != SURF_RESOURCE_ON, this, READ);
+ return action;
+}
+
+StorageActionLmmPtr Storage::write(const void* ptr, size_t size, surf_file_t fd)
+{
+ char *filename = fd->name;
+ XBT_DEBUG("\tWrite file '%s' size '%zu/%zu'",filename,size,fd->size);
+
+ StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, m_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;
+}
+
+/**********
+ * Action *
+ **********/
+
+StorageActionLmm::StorageActionLmm(ModelPtr model, double cost, bool failed, StoragePtr storage, e_surf_action_storage_type_t type)
+ : ActionLmm(model, cost, failed), p_storage(storage), m_type(type) {
+ XBT_IN("(%s,%zu", storage->m_name, cost);
+ // Must be less than the max bandwidth for all actions
+ lmm_expand(storage_maxmin_system, storage->p_constraint, p_variable, 1.0);
+ switch(type) {
+ case OPEN:
+ case CLOSE:
+ case STAT:
+ case LS:
+ break;
+ case READ:
+ lmm_expand(storage_maxmin_system, storage->p_constraintRead,
+ p_variable, 1.0);
+ break;
+ case WRITE:
+ lmm_expand(storage_maxmin_system, storage->p_constraintWrite,
+ p_variable, 1.0);
+ xbt_dynar_push(storage->p_writeActions,this);
+ break;
+ }
+ XBT_OUT();
+}
+
+int StorageActionLmm::unref()
+{
+ m_refcount--;
+ if (!m_refcount) {
+ xbt_swag_remove(this, p_stateSet);
+ if (p_variable)
+ lmm_variable_free(storage_maxmin_system, 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(storage_maxmin_system,
+ 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
+#include "surf.hpp"
+
+#ifndef STORAGE_HPP_
+#define STORAGE_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class StorageModel;
+typedef StorageModel *StorageModelPtr;
+
+class Storage;
+typedef Storage *StoragePtr;
+
+class StorageActionLmm;
+typedef StorageActionLmm *StorageActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class StorageModel : Model {
+public:
+ StorageModel();
+ ~StorageModel();
+ StoragePtr createResource(const char* id, const char* model, const char* type_id, const char* content_name);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+
+ xbt_dict_t parseContent(char *filename, size_t *used_size);
+};
+
+/************
+ * Resource *
+ ************/
+
+class Storage : public ResourceLmm {
+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);
+
+ lmm_constraint_t p_constraintWrite; /* Constraint for maximum write bandwidth*/
+ lmm_constraint_t p_constraintRead; /* Constraint for maximum write bandwidth*/
+ xbt_dict_t p_content; /* char * -> s_surf_file_t */
+
+ StorageActionLmmPtr open(const char* mount, const char* path);
+ StorageActionLmmPtr close(surf_file_t fd);
+ StorageActionLmmPtr unlink(surf_file_t fd);
+ StorageActionLmmPtr ls(const char *path);
+ size_t getSize(surf_file_t fd);
+ StorageActionLmmPtr read(void* ptr, size_t size, surf_file_t fd);//FIXME:why we have a useless param ptr ??
+ StorageActionLmmPtr write(const void* ptr, size_t size, surf_file_t fd);//FIXME:why we have a useless param ptr ??
+
+ size_t m_size;
+ size_t m_usedSize;
+ xbt_dynar_t p_writeActions;
+};
+
+/**********
+ * Action *
+ **********/
+
+typedef enum {
+ READ=0, WRITE, STAT, OPEN, CLOSE, LS
+} e_surf_action_storage_type_t;
+
+class StorageActionLmm : public ActionLmm {
+public:
+ StorageActionLmm(){};
+ StorageActionLmm(ModelPtr model, double cost, bool failed, StoragePtr storage, e_surf_action_storage_type_t type);
+
+ int unref();
+ void cancel();
+ //FIXME:??void recycle();
+ void suspend();
+ void resume();
+ bool isSuspended();
+ void setMaxDuration(double duration);
+ void setPriority(double priority);
+
+ e_surf_action_storage_type_t m_type;
+ StoragePtr p_storage;
+ surf_file_t p_file;
+ xbt_dict_t p_lsDict;
+};
+
+
+typedef struct s_storage_type {
+ char *model;
+ char *content;
+ char *type_id;
+ xbt_dict_t properties;
+ size_t size;
+} s_storage_type_t, *storage_type_t;
+
+typedef struct s_mount {
+ void *id;
+ char *name;
+} s_mount_t, *mount_t;
+
+typedef struct surf_file {
+ char *name;
+ char *storage;
+ size_t size;
+} s_surf_file_t;
+
+
+#endif /* STORAGE_HPP_ */
} s_surf_file_t;
typedef struct storage {
- s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */
+ //FIXME:s_surf_resource_t generic_resource; /*< Structure with generic data. Needed at begin to interact with SURF */
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*/
} e_surf_action_storage_type_t;
typedef struct surf_action_storage {
- s_surf_action_lmm_t generic_lmm_action;
+ //FIXME:s_surf_action_lmm_t generic_lmm_action;
e_surf_action_storage_type_t type;
void *storage;
} s_surf_action_storage_t, *surf_action_storage_t;
+#include "surf_private.h"
#include "surf.hpp"
#include "cpu.hpp"
#include "simix/smx_host_private.h"
+#include "surf_routing.hpp"
+#include "simgrid/sg_config.h"
+#include "mc/mc.h"
-XBT_LOG_NEW_CATEGORY(surfpp, "All SURF categories");
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_kernel, surfpp,
+extern "C" {
+XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
"Logging specific to SURF (kernel)");
+}
/*********
* Utils *
*********/
-double NOWW = 0;
-
-XBT_INLINE double surf_get_clock(void)
-{
- return NOWW;
-}
-
/* 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.
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);
+}
+
+
+xbt_dynar_t model_list = NULL;
+tmgr_history_t history = NULL;
+lmm_system_t maxmin_system = NULL;
+xbt_dynar_t surf_path = NULL;
+
+/* 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 */
+};
+
+/* ********************************************************************* */
+/* TUTORIAL: New model */
+s_surf_model_description_t surf_new_model_description[] = {
+ {"default",
+ "Tutorial model.",
+ surf_new_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;
+
+XBT_INLINE double surf_get_clock(void)
+{
+ return NOW;
+}
+
/*TODO: keepit void surf_watched_hosts(void)
{
char *key;
xbt_dynar_free(&hosts);
}*/
+#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_resource_free(void *r)
+{
+ ResourcePtr resource = (ResourcePtr) r;
+ delete resource;
+}
+
+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();
+
+ 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_resource_free);
+ SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
+ SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_resource_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;
+
+ 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_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)
+{
+ 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: to implement
+}
+
double Model::shareResourcesLazy(double now)
{
ActionLmmPtr action = NULL;
return min;
}
-double Model::shareResourcesFull(xbt_swag_t running_actions,
+double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
size_t offset,
lmm_system_t sys,
void (*solve) (lmm_system_t))
return min;
}
-void Model::gapRemove(ActionLmmPtr action) {}
-
+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)
{
* Resource *
************/
-string Resource::getName() {
+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);
+ 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 m_stateCurrent;
}
}
+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, 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, this);
+}
+
/**********
* Action *
**********/
-/* added to manage the communication action's heap */
-void surf_action_lmm_update_index_heap(void *action, int i) {
- ((ActionLmmPtr)action)->updateIndexHeap(i);
-}
-void ActionLmm::updateIndexHeap(int i)
-{
- m_indexHeap = i;
-}
-
-/*TODO/const char *surf_action_state_names[6] = {
+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
+ 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()
{
}
#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(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:
*
}
}
+/* 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);
#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;
-// TODO: put in surf_private.hpp
-extern xbt_dict_t watched_hosts_lib;
-
/** \ingroup SURF_simulation
* \brief Return the current time
*
* 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
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;
+//class Model;
typedef Model* ModelPtr;
-class Resource;
+//class Resource;
typedef Resource* ResourcePtr;
typedef boost::function<void (ResourcePtr r)> ResourceCallback;
-class Action;
+//class Action;
typedef Action* ActionPtr;
typedef boost::function<void (ActionPtr a)> ActionCallback;
-class ActionLmm;
+//class ActionLmm;
typedef ActionLmm* ActionLmmPtr;
enum heap_action_type{
NOTSET
};
-typedef enum {
- UM_FULL,
- UM_LAZY,
- UM_UNDEFINED
-} e_UM_t;
-
/*********
* Trace *
*********/
class Model {
public:
- Model(string name) {
- m_name = name;
- m_resOnCB = m_resOffCB= 0;
- m_actSuspendCB = m_actCancelCB = m_actResumeCB = 0;
- }
- virtual ~Model() {
- xbt_swag_free(p_readyActionSet);
- xbt_swag_free(p_runningActionSet);
- xbt_swag_free(p_failedActionSet);
- xbt_swag_free(p_doneActionSet);
- }
+ Model(string name);
+ virtual ~Model();
+
ResourcePtr createResource(string name);
ActionPtr createAction(double _cost, bool _failed);
- double (Model::*shareResources)(double now);
+ virtual double shareResources(double now);
double shareResourcesLazy(double now);
- double shareResourcesFull(xbt_swag_t running_actions,
+ //double shareResourcesFull(double now);
+ double shareResourcesMaxMin(xbt_swag_t running_actions,
size_t offset,
lmm_system_t sys,
void (*solve) (lmm_system_t));
- void (Model::*updateActionsState)(double now, double delta);
+ void updateActionsState(double now, double delta);
void updateActionsStateLazy(double now, double delta);
void updateActionsStateFull(double now, double delta);
string getName() {return m_name;};
- void gapRemove(ActionLmmPtr action);
void addTurnedOnCallback(ResourceCallback rc);
void notifyResourceTurnedOn(ResourcePtr r);
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:
- string m_name;
ResourceCallback m_resOnCB, m_resOffCB;
ActionCallback m_actCancelCB, m_actSuspendCB, m_actResumeCB;
};
class Resource {
public:
- Resource() {};
- Resource(ModelPtr model, const char *name, xbt_dict_t properties):
- m_name(name),m_running(true),p_model(model),m_properties(properties) {};
+ Resource();
+ Resource(ModelPtr model, const char *name, xbt_dict_t properties);
virtual ~Resource() {};
- void updateState(tmgr_trace_event_t event_type, double value, double date);
+ virtual void updateState(tmgr_trace_event_t event_type, double value, double date)=0;
//private
- bool isUsed();
+ virtual bool isUsed()=0;
//TODOupdateActionState();
//TODOupdateResourceState();
//TODOfinilize();
void turnOn();
void turnOff();
void setName(string name);
- string getName();
+ const char *getName();
+ xbt_dict_t getProperties();
+
ModelPtr getModel() {return p_model;};
e_surf_resource_state_t getState();
void printModel() { std::cout << p_model->getName() << "<<plop"<<std::endl;};
void *p_resource;
e_surf_resource_state_t m_stateCurrent;
const char *m_name;
+ xbt_dict_t m_properties;
+ ModelPtr p_model;
protected:
- ModelPtr p_model;
- xbt_dict_t m_properties;
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;
e_surf_resource_state_t p_stateCurrent;
tmgr_trace_event_t p_stateEvent;
s_surf_metric_t p_power;
};
-static inline void *surf_cpu_resource_priv(const void *host) {
- return xbt_lib_get_level((xbt_dictelm_t)host, SURF_CPU_LEVEL);
-}
-/*static inline void *surf_workstation_resource_priv(const void *host){
- return xbt_lib_get_level((xbt_dictelm_t)host, SURF_WKS_LEVEL);
-}
-static inline void *surf_storage_resource_priv(const void *host){
- return xbt_lib_get_level((xbt_dictelm_t)host, SURF_STORAGE_LEVEL);
-}*/
-
-static inline void *surf_cpu_resource_by_name(const char *name) {
- return xbt_lib_get_elm_or_null(host_lib, name);
-}
-/*static inline void *surf_workstation_resource_by_name(const char *name){
- return xbt_lib_get_elm_or_null(host_lib, name);
-}
-static inline void *surf_storage_resource_by_name(const char *name){
- return xbt_lib_get_elm_or_null(storage_lib, name);*/
-
/**********
* Action *
**********/
-/** \ingroup SURF_actions
- * \brief Action states
- *
- * Action states.
- *
- * \see surf_action_t, surf_action_state_t
- */
-extern const char *surf_action_state_names[6];
-
-typedef enum {
- SURF_ACTION_READY = 0, /**< Ready */
- SURF_ACTION_RUNNING, /**< Running */
- SURF_ACTION_FAILED, /**< Task Failure */
- SURF_ACTION_DONE, /**< Completed */
- SURF_ACTION_TO_FREE, /**< Action to free in next cleanup */
- SURF_ACTION_NOT_IN_THE_SYSTEM
- /**< Not in the system anymore. Why did you ask ? */
-} e_surf_action_state_t;
-
class Action {
public:
- Action() {};
- Action(ModelPtr model, double cost, bool failed):
- m_cost(cost), p_model(model), m_failed(failed),
- m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
- m_start(surf_get_clock()), m_finish(-1.0)
- {
- m_priority = m_start = m_finish = m_maxDuration = -1.0;
- m_start = 10;//surf_get_clock();
- m_suspended = false;
- };
- virtual ~Action() {};
+ 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*/
double getFinishTime(); /**< Return the finish time of an action */
void setData(void* data);
- virtual int unref()=0; /**< 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()=0; /**< Cancel a running action */
- virtual void recycle()=0; /**< Recycle an action */
+ 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 */
- void suspend(); /**< Suspend an action */
- void resume(); /**< Resume a suspended action */
- bool isSuspended(); /**< Return whether an action is suspended */
- void setMaxDuration(double duration); /**< Set the max duration of an action*/
- void setPriority(double priority); /**< Set the priority of 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
double m_priority; /**< priority (1.0 by default) */
bool m_failed;
- bool m_suspended;
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 */
#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_cost;
int m_refcount;
- void *p_data; /**< for your convenience */
#ifdef HAVE_TRACING
#endif
e_UM_t p_updateMechanism;
void updateActionsState(double now, double delta);
void updateResourceState(void *id, tmgr_trace_event_t event_type,
double value, double time);
- void finalize(void);
lmm_system_t p_maxminSystem;
xbt_swag_t p_modifiedSet;
int m_selectiveUpdate;
};
+//FIXME:REMOVE
void surf_action_lmm_update_index_heap(void *action, int i);
class ActionLmm: virtual public Action {
public:
- ActionLmm() {};
- ActionLmm(ModelPtr model, double cost, bool failed) {};
+ ActionLmm() : m_suspended(false) {};
+ ActionLmm(ModelPtr model, double cost, bool failed) : m_suspended(false) {};
- virtual void updateRemainingLazy(double now)=0;
+ void updateRemainingLazy(double now) {};//FIXME:
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);
+ 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;
//bool m_suspended;
double m_lastUpdate;
double m_lastValue;
enum heap_action_type m_hat;
+ int m_suspended;
};
#endif /* SURF_MODEL_H_ */
return SURF_ACTION_NOT_IN_THE_SYSTEM;
}
-double surf_action_get_start_time(surf_action_t action)
+/*FIXME:DELETEdouble surf_action_get_start_time(surf_action_t action)
{
return action->start;
-}
+}*/
double surf_action_get_finish_time(surf_action_t action)
{
--- /dev/null
+#include "surf.hpp"
+#include "workstation.hpp"
+#include "network.hpp"
+#include "instr/instr_private.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
+
+/*********
+ * TOOLS *
+ *********/
+extern double NOW;
+
+#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;
+ surf_resource_t resource = NULL;
+ surf_model_t 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;
+ surf_resource_t resource = NULL;
+ surf_model_t model = NULL;
+ tmgr_trace_event_t event = NULL;
+ unsigned int iter;
+
+ 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(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))) {
+ if (resource->isUsed()) {
+ 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",
+ resource->p_model->m_name.c_str(), 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 *
+ *********/
+
+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 model->executeParallelTask(workstation_nb, workstation_list, computation_amount, communication_amount, rate);
+}
+
+surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_workstation_CLM03_t src, surf_workstation_CLM03_t dst, double size, double rate){
+ model->communicate(src, dst, size, rate);
+}
+
+xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model,
+ surf_workstation_t src, surf_workstation_t dst){
+ return model->getRoute((WorkstationCLM03Ptr)surf_workstation_resource_priv(src),(WorkstationCLM03Ptr)surf_workstation_resource_priv(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){
+ model->communicate(src, dst, size, rate);
+}
+
+const char *surf_resource_name(surf_resource_t resource){
+ return resource->m_name;
+}
+
+xbt_dict_t surf_resource_get_properties(surf_resource_t resource){
+ return resource->m_properties;
+}
+
+e_surf_resource_state_t surf_resource_get_state(surf_resource_t resource){
+ return resource->getState();
+}
+
+surf_action_t surf_workstation_sleep(surf_workstation_t resource, double duration){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->sleep(duration);
+}
+
+double surf_workstation_get_speed(surf_workstation_t resource, double load){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->getSpeed(load);
+}
+
+double surf_workstation_get_available_speed(surf_workstation_t resource){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->getAvailableSpeed();
+}
+
+int surf_workstation_get_core(surf_workstation_t resource){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->getCore();
+}
+
+surf_action_t surf_workstation_execute(surf_workstation_t resource, double size){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->execute(size);
+}
+
+surf_action_t surf_workstation_communicate(surf_workstation_t workstation_src, surf_workstation_t workstation_dst, double size, double rate){
+ return surf_workstation_model->communicate((surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation_src),(surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation_dst), size, rate);
+}
+
+surf_action_t surf_workstation_open(surf_workstation_t workstation, const char* mount, const char* path){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation))->open(mount, path);
+}
+
+surf_action_t surf_workstation_close(surf_workstation_t workstation, surf_file_t fd){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation))->close(fd);
+}
+
+int surf_workstation_unlink(surf_workstation_t workstation, surf_file_t fd){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation))->unlink(fd);
+}
+
+surf_action_t surf_workstation_ls(surf_workstation_t workstation, const char* mount, const char *path){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation))->ls(mount, path);
+}
+
+size_t surf_workstation_get_size(surf_workstation_t workstation, surf_file_t fd){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(workstation))->getSize(fd);
+}
+
+surf_action_t surf_workstation_read(surf_workstation_t resource, void *ptr, size_t size, surf_file_t fd){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->read(ptr, size, fd);
+}
+
+surf_action_t surf_workstation_write(surf_workstation_t resource, const void *ptr, size_t size, surf_file_t fd){
+ return ((surf_workstation_CLM03_t)surf_workstation_resource_priv(resource))->write(ptr, size, fd);
+}
+
+int surf_network_link_is_shared(surf_network_link_t link){
+ return link->isShared();
+}
+
+double surf_network_link_get_bandwidth(surf_network_link_t link){
+ return link->getBandwidth();
+}
+
+double surf_network_link_get_latency(surf_network_link_t link){
+ return link->getLatency();
+}
+
+surf_action_t surf_cpu_execute(surf_cpu_t cpu, double size){
+ return cpu->execute(size);
+}
+
+surf_action_t surf_cpu_sleep(surf_cpu_t cpu, double duration){
+ return 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->m_remains;
+}
+
+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->suspend();
+}
+
+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_storage_action_lmm_t action){
+ return action->p_file;
+}
+
+xbt_dict_t surf_storage_action_get_ls_dict(surf_storage_action_lmm_t action){
+ return action->p_lsDict;
+}
#ifndef _SURF_SURF_PRIVATE_H
#define _SURF_SURF_PRIVATE_H
-#include "surf/solver.h"
#include "surf/surf.h"
+#include "surf/maxmin.h"
#include "surf/trace_mgr.h"
#include "xbt/log.h"
#include "surf/surfxml_parse.h"
#define NO_MAX_DURATION -1.0
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern xbt_dict_t watched_hosts_lib;
extern const char *surf_action_state_names[6];
} s_surf_model_private_t;
-double generic_maxmin_share_resources(xbt_swag_t running_actions,
+/*FIXME:REMOVEdouble generic_maxmin_share_resources(xbt_swag_t running_actions,
size_t offset,
lmm_system_t sys,
- void (*solve) (lmm_system_t));
+ void (*solve) (lmm_system_t));*/
double generic_share_resources_lazy(double now, surf_model_t model);
/* Generic functions common to all models */
void surf_action_init(void);
void surf_action_exit(void);
e_surf_action_state_t surf_action_state_get(surf_action_t action); /* cannot declare inline since we use a pointer to it */
-double surf_action_get_start_time(surf_action_t action); /* cannot declare inline since we use a pointer to it */
+//FIXME:DELETEdouble surf_action_get_start_time(surf_action_t action); /* cannot declare inline since we use a pointer to it */
double surf_action_get_finish_time(surf_action_t action); /* cannot declare inline since we use a pointer to it */
void surf_action_free(surf_action_t * action);
-void surf_action_state_set(surf_action_t action,
- e_surf_action_state_t state);
-void surf_action_data_set(surf_action_t action, void *data); /* cannot declare inline since we use a pointer to it */
+/*FIXME:void surf_action_state_set(surf_action_t action,
+ e_surf_action_state_t state);*/
+//FIXME:void surf_action_data_set(surf_action_t action, void *data); /* cannot declare inline since we use a pointer to it */
void surf_action_lmm_update_index_heap(void *action, int i); /* callback for heap management shared by cpu and net models */
-void surf_action_lmm_heap_insert(xbt_heap_t heap, surf_action_lmm_t action,
- double key, enum heap_action_type hat);
+/*FIXME:void surf_action_lmm_heap_insert(xbt_heap_t heap, surf_action_lmm_t action,
+ double key, enum heap_action_type hat);*/
void surf_action_lmm_heap_remove(xbt_heap_t heap,surf_action_lmm_t action);
void surf_action_cancel(surf_action_t action);
-int surf_action_unref(surf_action_t action);
+//FIXME:removeint surf_action_unref(surf_action_t action);
void surf_action_suspend(surf_action_t action);
void surf_action_resume(surf_action_t action);
int surf_action_is_suspended(surf_action_t action);
/**
* Resource protected methods
*/
-XBT_PUBLIC(void) surfxml_bufferstack_push(int new);
-XBT_PUBLIC(void) surfxml_bufferstack_pop(int new);
+XBT_PUBLIC(void) surfxml_bufferstack_push(int _new);
+XBT_PUBLIC(void) surfxml_bufferstack_pop(int _new);
XBT_PUBLIC_DATA(int) surfxml_bufferstack_size;
void TRACE_surf_host_set_power(double date, const char *resource, double power);
void TRACE_surf_link_set_bandwidth(double date, const char *resource, double bandwidth);
+#ifdef __cplusplus
+}
+#endif
#endif /* _SURF_SURF_PRIVATE_H */
--- /dev/null
+
+#ifndef SURF_PRIVATE_HPP_
+#define SURF_PRIVATE_HPP_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+FILE *surf_fopen(const char *name, const char *mode);
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* SURF_PRIVATE_HPP_ */
--- /dev/null
+#include "surf_routing.hpp"
+#include "surf_routing_private.hpp"
+#include "surf/surfxml_parse_values.h"
+#include "surf/random_mgr.h"
+
+/**
+ * @ingroup SURF_build_api
+ * @brief A library containing all known workstations
+ */
+xbt_lib_t host_lib;
+
+int ROUTING_HOST_LEVEL; //Routing level
+int SURF_CPU_LEVEL; //Surf cpu level
+int SURF_WKS_LEVEL; //Surf workstation level
+int SIMIX_HOST_LEVEL; //Simix level
+int MSG_HOST_LEVEL; //Msg level
+int SD_HOST_LEVEL; //Simdag level
+int COORD_HOST_LEVEL=0; //Coordinates level
+int NS3_HOST_LEVEL; //host node for ns3
+
+xbt_dict_t watched_hosts_lib;
+
+/**
+ * @ingroup SURF_build_api
+ * @brief A library containing all known links
+ */
+xbt_lib_t link_lib;
+int SD_LINK_LEVEL; //Simdag level
+int SURF_LINK_LEVEL; //Surf level
+int NS3_LINK_LEVEL; //link for ns3
+
+xbt_lib_t as_router_lib;
+int ROUTING_ASR_LEVEL; //Routing level
+int COORD_ASR_LEVEL; //Coordinates level
+int NS3_ASR_LEVEL; //host node for ns3
+int ROUTING_PROP_ASR_LEVEL; //Where the properties are stored
+
+static xbt_dict_t random_value = NULL;
+
+
+/** @brief Retrieve a routing edge from its name
+ *
+ * Routing edges are either CPU/workstation and routers, whatever
+ */
+RoutingEdgePtr sg_routing_edge_by_name_or_null(const char *name) {
+ RoutingEdgePtr net_elm = (RoutingEdgePtr) xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
+ if (!net_elm)
+ net_elm = (RoutingEdgePtr) xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
+ return net_elm;
+}
+
+/* Global vars */
+RoutingPlatfPtr routing_platf = NULL;
+AsPtr current_routing = NULL;
+
+/* global parse functions */
+extern xbt_dynar_t mount_list;
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
+}
+
+static void routing_parse_peer(sg_platf_peer_cbarg_t peer); /* peer bypass */
+static void routing_parse_Srandom(void); /* random bypass */
+
+static void routing_parse_postparse(void);
+
+/* this lines are only for replace use like index in the model table */
+typedef enum {
+ SURF_MODEL_FULL = 0,
+ SURF_MODEL_FLOYD,
+ SURF_MODEL_DIJKSTRA,
+ SURF_MODEL_DIJKSTRACACHE,
+ SURF_MODEL_NONE,
+ SURF_MODEL_VIVALDI,
+ SURF_MODEL_CLUSTER
+} e_routing_types;
+
+struct s_model_type routing_models[] = {
+ {"Full",
+ "Full routing data (fast, large memory requirements, fully expressive)",
+ model_full_create, model_full_end},
+ {"Floyd",
+ "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
+ model_floyd_create, model_floyd_end},
+ {"Dijkstra",
+ "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
+ model_dijkstra_create, model_dijkstra_both_end},
+ {"DijkstraCache",
+ "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
+ model_dijkstracache_create, model_dijkstra_both_end},
+ {"none", "No routing (Unless you know what you are doing, avoid using this mode in combination with a non Constant network model).",
+ model_none_create, NULL},
+ {"Vivaldi", "Vivaldi routing",
+ model_vivaldi_create, NULL},
+ {"Cluster", "Cluster routing",
+ model_cluster_create, NULL},
+ {NULL, NULL, NULL, NULL}
+};
+
+/**
+ * \brief Add a "host_link" to the network element list
+ */
+static void parse_S_host_link(sg_platf_host_link_cbarg_t host)
+{
+ RoutingEdgePtr info = (RoutingEdgePtr) xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL);
+ xbt_assert(info, "Host '%s' not found!", host->id);
+ xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER] ||
+ current_routing->p_modelDesc == &routing_models[SURF_MODEL_VIVALDI],
+ "You have to be in model Cluster to use tag host_link!");
+
+ s_surf_parsing_link_up_down_t link_up_down;
+ link_up_down.link_up = xbt_lib_get_or_null(link_lib, host->link_up, SURF_LINK_LEVEL);
+ link_up_down.link_down = xbt_lib_get_or_null(link_lib, host->link_down, SURF_LINK_LEVEL);
+ link_up_down.limiter_link = NULL;
+ link_up_down.loopback_link = NULL;
+
+ xbt_assert(link_up_down.link_up, "Link '%s' not found!",host->link_up);
+ xbt_assert(link_up_down.link_down, "Link '%s' not found!",host->link_down);
+
+ if(!current_routing->p_linkUpDownList)
+ current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
+
+ // If dynar is is greater than edge id and if the host_link is already defined
+ if(xbt_dynar_length(current_routing->p_linkUpDownList) > info->m_id &&
+ xbt_dynar_get_as(current_routing->p_linkUpDownList, info->m_id, void*))
+ xbt_die("Host_link for '%s' is already defined!",host->id);
+
+ XBT_DEBUG("Push Host_link for host '%s' to position %d", info->p_name, info->m_id);
+ xbt_dynar_set_as(current_routing->p_linkUpDownList, info->m_id, s_surf_parsing_link_up_down_t, link_up_down);
+}
+
+/**
+ * \brief Add a "host" to the network element list
+ */
+static void parse_S_host(sg_platf_host_cbarg_t host)
+{
+ if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
+ current_routing->p_hierarchy = SURF_ROUTING_BASE;
+ xbt_assert(!xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL),
+ "Reading a host, processing unit \"%s\" already exists", host->id);
+
+ RoutingEdgePtr info = new RoutingEdge();
+ info->p_rcComponent = current_routing;
+ info->p_rcType = SURF_NETWORK_ELEMENT_HOST;
+ info->p_name = xbt_strdup(host->id);
+ info->m_id = current_routing->parsePU(info);
+ xbt_lib_set(host_lib, host->id, ROUTING_HOST_LEVEL, (void *) info);
+ XBT_DEBUG("Having set name '%s' id '%d'", host->id, info->m_id);
+
+ if(mount_list){
+ xbt_lib_set(storage_lib, host->id, ROUTING_STORAGE_HOST_LEVEL, (void *) mount_list);
+ mount_list = NULL;
+ }
+
+ if (host->coord && strcmp(host->coord, "")) {
+ unsigned int cursor;
+ char*str;
+
+ if (!COORD_HOST_LEVEL)
+ xbt_die ("To use host coordinates, please add --cfg=network/coordinates:yes to your command line");
+ /* Pre-parse the host coordinates -- FIXME factorize with routers by overloading the routing->parse_PU function*/
+ xbt_dynar_t ctn_str = xbt_str_split_str(host->coord, " ");
+ xbt_dynar_t ctn = xbt_dynar_new(sizeof(double),NULL);
+ xbt_dynar_foreach(ctn_str,cursor, str) {
+ double val = atof(str);
+ xbt_dynar_push(ctn,&val);
+ }
+ xbt_dynar_shrink(ctn, 0);
+ xbt_dynar_free(&ctn_str);
+ xbt_lib_set(host_lib, host->id, COORD_HOST_LEVEL, (void *) ctn);
+ XBT_DEBUG("Having set host coordinates for '%s'",host->id);
+ }
+}
+
+/**
+ * \brief Add a "router" to the network element list
+ */
+static void parse_S_router(sg_platf_router_cbarg_t router)
+{
+ if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
+ current_routing->p_hierarchy = SURF_ROUTING_BASE;
+ xbt_assert(!xbt_lib_get_or_null(as_router_lib, router->id, ROUTING_ASR_LEVEL),
+ "Reading a router, processing unit \"%s\" already exists",
+ router->id);
+
+ RoutingEdgePtr info = new RoutingEdge();
+ info->p_rcComponent = current_routing;
+ info->p_rcType = SURF_NETWORK_ELEMENT_ROUTER;
+ info->p_name = xbt_strdup(router->id);
+ info->m_id = current_routing->parsePU(info);
+ xbt_lib_set(as_router_lib, router->id, ROUTING_ASR_LEVEL, (void *) info);
+ XBT_DEBUG("Having set name '%s' id '%d'", router->id, info->m_id);
+
+ if (router->coord && strcmp(router->coord, "")) {
+ unsigned int cursor;
+ char*str;
+
+ if (!COORD_ASR_LEVEL)
+ xbt_die ("To use host coordinates, please add --cfg=network/coordinates:yes to your command line");
+ /* Pre-parse the host coordinates */
+ xbt_dynar_t ctn_str = xbt_str_split_str(router->coord, " ");
+ xbt_dynar_t ctn = xbt_dynar_new(sizeof(double),NULL);
+ xbt_dynar_foreach(ctn_str,cursor, str) {
+ double val = atof(str);
+ xbt_dynar_push(ctn,&val);
+ }
+ xbt_dynar_shrink(ctn, 0);
+ xbt_dynar_free(&ctn_str);
+ xbt_lib_set(as_router_lib, router->id, COORD_ASR_LEVEL, (void *) ctn);
+ XBT_DEBUG("Having set router coordinates for '%s'",router->id);
+ }
+}
+
+/**
+ * \brief Store the route by calling the set_route function of the current routing component
+ */
+static void parse_E_route(sg_platf_route_cbarg_t route)
+{
+ /*FIXME:REMOVE:xbt_assert(current_routing->parse_route,
+ "no defined method \"set_route\" in \"%s\"",
+ current_routing->name);*/
+
+ current_routing->parseRoute(route);
+}
+
+/**
+ * \brief Store the ASroute by calling the set_ASroute function of the current routing component
+ */
+static void parse_E_ASroute(sg_platf_route_cbarg_t ASroute)
+{
+ /*FIXME:REMOVE:xbt_assert(current_routing->parse_ASroute,
+ "no defined method \"set_ASroute\" in \"%s\"",
+ current_routing->name);*/
+ current_routing->parseASroute(ASroute);
+}
+
+/**
+ * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
+ */
+static void parse_E_bypassRoute(sg_platf_route_cbarg_t route)
+{
+ /*FIXME:REMOVE:xbt_assert(current_routing->parse_bypassroute,
+ "Bypassing mechanism not implemented by routing '%s'",
+ current_routing->name);*/
+
+ current_routing->parseBypassroute(route);
+}
+
+/**
+ * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
+ */
+static void parse_E_bypassASroute(sg_platf_route_cbarg_t ASroute)
+{
+ /*FIXME:REMOVE:xbt_assert(current_routing->parse_bypassroute,
+ "Bypassing mechanism not implemented by routing '%s'",
+ current_routing->name);*/
+ current_routing->parseBypassroute(ASroute);
+}
+
+static void routing_parse_trace(sg_platf_trace_cbarg_t trace)
+{
+ tmgr_trace_t tmgr_trace;
+ if (!trace->file || strcmp(trace->file, "") != 0) {
+ tmgr_trace = tmgr_trace_new_from_file(trace->file);
+ } else if (strcmp(trace->pc_data, "") == 0) {
+ tmgr_trace = NULL;
+ } else {
+ tmgr_trace =
+ tmgr_trace_new_from_string(trace->id, trace->pc_data,
+ trace->periodicity);
+ }
+ xbt_dict_set(traces_set_list, trace->id, (void *) tmgr_trace, NULL);
+}
+
+static void routing_parse_trace_connect(sg_platf_trace_connect_cbarg_t trace_connect)
+{
+ xbt_assert(xbt_dict_get_or_null
+ (traces_set_list, trace_connect->trace),
+ "Cannot connect trace %s to %s: trace unknown",
+ trace_connect->trace,
+ trace_connect->element);
+
+ switch (trace_connect->kind) {
+ case SURF_TRACE_CONNECT_KIND_HOST_AVAIL:
+ xbt_dict_set(trace_connect_list_host_avail,
+ trace_connect->trace,
+ xbt_strdup(trace_connect->element), NULL);
+ break;
+ case SURF_TRACE_CONNECT_KIND_POWER:
+ xbt_dict_set(trace_connect_list_power, trace_connect->trace,
+ xbt_strdup(trace_connect->element), NULL);
+ break;
+ case SURF_TRACE_CONNECT_KIND_LINK_AVAIL:
+ xbt_dict_set(trace_connect_list_link_avail,
+ trace_connect->trace,
+ xbt_strdup(trace_connect->element), NULL);
+ break;
+ case SURF_TRACE_CONNECT_KIND_BANDWIDTH:
+ xbt_dict_set(trace_connect_list_bandwidth,
+ trace_connect->trace,
+ xbt_strdup(trace_connect->element), NULL);
+ break;
+ case SURF_TRACE_CONNECT_KIND_LATENCY:
+ xbt_dict_set(trace_connect_list_latency, trace_connect->trace,
+ xbt_strdup(trace_connect->element), NULL);
+ break;
+ default:
+ xbt_die("Cannot connect trace %s to %s: kind of trace unknown",
+ trace_connect->trace, trace_connect->element);
+ break;
+ }
+}
+
+extern int _sg_init_status; /* yay, this is an horrible hack */
+
+/**
+ * \brief Make a new routing component to the platform
+ *
+ * Add a new autonomous system to the platform. Any elements (such as host,
+ * router or sub-AS) added after this call and before the corresponding call
+ * to sg_platf_new_AS_close() will be added to this AS.
+ *
+ * Once this function was called, the configuration concerning the used
+ * models cannot be changed anymore.
+ *
+ * @param AS_id name of this autonomous system. Must be unique in the platform
+ * @param wanted_routing_type one of Full, Floyd, Dijkstra or similar. Full list in the variable routing_models, in src/surf/surf_routing.c
+ */
+void routing_AS_begin(sg_platf_AS_cbarg_t AS)
+{
+ XBT_DEBUG("routing_AS_begin");
+ routing_model_description_t model = NULL;
+
+ xbt_assert(!xbt_lib_get_or_null
+ (as_router_lib, AS->id, ROUTING_ASR_LEVEL),
+ "The AS \"%s\" already exists", AS->id);
+
+ _sg_init_status = 2; /* horrible hack: direct access to the global controlling the level of configuration to prevent any further config */
+
+ /* search the routing model */
+ switch(AS->routing){
+ case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break;
+ case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break;
+ case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break;
+ case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break;
+ case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break;
+ case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break;
+ case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break;
+ default: xbt_die("Not a valid model!!!");
+ break;
+ }
+
+ /* make a new routing component */
+ AsPtr new_as = model->create();
+
+ new_as->p_modelDesc = model;
+ new_as->p_hierarchy = SURF_ROUTING_NULL;
+ new_as->p_name = xbt_strdup(AS->id);
+
+ RoutingEdgePtr info = new RoutingEdge();
+
+ if (current_routing == NULL && routing_platf->p_root == NULL) {
+
+ /* it is the first one */
+ new_as->p_routingFather = NULL;
+ routing_platf->p_root = new_as;
+ info->m_id = -1;
+ } else if (current_routing != NULL && routing_platf->p_root != NULL) {
+
+ xbt_assert(!xbt_dict_get_or_null
+ (current_routing->p_routingSons, AS->id),
+ "The AS \"%s\" already exists", AS->id);
+ /* it is a part of the tree */
+ new_as->p_routingFather = current_routing;
+ /* set the father behavior */
+ if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
+ current_routing->p_hierarchy = SURF_ROUTING_RECURSIVE;
+ /* add to the sons dictionary */
+ xbt_dict_set(current_routing->p_routingSons, AS->id,
+ (void *) new_as, NULL);
+ /* add to the father element list */
+ info->m_id = current_routing->parseAS(info);
+ } else {
+ THROWF(arg_error, 0, "All defined components must be belong to a AS");
+ }
+
+ info->p_rcComponent = new_as->p_routingFather;
+ info->p_rcType = SURF_NETWORK_ELEMENT_AS;
+ info->p_name = new_as->p_name;
+
+ xbt_lib_set(as_router_lib, info->p_name, ROUTING_ASR_LEVEL,
+ (void *) info);
+ XBT_DEBUG("Having set name '%s' id '%d'", new_as->p_name, info->m_id);
+
+ /* set the new current component of the tree */
+ current_routing = new_as;
+ current_routing->p_netElem = info;
+
+}
+
+/**
+ * \brief Specify that the current description of AS is finished
+ *
+ * Once you've declared all the content of your AS, you have to close
+ * it with this call. Your AS is not usable until you call this function.
+ *
+ * @fixme: this call is not as robust as wanted: bad things WILL happen
+ * if you call it twice for the same AS, or if you forget calling it, or
+ * even if you add stuff to a closed AS
+ *
+ */
+void routing_AS_end(sg_platf_AS_cbarg_t AS)
+{
+
+ if (current_routing == NULL) {
+ THROWF(arg_error, 0, "Close an AS, but none was under construction");
+ } else {
+ if (current_routing->p_modelDesc->end)
+ current_routing->p_modelDesc->end(current_routing);
+ current_routing = current_routing->p_routingFather;
+ }
+}
+
+/* Aux Business methods */
+
+/**
+ * \brief Get the AS father and the first elements of the chain
+ *
+ * \param src the source host name
+ * \param dst the destination host name
+ *
+ * Get the common father of the to processing units, and the first different
+ * father in the chain
+ */
+static void elements_father(sg_routing_edge_t src, sg_routing_edge_t dst,
+ AS_t * res_father,
+ AS_t * res_src,
+ AS_t * res_dst)
+{
+ xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
+#define ELEMENTS_FATHER_MAXDEPTH 16 /* increase if it is not enough */
+ AS_t src_as, dst_as;
+ AS_t path_src[ELEMENTS_FATHER_MAXDEPTH];
+ AS_t path_dst[ELEMENTS_FATHER_MAXDEPTH];
+ int index_src = 0;
+ int index_dst = 0;
+ AS_t current;
+ AS_t current_src;
+ AS_t current_dst;
+ AS_t father;
+
+ /* (1) find the as where the src and dst are located */
+ sg_routing_edge_t src_data = src;
+ sg_routing_edge_t dst_data = dst;
+ src_as = src_data->p_rcComponent;
+ dst_as = dst_data->p_rcComponent;
+#ifndef NDEBUG
+ char* src_name = src_data->p_name;
+ char* dst_name = dst_data->p_name;
+#endif
+
+ xbt_assert(src_as && dst_as,
+ "Ask for route \"from\"(%s) or \"to\"(%s) no found", src_name, dst_name);
+
+ /* (2) find the path to the root routing component */
+ for (current = src_as; current != NULL; current = current->p_routingFather) {
+ if (index_src >= ELEMENTS_FATHER_MAXDEPTH)
+ xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_src");
+ path_src[index_src++] = current;
+ }
+ for (current = dst_as; current != NULL; current = current->p_routingFather) {
+ if (index_dst >= ELEMENTS_FATHER_MAXDEPTH)
+ xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_dst");
+ path_dst[index_dst++] = current;
+ }
+
+ /* (3) find the common father */
+ do {
+ current_src = path_src[--index_src];
+ current_dst = path_dst[--index_dst];
+ } while (index_src > 0 && index_dst > 0 && current_src == current_dst);
+
+ /* (4) they are not in the same routing component, make the path */
+ if (current_src == current_dst)
+ father = current_src;
+ else
+ father = path_src[index_src + 1];
+
+ /* (5) result generation */
+ *res_father = father; /* first the common father of src and dst */
+ *res_src = current_src; /* second the first different father of src */
+ *res_dst = current_dst; /* three the first different father of dst */
+
+#undef ELEMENTS_FATHER_MAXDEPTH
+}
+
+/* Global Business methods */
+
+/**
+ * \brief Recursive function for get_route_latency
+ *
+ * \param src the source host name
+ * \param dst the destination host name
+ * \param *route the route where the links are stored. It is either NULL or a ready to use dynar
+ * \param *latency the latency, if needed
+ *
+ * This function is called by "get_route" and "get_latency". It allows to walk
+ * recursively through the ASes tree.
+ */
+static void _get_route_and_latency(RoutingEdgePtr src, RoutingEdgePtr dst,
+ xbt_dynar_t * links, double *latency)
+{
+ s_sg_platf_route_cbarg_t route;
+ memset(&route,0,sizeof(route));
+
+ xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
+ XBT_DEBUG("Solve route/latency \"%s\" to \"%s\"", src->p_name, dst->p_name);
+
+ /* Find how src and dst are interconnected */
+ AsPtr common_father, src_father, dst_father;
+ elements_father(src, dst, &common_father, &src_father, &dst_father);
+ XBT_DEBUG("elements_father: common father '%s' src_father '%s' dst_father '%s'",
+ common_father->p_name, src_father->p_name, dst_father->p_name);
+
+ /* Check whether a direct bypass is defined */
+ sg_platf_route_cbarg_t e_route_bypass = NULL;
+ //FIXME:REMOVE:if (common_father->get_bypass_route)
+ e_route_bypass = common_father->getBypassRoute(src, dst, latency);
+
+ /* Common ancestor is kind enough to declare a bypass route from src to dst -- use it and bail out */
+ if (e_route_bypass) {
+ xbt_dynar_merge(links, &e_route_bypass->link_list);
+ //FIXME:generic_free_route(e_route_bypass);
+ return;
+ }
+
+ /* If src and dst are in the same AS, life is good */
+ if (src_father == dst_father) { /* SURF_ROUTING_BASE */
+ route.link_list = *links;
+ common_father->getRouteAndLatency(src, dst, &route, latency);
+ // if vivaldi latency+=vivaldi(src,dst)
+ return;
+ }
+
+ /* Not in the same AS, no bypass. We'll have to find our path between the ASes recursively*/
+
+ route.link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+ // Find the net_card corresponding to father
+ RoutingEdgePtr src_father_net_elm = src_father->p_netElem;
+ RoutingEdgePtr dst_father_net_elm = dst_father->p_netElem;
+
+ common_father->getRouteAndLatency(src_father_net_elm, dst_father_net_elm,
+ &route, latency);
+
+ xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
+ "bad gateways for route from \"%s\" to \"%s\"", src->p_name, dst->p_name);
+
+ sg_routing_edge_t src_gateway_net_elm = route.gw_src;
+ sg_routing_edge_t dst_gateway_net_elm = route.gw_dst;
+
+ /* If source gateway is not our source, we have to recursively find our way up to this point */
+ if (src != src_gateway_net_elm)
+ _get_route_and_latency(src, src_gateway_net_elm, links, latency);
+ xbt_dynar_merge(links, &route.link_list);
+
+ /* If dest gateway is not our destination, we have to recursively find our way from this point */
+ if (dst_gateway_net_elm != dst)
+ _get_route_and_latency(dst_gateway_net_elm, dst, links, latency);
+
+ // if vivaldi latency+=vivaldi(src_gateway,dst_gateway)
+}
+
+AS_t surf_platf_get_root(routing_platf_t platf){
+ return platf->p_root;
+}
+
+e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_routing_edge_t edge){
+ return edge->p_rcType;
+}
+
+
+/**
+ * \brief Find a route between hosts
+ *
+ * \param src the network_element_t for src host
+ * \param dst the network_element_t for dst host
+ * \param route where to store the list of links.
+ * If *route=NULL, create a short lived dynar. Else, fill the provided dynar
+ * \param latency where to store the latency experienced on the path (or NULL if not interested)
+ * It is the caller responsability to initialize latency to 0 (we add to provided route)
+ * \pre route!=NULL
+ *
+ * walk through the routing components tree and find a route between hosts
+ * by calling the differents "get_route" functions in each routing component.
+ */
+void RoutingPlatf::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst,
+ xbt_dynar_t* route, double *latency)
+{
+ XBT_DEBUG("routing_get_route_and_latency from %s to %s", src->p_name, dst->p_name);
+ if (!*route) {
+ xbt_dynar_reset(routing_platf->p_lastRoute);
+ *route = routing_platf->p_lastRoute;
+ }
+
+ _get_route_and_latency(src, dst, route, latency);
+
+ xbt_assert(!latency || *latency >= 0.0,
+ "negative latency on route between \"%s\" and \"%s\"", src->p_name, dst->p_name);
+}
+
+static xbt_dynar_t recursive_get_onelink_routes(AsPtr rc)
+{
+ xbt_dynar_t ret = xbt_dynar_new(sizeof(OnelinkPtr), xbt_free);
+
+ //adding my one link routes
+ xbt_dynar_t onelink_mine = rc->getOneLinkRoutes();
+ if (onelink_mine)
+ xbt_dynar_merge(&ret,&onelink_mine);
+
+ //recursing
+ char *key;
+ xbt_dict_cursor_t cursor = NULL;
+ AS_t rc_child;
+ xbt_dict_foreach(rc->p_routingSons, cursor, key, rc_child) {
+ xbt_dynar_t onelink_child = recursive_get_onelink_routes(rc_child);
+ if (onelink_child)
+ xbt_dynar_merge(&ret,&onelink_child);
+ }
+ return ret;
+}
+
+static xbt_dynar_t get_onelink_routes(void)
+{
+ return recursive_get_onelink_routes(routing_platf->p_root);
+}
+
+e_surf_network_element_type_t routing_get_network_element_type(const char *name)
+{
+ RoutingEdgePtr rc = sg_routing_edge_by_name_or_null(name);
+ if (rc)
+ return rc->p_rcType;
+
+ return SURF_NETWORK_ELEMENT_NULL;
+}
+
+/**
+ * \brief Generic method: create the global routing schema
+ *
+ * Make a global routing structure and set all the parsing functions.
+ */
+void routing_model_create( void *loopback)
+{
+ /* config the uniq global routing */
+ routing_platf = new RoutingPlatf();
+ routing_platf->p_root = NULL;
+ //FIXME:routing_platf->get_onelink_routes = get_onelink_routes;
+ //FIXME:routing_platf->loopback = loopback;
+ routing_platf->p_lastRoute = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
+ /* no current routing at moment */
+ current_routing = NULL;
+}
+
+
+/* ************************************************** */
+/* ********** PATERN FOR NEW ROUTING **************** */
+
+/* The minimal configuration of a new routing model need the next functions,
+ * also you need to set at the start of the file, the new model in the model
+ * list. Remember keep the null ending of the list.
+ */
+/*** Routing model structure ***/
+// typedef struct {
+// s_routing_component_t generic_routing;
+// /* things that your routing model need */
+// } s_routing_component_NEW_t,*routing_component_NEW_t;
+
+/*** Parse routing model functions ***/
+// static void model_NEW_set_processing_unit(routing_component_t rc, const char* name) {}
+// static void model_NEW_set_autonomous_system(routing_component_t rc, const char* name) {}
+// static void model_NEW_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {}
+// static void model_NEW_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {}
+// static void model_NEW_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {}
+
+/*** Business methods ***/
+// static route_extended_t NEW_get_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
+// static route_extended_t NEW_get_bypass_route(routing_component_t rc, const char* src,const char* dst) {return NULL;}
+// static void NEW_finalize(routing_component_t rc) { xbt_free(rc);}
+
+/*** Creation routing model functions ***/
+// static void* model_NEW_create(void) {
+// routing_component_NEW_t new_component = xbt_new0(s_routing_component_NEW_t,1);
+// new_component->generic_routing.set_processing_unit = model_NEW_set_processing_unit;
+// new_component->generic_routing.set_autonomous_system = model_NEW_set_autonomous_system;
+// new_component->generic_routing.set_route = model_NEW_set_route;
+// new_component->generic_routing.set_ASroute = model_NEW_set_ASroute;
+// new_component->generic_routing.set_bypassroute = model_NEW_set_bypassroute;
+// new_component->generic_routing.get_route = NEW_get_route;
+// new_component->generic_routing.get_bypass_route = NEW_get_bypass_route;
+// new_component->generic_routing.finalize = NEW_finalize;
+// /* initialization of internal structures */
+// return new_component;
+// } /* mandatory */
+// static void model_NEW_load(void) {} /* mandatory */
+// static void model_NEW_unload(void) {} /* mandatory */
+// static void model_NEW_end(void) {} /* mandatory */
+
+/* ************************************************************************** */
+/* ************************* GENERIC PARSE FUNCTIONS ************************ */
+
+void routing_cluster_add_backbone(void* bb) {
+ xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER],
+ "You have to be in model Cluster to use tag backbone!");
+ /*FIXME:xbt_assert(!((as_cluster_t)current_routing)->p_backbone, "The backbone link is already defined!");
+ ((as_cluster_t)current_routing)->p_backbone = bb;*/
+ XBT_DEBUG("Add a backbone to AS '%s'",current_routing->p_name);
+}
+
+static void routing_parse_cabinet(sg_platf_cabinet_cbarg_t cabinet)
+{
+ int start, end, i;
+ char *groups , *host_id , *link_id = NULL;
+ unsigned int iter;
+ xbt_dynar_t radical_elements;
+ xbt_dynar_t radical_ends;
+
+ //Make all hosts
+ radical_elements = xbt_str_split(cabinet->radical, ",");
+ xbt_dynar_foreach(radical_elements, iter, groups) {
+
+ radical_ends = xbt_str_split(groups, "-");
+ start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
+
+ switch (xbt_dynar_length(radical_ends)) {
+ case 1:
+ end = start;
+ break;
+ case 2:
+ end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
+ break;
+ default:
+ surf_parse_error("Malformed radical");
+ break;
+ }
+ s_sg_platf_host_cbarg_t host;
+ memset(&host, 0, sizeof(host));
+ host.initial_state = SURF_RESOURCE_ON;
+ host.power_peak = cabinet->power;
+ host.power_scale = 1.0;
+ host.core_amount = 1;
+
+ s_sg_platf_link_cbarg_t link;
+ memset(&link, 0, sizeof(link));
+ link.state = SURF_RESOURCE_ON;
+ link.policy = SURF_LINK_FULLDUPLEX;
+ link.latency = cabinet->lat;
+ link.bandwidth = cabinet->bw;
+
+ s_sg_platf_host_link_cbarg_t host_link;
+ memset(&host_link, 0, sizeof(host_link));
+
+ for (i = start; i <= end; i++) {
+ host_id = bprintf("%s%d%s",cabinet->prefix,i,cabinet->suffix);
+ link_id = bprintf("link_%s%d%s",cabinet->prefix,i,cabinet->suffix);
+ host.id = host_id;
+ link.id = link_id;
+ sg_platf_new_host(&host);
+ sg_platf_new_link(&link);
+
+ char* link_up = bprintf("%s_UP",link_id);
+ char* link_down = bprintf("%s_DOWN",link_id);
+ host_link.id = host_id;
+ host_link.link_up = link_up;
+ host_link.link_down= link_down;
+ sg_platf_new_host_link(&host_link);
+
+ free(host_id);
+ free(link_id);
+ free(link_up);
+ free(link_down);
+ }
+
+ xbt_dynar_free(&radical_ends);
+ }
+ xbt_dynar_free(&radical_elements);
+}
+
+static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
+{
+ char *host_id, *groups, *link_id = NULL;
+ xbt_dict_t patterns = NULL;
+
+ s_sg_platf_host_cbarg_t host;
+ s_sg_platf_link_cbarg_t link;
+
+ unsigned int iter;
+ int start, end, i;
+ xbt_dynar_t radical_elements;
+ xbt_dynar_t radical_ends;
+
+ if ((cluster->availability_trace && strcmp(cluster->availability_trace, ""))
+ || (cluster->state_trace && strcmp(cluster->state_trace, ""))) {
+ patterns = xbt_dict_new_homogeneous(xbt_free_f);
+ xbt_dict_set(patterns, "id", xbt_strdup(cluster->id), NULL);
+ xbt_dict_set(patterns, "prefix", xbt_strdup(cluster->prefix), NULL);
+ xbt_dict_set(patterns, "suffix", xbt_strdup(cluster->suffix), NULL);
+ }
+
+ XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", cluster->id);
+ s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+ AS.id = cluster->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);
+
+ //Make all hosts
+ radical_elements = xbt_str_split(cluster->radical, ",");
+ xbt_dynar_foreach(radical_elements, iter, groups) {
+
+ radical_ends = xbt_str_split(groups, "-");
+ start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
+
+ switch (xbt_dynar_length(radical_ends)) {
+ case 1:
+ end = start;
+ break;
+ case 2:
+ end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
+ break;
+ default:
+ surf_parse_error("Malformed radical");
+ break;
+ }
+ for (i = start; i <= end; i++) {
+ host_id =
+ bprintf("%s%d%s", cluster->prefix, i, cluster->suffix);
+ link_id = bprintf("%s_link_%d", cluster->id, i);
+
+ XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\">", host_id, cluster->power);
+
+ memset(&host, 0, sizeof(host));
+ host.id = host_id;
+ if (cluster->availability_trace && strcmp(cluster->availability_trace, "")) {
+ xbt_dict_set(patterns, "radical", bprintf("%d", i), NULL);
+ char *avail_file = xbt_str_varsubst(cluster->availability_trace, patterns);
+ XBT_DEBUG("\tavailability_file=\"%s\"", avail_file);
+ host.power_trace = tmgr_trace_new_from_file(avail_file);
+ xbt_free(avail_file);
+ } else {
+ XBT_DEBUG("\tavailability_file=\"\"");
+ }
+
+ if (cluster->state_trace && strcmp(cluster->state_trace, "")) {
+ char *avail_file = xbt_str_varsubst(cluster->state_trace, patterns);
+ XBT_DEBUG("\tstate_file=\"%s\"", avail_file);
+ host.state_trace = tmgr_trace_new_from_file(avail_file);
+ xbt_free(avail_file);
+ } else {
+ XBT_DEBUG("\tstate_file=\"\"");
+ }
+
+ host.power_peak = cluster->power;
+ host.power_scale = 1.0;
+ host.core_amount = cluster->core_amount;
+ host.initial_state = SURF_RESOURCE_ON;
+ host.coord = "";
+ sg_platf_new_host(&host);
+ XBT_DEBUG("</host>");
+
+ XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_id,
+ cluster->bw, cluster->lat);
+
+ memset(&link, 0, sizeof(link));
+ link.id = link_id;
+ link.bandwidth = cluster->bw;
+ link.latency = cluster->lat;
+ link.state = SURF_RESOURCE_ON;
+ link.policy = cluster->sharing_policy;
+ sg_platf_new_link(&link);
+
+ s_surf_parsing_link_up_down_t info;
+
+ if (link.policy == SURF_LINK_FULLDUPLEX) {
+ char *tmp_link = bprintf("%s_UP", link_id);
+ info.link_up =
+ xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL);
+ free(tmp_link);
+ tmp_link = bprintf("%s_DOWN", link_id);
+ info.link_down =
+ xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL);
+ free(tmp_link);
+ } else {
+ info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL);
+ info.link_down = info.link_up;
+ }
+
+ if(cluster->limiter_link!=0){
+ char *tmp_link = bprintf("%s_limiter", link_id);
+ XBT_DEBUG("<limiter\tid=\"%s\"\tbw=\"%f\"/>", tmp_link,
+ cluster->limiter_link);
+
+
+ memset(&link, 0, sizeof(link));
+ link.id = tmp_link;
+ link.bandwidth = cluster->limiter_link;
+ link.latency = 0;
+ link.state = SURF_RESOURCE_ON;
+ link.policy = SURF_LINK_SHARED;
+ sg_platf_new_link(&link);
+ info.limiter_link =
+ xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL);
+ free(tmp_link);
+ }else{
+ info.limiter_link =NULL;
+ }
+
+ if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){
+ char *tmp_link = bprintf("%s_loopback", link_id);
+ XBT_DEBUG("<loopback\tid=\"%s\"\tbw=\"%f\"/>", tmp_link,
+ cluster->limiter_link);
+
+
+ memset(&link, 0, sizeof(link));
+ link.id = tmp_link;
+ link.bandwidth = cluster->loopback_bw;
+ link.latency = cluster->loopback_lat;
+ link.state = SURF_RESOURCE_ON;
+ link.policy = SURF_LINK_FATPIPE;
+ sg_platf_new_link(&link);
+ info.loopback_link =
+ xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL);
+ free(tmp_link);
+ }else{
+ info.loopback_link =NULL;
+ }
+
+ xbt_dynar_push(current_routing->p_linkUpDownList, &info);
+ xbt_free(link_id);
+ xbt_free(host_id);
+ }
+
+ xbt_dynar_free(&radical_ends);
+ }
+ xbt_dynar_free(&radical_elements);
+
+ // Add a router. It is magically used thanks to the way in which surf_routing_cluster is written,
+ // and it's very useful to connect clusters together
+ XBT_DEBUG(" ");
+ XBT_DEBUG("<router id=\"%s\"/>", cluster->router_id);
+ char *newid = NULL;
+ s_sg_platf_router_cbarg_t router;
+ memset(&router, 0, sizeof(router));
+ router.id = cluster->router_id;
+ router.coord = "";
+ if (!router.id || !strcmp(router.id, ""))
+ router.id = newid =
+ bprintf("%s%s_router%s", cluster->prefix, cluster->id,
+ cluster->suffix);
+ sg_platf_new_router(&router);
+ ((AsClusterPtr)current_routing)->p_router = (RoutingEdgePtr) xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL);
+ free(newid);
+
+ //Make the backbone
+ if ((cluster->bb_bw != 0) || (cluster->bb_lat != 0)) {
+ char *link_backbone = bprintf("%s_backbone", cluster->id);
+ XBT_DEBUG("<link\tid=\"%s\" bw=\"%f\" lat=\"%f\"/>", link_backbone,
+ cluster->bb_bw, cluster->bb_lat);
+
+ memset(&link, 0, sizeof(link));
+ link.id = link_backbone;
+ link.bandwidth = cluster->bb_bw;
+ link.latency = cluster->bb_lat;
+ link.state = SURF_RESOURCE_ON;
+ link.policy = cluster->bb_sharing_policy;
+
+ sg_platf_new_link(&link);
+
+ routing_cluster_add_backbone(xbt_lib_get_or_null(link_lib, link_backbone, SURF_LINK_LEVEL));
+
+ free(link_backbone);
+ }
+
+ XBT_DEBUG("</AS>");
+ sg_platf_new_AS_end();
+ XBT_DEBUG(" ");
+ xbt_dict_free(&patterns); // no op if it were never set
+}
+
+static void routing_parse_postparse(void) {
+ xbt_dict_free(&random_value);
+}
+
+static void routing_parse_peer(sg_platf_peer_cbarg_t peer)
+{
+ char *host_id = NULL;
+ char *link_id;
+
+ XBT_DEBUG(" ");
+ host_id = HOST_PEER(peer->id);
+ link_id = LINK_PEER(peer->id);
+
+ XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->power);
+ s_sg_platf_host_cbarg_t host;
+ memset(&host, 0, sizeof(host));
+ host.initial_state = SURF_RESOURCE_ON;
+ host.id = host_id;
+ host.power_peak = peer->power;
+ host.power_scale = 1.0;
+ host.power_trace = peer->availability_trace;
+ host.state_trace = peer->state_trace;
+ host.core_amount = 1;
+ host.coord = peer->coord;
+ sg_platf_new_host(&host);
+
+ s_sg_platf_link_cbarg_t link;
+ memset(&link, 0, sizeof(link));
+ link.state = SURF_RESOURCE_ON;
+ link.policy = SURF_LINK_SHARED;
+ link.latency = peer->lat;
+
+ char* link_up = bprintf("%s_UP",link_id);
+ XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_up,
+ peer->bw_out, peer->lat);
+ link.id = link_up;
+ link.bandwidth = peer->bw_out;
+ sg_platf_new_link(&link);
+
+ char* link_down = bprintf("%s_DOWN",link_id);
+ XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_down,
+ peer->bw_in, peer->lat);
+ link.id = link_down;
+ link.bandwidth = peer->bw_in;
+ sg_platf_new_link(&link);
+
+ XBT_DEBUG("<host_link\tid=\"%s\"\tup=\"%s\"\tdown=\"%s\" />", host_id,link_up,link_down);
+ s_sg_platf_host_link_cbarg_t host_link;
+ memset(&host_link, 0, sizeof(host_link));
+ host_link.id = host_id;
+ host_link.link_up = link_up;
+ host_link.link_down= link_down;
+ sg_platf_new_host_link(&host_link);
+
+ XBT_DEBUG(" ");
+
+ //xbt_dynar_free(&tab_elements_num);
+ free(host_id);
+ free(link_id);
+ free(link_up);
+ free(link_down);
+}
+
+static void routing_parse_Srandom(void)
+{
+ double mean, std, min, max, seed;
+ char *random_id = A_surfxml_random_id;
+ char *random_radical = A_surfxml_random_radical;
+ char *rd_name = NULL;
+ char *rd_value;
+ mean = surf_parse_get_double(A_surfxml_random_mean);
+ std = surf_parse_get_double(A_surfxml_random_std___deviation);
+ min = surf_parse_get_double(A_surfxml_random_min);
+ max = surf_parse_get_double(A_surfxml_random_max);
+ seed = surf_parse_get_double(A_surfxml_random_seed);
+
+ double res = 0;
+ int i = 0;
+ random_data_t random = xbt_new0(s_random_data_t, 1);
+ char *tmpbuf;
+
+ xbt_dynar_t radical_elements;
+ unsigned int iter;
+ char *groups;
+ int start, end;
+ xbt_dynar_t radical_ends;
+
+ switch (A_surfxml_random_generator) {
+ case AU_surfxml_random_generator:
+ case A_surfxml_random_generator_NONE:
+ random->generator = NONE;
+ break;
+ case A_surfxml_random_generator_DRAND48:
+ random->generator = DRAND48;
+ break;
+ case A_surfxml_random_generator_RAND:
+ random->generator = RAND;
+ break;
+ case A_surfxml_random_generator_RNGSTREAM:
+ random->generator = RNGSTREAM;
+ break;
+ default:
+ surf_parse_error("Invalid random generator");
+ break;
+ }
+ random->seed = seed;
+ random->min = min;
+ random->max = max;
+
+ /* Check user stupidities */
+ if (max < min)
+ THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
+ if (mean < min)
+ THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean, min);
+ if (mean > max)
+ THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean, max);
+
+ /* normalize the mean and standard deviation before storing */
+ random->mean = (mean - min) / (max - min);
+ random->std = std / (max - min);
+
+ if (random->mean * (1 - random->mean) < random->std * random->std)
+ THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
+ random->mean, random->std);
+
+ XBT_DEBUG
+ ("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
+ random_id, random->min, random->max, random->mean, random->std,
+ (int)random->generator, random->seed, random_radical);
+
+ if (!random_value)
+ random_value = xbt_dict_new_homogeneous(free);
+
+ if (!strcmp(random_radical, "")) {
+ res = random_generate(random);
+ rd_value = bprintf("%f", res);
+ xbt_dict_set(random_value, random_id, rd_value, NULL);
+ } else {
+ radical_elements = xbt_str_split(random_radical, ",");
+ xbt_dynar_foreach(radical_elements, iter, groups) {
+ radical_ends = xbt_str_split(groups, "-");
+ switch (xbt_dynar_length(radical_ends)) {
+ case 1:
+ xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
+ "Custom Random '%s' already exists !", random_id);
+ res = random_generate(random);
+ tmpbuf =
+ bprintf("%s%d", random_id,
+ atoi(xbt_dynar_getfirst_as(radical_ends, char *)));
+ xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
+ xbt_free(tmpbuf);
+ break;
+
+ case 2:
+ start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
+ end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
+ for (i = start; i <= end; i++) {
+ xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
+ "Custom Random '%s' already exists !", bprintf("%s%d",
+ random_id,
+ i));
+ res = random_generate(random);
+ tmpbuf = bprintf("%s%d", random_id, i);
+ xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
+ xbt_free(tmpbuf);
+ }
+ break;
+ default:
+ XBT_CRITICAL("Malformed radical");
+ break;
+ }
+ res = random_generate(random);
+ rd_name = bprintf("%s_router", random_id);
+ rd_value = bprintf("%f", res);
+ xbt_dict_set(random_value, rd_name, rd_value, NULL);
+
+ xbt_dynar_free(&radical_ends);
+ }
+ free(rd_name);
+ xbt_dynar_free(&radical_elements);
+ }
+}
+
+void routing_register_callbacks()
+{
+ sg_platf_host_add_cb(parse_S_host);
+ sg_platf_router_add_cb(parse_S_router);
+ sg_platf_host_link_add_cb(parse_S_host_link);
+ sg_platf_route_add_cb(parse_E_route);
+ sg_platf_ASroute_add_cb(parse_E_ASroute);
+ sg_platf_bypassRoute_add_cb(parse_E_bypassRoute);
+ sg_platf_bypassASroute_add_cb(parse_E_bypassASroute);
+
+ sg_platf_cluster_add_cb(routing_parse_cluster);
+ sg_platf_cabinet_add_cb(routing_parse_cabinet);
+
+ sg_platf_peer_add_cb(routing_parse_peer);
+ sg_platf_postparse_add_cb(routing_parse_postparse);
+
+ /* we care about the ASes while parsing the platf. Incredible, isnt it? */
+ sg_platf_AS_end_add_cb(routing_AS_end);
+ sg_platf_AS_begin_add_cb(routing_AS_begin);
+
+ sg_platf_trace_add_cb(routing_parse_trace);
+ sg_platf_trace_connect_add_cb(routing_parse_trace_connect);
+
+#ifdef HAVE_TRACING
+ instr_routing_define_callbacks();
+#endif
+}
+
+/**
+ * \brief Recursive function for finalize
+ *
+ * \param rc the source host name
+ *
+ * This fuction is call by "finalize". It allow to finalize the
+ * AS or routing components. It delete all the structures.
+ */
+static void finalize_rec(AsPtr as) {
+ xbt_dict_cursor_t cursor = NULL;
+ char *key;
+ AS_t elem;
+
+ xbt_dict_foreach(as->p_routingSons, cursor, key, elem) {
+ finalize_rec(elem);
+ }
+
+ delete as;;
+}
+
+/** \brief Frees all memory allocated by the routing module */
+void routing_exit(void) {
+ if (!routing_platf)
+ return;
+ xbt_dynar_free(&routing_platf->p_lastRoute);
+ finalize_rec(routing_platf->p_root);
+ xbt_free(routing_platf);
+}
+
+AS_t surf_AS_get_routing_root() {
+ return routing_platf->p_root;
+}
+
+const char *surf_AS_get_name(AsPtr as) {
+ return as->p_name;
+}
+
+xbt_dict_t surf_AS_get_routing_sons(AsPtr as) {
+ return as->p_routingSons;
+}
+
+const char *surf_AS_get_model(AsPtr as) {
+ return as->p_modelDesc->name;
+}
+
+xbt_dynar_t surf_AS_get_hosts(AsPtr as) {
+ xbt_dynar_t elms = as->p_indexNetworkElm;
+ sg_routing_edge_t relm;
+ xbt_dictelm_t delm;
+ int index;
+ int count = xbt_dynar_length(elms);
+ xbt_dynar_t res = xbt_dynar_new(sizeof(xbt_dictelm_t), NULL);
+ for (index = 0; index < count; index++) {
+ relm = xbt_dynar_get_as(elms, index, RoutingEdgePtr);
+ delm = xbt_lib_get_elm_or_null(host_lib, relm->p_name);
+ if (delm!=NULL) {
+ xbt_dynar_push(res, &delm);
+ }
+ }
+ return res;
+}
+
+void surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) {
+ as->getGraph(graph, nodes, edges);
+}
+
--- /dev/null
+#include "surf.hpp"
+
+#ifndef NETWORK_ROUTING_HPP_
+#define NETWORK_ROUTING_HPP_
+
+void routing_model_create( void *loopback);
+
+/***********
+ * Classes *
+ ***********/
+class As;
+typedef As *AsPtr;
+
+class RoutingModelDescription;
+typedef RoutingModelDescription *RoutingModelDescriptionPtr;
+
+class RoutingEdge;
+typedef RoutingEdge *RoutingEdgePtr;
+
+class Onelink;
+typedef Onelink *OnelinkPtr;
+
+class RoutingPlatf;
+typedef RoutingPlatf *RoutingPlatfPtr;
+
+
+/*FIXME:class RoutingModelDescription {
+ const char *p_name;
+ const char *p_desc;
+ AsPtr create();
+ void end(AsPtr as);
+};*/
+
+class As {
+public:
+ xbt_dynar_t p_indexNetworkElm;
+ xbt_dict_t p_bypassRoutes; /* store bypass routes */
+ routing_model_description_t p_modelDesc;
+ e_surf_routing_hierarchy_t p_hierarchy;
+ char *p_name;
+ AsPtr p_routingFather;
+ xbt_dict_t p_routingSons;
+ RoutingEdgePtr p_netElem;
+ xbt_dynar_t p_linkUpDownList;
+
+ As(){};
+ ~As(){};
+ virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency)=0;
+ virtual xbt_dynar_t getOneLinkRoutes()=0;
+ virtual void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)=0;
+ virtual sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat)=0;
+
+ /* The parser calls the following functions to inform the routing models
+ * that a new element is added to the AS currently built.
+ *
+ * Of course, only the routing model of this AS is informed, not every ones */
+ virtual int parsePU(RoutingEdgePtr elm)=0; /* A host or a router, whatever */
+ virtual int parseAS( RoutingEdgePtr elm)=0;
+ virtual void parseRoute(sg_platf_route_cbarg_t route)=0;
+ virtual void parseASroute(sg_platf_route_cbarg_t route)=0;
+ virtual void parseBypassroute(sg_platf_route_cbarg_t e_route)=0;
+};
+
+class RoutingEdge {
+public:
+ AsPtr p_rcComponent;
+ e_surf_network_element_type_t p_rcType;
+ int m_id;
+ char *p_name;
+};
+
+/*
+ * Link of lenght 1, alongside with its source and destination. This is mainly usefull in the bindings to gtnets and ns3
+ */
+class Onelink {
+public:
+ RoutingEdgePtr p_src;
+ RoutingEdgePtr p_dst;
+ void *p_linkPtr;
+};
+
+class RoutingPlatf {
+public:
+ AsPtr p_root;
+ void *p_loopback;
+ xbt_dynar_t p_lastRoute;
+ xbt_dynar_t getOneLinkRoutes(void);
+ void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, xbt_dynar_t * links, double *latency);
+};
+
+#endif /* NETWORK_ROUTING_HPP_ */
--- /dev/null
+#include "surf_routing_private.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster, surf, "Routing part of surf");
+}
+
+AS_t model_cluster_create(void)
+{
+//FIXME:
+}
--- /dev/null
+/* 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_dijkstra.hpp"
+#include "surf_routing_private.h"
+#include "network.hpp"
+
+/* Global vars */
+extern routing_platf_t routing_platf;
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_dijkstra, surf, "Routing part of surf -- dijkstra routing logic");
+}
+
+AS_t model_dijkstra_create(void){
+ return new AsDijkstra(0);
+}
+
+AS_t model_dijkstracache_create(void){
+ return new AsDijkstra(1);
+}
+
+void model_dijkstra_both_end(AS_t as)
+{
+ delete as;
+}
+
+/* Free functions */
+
+static void route_cache_elem_free(void *e)
+{
+ route_cache_element_t elm = (route_cache_element_t) e;
+ if (elm) {
+ xbt_free(elm->pred_arr);
+ xbt_free(elm);
+ }
+}
+
+static void graph_node_map_elem_free(void *e)
+{
+ graph_node_map_element_t elm = (graph_node_map_element_t) e;
+ xbt_free(elm);
+}
+
+static void graph_edge_data_free(void *e) // FIXME: useless code duplication
+{
+ sg_platf_route_cbarg_t e_route = (sg_platf_route_cbarg_t) e;
+ if (e_route) {
+ xbt_dynar_free(&(e_route->link_list));
+ xbt_free(e_route);
+ }
+}
+
+/* Utility functions */
+
+xbt_node_t AsDijkstra::routeGraphNewNode(int id, int graph_id)
+{
+ xbt_node_t node = NULL;
+ graph_node_data_t data = NULL;
+ graph_node_map_element_t elm = NULL;
+
+ data = xbt_new0(struct graph_node_data, 1);
+ data->id = id;
+ data->graph_id = graph_id;
+ node = xbt_graph_new_node(p_routeGraph, data);
+
+ elm = xbt_new0(struct graph_node_map_element, 1);
+ elm->node = node;
+ xbt_dict_set_ext(p_graphNodeMap, (char *) (&id), sizeof(int),
+ (xbt_set_elm_t) elm, NULL);
+
+ return node;
+}
+
+graph_node_map_element_t AsDijkstra::nodeMapSearch(int id)
+{
+ graph_node_map_element_t elm = (graph_node_map_element_t)
+ xbt_dict_get_or_null_ext(p_graphNodeMap,
+ (char *) (&id),
+ sizeof(int));
+ return elm;
+}
+
+/* Parsing */
+
+void AsDijkstra::newRoute(int src_id, int dst_id, sg_platf_route_cbarg_t e_route)
+{
+ XBT_DEBUG("Load Route from \"%d\" to \"%d\"", src_id, dst_id);
+ xbt_node_t src = NULL;
+ xbt_node_t dst = NULL;
+
+ graph_node_map_element_t src_elm = (graph_node_map_element_t)
+ xbt_dict_get_or_null_ext(p_graphNodeMap,
+ (char *) (&src_id),
+ sizeof(int));
+ graph_node_map_element_t dst_elm = (graph_node_map_element_t)
+ xbt_dict_get_or_null_ext(p_graphNodeMap,
+ (char *) (&dst_id),
+ sizeof(int));
+
+
+ if (src_elm)
+ src = src_elm->node;
+
+ if (dst_elm)
+ dst = dst_elm->node;
+
+ /* add nodes if they don't exist in the graph */
+ if (src_id == dst_id && src == NULL && dst == NULL) {
+ src = this->routeGraphNewNode(src_id, -1);
+ dst = src;
+ } else {
+ if (src == NULL) {
+ src = this->routeGraphNewNode(src_id, -1);
+ }
+ if (dst == NULL) {
+ dst = this->routeGraphNewNode(dst_id, -1);
+ }
+ }
+
+ /* add link as edge to graph */
+ xbt_graph_new_edge(p_routeGraph, src, dst, e_route);
+}
+
+void AsDijkstra::addLoopback() {
+ xbt_dynar_t nodes = xbt_graph_get_nodes(p_routeGraph);
+
+ xbt_node_t node = NULL;
+ unsigned int cursor2;
+ xbt_dynar_foreach(nodes, cursor2, node) {
+ xbt_dynar_t out_edges = xbt_graph_node_get_outedges(node);
+ xbt_edge_t edge = NULL;
+ unsigned int cursor;
+
+ int found = 0;
+ xbt_dynar_foreach(out_edges, cursor, edge) {
+ xbt_node_t other_node = xbt_graph_edge_get_target(edge);
+ if (other_node == node) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ sg_platf_route_cbarg_t e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+ e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+ xbt_dynar_push(e_route->link_list, &routing_platf->p_loopback);
+ xbt_graph_new_edge(p_routeGraph, node, node, e_route);
+ }
+ }
+}
+
+xbt_dynar_t AsDijkstra::getOnelinkRoutes()
+{
+ xbt_dynar_t ret = xbt_dynar_new(sizeof(OnelinkPtr), xbt_free);
+ sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1);
+ route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
+
+ int src,dst;
+ RoutingEdgePtr src_elm, dst_elm;
+ size_t table_size = xbt_dynar_length(p_indexNetworkElm);
+ for(src=0; src < table_size; src++) {
+ for(dst=0; dst< table_size; dst++) {
+ xbt_dynar_reset(route->link_list);
+ src_elm = xbt_dynar_get_as(p_indexNetworkElm, src, RoutingEdgePtr);
+ dst_elm = xbt_dynar_get_as(p_indexNetworkElm, dst, RoutingEdgePtr);
+ this->getRouteAndLatency(src_elm, dst_elm,route, NULL);
+
+ if (xbt_dynar_length(route->link_list) == 1) {
+ void *link = *(void **) xbt_dynar_get_ptr(route->link_list, 0);
+ OnelinkPtr onelink = new Onelink();
+ onelink->p_linkPtr = link;
+ if (p_hierarchy == SURF_ROUTING_BASE) {
+ onelink->p_src = src_elm;
+ onelink->p_dst = dst_elm;
+ } else if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
+ onelink->p_src = route->gw_src;
+ onelink->p_dst = route->gw_dst;
+ }
+ xbt_dynar_push(ret, &onelink);
+ }
+ }
+ }
+ return ret;
+}
+
+void AsDijkstra::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat)
+{
+
+ /* set utils vars */
+
+ srcDstCheck(src, dst);
+ int *src_id = &(src->m_id);
+ int *dst_id = &(dst->m_id);
+
+ if (!src_id || !dst_id)
+ THROWF(arg_error,0,"No route from '%s' to '%s'",src->p_name,dst->p_name);
+
+ int *pred_arr = NULL;
+ int src_node_id = 0;
+ int dst_node_id = 0;
+ int *nodeid = NULL;
+ int v;
+ sg_platf_route_cbarg_t e_route;
+ int size = 0;
+ unsigned int cpt;
+ NetworkCm02LinkPtr link;
+ xbt_dynar_t links = NULL;
+ route_cache_element_t elm = NULL;
+ xbt_dynar_t nodes = xbt_graph_get_nodes(p_routeGraph);
+
+ /* Use the graph_node id mapping set to quickly find the nodes */
+ graph_node_map_element_t src_elm = nodeMapSearch(*src_id);
+ graph_node_map_element_t dst_elm = nodeMapSearch(*dst_id);
+
+ src_node_id = ((graph_node_data_t)
+ xbt_graph_node_get_data(src_elm->node))->graph_id;
+ dst_node_id = ((graph_node_data_t)
+ xbt_graph_node_get_data(dst_elm->node))->graph_id;
+
+ /* if the src and dst are the same */
+ if (src_node_id == dst_node_id) {
+
+ xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
+ xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
+ xbt_edge_t edge = xbt_graph_get_edge(p_routeGraph, node_s_v, node_e_v);
+
+ if (edge == NULL)
+ THROWF(arg_error, 0, "No route from '%s' to '%s'", src->p_name, dst->p_name);
+
+ e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
+
+ links = e_route->link_list;
+ xbt_dynar_foreach(links, cpt, link) {
+ xbt_dynar_unshift(route->link_list, &link);
+ if (lat)
+ *lat += link->getLatency();
+ }
+
+ }
+
+ if (m_cached) {
+ /*check if there is a cached predecessor list avail */
+ elm = (route_cache_element_t)
+ xbt_dict_get_or_null_ext(p_routeCache, (char *) (&src_id),
+ sizeof(int));
+ }
+
+ if (elm) { /* cached mode and cache hit */
+ pred_arr = elm->pred_arr;
+ } else { /* not cached mode or cache miss */
+ double *cost_arr = NULL;
+ xbt_heap_t pqueue = NULL;
+ int i = 0;
+
+ int nr_nodes = xbt_dynar_length(nodes);
+ cost_arr = xbt_new0(double, nr_nodes); /* link cost from src to other hosts */
+ pred_arr = xbt_new0(int, nr_nodes); /* predecessors in path from src */
+ pqueue = xbt_heap_new(nr_nodes, xbt_free);
+
+ /* initialize */
+ cost_arr[src_node_id] = 0.0;
+
+ for (i = 0; i < nr_nodes; i++) {
+ if (i != src_node_id) {
+ cost_arr[i] = DBL_MAX;
+ }
+
+ pred_arr[i] = 0;
+
+ /* initialize priority queue */
+ nodeid = xbt_new0(int, 1);
+ *nodeid = i;
+ xbt_heap_push(pqueue, nodeid, cost_arr[i]);
+
+ }
+
+ /* apply dijkstra using the indexes from the graph's node array */
+ while (xbt_heap_size(pqueue) > 0) {
+ int *v_id = (int *) xbt_heap_pop(pqueue);
+ xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
+ xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node);
+ xbt_edge_t edge = NULL;
+ unsigned int cursor;
+
+ xbt_dynar_foreach(out_edges, cursor, edge) {
+ xbt_node_t u_node = xbt_graph_edge_get_target(edge);
+ graph_node_data_t data = (graph_node_data_t) xbt_graph_node_get_data(u_node);
+ int u_id = data->graph_id;
+ sg_platf_route_cbarg_t tmp_e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
+ int cost_v_u = (tmp_e_route->link_list)->used; /* count of links, old model assume 1 */
+
+ if (cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
+ pred_arr[u_id] = *v_id;
+ cost_arr[u_id] = cost_v_u + cost_arr[*v_id];
+ nodeid = xbt_new0(int, 1);
+ *nodeid = u_id;
+ xbt_heap_push(pqueue, nodeid, cost_arr[u_id]);
+ }
+ }
+
+ /* free item popped from pqueue */
+ xbt_free(v_id);
+ }
+
+ xbt_free(cost_arr);
+ xbt_heap_free(pqueue);
+ }
+
+ /* compose route path with links */
+ RoutingEdgePtr gw_src = NULL, gw_dst, prev_gw_src, first_gw = NULL;
+ RoutingEdgePtr gw_dst_net_elm = NULL, prev_gw_src_net_elm = NULL;
+
+ for (v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
+ xbt_node_t node_pred_v =
+ xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
+ xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
+ xbt_edge_t edge =
+ xbt_graph_get_edge(p_routeGraph, node_pred_v, node_v);
+
+ if (edge == NULL)
+ THROWF(arg_error, 0, "No route from '%s' to '%s'", src->p_name, dst->p_name);
+
+ prev_gw_src = gw_src;
+
+ e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
+ gw_src = e_route->gw_src;
+ gw_dst = e_route->gw_dst;
+
+ if (v == dst_node_id)
+ first_gw = gw_dst;
+
+ if (p_hierarchy == SURF_ROUTING_RECURSIVE && v != dst_node_id
+ && strcmp(gw_dst->p_name, prev_gw_src->p_name)) {
+ xbt_dynar_t e_route_as_to_as=NULL;
+
+ routing_platf->getRouteAndLatency(gw_dst_net_elm, prev_gw_src_net_elm, &e_route_as_to_as, NULL);
+ if (edge == NULL)
+ THROWF(arg_error,0,"No route from '%s' to '%s'", src->p_name, dst->p_name);
+ links = e_route_as_to_as;
+ int pos = 0;
+ xbt_dynar_foreach(links, cpt, link) {
+ xbt_dynar_insert_at(route->link_list, pos, &link);
+ if (lat)
+ *lat += link->getLatency();
+ pos++;
+ }
+ }
+
+ links = e_route->link_list;
+ xbt_dynar_foreach(links, cpt, link) {
+ xbt_dynar_unshift(route->link_list, &link);
+ if (lat)
+ *lat += link->getLatency();
+ }
+ size++;
+ }
+
+ if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
+ route->gw_src = gw_src;
+ route->gw_dst = first_gw;
+ }
+
+ if (m_cached && elm == NULL) {
+ /* add to predecessor list of the current src-host to cache */
+ elm = xbt_new0(struct route_cache_element, 1);
+ elm->pred_arr = pred_arr;
+ elm->size = size;
+ xbt_dict_set_ext(p_routeCache, (char *) (&src_id), sizeof(int),
+ (xbt_set_elm_t) elm, NULL);
+ }
+
+ if (!m_cached)
+ xbt_free(pred_arr);
+}
+
+AsDijkstra::~AsDijkstra()
+{
+ xbt_graph_free_graph(p_routeGraph, &xbt_free,
+ &graph_edge_data_free, &xbt_free);
+ xbt_dict_free(&p_graphNodeMap);
+ if (m_cached)
+ xbt_dict_free(&p_routeCache);
+}
+
+/* Creation routing model functions */
+
+AsDijkstra::AsDijkstra() : AsGeneric(), m_cached(0) {}
+
+AsDijkstra::AsDijkstra(int cached) : AsGeneric(), m_cached(cached)
+{
+ /*new_component->generic_routing.parse_route = model_dijkstra_both_parse_route;
+ new_component->generic_routing.parse_ASroute = model_dijkstra_both_parse_route;
+ new_component->generic_routing.get_route_and_latency = dijkstra_get_route_and_latency;
+ new_component->generic_routing.get_onelink_routes =
+ dijkstra_get_onelink_routes;
+ new_component->generic_routing.get_graph = generic_get_graph;
+ new_component->generic_routing.finalize = dijkstra_finalize;
+ new_component->cached = cached;*/
+}
+
+void AsDijkstra::end()
+{
+ xbt_node_t node = NULL;
+ unsigned int cursor2;
+ xbt_dynar_t nodes = NULL;
+
+ /* Create the topology graph */
+ if(!p_routeGraph)
+ p_routeGraph = xbt_graph_new_graph(1, NULL);
+ if(!p_graphNodeMap)
+ p_graphNodeMap = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
+
+ if (m_cached && p_routeCache)
+ p_routeCache = xbt_dict_new_homogeneous(&route_cache_elem_free);
+
+ /* Add the loopback if needed */
+ if (routing_platf->p_loopback && p_hierarchy == SURF_ROUTING_BASE)
+ addLoopback();
+
+ /* initialize graph indexes in nodes after graph has been built */
+ nodes = xbt_graph_get_nodes(p_routeGraph);
+
+ xbt_dynar_foreach(nodes, cursor2, node) {
+ graph_node_data_t data = (graph_node_data_t) xbt_graph_node_get_data(node);
+ data->graph_id = cursor2;
+ }
+
+}
+void AsDijkstra::parseRoute(sg_platf_route_cbarg_t route)
+{
+ char *src = (char*)(route->src);
+ char *dst = (char*)(route->dst);
+
+ int as_route = 0;
+ if(!route->gw_dst && !route->gw_src)
+ XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
+ else{
+ XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
+ route->gw_src->p_name, dst, route->gw_dst->p_name);
+ as_route = 1;
+ if(route->gw_dst->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+ xbt_die("The gw_dst '%s' does not exist!",route->gw_dst->p_name);
+ if(route->gw_src->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+ xbt_die("The gw_src '%s' does not exist!",route->gw_src->p_name);
+ }
+
+ RoutingEdgePtr src_net_elm, dst_net_elm;
+
+ src_net_elm = sg_routing_edge_by_name_or_null(src);
+ dst_net_elm = sg_routing_edge_by_name_or_null(dst);
+
+ xbt_assert(src_net_elm, "Network elements %s not found", src);
+ xbt_assert(dst_net_elm, "Network elements %s not found", dst);
+
+ /* Create the topology graph */
+ if(!p_routeGraph)
+ p_routeGraph = xbt_graph_new_graph(1, NULL);
+ if(!p_graphNodeMap)
+ p_graphNodeMap = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
+
+ if (m_cached && !p_routeCache)
+ p_routeCache = xbt_dict_new_homogeneous(&route_cache_elem_free);
+
+ sg_platf_route_cbarg_t e_route = newExtendedRoute(p_hierarchy, route, 1);
+ newRoute(src_net_elm->m_id, dst_net_elm->m_id, e_route);
+
+ // Symmetrical YES
+ if ( (route->symmetrical == TRUE && as_route == 0)
+ || (route->symmetrical == TRUE && as_route == 1)
+ )
+ {
+ if(!route->gw_dst && !route->gw_src)
+ XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
+ else
+ XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
+ route->gw_dst->p_name, src, route->gw_src->p_name);
+
+ xbt_dynar_t nodes = xbt_graph_get_nodes(p_routeGraph);
+ xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_net_elm->m_id, xbt_node_t);
+ xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_net_elm->m_id, xbt_node_t);
+ xbt_edge_t edge =
+ xbt_graph_get_edge(p_routeGraph, node_e_v, node_s_v);
+
+ if (edge)
+ THROWF(arg_error,0,"(AS)Route from '%s' to '%s' already exists",src,dst);
+
+ if (route->gw_dst && route->gw_src) {
+ RoutingEdgePtr gw_tmp;
+ gw_tmp = route->gw_src;
+ route->gw_src = route->gw_dst;
+ route->gw_dst = gw_tmp;
+ }
+ sg_platf_route_cbarg_t link_route_back = newExtendedRoute(p_hierarchy, route, 0);
+ newRoute(dst_net_elm->m_id, src_net_elm->m_id, link_route_back);
+ }
+ xbt_dynar_free(&route->link_list);
+}
--- /dev/null
+#include "surf_routing_generic.hpp"
+
+#ifndef SURF_ROUTING_DIJKSTRA_HPP_
+#define SURF_ROUTING_DIJKSTRA_HPP_
+
+typedef struct graph_node_data {
+ int id;
+ int graph_id; /* used for caching internal graph id's */
+} s_graph_node_data_t, *graph_node_data_t;
+
+typedef struct graph_node_map_element {
+ xbt_node_t node;
+} s_graph_node_map_element_t, *graph_node_map_element_t;
+
+typedef struct route_cache_element {
+ int *pred_arr;
+ int size;
+} s_route_cache_element_t, *route_cache_element_t;
+
+class AsDijkstra : public AsGeneric {
+public:
+ AsDijkstra();
+ AsDijkstra(int cached);
+ ~AsDijkstra();
+ xbt_node_t routeGraphNewNode(int id, int graph_id);
+ graph_node_map_element_t nodeMapSearch(int id);
+ void newRoute(int src_id, int dst_id, sg_platf_route_cbarg_t e_route);
+ void addLoopback();
+ void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat);
+ xbt_dynar_t getOnelinkRoutes();
+ void getRouteAndLatency(sg_platf_route_cbarg_t route, double *lat);
+ void parseRoute(sg_platf_route_cbarg_t route);
+ void end();
+
+ xbt_graph_t p_routeGraph; /* xbt_graph */
+ xbt_dict_t p_graphNodeMap; /* map */
+ xbt_dict_t p_routeCache; /* use in cache mode */
+ int m_cached;
+};
+
+#endif /* SURF_ROUTING_DIJKSTRA_HPP_ */
--- /dev/null
+#include "surf_routing_private.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_floyd, surf, "Routing part of surf");
+}
+
+AS_t model_floyd_create(void)
+{//FIXME:
+}
+
+void model_floyd_end(AS_t current_routing)
+{
+//FIXME:
+}
--- /dev/null
+#include "surf_routing_private.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf");
+}
+
+AS_t model_full_create(void)
+{//FIXME:
+}
+
+void model_full_end(AS_t current_routing)
+{}
--- /dev/null
+/* 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 "simgrid/platf_interface.h" // platform creation API internal interface
+
+#include "surf_routing_generic.hpp"
+#include "network.hpp"
+#include "xbt/graph.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_routing_generic, surf_route, "Generic implementation of the surf routing");
+}
+
+static int no_bypassroute_declared = 1;
+
+void generic_free_route(sg_platf_route_cbarg_t route)
+{
+ if (route) {
+ xbt_dynar_free(&route->link_list);
+ xbt_free(route);
+ }
+}
+
+void AsGeneric::parseRoute(sg_platf_route_cbarg_t route){
+ THROW_IMPOSSIBLE;
+}
+
+void AsGeneric::parseASroute(sg_platf_route_cbarg_t route){
+ THROW_IMPOSSIBLE;
+}
+
+void AsGeneric::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency){
+ THROW_IMPOSSIBLE;
+}
+
+xbt_dynar_t AsGeneric::getOneLinkRoutes(){
+ THROW_IMPOSSIBLE;
+}
+
+AsGeneric::AsGeneric() {
+ p_bypassRoutes = xbt_dict_new_homogeneous((void (*)(void *)) generic_free_route);
+}
+
+AsGeneric::~AsGeneric() {
+ xbt_dict_free(&p_bypassRoutes);
+}
+
+int AsGeneric::parsePU(RoutingEdgePtr elm)
+{
+ XBT_DEBUG("Load process unit \"%s\"", elm->p_name);
+ xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+ return xbt_dynar_length(p_indexNetworkElm)-1;
+}
+
+int AsGeneric::parseAS(RoutingEdgePtr elm)
+{
+ XBT_DEBUG("Load Autonomous system \"%s\"", elm->p_name);
+ xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+ return xbt_dynar_length(p_indexNetworkElm)-1;
+}
+
+void AsGeneric::parseBypassroute(sg_platf_route_cbarg_t e_route)
+{
+ char *src = (char*)(e_route->src);
+ char *dst = (char*)(e_route->dst);
+
+ if(e_route->gw_dst)
+ XBT_DEBUG("Load bypassASroute from \"%s\" to \"%s\"", src, dst);
+ else
+ XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
+ xbt_dict_t dict_bypassRoutes = p_bypassRoutes;
+ char *route_name;
+
+ route_name = bprintf("%s#%s", src, dst);
+ xbt_assert(!xbt_dynar_is_empty(e_route->link_list),
+ "Invalid count of links, must be greater than zero (%s,%s)",
+ src, dst);
+ xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
+ "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
+ src, e_route->gw_src->p_name, dst, e_route->gw_dst->p_name);
+
+ sg_platf_route_cbarg_t new_e_route = NULL;
+ if(e_route->gw_dst)
+ new_e_route = newExtendedRoute(SURF_ROUTING_RECURSIVE, e_route, 1);
+ else
+ new_e_route = newExtendedRoute(SURF_ROUTING_BASE, e_route, 1);
+
+ xbt_dynar_free(&(e_route->link_list));
+
+ xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, NULL);
+ no_bypassroute_declared = 0;
+ xbt_free(route_name);
+}
+
+/* ************************************************************************** */
+/* *********************** GENERIC BUSINESS METHODS ************************* */
+
+xbt_dynar_t AsGeneric::getOnelinkRoutes() { // FIXME: kill that stub
+ xbt_die("\"generic_get_onelink_routes\" not implemented yet");
+ return NULL;
+}
+
+static const char *instr_node_name(xbt_node_t node)
+{
+ void *data = xbt_graph_node_get_data(node);
+ char *str = (char *) data;
+ return str;
+}
+
+xbt_node_t new_xbt_graph_node(xbt_graph_t graph, const char *name,
+ xbt_dict_t nodes)
+{
+ xbt_node_t ret = (xbt_node_t) xbt_dict_get_or_null(nodes, name);
+ if (ret)
+ return ret;
+
+ ret = xbt_graph_new_node(graph, xbt_strdup(name));
+ xbt_dict_set(nodes, name, ret, NULL);
+ return ret;
+}
+
+xbt_edge_t new_xbt_graph_edge(xbt_graph_t graph, xbt_node_t s, xbt_node_t d,
+ xbt_dict_t edges)
+{
+ xbt_edge_t ret;
+
+ const char *sn = instr_node_name(s);
+ const char *dn = instr_node_name(d);
+ int len = strlen(sn) + strlen(dn) + 1;
+ char *name = (char *) xbt_malloc(len * sizeof(char));
+
+
+ snprintf(name, len, "%s%s", sn, dn);
+ ret = (xbt_edge_t) xbt_dict_get_or_null(edges, name);
+ if (ret == NULL) {
+ snprintf(name, len, "%s%s", dn, sn);
+ ret = (xbt_edge_t) xbt_dict_get_or_null(edges, name);
+ }
+
+ if (ret == NULL) {
+ ret = xbt_graph_new_edge(graph, s, d, NULL);
+ xbt_dict_set(edges, name, ret, NULL);
+ }
+ free(name);
+ return ret;
+}
+
+void AsGeneric::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)
+{
+ int src, dst;
+ int table_size = xbt_dynar_length(p_indexNetworkElm);
+
+
+ for (src = 0; src < table_size; src++) {
+ RoutingEdgePtr my_src =
+ xbt_dynar_get_as(p_indexNetworkElm, src, RoutingEdgePtr);
+ for (dst = 0; dst < table_size; dst++) {
+ if (src == dst)
+ continue;
+ RoutingEdgePtr my_dst =
+ xbt_dynar_get_as(p_indexNetworkElm, dst, RoutingEdgePtr);
+
+ sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+ route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+
+ getRouteAndLatency(my_src, my_dst, route, NULL);
+
+ XBT_DEBUG ("get_route_and_latency %s -> %s", my_src->p_name, my_dst->p_name);
+
+ unsigned int cpt;
+ void *link;
+
+ xbt_node_t current, previous;
+ const char *previous_name, *current_name;
+
+ if (route->gw_src) {
+ previous = new_xbt_graph_node(graph, route->gw_src->p_name, nodes);
+ previous_name = route->gw_src->p_name;
+ } else {
+ previous = new_xbt_graph_node(graph, my_src->p_name, nodes);
+ previous_name = my_src->p_name;
+ }
+
+ xbt_dynar_foreach(route->link_list, cpt, link) {
+ const char *link_name = ((ResourcePtr) link)->m_name;
+ current = new_xbt_graph_node(graph, link_name, nodes);
+ current_name = link_name;
+ new_xbt_graph_edge(graph, previous, current, edges);
+ XBT_DEBUG (" %s -> %s", previous_name, current_name);
+ previous = current;
+ previous_name = current_name;
+ }
+
+ if (route->gw_dst) {
+ current = new_xbt_graph_node(graph, route->gw_dst->p_name, nodes);
+ current_name = route->gw_dst->p_name;
+ } else {
+ current = new_xbt_graph_node(graph, my_dst->p_name, nodes);
+ current_name = my_dst->p_name;
+ }
+ new_xbt_graph_edge(graph, previous, current, edges);
+ XBT_DEBUG (" %s -> %s", previous_name, current_name);
+
+ xbt_dynar_free (&(route->link_list));
+ xbt_free (route);
+ }
+ }
+}
+
+sg_platf_route_cbarg_t AsGeneric::getBypassRoute(RoutingEdgePtr src,
+ RoutingEdgePtr dst,
+ double *lat)
+{
+ // If never set a bypass route return NULL without any further computations
+ XBT_DEBUG("generic_get_bypassroute from %s to %s", src->p_name, dst->p_name);
+ if (no_bypassroute_declared)
+ return NULL;
+
+ sg_platf_route_cbarg_t e_route_bypass = NULL;
+ xbt_dict_t dict_bypassRoutes = p_bypassRoutes;
+
+ if(dst->p_rcComponent == this && src->p_rcComponent == this ){
+ char *route_name = bprintf("%s#%s", src->p_name, dst->p_name);
+ e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+ if(e_route_bypass)
+ XBT_DEBUG("Find bypass route with %ld links",xbt_dynar_length(e_route_bypass->link_list));
+ free(route_name);
+ }
+ else{
+ AsPtr src_as, dst_as;
+ int index_src, index_dst;
+ xbt_dynar_t path_src = NULL;
+ xbt_dynar_t path_dst = NULL;
+ AsPtr current = NULL;
+ AsPtr *current_src = NULL;
+ AsPtr *current_dst = NULL;
+
+ if (src == NULL || dst == NULL)
+ xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
+ src->p_name, dst->p_name, p_name);
+
+ src_as = src->p_rcComponent;
+ dst_as = dst->p_rcComponent;
+
+ /* (2) find the path to the root routing component */
+ path_src = xbt_dynar_new(sizeof(AsPtr), NULL);
+ current = src_as;
+ while (current != NULL) {
+ xbt_dynar_push(path_src, ¤t);
+ current = current->p_routingFather;
+ }
+ path_dst = xbt_dynar_new(sizeof(AsPtr), NULL);
+ current = dst_as;
+ while (current != NULL) {
+ xbt_dynar_push(path_dst, ¤t);
+ current = current->p_routingFather;
+ }
+
+ /* (3) find the common father */
+ index_src = path_src->used - 1;
+ index_dst = path_dst->used - 1;
+ current_src = (AsPtr *) xbt_dynar_get_ptr(path_src, index_src);
+ current_dst = (AsPtr *) xbt_dynar_get_ptr(path_dst, index_dst);
+ while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
+ xbt_dynar_pop_ptr(path_src);
+ xbt_dynar_pop_ptr(path_dst);
+ index_src--;
+ index_dst--;
+ current_src = (AsPtr *) xbt_dynar_get_ptr(path_src, index_src);
+ current_dst = (AsPtr *) xbt_dynar_get_ptr(path_dst, index_dst);
+ }
+
+ int max_index_src = path_src->used - 1;
+ int max_index_dst = path_dst->used - 1;
+
+ int max_index = max(max_index_src, max_index_dst);
+ int i, max;
+
+ for (max = 0; max <= max_index; max++) {
+ for (i = 0; i < max; i++) {
+ if (i <= max_index_src && max <= max_index_dst) {
+ char *route_name = bprintf("%s#%s",
+ (*(AsPtr *)
+ (xbt_dynar_get_ptr(path_src, i)))->p_name,
+ (*(AsPtr *)
+ (xbt_dynar_get_ptr(path_dst, max)))->p_name);
+ e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+ xbt_free(route_name);
+ }
+ if (e_route_bypass)
+ break;
+ if (max <= max_index_src && i <= max_index_dst) {
+ char *route_name = bprintf("%s#%s",
+ (*(AsPtr *)
+ (xbt_dynar_get_ptr(path_src, max)))->p_name,
+ (*(AsPtr *)
+ (xbt_dynar_get_ptr(path_dst, i)))->p_name);
+ e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+ xbt_free(route_name);
+ }
+ if (e_route_bypass)
+ break;
+ }
+
+ if (e_route_bypass)
+ break;
+
+ if (max <= max_index_src && max <= max_index_dst) {
+ char *route_name = bprintf("%s#%s",
+ (*(AsPtr *)
+ (xbt_dynar_get_ptr(path_src, max)))->p_name,
+ (*(AsPtr *)
+ (xbt_dynar_get_ptr(path_dst, max)))->p_name);
+ e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+ xbt_free(route_name);
+ }
+ if (e_route_bypass)
+ break;
+ }
+
+ xbt_dynar_free(&path_src);
+ xbt_dynar_free(&path_dst);
+ }
+
+ sg_platf_route_cbarg_t new_e_route = NULL;
+ if (e_route_bypass) {
+ NetworkCm02LinkPtr link;
+ unsigned int cpt = 0;
+ new_e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+ new_e_route->gw_src = e_route_bypass->gw_src;
+ new_e_route->gw_dst = e_route_bypass->gw_dst;
+ new_e_route->link_list =
+ xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+ xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
+ xbt_dynar_push(new_e_route->link_list, &link);
+ if (lat)
+ *lat += link->getLatency();
+ }
+ }
+
+ return new_e_route;
+}
+
+/* ************************************************************************** */
+/* ************************* GENERIC AUX FUNCTIONS ************************** */
+/* change a route containing link names into a route containing link entities */
+sg_platf_route_cbarg_t AsGeneric::newExtendedRoute(e_surf_routing_hierarchy_t hierarchy,
+ sg_platf_route_cbarg_t routearg, int change_order) {
+
+ sg_platf_route_cbarg_t result;
+ char *link_name;
+ unsigned int cpt;
+
+ result = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+ result->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+
+ xbt_assert(hierarchy == SURF_ROUTING_BASE
+ || hierarchy == SURF_ROUTING_RECURSIVE,
+ "The hierarchy of this AS is neither BASIC nor RECURSIVE, I'm lost here.");
+
+ if (hierarchy == SURF_ROUTING_RECURSIVE) {
+
+ xbt_assert(routearg->gw_src && routearg->gw_dst,
+ "NULL is obviously a bad gateway");
+
+ /* remeber not erase the gateway names */
+ result->gw_src = routearg->gw_src;
+ result->gw_dst = routearg->gw_dst;
+ }
+
+ xbt_dynar_foreach(routearg->link_list, cpt, link_name) {
+
+ void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
+ if (link) {
+ if (change_order)
+ xbt_dynar_push(result->link_list, &link);
+ else
+ xbt_dynar_unshift(result->link_list, &link);
+ } else
+ THROWF(mismatch_error, 0, "Link %s not found", link_name);
+ }
+
+ return result;
+}
+
+
+
+AsPtr AsGeneric::asExist(AsPtr to_find)
+{
+ //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
+ xbt_dict_cursor_t cursor = NULL;
+ char *key;
+ int found = 0;
+ AsGenericPtr elem;
+ xbt_dict_foreach(p_routingSons, cursor, key, elem) {
+ if (to_find == elem || elem->asExist(to_find)) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ return to_find;
+ return NULL;
+}
+
+AsPtr AsGeneric::autonomousSystemExist(char *element)
+{
+ //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
+ AsPtr element_as, result, elem;
+ xbt_dict_cursor_t cursor = NULL;
+ char *key;
+ element_as = ((RoutingEdgePtr)
+ xbt_lib_get_or_null(as_router_lib, element,
+ ROUTING_ASR_LEVEL))->p_rcComponent;
+ result = ((AsPtr) - 1);
+ if (element_as != this)
+ result = asExist(element_as);
+
+ int found = 0;
+ if (result) {
+ xbt_dict_foreach(element_as->p_routingSons, cursor, key, elem) {
+ found = !strcmp(elem->p_name, element);
+ if (found)
+ break;
+ }
+ if (found)
+ return element_as;
+ }
+ return NULL;
+}
+
+AsPtr AsGeneric::processingUnitsExist(char *element)
+{
+ AsPtr element_as;
+ element_as = ((RoutingEdgePtr)
+ xbt_lib_get_or_null(host_lib,
+ element, ROUTING_HOST_LEVEL))->p_rcComponent;
+ if (element_as == this)
+ return element_as;
+ return asExist(element_as);
+}
+
+void AsGeneric::srcDstCheck(RoutingEdgePtr src, RoutingEdgePtr dst)
+{
+
+ RoutingEdgePtr src_data = src;
+ RoutingEdgePtr dst_data = dst;
+
+ if (src_data == NULL || dst_data == NULL)
+ xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
+ src->p_name,
+ dst->p_name,
+ p_name);
+
+ AsPtr src_as =
+ (src_data)->p_rcComponent;
+ AsPtr dst_as =
+ (dst_data)->p_rcComponent;
+
+ if (src_as != dst_as)
+ xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
+ src->p_name, src_as->p_name,
+ dst->p_name, dst_as->p_name);
+
+ if (this != dst_as)
+ xbt_die
+ ("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",
+ src->p_name,
+ dst->p_name,
+ src_as->p_name,
+ dst_as->p_name,
+ p_name);
+}
--- /dev/null
+#include "surf_routing_none.hpp"
+
+#ifndef SURF_ROUTING_GENERIC_HPP_
+#define SURF_ROUTING_GENERIC_HPP_
+
+class AsGeneric;
+typedef AsGeneric *AsGenericPtr;
+
+class AsGeneric : public AsNone {
+public:
+ AsGeneric();
+ ~AsGeneric();
+ void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+ xbt_dynar_t getOneLinkRoutes();
+ void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+ sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+ void finalize();
+
+ /* The parser calls the following functions to inform the routing models
+ * that a new element is added to the AS currently built.
+ *
+ * Of course, only the routing model of this AS is informed, not every ones */
+ int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+ int parseAS( RoutingEdgePtr elm);
+ void parseRoute(sg_platf_route_cbarg_t route);
+ void parseASroute(sg_platf_route_cbarg_t route);
+ void parseBypassroute(sg_platf_route_cbarg_t e_route);
+
+ xbt_dynar_t getOnelinkRoutes();
+ sg_platf_route_cbarg_t getBypassroute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+ sg_platf_route_cbarg_t newExtendedRoute(e_surf_routing_hierarchy_t hierarchy, sg_platf_route_cbarg_t routearg, int change_order);
+ AsPtr asExist(AsPtr to_find);
+ AsPtr autonomousSystemExist(char *element);
+ AsPtr processingUnitsExist(char *element);
+ void srcDstCheck(RoutingEdgePtr src, RoutingEdgePtr dst);
+};
+
+#endif /* SURF_ROUTING_GENERIC_HPP_ */
#include "surf_routing_private.h"
+extern "C" {
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_none, surf, "Routing part of surf");
+}
static xbt_dynar_t none_get_onelink_routes(AS_t rc) {
return NULL;
--- /dev/null
+/* 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_none.hpp"
+#include "surf_routing_private.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_none, surf, "Routing part of surf");
+}
+
+AS_t model_none_create(void)
+{//FIXME:
+}
+
+xbt_dynar_t AsNone::getOneLinkRoutes() {
+ return NULL;
+}
+
+void AsNone::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst,
+ sg_platf_route_cbarg_t res, double *lat)
+{
+ *lat = 0.0;
+}
+
+void AsNone::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)
+{
+ XBT_INFO("No routing no graph");
+}
+
+sg_platf_route_cbarg_t AsNone::getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat) {
+ return NULL;
+}
+
+int AsNone::parsePU(RoutingEdgePtr elm) {
+ XBT_DEBUG("Load process unit \"%s\"", elm->p_name);
+ xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+ /* don't care about PUs */
+ return -1;
+}
+
+int AsNone::parseAS(RoutingEdgePtr elm) {
+ XBT_DEBUG("Load Autonomous system \"%s\"", elm->p_name);
+ xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+ /* even don't care about sub-ASes -- I'm as nihilist as an old punk*/
+ return -1;
+}
+
+void AsNone::parseRoute(sg_platf_route_cbarg_t route){
+ THROW_IMPOSSIBLE;
+}
+
+void AsNone::parseASroute(sg_platf_route_cbarg_t route){
+ THROW_IMPOSSIBLE;
+}
+void AsNone::parseBypassroute(sg_platf_route_cbarg_t e_route){
+ THROW_IMPOSSIBLE;
+}
+
+/* Creation routing model functions */
+AsNone::AsNone() {
+ p_routingSons = xbt_dict_new_homogeneous(NULL);
+ p_indexNetworkElm = xbt_dynar_new(sizeof(char*),NULL);
+}
+
+AsNone::~AsNone() {
+ xbt_dict_free(&p_routingSons);
+ xbt_dynar_free(&p_indexNetworkElm);
+ xbt_dynar_free(&p_linkUpDownList);
+}
+
--- /dev/null
+#include "surf_routing.hpp"
+
+#ifndef SURF_ROUTING_NONE_HPP_
+#define SURF_ROUTING_NONE_HPP_
+
+class AsNone : public As {
+public:
+ AsNone();
+ ~AsNone();
+ void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+ xbt_dynar_t getOneLinkRoutes();
+ void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+ sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+ void finalize();
+
+ /* The parser calls the following functions to inform the routing models
+ * that a new element is added to the AS currently built.
+ *
+ * Of course, only the routing model of this AS is informed, not every ones */
+ int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+ int parseAS( RoutingEdgePtr elm);
+ void parseRoute(sg_platf_route_cbarg_t route);
+ void parseASroute(sg_platf_route_cbarg_t route);
+ void parseBypassroute(sg_platf_route_cbarg_t e_route);
+};
+
+
+#endif /* SURF_ROUTING_NONE_HPP_ */
#include <float.h>
#include "internal_config.h"
-#include "surf_private.h"
+//#include "surf_private.h"
#include "xbt/dynar.h"
#include "xbt/str.h"
#include "xbt/config.h"
#include "xbt/graph.h"
#include "xbt/set.h"
#include "surf/surfxml_parse.h"
+#include "surf_routing.hpp"
/* ************************************************************************** */
/* ******************************* NO ROUTING ******************************* */
/* Only save the AS tree, and forward calls to child ASes */
-AS_t model_none_create(void);
-AS_t model_none_create_sized(size_t childsize);
-void model_none_finalize(AS_t as);
+AsPtr model_none_create(void);
+AsPtr model_none_create_sized(size_t childsize);
+void model_none_finalize(AsPtr as);
/* ************************************************************************** */
/* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
-AS_t model_generic_create_sized(size_t childsize);
-void model_generic_finalize(AS_t as);
+AsPtr model_generic_create_sized(size_t childsize);
+void model_generic_finalize(AsPtr as);
-int generic_parse_PU(AS_t rc, sg_routing_edge_t elm);
-int generic_parse_AS(AS_t rc, sg_routing_edge_t elm);
-void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route);
+int generic_parse_PU(AsPtr rc, RoutingEdgePtr elm);
+int generic_parse_AS(AsPtr rc, RoutingEdgePtr elm);
+void generic_parse_bypassroute(AsPtr rc, sg_platf_route_cbarg_t e_route);
/* ************************************************************************** */
/* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
-xbt_dynar_t generic_get_onelink_routes(AS_t rc);
-sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc,
- sg_routing_edge_t src,
- sg_routing_edge_t dst,
+xbt_dynar_t generic_get_onelink_routes(AsPtr rc);
+sg_platf_route_cbarg_t generic_get_bypassroute(AsPtr rc,
+ RoutingEdgePtr src,
+ RoutingEdgePtr dst,
double *lat);
/* ************************************************************************** */
* produced route */
sg_platf_route_cbarg_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
sg_platf_route_cbarg_t data, int preserve_order);
-AS_t
-generic_autonomous_system_exist(AS_t rc, char *element);
-AS_t
-generic_processing_units_exist(AS_t rc, char *element);
-void generic_src_dst_check(AS_t rc, sg_routing_edge_t src,
- sg_routing_edge_t dst);
+AsPtr
+generic_autonomous_system_exist(AsPtr rc, char *element);
+AsPtr
+generic_processing_units_exist(AsPtr rc, char *element);
+void generic_src_dst_check(AsPtr rc, RoutingEdgePtr src,
+ RoutingEdgePtr dst);
/* ************************************************************************** */
/* *************************** FLOYD ROUTING ******************************** */
-AS_t model_floyd_create(void); /* create structures for floyd routing model */
-void model_floyd_end(AS_t as); /* finalize the creation of floyd routing model */
-void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route);
+AsPtr model_floyd_create(void); /* create structures for floyd routing model */
+void model_floyd_end(AsPtr as); /* finalize the creation of floyd routing model */
+void model_floyd_parse_route(AsPtr rc, sg_platf_route_cbarg_t route);
/* ************************************************** */
/* ************** Cluster ROUTING **************** */
-typedef struct {
- s_as_t generic_routing;
- void *backbone;
- void *loopback;
- sg_routing_edge_t router;
-} s_as_cluster_t, *as_cluster_t;
+class AsCluster : public As {
+ void *p_backbone;
+ void *p_loopback;
+ RoutingEdgePtr router;
+};
-AS_t model_cluster_create(void); /* create structures for cluster routing model */
+AsPtr model_cluster_create(void); /* create structures for cluster routing model */
/* ************************************************** */
/* ************** Vivaldi ROUTING **************** */
-AS_t model_vivaldi_create(void); /* create structures for vivaldi routing model */
+AsPtr model_vivaldi_create(void); /* create structures for vivaldi routing model */
#define HOST_PEER(peername) bprintf("peer_%s", peername)
#define ROUTER_PEER(peername) bprintf("router_%s", peername)
#define LINK_PEER(peername) bprintf("link_%s", peername)
/* ************************************************************************** */
/* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
-AS_t model_dijkstra_both_create(int cached); /* create by calling dijkstra or dijkstracache */
-AS_t model_dijkstra_create(void); /* create structures for dijkstra routing model */
-AS_t model_dijkstracache_create(void); /* create structures for dijkstracache routing model */
-void model_dijkstra_both_end(AS_t as); /* finalize the creation of dijkstra routing model */
-void model_dijkstra_both_parse_route (AS_t rc, sg_platf_route_cbarg_t route);
+AsPtr model_dijkstra_both_create(int cached); /* create by calling dijkstra or dijkstracache */
+AsPtr model_dijkstra_create(void); /* create structures for dijkstra routing model */
+AsPtr model_dijkstracache_create(void); /* create structures for dijkstracache routing model */
+void model_dijkstra_both_end(AsPtr as); /* finalize the creation of dijkstra routing model */
+void model_dijkstra_both_parse_route (AsPtr rc, sg_platf_route_cbarg_t route);
/* ************************************************************************** */
/* *************************** FULL ROUTING ********************************* */
-AS_t model_full_create(void); /* create structures for full routing model */
-void model_full_end(AS_t as); /* finalize the creation of full routing model */
+AsPtr model_full_create(void); /* create structures for full routing model */
+void model_full_end(AsPtr as); /* finalize the creation of full routing model */
void model_full_set_route( /* Set the route and ASroute between src and dst */
- AS_t rc, sg_platf_route_cbarg_t route);
+ AsPtr rc, sg_platf_route_cbarg_t route);
/* ************************************************************************** */
/* ************************* GRAPH EXPORTING FUNCTIONS ********************** */
xbt_node_t new_xbt_graph_node (xbt_graph_t graph, const char *name, xbt_dict_t nodes);
--- /dev/null
+/* 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. */
+
+#ifndef _SURF_SURF_ROUTING_PRIVATE_H
+#define _SURF_SURF_ROUTING_PRIVATE_H
+
+#include <float.h>
+#include "internal_config.h"
+
+#include "surf.hpp"
+#include "xbt/dynar.h"
+#include "xbt/str.h"
+#include "xbt/config.h"
+#include "xbt/graph.h"
+#include "xbt/set.h"
+#include "surf/surfxml_parse.h"
+
+/* ************************************************************************** */
+/* ******************************* NO ROUTING ******************************* */
+/* Only save the AS tree, and forward calls to child ASes */
+AS_t model_none_create(void);
+AS_t model_none_create_sized(size_t childsize);
+void model_none_finalize(AS_t as);
+/* ************************************************************************** */
+/* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
+AS_t model_generic_create_sized(size_t childsize);
+void model_generic_finalize(AS_t as);
+
+int generic_parse_PU(AS_t rc, sg_routing_edge_t elm);
+int generic_parse_AS(AS_t rc, sg_routing_edge_t elm);
+void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route);
+
+/* ************************************************************************** */
+/* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
+
+xbt_dynar_t generic_get_onelink_routes(AS_t rc);
+sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc,
+ sg_routing_edge_t src,
+ sg_routing_edge_t dst,
+ double *lat);
+
+/* ************************************************************************** */
+/* ****************** GENERIC AUX FUNCTIONS (declarations) ****************** */
+
+/* change a route containing link names into a route containing link entities.
+ * If change_order is true, the links are put in reverse order in the
+ * produced route */
+sg_platf_route_cbarg_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
+ sg_platf_route_cbarg_t data, int preserve_order);
+AS_t
+generic_autonomous_system_exist(AS_t rc, char *element);
+AS_t
+generic_processing_units_exist(AS_t rc, char *element);
+void generic_src_dst_check(AS_t rc, sg_routing_edge_t src,
+ sg_routing_edge_t dst);
+
+/* ************************************************************************** */
+/* *************************** FLOYD ROUTING ******************************** */
+AS_t model_floyd_create(void); /* create structures for floyd routing model */
+void model_floyd_end(AS_t as); /* finalize the creation of floyd routing model */
+void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route);
+
+/* ************************************************** */
+/* ************** Cluster ROUTING **************** */
+class AsCluster : public As {
+public:
+ void *backbone;
+ void *loopback;
+ RoutingEdgePtr p_router;
+};
+typedef AsCluster *AsClusterPtr;
+//FIXME:remove} s_as_cluster_t, *as_cluster_t;
+
+AsPtr model_cluster_create(void); /* create structures for cluster routing model */
+
+/* ************************************************** */
+/* ************** Vivaldi ROUTING **************** */
+AS_t model_vivaldi_create(void); /* create structures for vivaldi routing model */
+#define HOST_PEER(peername) bprintf("peer_%s", peername)
+#define ROUTER_PEER(peername) bprintf("router_%s", peername)
+#define LINK_PEER(peername) bprintf("link_%s", peername)
+
+/* ************************************************************************** */
+/* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
+AS_t model_dijkstra_both_create(int cached); /* create by calling dijkstra or dijkstracache */
+AS_t model_dijkstra_create(void); /* create structures for dijkstra routing model */
+AS_t model_dijkstracache_create(void); /* create structures for dijkstracache routing model */
+void model_dijkstra_both_end(AS_t as); /* finalize the creation of dijkstra routing model */
+void model_dijkstra_both_parse_route (AS_t rc, sg_platf_route_cbarg_t route);
+
+/* ************************************************************************** */
+/* *************************** FULL ROUTING ********************************* */
+AS_t model_full_create(void); /* create structures for full routing model */
+void model_full_end(AS_t as); /* finalize the creation of full routing model */
+void model_full_set_route( /* Set the route and ASroute between src and dst */
+ AS_t rc, sg_platf_route_cbarg_t route);
+/* ************************************************************************** */
+/* ************************* GRAPH EXPORTING FUNCTIONS ********************** */
+xbt_node_t new_xbt_graph_node (xbt_graph_t graph, const char *name, xbt_dict_t nodes);
+xbt_edge_t new_xbt_graph_edge (xbt_graph_t graph, xbt_node_t s, xbt_node_t d, xbt_dict_t edges);
+
+
+#endif /* _SURF_SURF_ROUTING_PRIVATE_H */
--- /dev/null
+#include "surf_routing_private.h"
+
+extern "C" {
+ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_vivaldi, surf, "Routing part of surf");
+}
+
+
+AS_t model_vivaldi_create(void)
+{//FIXME:
+}
#include "xbt/dict.h"
#include "surf/surfxml_parse.h"
#include "surf/surf_private.h"
+#include "surf/random_mgr.h"
#include "simgrid/sg_config.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_parse, surf,
--- /dev/null
+#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
+
+/*********
+ * Model *
+ *********/
+
+void surf_workstation_model_init_current_default(void)
+{
+ surf_workstation_model = new WorkstationModel();
+ xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes"));
+ surf_cpu_model_init_Cas01();
+ surf_network_model_init_LegrandVelho();
+
+ xbt_dynar_push(model_list, &surf_workstation_model);
+ //FIXME: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();
+ xbt_dynar_push(model_list, &surf_workstation_model);
+ //FIXME:sg_platf_host_add_cb(workstation_new);
+}
+
+WorkstationModel::WorkstationModel() : Model("Workstation") {
+ //FIXME:xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes"));
+ //FIXME:surf_cpu_model_init_Cas01();
+ //FIXME:surf_network_model_init_LegrandVelho();
+
+ xbt_dynar_push(model_list, this);
+ //FIXME:sg_platf_host_add_cb(workstation_new);
+}
+
+
+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),
+ (CpuPtr)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, 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){
+ 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();
+}
+
+xbt_dict_t WorkstationCLM03::getProperties()
+{
+ return p_cpu->m_properties;
+}
+
+
+StoragePtr WorkstationCLM03::findStorageOnMountList(const char* storage)
+{
+ StoragePtr st = NULL;
+ s_mount_t mnt;
+ unsigned int cursor;
+
+ XBT_DEBUG("Search for storage name '%s' on '%s'",storage,m_name);
+ xbt_dynar_foreach(p_storage,cursor,mnt)
+ {
+ XBT_DEBUG("See '%s'",mnt.name);
+ if(!strcmp(storage,mnt.name)){
+ st = (StoragePtr)mnt.id;
+ break;
+ }
+ }
+ if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,m_name);
+ return st;
+}
+
+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) {
+ StoragePtr st = findStorageOnMountList(fd->storage);
+ XBT_DEBUG("CLOSE on disk '%s'",st->m_name);
+ return st->close(fd);
+}
+
+ActionPtr WorkstationCLM03::read(void* ptr, size_t size, surf_file_t fd) {
+ StoragePtr st = findStorageOnMountList(fd->storage);
+ XBT_DEBUG("READ on disk '%s'",st->m_name);
+ return st->read(ptr, size, fd);
+}
+
+ActionPtr WorkstationCLM03::write(const void* ptr, size_t size, surf_file_t fd) {
+ StoragePtr st = findStorageOnMountList(fd->storage);
+ XBT_DEBUG("WRITE on disk '%s'",st->m_name);
+ return st->write(ptr, size, fd);
+}
+
+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);
+ StoragePtr st = findStorageOnMountList(fd->storage);
+ /* 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);
+ free(fd->storage);
+ 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);
+}
+
+size_t WorkstationCLM03::getSize(surf_file_t fd){
+ return fd->size;
+}
+
+/**********
+ * Action *
+ **********/
--- /dev/null
+#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 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();
+ void parseInit(sg_platf_host_cbarg_t host);
+ WorkstationCLM03Ptr createResource(string name);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+
+ 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);
+};
+
+/************
+ * 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);
+
+ ActionPtr execute(double size);
+ ActionPtr sleep(double duration);
+ e_surf_resource_state_t getState();
+
+ int getCore();
+ double getSpeed(double load);
+ double getAvailableSpeed();
+
+ xbt_dict_t getProperties();
+
+ StoragePtr findStorageOnMountList(const char* storage);
+ 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);
+ 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);
+ 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): WorkstationCLM03(model, name, props, NULL, NULL, NULL){};
+};
+
+/**********
+ * 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
+/* 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);
+ routing_model_create(createLinkResource("__loopback__",
+ 498000000, NULL,
+ 0.000015, NULL,
+ SURF_RESOURCE_ON, NULL,
+ SURF_LINK_FATPIPE, NULL));
+
+ surf_network_model = new NetworkL07Model();
+}
+
+double WorkstationL07Model::shareResources(double now)
+{
+ void *_action;
+ WorkstationL07ActionLmmPtr action;
+
+ xbt_swag_t running_actions = surf_workstation_model->p_runningActionSet;
+ double min = this->shareResourcesMaxMin(running_actions,
+ xbt_swag_offset((*action),
+ p_variable),
+ ptask_maxmin_system,
+ bottleneck_solve);
+
+ xbt_swag_foreach(_action, running_actions) {
+ action = (WorkstationL07ActionLmmPtr) _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_t running_actions =
+ surf_workstation_model->p_runningActionSet;
+
+ xbt_swag_foreach_safe(_action, _next_action, running_actions) {
+ action = (WorkstationL07ActionLmmPtr) _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 (((WorkstationCLM03Ptr)constraint_id)->m_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;
+ LinkL07Ptr link;
+
+ routing_platf->getRouteAndLatency(((CpuL07Ptr)workstation_list[i])->p_info, ((CpuL07Ptr)workstation_list[j])->p_info, &route,&lat);
+ latency = MAX(latency, lat);
+
+ xbt_dynar_foreach(route, cpt, 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, ((CpuL07Ptr)workstation_list[i])->p_constraint,
+ action->p_variable, computation_amount[i]);
+
+ for (i = 0; i < workstation_nb; i++) {
+ for (j = 0; j < workstation_nb; j++) {
+ LinkL07Ptr link;
+ xbt_dynar_t route=NULL;
+ if (communication_amount[i * workstation_nb + j] == 0.0)
+ continue;
+
+ routing_platf->getRouteAndLatency(((CpuL07Ptr)workstation_list[i])->p_info, ((CpuL07Ptr)workstation_list[j])->p_info, &route,NULL);
+
+ xbt_dynar_foreach(route, cpt, 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 (surf_action_t) action;
+}
+
+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] = src;
+ workstation_list[1] = 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(((CpuL07Ptr)src)->p_info, ((CpuL07Ptr)dst)->p_info, &route,NULL);
+ return route;
+}
+
+WorkstationCLM03Ptr WorkstationL07Model::createCpuResource(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_info = (RoutingEdgePtr) xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
+ if(!(cpu->p_info)) xbt_die("Don't find ROUTING_HOST_LEVEL for '%s'",name);
+
+ 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, cpu);
+
+ cpu->m_stateCurrent = state_initial;
+ if (state_trace)
+ cpu->p_stateEvent =
+ tmgr_history_add_trace(history, state_trace, 0.0, 0, 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_WKS_LEVEL, cpu);
+
+ return cpu;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+WorkstationCLM03Ptr WorkstationL07Model::createLinkResource(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, 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, nw_link);
+ if (state_trace)
+ nw_link->p_stateEvent =
+ tmgr_history_add_trace(history, state_trace, 0.0, 0, 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, 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 = (CpuL07Ptr) surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
+
+ xbt_assert(host, "Host %s undefined", elm);
+ xbt_assert(trace, "Trace %s undefined", trace_name);
+
+ host->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, host);
+ }
+
+ xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
+ tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+ CpuL07Ptr host = (CpuL07Ptr) surf_workstation_resource_priv(surf_workstation_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, 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 = (LinkL07Ptr) 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, 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 = (LinkL07Ptr) 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, 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 = (LinkL07Ptr) 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, link);
+ }
+}
+
+/************
+ * Resource *
+ ************/
+
+CpuL07::CpuL07(WorkstationL07ModelPtr model, const char* name, xbt_dict_t props) : WorkstationCLM03Lmm(model, name, props) {
+
+}
+
+LinkL07::LinkL07(WorkstationL07ModelPtr model, const char* name, xbt_dict_t props) : WorkstationCLM03Lmm(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 CpuL07::getState()
+{
+ return p_stateCurrent;
+}
+
+double CpuL07::getSpeed(double load)
+{
+ return load * p_power.scale;
+}
+
+double CpuL07::getAvailableSpeed()
+{
+ return m_powerCurrent;
+}
+
+ActionPtr CpuL07::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] = this;
+ communication_amount[0] = 0.0;
+ computation_amount[0] = size;
+
+ return ((WorkstationL07ModelPtr)p_model)->executeParallelTask(1, workstation_list,
+ computation_amount,
+ communication_amount, -1);
+}
+
+ActionPtr CpuL07::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(((CpuL07Ptr) p_workstationList[i])->p_info, ((CpuL07Ptr)p_workstationList[j])->p_info, &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(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_cpu_init(sg_platf_host_cbarg_t host)
+{
+ ((WorkstationL07ModelPtr)surf_workstation_model)->createCpuResource(
+ host->id,
+ host->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);
+ ((WorkstationL07ModelPtr)surf_workstation_model)->createLinkResource(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);
+ ((WorkstationL07ModelPtr)surf_workstation_model)->createLinkResource(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 {
+ ((WorkstationL07ModelPtr)surf_workstation_model)->createLinkResource(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_define_callbacks()
+{
+ sg_platf_host_add_cb(ptask_parse_cpu_init);
+ sg_platf_link_add_cb(ptask_parse_link_init);
+ //FIXME: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();
+ new WorkstationL07Model();
+ xbt_dynar_push(model_list, &surf_workstation_model);
+}
--- /dev/null
+#include "workstation.hpp"
+
+#ifndef WORKSTATION_L07_HPP_
+#define WORKSTATION_L07_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class WorkstationL07Model;
+typedef WorkstationL07Model *WorkstationL07ModelPtr;
+
+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();
+ void parseInit(sg_platf_host_cbarg_t host);
+ WorkstationCLM03Ptr createCpuResource(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);
+ WorkstationCLM03Ptr createLinkResource(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);
+ double shareResources(double now);
+ void updateActionsState(double now, double delta);
+ void addTraces();
+
+ 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);
+};
+
+class NetworkL07Model : public NetworkCm02Model {
+public:
+ NetworkL07Model(): NetworkCm02Model() {};
+ xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst) {DIE_IMPOSSIBLE;};
+ ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate) {DIE_IMPOSSIBLE;};
+ void addTraces() {DIE_IMPOSSIBLE;};
+};
+
+/************
+ * Resource *
+ ************/
+
+class CpuL07 : public WorkstationCLM03Lmm {
+public:
+ CpuL07(WorkstationL07ModelPtr model, const char* name, xbt_dict_t properties);
+ bool isUsed();
+ 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);
+ ActionPtr sleep(double duration);
+
+ double m_powerCurrent;
+ RoutingEdgePtr p_info;
+};
+
+class LinkL07 : public WorkstationCLM03Lmm {
+public:
+ LinkL07(WorkstationL07ModelPtr 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): 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_ */
// Routers
xbt_lib_foreach(as_router_lib, cursor_src, key, value1) {
- if(((sg_routing_edge_t)xbt_lib_get_or_null(as_router_lib, key,
- ROUTING_ASR_LEVEL))->rc_type == SURF_NETWORK_ELEMENT_ROUTER)
+ if(surf_routing_edge_get_rc_type(xbt_lib_get_or_null(as_router_lib, key,
+ ROUTING_ASR_LEVEL)) == SURF_NETWORK_ELEMENT_ROUTER)
{
printf(" <router id=\"%s\"/>\n",key);
}
{
void *link = xbt_dynar_get_as(route,i,void *);
- char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+ char *link_name = xbt_strdup(surf_resource_name(link));
printf("<%s id=\"%s\"/>",link_ctn,link_name);
free(link_name);
}
{
void *link = xbt_dynar_get_as(route,i,void *);
- char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+ char *link_name = xbt_strdup(surf_resource_name(link));
printf("<%s id=\"%s\"/>",link_ctn,link_name);
free(link_name);
}
{
void *link = xbt_dynar_get_as(route,i,void *);
- char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+ char *link_name = xbt_strdup(surf_resource_name(link));
printf("<%s id=\"%s\"/>",link_ctn,link_name);
free(link_name);
}
{
void *link = xbt_dynar_get_as(route,i,void *);
- char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+ char *link_name = xbt_strdup(surf_resource_name(link));
printf("<%s id=\"%s\"/>",link_ctn,link_name);
free(link_name);
}
#endif
#include "xbt/sysdep.h"
-#include "surf/solver.h"
+#include "surf/maxmin.h"
#include "xbt/log.h"
#include "xbt/module.h"
#include <math.h>
#endif
-#include "surf/solver.h"
+#include "surf/maxmin.h"
#include "xbt/module.h"
#include "xbt/xbt_os_time.h"
#include "xbt/sysdep.h" /* time manipulation for benchmarking */
XBT_DEBUG("%s : %p", surf_resource_name(cpuB), cpuB);
/* Let's do something on it */
- actionA = surf_cpu_model->extension.cpu.execute(cpuA, 1000.0);
- actionB = surf_cpu_model->extension.cpu.execute(cpuB, 1000.0);
- actionC = surf_cpu_model->extension.cpu.sleep(cpuB, 7.32);
+ actionA = surf_cpu_execute(cpuA, 1000.0);
+ actionB = surf_cpu_execute(cpuB, 1000.0);
+ actionC = surf_cpu_sleep(cpuB, 7.32);
/* Use whatever calling style you want... */
- stateActionA = surf_cpu_model->action_state_get(actionA); /* When you know actionA model type */
- stateActionB = actionB->model_type->action_state_get(actionB); /* If you're unsure about it's model type */
- stateActionC = surf_cpu_model->action_state_get(actionC); /* When you know actionA model type */
+ stateActionA = surf_action_get_state(actionA); /* When you know actionA model type */
+ stateActionB = surf_action_get_state(actionB); /* If you're unsure about it's model type */
+ stateActionC = surf_action_get_state(actionC); /* When you know actionA model type */
/* And just look at the state of these tasks */
XBT_DEBUG("actionA : %p (%s)", actionA, string_action(stateActionA));
XBT_DEBUG("%s : %p", surf_resource_name(cardB), cardB);
/* Let's do something on it */
- surf_network_model->extension.network.communicate(cardA, cardB,
- 150.0, -1.0);
+ surf_network_model_communicate(surf_network_model, cardA, cardB, 150.0, -1.0);
surf_solve(-1.0); /* Takes traces into account. Returns 0.0 */
do {
XBT_DEBUG("Next Event : %g", now);
XBT_DEBUG("\t CPU actions");
while ((action =
- xbt_swag_extract(surf_cpu_model->states.failed_action_set))) {
+ xbt_swag_extract(surf_model_failed_action_set((surf_model_t)surf_cpu_model)))) {
XBT_DEBUG("\t * Failed : %p", action);
- action->model_type->action_unref(action);
+ surf_action_unref(action);
}
while ((action =
- xbt_swag_extract(surf_cpu_model->states.done_action_set))) {
+ xbt_swag_extract(surf_model_done_action_set((surf_model_t)surf_cpu_model)))) {
XBT_DEBUG("\t * Done : %p", action);
- action->model_type->action_unref(action);
+ surf_action_unref(action);
}
XBT_DEBUG("\t Network actions");
while ((action =
- xbt_swag_extract(surf_network_model->states.
- failed_action_set))) {
+ xbt_swag_extract(surf_model_failed_action_set((surf_model_t)surf_network_model)))) {
XBT_DEBUG("\t * Failed : %p", action);
- action->model_type->action_unref(action);
+ surf_action_unref(action);
}
while ((action =
- xbt_swag_extract(surf_network_model->states.
- done_action_set))) {
+ xbt_swag_extract(surf_model_done_action_set((surf_model_t)surf_network_model)))) {
XBT_DEBUG("\t * Done : %p", action);
- action->model_type->action_unref(action);
+ surf_action_unref(action);
}
- } while ((xbt_swag_size(surf_network_model->states.running_action_set) ||
- xbt_swag_size(surf_cpu_model->states.running_action_set)) &&
+ } while ((xbt_swag_size(surf_model_running_action_set((surf_model_t)surf_network_model)) ||
+ xbt_swag_size(surf_model_running_action_set((surf_model_t)surf_cpu_model))) &&
surf_solve(-1.0) >= 0.0);
XBT_DEBUG("Simulation Terminated");
XBT_DEBUG("%s : %p", surf_resource_name(workstationB), workstationB);
/* Let's do something on it */
- surf_workstation_model->extension.workstation.execute(workstationA, 1000.0);
- surf_workstation_model->extension.workstation.execute(workstationB, 1000.0);
- surf_workstation_model->extension.workstation.sleep(workstationB, 7.32);
+ surf_workstation_execute(workstationA, 1000.0);
+ surf_workstation_execute(workstationB, 1000.0);
+ surf_workstation_sleep(workstationB, 7.32);
- surf_workstation_model->extension.workstation.
- communicate(workstationA, workstationB, 150.0, -1.0);
+ surf_workstation_model_communicate(surf_workstation_model, workstationA, workstationB, 150.0, -1.0);
surf_solve(-1.0); /* Takes traces into account. Returns 0.0 */
do {
XBT_DEBUG("Next Event : %g", now);
xbt_dynar_foreach(model_list, iter, model) {
- XBT_DEBUG("\t %s actions", model->name);
- while ((action = xbt_swag_extract(model->states.failed_action_set))) {
+ XBT_DEBUG("\t %s actions", surf_model_name(model));
+ while ((action = xbt_swag_extract(surf_model_failed_action_set((surf_model_t)model)))) {
XBT_DEBUG("\t * Failed : %p", action);
- model->action_unref(action);
+ surf_action_unref(action);
}
- while ((action = xbt_swag_extract(model->states.done_action_set))) {
+ while ((action = xbt_swag_extract(surf_model_done_action_set((surf_model_t)model)))) {
XBT_DEBUG("\t * Done : %p", action);
- model->action_unref(action);
+ surf_action_unref(action);
}
- if (xbt_swag_size(model->states.running_action_set)) {
- XBT_DEBUG("running %s", model->name);
+ if (xbt_swag_size(surf_model_running_action_set((surf_model_t)model))) {
+ XBT_DEBUG("running %s", surf_model_name(model));
running = 1;
}
}