From: schnorr Date: Mon, 9 Aug 2010 15:51:17 +0000 (+0000) Subject: fullduplex support X-Git-Tag: v3_5~687 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/2c8e75834bbb63acef15c560c3de978ab3cb6fbf fullduplex support details: - added by Pedro - LV08 model accepts a new option 'fullduplex', enabling a more realistic TCP behavior - more details on the FAQ (that will be updated soon) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@8134 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/examples/msg/gtnets/gtnets.c b/examples/msg/gtnets/gtnets.c index b6f07accb3..196bd1baf1 100644 --- a/examples/msg/gtnets/gtnets.c +++ b/examples/msg/gtnets/gtnets.c @@ -56,17 +56,16 @@ int master(int argc, char *argv[]) /* 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; @@ -77,6 +76,7 @@ int master(int argc, char *argv[]) } /* time measurement */ + sprintf(id_alias, "%d", id); start_time = MSG_get_clock(); MSG_task_send(todo, id_alias); end_time = MSG_get_clock(); @@ -98,6 +98,7 @@ int slave(int argc, char *argv[]) m_task_t task = NULL; int a; int id = 0; + int limited_latency=0; double remaining = 0; char id_alias[10]; @@ -122,18 +123,29 @@ int slave(int argc, char *argv[]) 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); diff --git a/examples/msg/tracing/ms.c b/examples/msg/tracing/ms.c index 51e460ff71..d63b04de50 100644 --- a/examples/msg/tracing/ms.c +++ b/examples/msg/tracing/ms.c @@ -28,6 +28,7 @@ int master(int argc, char *argv[]) //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; @@ -41,6 +42,7 @@ int master(int argc, char *argv[]) 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); @@ -120,6 +122,9 @@ int main(int argc, char *argv[]) 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"); diff --git a/include/msg/msg.h b/include/msg/msg.h index 11faa2bd3f..20a767d697 100644 --- a/include/msg/msg.h +++ b/include/msg/msg.h @@ -155,6 +155,7 @@ XBT_PUBLIC(MSG_error_t) MSG_get_errno(void); 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); diff --git a/src/include/simix/simix.h b/src/include/simix/simix.h index ab928468e8..325a5df296 100644 --- a/src/include/simix/simix.h +++ b/src/include/simix/simix.h @@ -184,6 +184,7 @@ XBT_INLINE XBT_PUBLIC(void) SIMIX_unregister_action_to_semaphore(smx_action_t ac 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); @@ -216,6 +217,7 @@ XBT_PUBLIC(void*) SIMIX_rdv_get_data(smx_rdv_t rdv); 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); diff --git a/src/include/surf/maxmin.h b/src/include/surf/maxmin.h index 5fb85bae1a..0de4266d61 100644 --- a/src/include/surf/maxmin.h +++ b/src/include/surf/maxmin.h @@ -68,6 +68,8 @@ XBT_PUBLIC(void) lmm_expand(lmm_system_t sys, lmm_constraint_t cnst, 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); diff --git a/src/include/surf/surf.h b/src/include/surf/surf.h index 63aa9fa555..d32041fddf 100644 --- a/src/include/surf/surf.h +++ b/src/include/surf/surf.h @@ -77,6 +77,8 @@ XBT_PUBLIC(void) model_help(const char* category, s_surf_model_description_t * t 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 */ @@ -253,6 +255,7 @@ XBT_PUBLIC_DATA(routing_t) used_routing; 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; diff --git a/src/instr/interface.c b/src/instr/interface.c index 88a057681b..1d87e24154 100644 --- a/src/instr/interface.c +++ b/src/instr/interface.c @@ -4,11 +4,12 @@ /* 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; diff --git a/src/msg/task.c b/src/msg/task.c index 3479e4703b..01bd7e00ed 100644 --- a/src/msg/task.c +++ b/src/msg/task.c @@ -23,6 +23,15 @@ * message size and some private data. */ +#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. @@ -230,8 +239,6 @@ double MSG_task_get_remaining_computation(m_task_t task) } } - - /** \ingroup m_task_management * \brief Returns the total amount received by a task #m_task_t. * @@ -240,10 +247,22 @@ double MSG_task_get_remaining_communication(m_task_t task) { 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. * diff --git a/src/simix/smx_action.c b/src/simix/smx_action.c index 73867517d0..ce3ba8af36 100644 --- a/src/simix/smx_action.c +++ b/src/simix/smx_action.c @@ -374,6 +374,12 @@ XBT_INLINE double SIMIX_action_get_remains(smx_action_t action) 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, diff --git a/src/simix/smx_network.c b/src/simix/smx_network.c index fb73403e3e..d0e9d708e2 100644 --- a/src/simix/smx_network.c +++ b/src/simix/smx_network.c @@ -11,6 +11,7 @@ /* 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)"); @@ -160,6 +161,13 @@ smx_comm_t SIMIX_communication_new(smx_comm_type_t type) 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; @@ -184,6 +192,8 @@ void SIMIX_communication_destroy(smx_comm_t comm) comm->dst_timeout = NULL; } + + xbt_free(comm); } @@ -248,7 +258,7 @@ static XBT_INLINE void SIMIX_communication_cleanup(smx_comm_t 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); @@ -343,9 +353,32 @@ XBT_INLINE void SIMIX_communication_cancel(smx_comm_t 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 */ /******************************************************************************/ diff --git a/src/surf/gtnets/gtnets_interface.cc b/src/surf/gtnets/gtnets_interface.cc index 7ff053ccfe..7f06cf745c 100644 --- a/src/surf/gtnets/gtnets_interface.cc +++ b/src/surf/gtnets/gtnets_interface.cc @@ -22,13 +22,17 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets_interface, surf_network_gtne // 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; } @@ -89,7 +93,7 @@ double gtnets_get_time_to_next_flow_completion(){ } // 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; @@ -109,7 +113,7 @@ int gtnets_run_until_next_flow_completion(void ***metadata, int *number_of_flows cout.rdbuf(sbuf); file.close(); } - return value; + return (double) value; } // get the total received in bytes using the TCPServer object totRx field diff --git a/src/surf/gtnets/gtnets_interface.h b/src/surf/gtnets/gtnets_interface.h index 10a358ce14..9b5bbd8cd0 100644 --- a/src/surf/gtnets/gtnets_interface.h +++ b/src/surf/gtnets/gtnets_interface.h @@ -12,14 +12,14 @@ 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); diff --git a/src/surf/gtnets/gtnets_simulator.cc b/src/surf/gtnets/gtnets_simulator.cc index e7a3089618..a2955febef 100644 --- a/src/surf/gtnets/gtnets_simulator.cc +++ b/src/surf/gtnets/gtnets_simulator.cc @@ -28,6 +28,76 @@ static int meta_flg = 0; 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(){ diff --git a/src/surf/gtnets/gtnets_simulator.h b/src/surf/gtnets/gtnets_simulator.h index 9a88c7417c..8f814531b2 100644 --- a/src/surf/gtnets/gtnets_simulator.h +++ b/src/surf/gtnets/gtnets_simulator.h @@ -35,6 +35,7 @@ class GTSim { public: GTSim(); + GTSim(int WindowSize); ~GTSim(); public: int add_link(int id, double bandwidth, double latency); diff --git a/src/surf/maxmin.c b/src/surf/maxmin.c index 027fca4747..c35b51936f 100644 --- a/src/surf/maxmin.c +++ b/src/surf/maxmin.c @@ -723,6 +723,12 @@ XBT_INLINE lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t sys, 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. * diff --git a/src/surf/network.c b/src/surf/network.c index 0acac74d37..867736f6fa 100644 --- a/src/surf/network.c +++ b/src/surf/network.c @@ -20,6 +20,7 @@ double sg_bandwidth_factor = 1.0; /* default value; can be set by model or from 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; /******************************************************************************/ @@ -257,6 +258,11 @@ static void net_action_recycle(surf_action_t action) 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; @@ -277,6 +283,11 @@ static double net_share_resources(double now) #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; @@ -400,11 +411,18 @@ static void net_update_resource_state(void *id, 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); @@ -442,6 +460,7 @@ static void net_update_resource_state(void *id, return; } + static surf_action_t net_communicate(const char *src_name, const char *dst_name, int src, int dst, double size, double rate) { @@ -454,6 +473,13 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name, 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 */ @@ -473,6 +499,7 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name, 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; @@ -499,14 +526,18 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name, /* 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) @@ -530,7 +561,14 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name, 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 */ @@ -548,11 +586,6 @@ static double net_get_link_bandwidth(const void *link) 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); @@ -638,6 +671,7 @@ static void surf_network_model_init_internal(void) 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; @@ -655,7 +689,6 @@ static void surf_network_model_init_internal(void) 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; diff --git a/src/surf/network_gtnets.c b/src/surf/network_gtnets.c index 11e6089998..feaa16587c 100644 --- a/src/surf/network_gtnets.c +++ b/src/surf/network_gtnets.c @@ -21,13 +21,43 @@ static void link_new(char *name, double bw, double lat, xbt_dict_t props) { 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"); } @@ -42,7 +72,10 @@ static void link_new(char *name, double bw, double lat, xbt_dict_t props) #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); } @@ -122,6 +155,7 @@ static void create_gtnets_topology() 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)){ @@ -337,11 +371,6 @@ static int action_is_suspended(surf_action_t action) static void finalize(void) { - xbt_dict_free(&surf_network_model->resource_set); - - surf_model_exit(surf_network_model); - surf_network_model = NULL; - gtnets_finalize(); } @@ -371,13 +400,17 @@ static void surf_network_model_init_internal(void) 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) { @@ -387,6 +420,8 @@ 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); diff --git a/src/surf/network_private.h b/src/surf/network_private.h index dd9a6f2cd7..db5364e5c6 100644 --- a/src/surf/network_private.h +++ b/src/surf/network_private.h @@ -27,6 +27,7 @@ typedef struct surf_action_network_CM02 { double weight; lmm_variable_t variable; double rate; + int latency_limited; int suspended; int src; /* saving source id for tracing */ diff --git a/src/surf/surf_config.c b/src/surf/surf_config.c index 62eaa2654d..8b20806bed 100644 --- a/src/surf/surf_config.c +++ b/src/surf/surf_config.c @@ -152,6 +152,11 @@ static void _surf_cfg_cb_model_check(const char *name, int pos) { 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); @@ -260,6 +265,11 @@ void surf_config_init(int *argc, char **argv) "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, diff --git a/src/surf/surf_private.h b/src/surf/surf_private.h index c64d330ce5..61a374b0fb 100644 --- a/src/surf/surf_private.h +++ b/src/surf/surf_private.h @@ -3,7 +3,6 @@ /* 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 @@ -23,6 +22,7 @@ extern double sg_latency_factor; 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; diff --git a/src/surf/workstation.c b/src/surf/workstation.c index 1fddb316f2..4363239a5c 100644 --- a/src/surf/workstation.c +++ b/src/surf/workstation.c @@ -184,6 +184,14 @@ static void ws_action_set_priority(surf_action_t action, double priority) 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) @@ -291,6 +299,7 @@ static void surf_workstation_model_init_internal(void) 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;