/* slave name */
slavename = argv[2];
id = atoi(argv[3]);
- sprintf(id_alias, "%d", id);
+ sprintf(id_alias, "flow_%d", id);
slavenames[id] = slavename;
-
- TRACE_category (slavename);
+ TRACE_category (id_alias);
masternames[id] = MSG_host_get_name(MSG_host_self());
{ /* Task creation. */
char sprintf_buffer[64] = "Task_0";
todo = MSG_task_create(sprintf_buffer, 0, task_comm_size, NULL);
- TRACE_msg_set_task_category(todo,slavename);
+ TRACE_msg_set_task_category(todo,id_alias);
//keep track of running tasks
gl_task_array[id] = todo;
gl_data_size[id] = task_comm_size;
}
/* time measurement */
+ sprintf(id_alias, "%d", id);
start_time = MSG_get_clock();
MSG_task_send(todo, id_alias);
end_time = MSG_get_clock();
m_task_t task = NULL;
int a;
int id = 0;
+ int limited_latency=0;
double remaining = 0;
char id_alias[10];
for (id = 0; id < NTASKS; id++) {
if (gl_task_array[id] == NULL) {
} else if (gl_task_array[id] == task) {
- INFO5
+ limited_latency = MSG_task_is_latency_bounded(gl_task_array[id]);
+ if(limited_latency){
+ INFO1("WARNING FLOW[%d] is limited by latency!!", id);
+ }
+ INFO5
("===> Estimated Bw of FLOW[%d] : %f ; message from %s to %s with remaining : %f",
id, gl_data_size[id] / elapsed_time, masternames[id],
slavenames[id], 0.0);
} else {
remaining = MSG_task_get_remaining_communication(gl_task_array[id]);
+ limited_latency = MSG_task_is_latency_bounded(gl_task_array[id]);
+
+ if(limited_latency){
+ INFO1("WARNING FLOW[%d] is limited by latency!!", id);
+ }
INFO5
("===> Estimated Bw of FLOW[%d] : %f ; message from %s to %s with remaining : %f",
id, (gl_data_size[id] - remaining) / elapsed_time, masternames[id],
slavenames[id], remaining);
}
+
}
+ TRACE_mark ("endmark", "finished");
}
MSG_task_destroy(task);
//setting the variable "is_master" (previously declared) to value 1
TRACE_host_variable_set ("is_master", 1);
+ TRACE_mark ("msmark", "start_send_tasks");
int i;
for (i = 0; i < number_of_tasks; i++) {
m_task_t task=NULL;
TRACE_msg_set_task_category (task, "compute");
MSG_task_send(task, "master_mailbox");
}
+ TRACE_mark ("msmark", "finish_send_tasks");
for (i = 0; i < slaves_count; i++) {
m_task_t finalize = MSG_task_create ("finalize", 0, 0, 0);
TRACE_host_variable_declare ("task_creation");
TRACE_host_variable_declare ("task_computation");
+ //declaring user markers
+ TRACE_declare_mark ("msmark");
+
//declaring user categories
TRACE_category ("compute");
TRACE_category ("finalize");
XBT_PUBLIC(double) MSG_task_get_compute_duration(m_task_t task);
XBT_PUBLIC(double) MSG_task_get_remaining_computation(m_task_t task);
XBT_PUBLIC(double) MSG_task_get_remaining_communication(m_task_t task);
+XBT_PUBLIC(int) MSG_task_is_latency_bounded(m_task_t task);
XBT_PUBLIC(double) MSG_task_get_data_size(m_task_t task);
XBT_PUBLIC(double) SIMIX_action_get_remains(smx_action_t action);
+XBT_PUBLIC(int) SIMIX_action_is_latency_bounded(smx_action_t action);
XBT_PUBLIC(e_surf_action_state_t) SIMIX_action_get_state(smx_action_t action);
XBT_INLINE XBT_PUBLIC(void) SIMIX_communication_cancel(smx_comm_t comm);
XBT_PUBLIC(void) SIMIX_communication_destroy(smx_comm_t comm);
XBT_PUBLIC(double) SIMIX_communication_get_remains(smx_comm_t comm);
+XBT_PUBLIC(int) SIMIX_communication_is_latency_bounded(smx_comm_t comm);
XBT_PUBLIC(void *) SIMIX_communication_get_data(smx_comm_t comm);
XBT_PUBLIC(void *) SIMIX_communication_get_src_buf(smx_comm_t comm);
lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t sys,
lmm_constraint_t cnst);
+ XBT_PUBLIC(int) lmm_is_variable_limited_by_latency(lmm_variable_t var);
+
void *lmm_constraint_id(lmm_constraint_t cnst);
void *lmm_variable_id(lmm_variable_t var);
the task is completed) */
double remains; /**< How much of that cost remains to
* be done in the currently running task */
+ int latency_limited; /**< Set to 1 if is limited by latency, 0 otherwise */
+
double start; /**< start time */
double finish; /**< finish time : this is modified during the run
* and fluctuates until the task is completed */
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 */
double (*get_remains) (surf_action_t action);/**< Get the remains of an action */
+ int (*get_latency_limited) (surf_action_t action);/**< Return 1 if action is limited by latency, 0 otherwise */
xbt_dict_t resource_set;
/* 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 "instr/private.h"
-
+#include "simgrid_config.h"
#ifdef HAVE_TRACING
+#include "instr/private.h"
+
XBT_LOG_NEW_DEFAULT_CATEGORY(tracing,"Tracing Interface");
static xbt_dict_t defined_types;
* <em>message size</em> and some <em>private data</em>.
*/
+#ifdef HAVE_RUBY /* FIXME: KILLME */
+XBT_LOG_EXTERNAL_CATEGORY(ruby);
+#endif
+
+
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_task, msg,
+ "Logging specific to MSG (task)");
+
/********************************* Task **************************************/
/** \ingroup m_task_management
* \brief Creates a new #m_task_t.
}
}
-
-
/** \ingroup m_task_management
* \brief Returns the total amount received by a task #m_task_t.
*
{
xbt_assert0((task != NULL)
&& (task->simdata != NULL), "Invalid parameter");
-
+ DEBUG1("calling SIMIX_communication_get_remains(%p)", task->simdata->comm);
return SIMIX_communication_get_remains(task->simdata->comm);
}
+/** \ingroup m_task_management
+ * \brief Return 1 if communication task is limited by latency, 0 otherwise
+ *
+ */
+int MSG_task_is_latency_bounded(m_task_t task)
+{
+ xbt_assert0((task != NULL)
+ && (task->simdata != NULL), "Invalid parameter");
+ DEBUG1("calling SIMIX_communication_is_latency_bounded(%p)", task->simdata->comm);
+ return SIMIX_communication_is_latency_bounded(task->simdata->comm);
+}
+
/** \ingroup m_task_management
* \brief Returns the size of the data attached to a task #m_task_t.
*
return surf_workstation_model->get_remains(action->surf_action);
}
+XBT_INLINE int SIMIX_action_is_latency_bounded(smx_action_t action)
+{
+ xbt_assert0((action != NULL), "Invalid parameter");
+ return surf_workstation_model->get_latency_limited(action->surf_action);
+}
+
smx_action_t SIMIX_action_parallel_execute(char *name, int host_nb,
smx_host_t * host_list,
double *computation_amount,
/* Pimple to get an histogram of message sizes in the simulation */
xbt_dict_t msg_sizes = NULL;
+xbt_dict_t latency_limited_dict = NULL;
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_network, simix,
"Logging specific to SIMIX (network)");
void SIMIX_communication_destroy(smx_comm_t comm)
{
VERB2("Destroy communication %p; refcount initially %d",comm,comm->refcount);
+
+ //save is latency limited flag to use afterwards
+ if (latency_limited_dict == NULL)
+ latency_limited_dict = xbt_dict_new();
+ DEBUG2("adding key %p with latency limited value %d to the dict", comm, SIMIX_action_is_latency_bounded(comm->act));
+ xbt_dicti_set(latency_limited_dict, comm, SIMIX_action_is_latency_bounded(comm->act));
+
comm->refcount--;
if(comm->refcount > 0)
return;
comm->dst_timeout = NULL;
}
+
+
xbt_free(comm);
}
if (!SIMIX_host_get_state(SIMIX_host_self())){
if(comm->rdv)
SIMIX_rdv_remove(comm->rdv, comm);
- SIMIX_communication_destroy(comm);
+ SIMIX_communication_destroy(comm);
THROW0(host_error, 0, "Host failed");
} else if (SIMIX_action_get_state(comm->act) == SURF_ACTION_FAILED){
SIMIX_communication_destroy(comm);
*/
XBT_INLINE double SIMIX_communication_get_remains(smx_comm_t comm)
{
+ DEBUG1("calling SIMIX_action_get_remains(%p)", comm->act);
return SIMIX_action_get_remains(comm->act);
}
+/**
+ * \brief verify if communication is latency bounded
+ * \param comm The communication
+ */
+XBT_INLINE int SIMIX_communication_is_latency_bounded(smx_comm_t comm)
+{
+ //try to find comm on the list of finished flows
+ uintptr_t key = 0;
+ uintptr_t data = 0;
+ xbt_dict_cursor_t cursor;
+ xbt_dict_foreach(latency_limited_dict,cursor,key,data) {
+ DEBUG2("comparing key=%p with comm=%p", key, comm);
+ if(comm == key){
+ DEBUG2("key %p found, return value latency limited value %d", key, data);
+ return (int)data;
+ }
+ }
+
+ DEBUG1("calling SIMIX_action_is_latency_bounded(%p)", comm->act);
+ return SIMIX_action_is_latency_bounded(comm->act);
+}
+
/******************************************************************************/
/* SIMIX_network_copy_data callbacks */
/******************************************************************************/
// initialize the GTNetS interface and environment
-int gtnets_initialize(){
-
+int gtnets_initialize(int wsize){
DEBUG0("Using logging.");
-
xbt_assert0(!gtnets_sim, "gtnets already initialized");
- gtnets_sim = new GTSim();
+ if(wsize > 0){
+ INFO1("TCP window maximum size : %d", wsize);
+ gtnets_sim = new GTSim(wsize);
+ }else{
+ gtnets_sim = new GTSim(wsize);
+ }
+
return 0;
}
}
// run until a flow completes (returns that flow's metadata)
-int gtnets_run_until_next_flow_completion(void ***metadata, int *number_of_flows){
+double gtnets_run_until_next_flow_completion(void ***metadata, int *number_of_flows){
ofstream file;
streambuf* sbuf;
double value;
cout.rdbuf(sbuf);
file.close();
}
- return value;
+ return (double) value;
}
// get the total received in bytes using the TCPServer object totRx field
extern "C" {
#endif
- int gtnets_initialize();
+ int gtnets_initialize(int wsize);
int gtnets_add_link(int id, double bandwidth, double latency);
int gtnets_add_route(int src, int dst, int *links, int nlink);
int gtnets_add_router(int id);
int gtnets_add_onehop_route(int src, int dst, int link);
int gtnets_create_flow(int src, int dst, long datasize, void *metadata);
double gtnets_get_time_to_next_flow_completion();
- int gtnets_run_until_next_flow_completion(void ***metadata,
+ double gtnets_run_until_next_flow_completion(void ***metadata,
int *number_of_flows);
double gtnets_get_flow_rx(void *metadata);
void static tcp_sent_callback(void* action, double completion_time);
+
+// Constructor.
+// TODO: check the default values.
+GTSim::GTSim(int WindowSize){
+ int wsize = WindowSize;
+ is_topology_ = 0;
+ nflow_ = 0;
+ jitter_ = 0;
+ jitter_seed_ = 10;
+
+ // EXTRACTED FROM GTNETS SOURCE CODE COMMENTS
+ // REDQueue::REDQueue(
+ // DCount_t in_w_q, Count_t in_min_th, Count_t in_max_th,
+ // Count_t in_limit, DCount_t in_max_p, Count_t in_mean_pktsize) : iface(nil)
+ // Set default values.
+ //Doc:Desc This constructor the critical RED parameters and builds a
+ //Doc:Desc correspoding RED queue
+ //Doc:Arg1 weight of the queue
+ //Doc:Arg2 minimum threshold
+ //Doc:Arg3 maximum threshold
+ //Doc:Arg4 Limit/max size for the queue
+ //Doc:Arg5 maximum value for mark/drop probability
+ //Doc:Arg6 Average packet size
+
+ //Default Parameters
+ //REDQueue *default_red_queue_ = new REDQueue(0.002, 2500, 7500, 30000, 0.10, 500);
+ //Same as above
+ //REDQueue *default_red_queue_ = new REDQueue();
+
+ //See for details of how those values are calucated below
+ //[1] Sally Floyd and Van Jacobson, "Random Early Detection Gateways with Congestion Avoidance",
+ // IEEE/ACM Transactions on Networking, vol. 1, n. 4, august 1993.
+ //
+ //[2] Kostas Pentikousis, "Active Queue Management", ACM Crossroads, vol. 7, n. 5,
+ // mid-summer 2001
+ //
+ //[3] Stefann De Cnodder, Omar Ecoumi, Kenny Paulwels, "RED behavior with different packet sizes",
+ // 5th IEEE Symposium on Computers and Communication, (ISCC 2000)
+ //
+ //[4] http://www.opalsoft.net/qos/DS-26.htm
+ //
+ //short explanation:
+ // q_weight = fixed to 0.002 in most literature
+ // min_bytes = max / 3 = 16,666,666
+ // max_bytes = mean_bw * max_tolerable_latency, set to 1e8 * 0.5 = 50,000,000
+ // limit_bytes = 8 * max = 400,000,000
+ // prob = follow most literature 0.02
+ // avgpkt = fixed to the same TCP segment size, 1000 Bytes
+ //
+ // burst = (2*(min+max))/(3*avgpkt) ***DON'T USED BY GTNetS***
+ REDQueue *default_red_queue_ = new REDQueue(0.002, 16666666, 50000000, 400000000, 0.02, 1000);
+
+ Queue::Default(*default_red_queue_);
+ delete default_red_queue_;
+
+ cout << "Set default window size to " << wsize << endl;
+ TCP::DefaultAdvWin(wsize);
+ TCP::DefaultSegSize(1000);
+ TCP::DefaultTxBuffer(128000);
+ TCP::DefaultRxBuffer(128000);
+
+ sim_ = new Simulator();
+ sim_->verbose=false;
+ topo_ = new GTNETS_Topology();
+
+ // Manual routing
+ rm_ = new RoutingManual();
+ Routing::SetRouting(rm_);
+}
+
// Constructor.
// TODO: check the default values.
GTSim::GTSim(){
public:
GTSim();
+ GTSim(int WindowSize);
~GTSim();
public:
int add_link(int id, double bandwidth, double latency);
return xbt_swag_getNext(cnst, (sys->active_constraint_set).offset);
}
+XBT_INLINE int lmm_is_variable_limited_by_latency(lmm_variable_t var)
+{
+ return (double_equals(var->bound, var->value));
+}
+
+
/** \brief Update the constraint set propagating recursively to
* other constraints so the system should not be entirely computed.
*
double sg_weight_S_parameter = 0.0;/* default value; can be set by model or from command line */
double sg_tcp_gamma = 0.0;
+int sg_network_fullduplex = 1;
/******************************************************************************/
return;
}
+static int net_get_link_latency(surf_action_t action)
+{
+ return action->latency_limited;
+}
+
static double net_action_get_remains(surf_action_t action)
{
return action->remains;
#define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + xbt_swag_offset(s_action, variable) )))
xbt_swag_foreach(action, running_actions) {
+ if( lmm_is_variable_limited_by_latency(action->variable) ){
+ (action->generic_action).latency_limited = 1;
+ }else{
+ (action->generic_action).latency_limited = 0;
+ }
if (action->latency > 0) {
if (min < 0)
min = action->latency;
if (action->rate < 0)
lmm_update_variable_bound(network_maxmin_system, action->variable,
sg_tcp_gamma / (2.0 * action->lat_current));
- else
+ else{
lmm_update_variable_bound(network_maxmin_system, action->variable,
min(action->rate,
sg_tcp_gamma / (2.0 *
action->lat_current)));
+
+ if(action->rate < sg_tcp_gamma / (2.0 * action->lat_current) ){
+ INFO0("Flow is limited BYBANDWIDTH");
+ }else{
+ INFO1("Flow is limited BYLATENCY, latency of flow is %f",action->lat_current);
+ }
+ }
if (!(action->suspended))
lmm_update_variable_weight(network_maxmin_system, action->variable,
action->weight);
return;
}
+
static surf_action_t net_communicate(const char *src_name, const char *dst_name,
int src, int dst, double size, double rate)
{
Add a link_CM02_t *link and a int link_nb to network_card_CM02_t. It will represent local links for this node
Use the cluster_id for ->id */
xbt_dynar_t route = used_routing->get_route(src, dst);
+ xbt_dynar_t back_route = NULL;
+ int constraints_per_variable = 0;
+
+ if( sg_network_fullduplex == 1){
+ back_route = used_routing->get_route(dst, src);
+ }
+
/* LARGE PLATFORMS HACK:
total_route_size = route_size + src->link_nb + dst->nb */
action =
surf_action_new(sizeof(s_surf_action_network_CM02_t), size,
surf_network_model, failed);
+ (action->generic_action).latency_limited = 0;
xbt_swag_insert(action, action->generic_action.state_set);
action->rate = rate;
/* LARGE PLATFORMS HACK:
lmm_variable_new(..., total_route_size) */
+ if(back_route != NULL){
+ constraints_per_variable = xbt_dynar_length(route)+xbt_dynar_length(back_route);
+ }else{
+ constraints_per_variable = xbt_dynar_length(route);
+ }
+
if (action->latency > 0)
action->variable =
- lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,
- xbt_dynar_length(route));
+ lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,constraints_per_variable);
else
action->variable =
- lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,
- xbt_dynar_length(route));
+ lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,constraints_per_variable);
if (action->rate < 0) {
if (action->lat_current > 0)
lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
action->variable, 1.0);
}
- /* LARGE PLATFORMS HACK:
+
+ if( sg_network_fullduplex == 1){
+ DEBUG1("Fullduplex active adding backward flow using 5%c", '%');
+ xbt_dynar_foreach(back_route, i, link) {
+ lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
+ action->variable, .05);
+ }
+ } /* LARGE PLATFORMS HACK:
expand also with src->link and dst->link */
/* saving the src and dst of this communication */
return lmm->power.peak * lmm->power.scale;
}
-static double net_get_link_latency(const void *link)
-{
- return ((link_CM02_t) link)->lat_current;
-}
-
static int net_link_shared(const void *link)
{
return lmm_constraint_is_shared(((surf_resource_lmm_t) link)->constraint);
surf_network_model->action_cancel = net_action_cancel;
surf_network_model->action_recycle = net_action_recycle;
surf_network_model->get_remains = net_action_get_remains;
+ surf_network_model->get_latency_limited = net_get_link_latency;
surf_network_model->model_private->resource_used = net_resource_used;
surf_network_model->model_private->share_resources = net_share_resources;
surf_network_model->extension.network.communicate = net_communicate;
surf_network_model->extension.network.get_link_bandwidth =
net_get_link_bandwidth;
- surf_network_model->extension.network.get_link_latency = net_get_link_latency;
surf_network_model->extension.network.link_shared = net_link_shared;
surf_network_model->extension.network.create_resource = network_create_resource;
surf_network_model->extension.network.add_traces = net_add_traces;
{
static int link_count = -1;
network_link_GTNETS_t gtnets_link;
+ int tmp_idsrc=-1;
+ int tmp_iddst=-1;
+ char *name_friend;
+ char *name_normal;
if (xbt_dict_get_or_null(surf_network_model->resource_set, name)) {
return;
}
+ DEBUG1("Scanning link name %s", name);
+ sscanf(name, "%d_%d", &tmp_idsrc, &tmp_iddst);
+ DEBUG2("Link name split into %d and %d", tmp_idsrc, tmp_iddst);
+
+ xbt_assert0( (tmp_idsrc!=-1)&&(tmp_idsrc!=-1), "You need to respect fullduplex convention x_y for xml link id.");
+
+ name_normal = (char *)calloc(strlen(name), sizeof(char));
+ name_friend = (char *)calloc(strlen(name), sizeof(char));
+
+ if(tmp_idsrc < tmp_iddst){
+ sprintf(name_normal, "%d_%d", tmp_idsrc, tmp_iddst);
+ sprintf(name_friend, "%d_%d", tmp_iddst, tmp_idsrc);
+ }else{
+ sprintf(name_normal, "%d_%d", tmp_iddst, tmp_idsrc);
+ sprintf(name_friend, "%d_%d", tmp_idsrc, tmp_iddst);
+ }
+
+ gtnets_link = xbt_dict_get_or_null(surf_network_model->resource_set, name_normal);
+
+ if (gtnets_link) {
+ DEBUG3("Link already added as friend normal=%s friend=%s (#%d)", name_normal, name_friend, ((network_link_GTNETS_t)gtnets_link)->id );
+ return;
+ }
+
link_count++;
+ DEBUG4("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_assert0(0, "Cannot create GTNetS link");
}
#ifdef HAVE_TRACING
TRACE_surf_link_declaration (name, bw, lat);
#endif
- xbt_dict_set(surf_network_model->resource_set, name, gtnets_link,
+ xbt_dict_set(surf_network_model->resource_set, name_normal, gtnets_link,
+ surf_resource_free);
+
+ xbt_dict_set(surf_network_model->resource_set, name_friend, gtnets_link,
surf_resource_free);
}
xbt_dict_foreach(onelink_routes, cursor, key, data){
s_onelink_t link = (s_onelink_t) data;
+
DEBUG3("Link (#%d), src (#%d), dst (#%d)", ((network_link_GTNETS_t)(link->link_ptr))->id , link->src_id, link->dst_id);
DEBUG0("Calling one link route");
if(used_routing->is_router(link->src_id)){
static void finalize(void)
{
- xbt_dict_free(&surf_network_model->resource_set);
-
- surf_model_exit(surf_network_model);
- surf_network_model = NULL;
-
gtnets_finalize();
}
surf_network_model->extension.network.communicate = communicate;
/* Added the initialization for GTNetS interface */
- if (gtnets_initialize()) {
+ if (gtnets_initialize(sg_tcp_gamma)) {
xbt_assert0(0, "Impossible to initialize GTNetS interface");
}
routing_model_create(sizeof(network_link_GTNETS_t), NULL);
}
+static int get_latency_limited(surf_action_t action){
+ return 0;
+}
+
#ifdef HAVE_GTNETS
void surf_network_model_init_GTNETS(const char *filename)
{
define_callbacks(filename);
xbt_dynar_push(model_list, &surf_network_model);
+ surf_network_model->get_latency_limited = get_latency_limited;
+
if(sg_gtnets_jitter > 0.0){
gtnets_set_jitter(sg_gtnets_jitter);
gtnets_set_jitter_seed(sg_gtnets_jitter_seed);
double weight;
lmm_variable_t variable;
double rate;
+ int latency_limited;
int suspended;
int src; /* saving source id for tracing */
xbt_dict_preinit();
}
+static void _surf_cfg_cb__surf_network_fullduplex(const char *name, int pos)
+{
+ sg_network_fullduplex = xbt_cfg_get_int(_surf_cfg_set, name);
+}
+
#ifdef HAVE_GTNETS
static void _surf_cfg_cb__gtnets_jitter(const char *name, int pos){
sg_gtnets_jitter = xbt_cfg_get_double(_surf_cfg_set, name);
"Activate the model-checking of the \"simulated\" system (EXPERIMENTAL -- msg only for now)",
xbt_cfgelm_int, &default_value_int, 0, 1, _surf_cfg_cb_model_check, NULL);
+ default_value_int = 0;
+ xbt_cfg_register(&_surf_cfg_set, "fullduplex",
+ "Update the constraint set propagating recursively to others constraints",
+ xbt_cfgelm_int, &default_value_int, 0, 1, _surf_cfg_cb__surf_network_fullduplex, NULL);
+
#ifdef HAVE_GTNETS
xbt_cfg_register(&_surf_cfg_set, "gtnets_jitter",
"Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)", xbt_cfgelm_double,
/* 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_PRIVATE_H
#define _SURF_SURF_PRIVATE_H
extern double sg_bandwidth_factor;
extern double sg_weight_S_parameter;
extern int sg_maxmin_selective_update;
+extern int sg_network_fullduplex;
#ifdef HAVE_GTNETS
extern double sg_gtnets_jitter;
extern int sg_gtnets_jitter_seed;
DIE_IMPOSSIBLE;
}
+static int ws_get_latency_limited(surf_action_t action)
+{
+ if (action->model_type == surf_network_model)
+ return surf_network_model->get_latency_limited(action);
+ INFO0("You tried to ask if a non network action is limited by latency, aborting...");
+ DIE_IMPOSSIBLE;
+}
+
static double ws_action_get_remains(surf_action_t action)
{
if (action->model_type == surf_network_model)
surf_workstation_model->set_max_duration = ws_action_set_max_duration;
surf_workstation_model->set_priority = ws_action_set_priority;
surf_workstation_model->get_remains = ws_action_get_remains;
+ surf_workstation_model->get_latency_limited = ws_get_latency_limited;
surf_workstation_model->extension.workstation.execute = ws_execute;
surf_workstation_model->extension.workstation.sleep = ws_action_sleep;