/********************************* MSG **************************************/
+static void _sg_cfg_cb_msg_multiple_backtraces(const char *name, int pos)
+{
+ msg_global->multiple_backtraces = xbt_cfg_get_boolean(_sg_cfg_set, name);
+}
+
/**
* \ingroup msg_simulation
* \brief Initialize MSG with less verifications
xbt_getpid = MSG_process_self_PID;
if (!msg_global) {
- SIMIX_global_init(argc, argv);
-
msg_global = xbt_new0(s_MSG_Global_t, 1);
+ xbt_cfg_register(&_sg_cfg_set, "msg/multiple_backtraces",
+ "Keep the severals backtraces",
+ xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_msg_multiple_backtraces, NULL);
+ xbt_cfg_setdefault_boolean(_sg_cfg_set, "msg/multiple_backtraces", "no");
+
+ SIMIX_global_init(argc, argv);
+
#ifdef MSG_USE_DEPRECATED
msg_global->max_channel = 0;
#endif
sg_platf_postparse_add_cb(MSG_post_create_environment);
}
-
+
if(MC_is_active()){
/* Ignore total amount of messages sent during the simulation for heap comparison */
MC_ignore_heap(&(msg_global->sent_msg), sizeof(msg_global->sent_msg));
xbt_assert((!simdata->compute) && (task->simdata->isused == 0),
"This task is executed somewhere else. Go fix your code! %d",
- task->simdata->isused);
+ task->simdata->isused!=NULL);
XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self()));
TRY {
-
- simdata->isused=1;
+ if (msg_global->multiple_backtraces)
+ MSG_BT(simdata->isused, "Using Backtrace");
+ else
+ simdata->isused = (void*)1;
if (simdata->host_nb > 0) {
simdata->compute = simcall_host_parallel_execute(task->name,
t_simdata->sender = process;
t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host;
- xbt_assert(t_simdata->isused == 0,
- "This task is still being used somewhere else. You cannot send it now. Go fix your code!");
+ if (t_simdata->isused != 0) {
+ if (msg_global->multiple_backtraces){
+ XBT_ERROR("This task is already used in there:");
+ xbt_backtrace_display(t_simdata->isused);
+ THROWF(unknown_error, 0, "And you try to reuse it from here. You cannot send it now. Go fix your code!");
+ } else {
+ THROWF(unknown_error, 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code! (use --cfg=msg/multiple_backtraces:on to get the backtrace of the other process)");
+ }
+ }
- t_simdata->isused = 1;
+ if (msg_global->multiple_backtraces)
+ MSG_BT(t_simdata->isused, "Using Backtrace");
+ else
+ t_simdata->isused = (void*)1;
t_simdata->comm = NULL;
msg_global->sent_msg++;
/** \ingroup msg_mailbox_management
* \brief Set the mailbox to receive in asynchronous mode
*
- * All messages sent to this mailbox will be transferred to
- * the receiver without waiting for the receive call.
+ * All messages sent to this mailbox will be transferred to
+ * the receiver without waiting for the receive call.
* The receive call will still be necessary to use the received data.
- * If there is a need to receive some messages asynchronously, and some not,
+ * If there is a need to receive some messages asynchronously, and some not,
* two different mailboxes should be used.
*
- * \param alias The name of the mailbox
+ * \param alias The name of the mailbox
*/
void MSG_mailbox_set_async(const char *alias){
msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
t_simdata->sender = process;
t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host;
- xbt_assert(t_simdata->isused == 0,
- "This task is still being used somewhere else. You cannot send it now. Go fix your code!");
+ if (t_simdata->isused != 0) {
+ if (msg_global->multiple_backtraces){
+ XBT_ERROR("This task is already used in there:");
+ xbt_backtrace_display(t_simdata->isused);
+ THROWF(unknown_error, 0, "And you try to reuse it from here. You cannot send it now. Go fix your code!");
+ } else {
+ THROWF(unknown_error, 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code! (use --cfg=msg/multiple_backtraces:on to get the backtrace of the other process)");
+ }
+ }
- t_simdata->isused=1;
+ if (msg_global->multiple_backtraces)
+ MSG_BT(t_simdata->isused, "Using Backtrace");
+ else
+ t_simdata->isused = (void*)1;
t_simdata->comm = NULL;
msg_global->sent_msg++;
/********************************* Task **************************************/
+
+#define MSG_BT(ptr, m) \
+ do {xbt_ex_t *_xbt_ex_t = xbt_new0(xbt_ex_t, 1); \
+ /* build the exception */ \
+ _xbt_ex_t->msg = (bprintf(m)); \
+ _xbt_ex_t->category = (xbt_errcat_t)(0); \
+ _xbt_ex_t->value = (0); \
+ _xbt_ex_t->procname = (char*)xbt_procname(); \
+ _xbt_ex_t->pid = xbt_getpid(); \
+ _xbt_ex_t->file = (char*)__FILE__; \
+ _xbt_ex_t->line = __LINE__; \
+ _xbt_ex_t->func = (char*)_XBT_FUNCTION; \
+ _xbt_ex_t->bt_strings = NULL; \
+ xbt_backtrace_current(_xbt_ex_t); \
+ ptr = _xbt_ex_t; } while(0)
+
typedef struct simdata_task {
smx_action_t compute; /* SIMIX modeling of computation */
smx_action_t comm; /* SIMIX modeling of communication */
/* CPU affinity database of this task */
xbt_dict_t affinity_mask_db; /* smx_host_t host => unsigned long mask */
- int isused; /* Indicates whether the task is used in SIMIX currently */
+ void *isused; /* Indicates whether the task is used in SIMIX currently */
int host_nb; /* ==0 if sequential task; parallel task if not */
/******* Parallel Tasks Only !!!! *******/
smx_host_t *host_list;
int max_channel;
#endif
int session;
+ int multiple_backtraces;
unsigned long int sent_msg; /* Total amount of messages sent during the simulation */
void (*task_copy_callback) (msg_task_t task, msg_process_t src, msg_process_t dst);
void_f_pvoid_t process_data_cleanup;
//class Resource;
typedef Resource* ResourcePtr;
-
+
//class Action;
typedef Action* ActionPtr;
XBT_PUBLIC_DATA(xbt_dict_t) traces_set_list;
XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_host_avail;
XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_power;
-XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_link_avail;
-XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_bandwidth;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_link_avail;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_bandwidth;
XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_latency;
/*********
*/
XBT_PUBLIC_CLASS Model {
public:
- /**
+ /**
* @brief Model constructor
- *
+ *
* @param name the name of the model
*/
Model(const char *name);
- /**
+ /**
* @brief Model destructor
*/
virtual ~Model();
/**
* @brief Get the name of the current Model
- *
+ *
* @return The name of the current Model
*/
const char *getName() {return p_name;}
/**
- * @brief Get the set of [actions](@ref Action) in *ready* state
- *
- * @return The set of [actions](@ref Action) in *ready* state
+ * @brief Get the set of [actions](@ref Action) in *ready* state
+ *
+ * @return The set of [actions](@ref Action) in *ready* state
*/
virtual ActionListPtr getReadyActionSet() {return p_readyActionSet;}
/**
* @brief Get the set of [actions](@ref Action) in *running* state
- *
+ *
* @return The set of [actions](@ref Action) in *running* state
*/
virtual ActionListPtr getRunningActionSet() {return p_runningActionSet;}
/**
* @brief Get the set of [actions](@ref Action) in *failed* state
- *
+ *
* @return The set of [actions](@ref Action) in *failed* state
*/
virtual ActionListPtr getFailedActionSet() {return p_failedActionSet;}
/**
* @brief Get the set of [actions](@ref Action) in *done* state
- *
+ *
* @return The set of [actions](@ref Action) in *done* state
*/
virtual ActionListPtr getDoneActionSet() {return p_doneActionSet;}
/**
* @brief Get the set of modified [actions](@ref Action)
- *
+ *
* @return The set of modified [actions](@ref Action)
*/
virtual ActionLmmListPtr getModifiedSet() {return p_modifiedSet;}
/**
* @brief Get the update mechanism of the current Model
* @see e_UM_t
- *
+ *
* @return [description]
*/
e_UM_t getUpdateMechanism() {return p_updateMechanism;}
/**
* @brief Get Action heap
* @details [TODO]
- *
+ *
* @return The Action heap
*/
xbt_heap_t getActionHeap() {return p_actionHeap;}
- /**
+ /**
* @brief share the resources
- * @details Share the resources between the actions
- *
- * @param now [TODO]
- * @return the date of the next action will finish
+ * @details Share the resources between the actions
+ *
+ * @param now The current time of the simulation
+ * @return The delta of time till the next action will finish
*/
virtual double shareResources(double now);
virtual double shareResourcesLazy(double now);
/**
* @brief Update state of actions
- * @details [TODO]
- *
- * @param now [TODO]
- * @param delta [TODO]
+ * @details Update action to the current time
+ *
+ * @param now The current time of the simulation
+ * @param delta The delta of time since the last update
*/
virtual void updateActionsState(double now, double delta);
virtual void updateActionsStateLazy(double now, double delta);
*/
XBT_PUBLIC_CLASS Resource {
public:
- /**
+ /**
* @brief Resource constructor
*/
Resource();
- /**
+ /**
* @brief Resource constructor
- *
+ *
* @param model Model associated to this Resource
* @param name The name of the Resource
* @param props Dictionary of properties associated to this Resource
*/
Resource(ModelPtr model, const char *name, xbt_dict_t props);
- /**
+ /**
* @brief Resource constructor
- *
+ *
* @param model Model associated to this Resource
* @param name The name of the Resource
* @param props Dictionary of properties associated to this Resource
*/
Resource(ModelPtr model, const char *name, xbt_dict_t props, lmm_constraint_t constraint);
- /**
+ /**
* @brief Resource constructor
- *
+ *
* @param model Model associated to this Resource
* @param name The name of the Resource
* @param props Dictionary of properties associated to this Resource
/**
* @brief Resource destructor
*/
- virtual ~Resource();
+ virtual ~Resource();
/**
* @brief Get the Model of the current Resource
- *
+ *
* @return The Model of the current Resource
*/
ModelPtr getModel();
/**
* @brief Get the name of the current Resource
- *
+ *
* @return The name of the current Resource
*/
const char *getName();
/**
* @brief Get the properties of the current Resource
- *
+ *
* @return The properties of the current Resource
*/
virtual xbt_dict_t getProperties();
/**
* @brief Update the state of the current Resource
* @details [TODO]
- *
+ *
* @param event_type [TODO]
* @param value [TODO]
* @param date [TODO]
/**
* @brief Set the [state](\ref e_surf_resource_state_t) of the current Resource
- *
+ *
* @param state The new state of the current Resource
*/
virtual void setState(e_surf_resource_state_t state);
public:
/**
* @brief Get the lmm constraint associated to this Resource if it is part of a LMM component
- *
+ *
* @return The lmm constraint associated to this Resource
*/
lmm_constraint_t getConstraint();
public:
/**
* @brief Action constructor
- *
+ *
* @param model The Model associated to this Action
* @param cost The cost of the Action
* @param failed If the action is impossible (e.g.: execute something on a switched off workstation)
/**
* @brief Action constructor
- *
+ *
* @param model The Model associated to this Action
* @param cost The cost of the Action
* @param failed If the action is impossible (e.g.: execute something on a switched off workstation)
* @brief Action destructor
*/
virtual ~Action();
-
+
/**
* @brief Finish the action
*/
/**
* @brief Get the [state](\ref e_surf_action_state_t) of the current Action
- *
+ *
* @return The state of the current Action
*/
e_surf_action_state_t getState(); /**< get the state*/
/**
* @brief Set the [state](\ref e_surf_action_state_t) of the current Action
- *
+ *
* @param state The new state of the current Action
*/
virtual void setState(e_surf_action_state_t state);
/**
* @brief Get the bound of the current Action
- *
+ *
* @return The bound of the current Action
*/
double getBound();
/**
* @brief Get the start time of the current action
- *
+ *
* @return The start time of the current action
*/
double getStartTime();
/**
* @brief Get the finish time of the current action
- *
+ *
* @return The finish time of the current action
*/
double getFinishTime();
/**
* @brief Get the data associated to the current action
- *
+ *
* @return The data associated to the current action
*/
void *getData() {return p_data;}
/**
* @brief Set the data associated to the current action
- *
+ *
* @param data The new data associated to the current action
*/
void setData(void* data);
/**
* @brief Get the maximum duration of the current action
- *
+ *
* @return The maximum duration of the current action
*/
double getMaxDuration() {return m_maxDuration;}
/**
* @brief Get the category associated to the current action
- *
+ *
* @return The category associated to the current action
*/
char *getCategory() {return p_category;}
/**
* @brief Get the cost of the current action
- *
+ *
* @return The cost of the current action
*/
double getCost() {return m_cost;}
/**
* @brief Set the cost of the current action
- *
+ *
* @param cost The new cost of the current action
*/
void setCost(double cost) {m_cost = cost;}
/**
* @brief Update the maximum duration of the current action
- *
+ *
* @param delta [TODO]
*/
void updateMaxDuration(double delta) {double_update(&m_maxDuration, delta,sg_surf_precision);}
/**
* @brief Update the remaining time of the current action
- *
+ *
* @param delta [TODO]
*/
void updateRemains(double delta) {double_update(&m_remains, delta, sg_maxmin_precision*sg_surf_precision);}
/**
* @brief Set the remaining time of the current action
- *
+ *
* @param value The new remaining time of the current action
*/
void setRemains(double value) {m_remains = value;}
/**
* @brief Set the finish time of the current action
- *
+ *
* @param value The new Finush time of the current action
*/
void setFinishTime(double value) {m_finish = value;}
/**
* @brief Remove a reference to the current action
* @details If the Action has no more reference, we destroy it
- *
+ *
* @return true if the action was destroyed and false if someone still has references on it
*/
virtual int unref();
/**
* @brief Check if the current action is running
- *
+ *
* @return true if the current Action is suspended, false otherwise
*/
virtual bool isSuspended();
/**
* @brief Set the maximum duration of the current Action
- *
+ *
* @param duration The new maximum duration of the current Action
*/
virtual void setMaxDuration(double duration);
/**
* @brief Set the priority of the current Action
- *
+ *
* @param priority The new priority of the current Action
*/
virtual void setPriority(double priority);
#ifdef HAVE_TRACING
/**
* @brief Set the category of the current Action
- *
+ *
* @param category The new category of the current Action
*/
void setCategory(const char *category);
/**
* @brief Get the remaining time of the current action after updating the resource
- *
+ *
* @return The remaining time
*/
virtual double getRemains();
/**
* @brief Get the remaining time of the current action without updating the resource
- *
+ *
* @return The remaining time
*/
double getRemainsNoUpdate();
/**
* @brief Get the priority of the current Action
- *
+ *
* @return The priority of the current Action
*/
double getPriority() {return m_priority;};
/**
* @brief Get the state set in which the action is
* @details [TODO]
- *
+ *
* @return The state set in which the action is
*/
ActionListPtr getStateSet() {return p_stateSet;};
/**
* @brief Share the resources to the actions
* @details [TODO]
- *
+ *
* @param now [TODO]
* @return in how much time the next action may terminatedescription]
*/
/**
* @brief Update the current action state
* @details [TODO]
- *
+ *
* @param now [TODO]
* @param delta [TODO]
*/
/**
* @brief Update the [TODO]
* @details [TODO]
- *
+ *
* @param id [TODO]
* @param event_type [TODO]
* @param value [TODO]
#include "surf_routing_cluster_fat_tree.hpp"
+#include "xbt/lib.h"
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
-
#include <iostream>
#include <fstream>
unsigned int nodesRequired = 0;
- for (unsigned int i = 0 ; i < this->levels ; i++) {
- int nodesInThisLevel = 1;
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ int nodesInThisLevel = 1;
- for (unsigned int j = 0 ; j < i ; j++) {
- nodesInThisLevel *= this->upperLevelNodesNumber[j];
- }
+ for (unsigned int j = 0 ; j < i ; j++) {
+ nodesInThisLevel *= this->upperLevelNodesNumber[j];
+ }
- for (unsigned int j = i+1 ; j < this->levels ; j++) {
- nodesInThisLevel *= this->lowerLevelNodesNumber[j];
- }
-
- this->nodesByLevel[i] = nodesInThisLevel;
- nodesRequired += nodesInThisLevel;
+ for (unsigned int j = i+1 ; j < this->levels ; j++) {
+ nodesInThisLevel *= this->lowerLevelNodesNumber[j];
}
+
+ this->nodesByLevel[i] = nodesInThisLevel;
+ nodesRequired += nodesInThisLevel;
+ }
- if(nodesRequired > this->nodes.size()) {
- surf_parse_error("There is not enough nodes to fit to the described topology."
- " Please check your platform description (We need %d nodes, we only got %lu)",
- nodesRequired, this->nodes.size());
- return;
- }
+ if(nodesRequired > this->nodes.size()) {
+ surf_parse_error("There is not enough nodes to fit to the described topology."
+ " Please check your platform description (We need %d nodes, we only got %lu)",
+ nodesRequired, this->nodes.size());
+ return;
+ }
- // Nodes are totally ordered, by level and then by position, in this->nodes
- int k = 0;
- for (unsigned int i = 0 ; i < this->levels ; i++) {
- for (unsigned int j = 0 ; j < this->nodesByLevel[i] ; j++) {
- this->nodes[k]->level = i;
- this->nodes[k]->position = j;
- if(i != 0) {
- int position, size;
- this->getLevelPosition(i - 1, &position, &size); // TODO : check position and size ?
- for (unsigned int l = this->upperLevelNodesNumber[i] * j ;
- l < this->upperLevelNodesNumber[i] * (j + 1) ; l++)
- this->addLink(this->nodes[position + l], this->nodes[k]);
- }
- k++;
+ // Nodes are totally ordered, by level and then by position, in this->nodes
+ int k = 0;
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ for (unsigned int j = 0 ; j < this->nodesByLevel[i] ; j++) {
+ this->nodes[k]->level = i;
+ this->nodes[k]->position = j;
+ if(i != 0) {
+ int position, size;
+ this->getLevelPosition(i - 1, &position, &size); // TODO : check position and size ?
+ /* We create the connexions between this nodes and all its parents
+ */
+ for (unsigned int l = this->upperLevelNodesNumber[i] * j ;
+ l < this->upperLevelNodesNumber[i] * (j + 1) ; l++)
+ this->addLink(cluster, this->nodes[position + l], this->nodes[k]);
}
+ k++;
}
-
+ }
}
void AsClusterFatTree::getLevelPosition(const unsigned int level, int *position, int *size) {
}
}
-void AsClusterFatTree::addLink(FatTreeNode *parent, FatTreeNode *child) {
+void AsClusterFatTree::addLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode *parent,
+ FatTreeNode *child) {
using std::make_pair;
if (parent->children.size() == this->nodesByLevel[parent->level] ||
child->parents.size() == this->nodesByLevel[child->level]) {
parent->children.push_back(child);
child->parents.push_back(parent);
- // FatTreeLink *newLink;
+ FatTreeLink *newLink;
- // newLink = new FatTreeLink(parent, child, this->lowerLevelPortsNumber[parent->level]);
- // this->links.insert(make_pair(make_pair(parent->id, child->id), newLink));
+ newLink = new FatTreeLink(cluster, parent, child, this->lowerLevelPortsNumber[parent->level]);
+ this->links.insert(make_pair(make_pair(parent->id, child->id), newLink));
// The first parts of topo_parameters should be the levels number
this->levels = std::atoi(tmp[0].c_str()); // stoi() only in C++11...
-
+
// Then, a l-sized vector standing for the childs number by level
boost::split(tmp, parameters[1], boost::is_any_of(","));
if(tmp.size() != this->levels) {
level(level),
position(position){}
-// FatTreeLink::FatTreeLink(FatTreeNode *source, FatTreeNode *destination,
-// int ports) : source(source), destination(destination),
-// ports(ports) {
-
-// }
+FatTreeLink::FatTreeLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode *source,
+ FatTreeNode *destination,
+ unsigned int ports) : ports(ports), source(source),
+ destination(destination) {
+ s_sg_platf_link_cbarg_t linkTemplate;
+ linkTemplate.bandwidth = cluster->bw;
+ linkTemplate.latency = cluster->lat;
+ linkTemplate.state = SURF_RESOURCE_ON;
+ linkTemplate.policy = cluster->sharing_policy; // Maybe should we do sthg with that ?
+
+ for(unsigned int i = 0 ; i < ports ; i++) {
+ NetworkLink* link;
+ linkTemplate.id = bprintf("link_from_%d_to_%d_%d_UP", source->id, destination->id, i);
+ sg_platf_new_link(&linkTemplate);
+ link = (NetworkLink*) xbt_lib_get_or_null(link_lib, linkTemplate.id, SURF_LINK_LEVEL);
+ this->linksUp.push_back(link); // check link?
+ linkTemplate.id = bprintf("link_from_%d_to_%d_%d_DOWN", source->id, destination->id, i);
+ sg_platf_new_link(&linkTemplate);
+ link = (NetworkLink*) xbt_lib_get_or_null(link_lib, linkTemplate.id, SURF_LINK_LEVEL);
+ this->linksDown.push_back(link); // check link ?
+ }
+}
* should certainly be checked for)
*/
+/* TODO : limiter link ? Loopback?
+ *
+ */
class FatTreeNode {
public:
class FatTreeLink {
public:
+ FatTreeLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode *source,
+ FatTreeNode *destination, unsigned int ports = 0);
unsigned int ports;
- std::vector<s_sg_platf_link_cbarg_t> linksUp; // From source to destination
- std::vector<s_sg_platf_link_cbarg_t> linksDown; // From destination to source
+ /* Links are dependant of the chosen network model, but must implement
+ * NetworkLink
+ */
+ std::vector<NetworkLink*> linksUp; // From source to destination
+ std::vector<NetworkLink*> linksDown; // From destination to source
/* As it is symetric, it might as well be first / second instead
* of source / destination
*/
FatTreeNode *source;
FatTreeNode *destination;
- //FatTreeLink(FatTreeNode *source, FatTreeNode *destination, unsigned int ports = 0);
};
class AsClusterFatTree : public AsCluster {
unsigned int levels;
std::vector<int> lowerLevelNodesNumber; // number of children by node
std::vector<int> upperLevelNodesNumber; // number of parents by node
- std::vector<int> lowerLevelPortsNumber;
+ std::vector<int> lowerLevelPortsNumber; // ports between each level l and l-1
std::vector<FatTreeNode*> nodes;
std::map<std::pair<int,int>, FatTreeLink*> links;
std::vector<unsigned int> nodesByLevel;
- void addLink(FatTreeNode *parent, FatTreeNode *child);
+ void addLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode *parent,
+ FatTreeNode *child);
void getLevelPosition(const unsigned int level, int *position, int *size);
};
#endif