From: kayof Date: Mon, 4 Jun 2007 10:11:58 +0000 (+0000) Subject: Fix bugs... X-Git-Tag: v3.3~1809 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/9b67f9757c2b3384bb3c0e8ef256fbdf6c2e7821 Fix bugs... git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3551 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/surf/gtnets/gtnets_interface.cc b/src/surf/gtnets/gtnets_interface.cc index c7df7d23a5..ab9b0aab39 100644 --- a/src/surf/gtnets/gtnets_interface.cc +++ b/src/surf/gtnets/gtnets_interface.cc @@ -1,3 +1,8 @@ +/* $Id$ */ +/* Copyright (c) 2007 Kayo Fujiwara. 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 "gtnets_simulator.h" #include "gtnets_interface.h" @@ -14,29 +19,34 @@ int gtnets_initialize(){ return 0; } -// adds a link (argument link is just an index starting at 0... +// add a link (argument link is just an index starting at 0... // add link 0, add link 1, etc.) int gtnets_add_link(int id, double bandwidth, double latency){ - printf("gtnets_add_link: %d, %f, %f\n", id, bandwidth, latency); return gtnets_sim->add_link(id, bandwidth, latency); } -// adds a route between a source and a destination as an array of link indices +// add a route between a source and a destination as an array of link indices // (note that there is no gtnets_add_network_card(), as we discover them // on the fly via calls to gtnets_add_route() int gtnets_add_route(int src, int dst, int* links, int nlink){ - int i; - printf("gtnets_add_route: %d, %d\n", src, dst); - for (i = 0; i < nlink; i++){ - printf("%d: %d\n", i, *links++); - } return gtnets_sim->add_route(src, dst, links, nlink); } +// add a router +int gtnets_add_router(int id){ + return gtnets_sim->add_router(id); +} + +// add a route between a source and a destination as an array of link indices +// (note that there is no gtnets_add_network_card(), as we discover them +// on the fly via calls to gtnets_add_route() +int gtnets_add_onehop_route(int src, int dst, int link){ + return gtnets_sim->add_onehop_route(src, dst, link); +} + // create a new flow on a route // one can attach arbitrary metadata to a flow int gtnets_create_flow(int src, int dst, long datasize, void* metadata){ - printf("gtnets_create_flow: %d, %d, %d\n", src, dst, datasize); return gtnets_sim->create_flow(src, dst, datasize, metadata); } @@ -60,7 +70,6 @@ int gtnets_run(Time_t deltat){ // clean up int gtnets_finalize(){ if (!gtnets_sim) return -1; - gtnets_sim->finalize(); delete gtnets_sim; gtnets_sim = 0; return 0; diff --git a/src/surf/gtnets/gtnets_interface.h b/src/surf/gtnets/gtnets_interface.h index 8936fa0a03..aa3f2d2469 100644 --- a/src/surf/gtnets/gtnets_interface.h +++ b/src/surf/gtnets/gtnets_interface.h @@ -1,6 +1,10 @@ -// Interface for GTNetS. -// Kayo Fujiwara 1/8/2007 +/* $Id$ */ +/* Copyright (c) 2007 Kayo Fujiwara. 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. */ +// Interface for GTNetS. #ifndef _GTNETS_INTERFACE_H #define _GTNETS_INTERFACE_H @@ -11,6 +15,8 @@ extern "C" { int gtnets_initialize(); 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, int* number_of_flows); diff --git a/src/surf/gtnets/gtnets_simulator.cc b/src/surf/gtnets/gtnets_simulator.cc index 7feb325450..eac36f447b 100644 --- a/src/surf/gtnets/gtnets_simulator.cc +++ b/src/surf/gtnets/gtnets_simulator.cc @@ -1,4 +1,9 @@ -//Kayo Fujiwara 1/8/2007 +/* $Id$ */ +/* Copyright (c) 2007 Kayo Fujiwara. 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 "gtnets_simulator.h" #include "gtnets_topology.h" #include @@ -19,7 +24,7 @@ GTSim::GTSim(){ is_topology_ = 0; nflow_ = 0; sim_ = new Simulator(); - topo_ = new SGTopology(); + topo_ = new GTNETS_Topology(); // Set default values. TCP::DefaultAdvWin(wsize); @@ -27,117 +32,228 @@ GTSim::GTSim(){ TCP::DefaultTxBuffer(128000); TCP::DefaultRxBuffer(128000); + // Manual routing + rm_ = new RoutingManual(); + Routing::SetRouting(rm_); } + GTSim::~GTSim(){ map::iterator it; for (it = gtnets_links_.begin(); it != gtnets_links_.end(); it++){ delete it->second; } - map::iterator it2; - for (it2 = tmp_links_.begin(); it2 != tmp_links_.end(); it2++){ - delete it2->second; - } + while (!gtnets_links_.empty()) + gtnets_links_.erase(gtnets_links_.begin()); + map::iterator it3; for (it3 = gtnets_nodes_.begin(); it3 != gtnets_nodes_.end(); it3++){ delete it3->second; } + while (!gtnets_nodes_.empty()) + gtnets_nodes_.erase(gtnets_nodes_.begin()); + map::iterator it4; for (it4 = gtnets_servers_.begin(); it4 != gtnets_servers_.end(); it4++){ delete it4->second; } + while (!gtnets_servers_.empty()) + gtnets_servers_.erase(gtnets_servers_.begin()); + map::iterator it5; for (it5 = gtnets_clients_.begin(); it5 != gtnets_clients_.end(); it5++){ delete it5->second; } - //TODO delete other objects! + while (!gtnets_clients_.empty()) + gtnets_clients_.erase(gtnets_clients_.begin()); + + is_topology_ = 0; + delete sim_; + delete topo_; + delete rm_; + sim_ = 0; + topo_ = 0; + rm_ = 0; } +int GTSim::add_router(int id){ + if (topo_->add_router(id) < 0){ + fprintf(stderr, "can't add router %d. already exists.\n", id); + return -1; + } +} +//bandwidth: in bytes. +//latency: in seconds. int GTSim::add_link(int id, double bandwidth, double latency){ - if (gtnets_links_.find(id) != gtnets_links_.end()){ + double bw = bandwidth * 8; //Bandwidth in bits (used in GTNETS). + if (topo_->add_link(id) < 0){ fprintf(stderr, "can't add link %d. already exists.\n", id); return -1; } - gtnets_links_[id] = new Linkp2p(bandwidth, latency); + gtnets_links_[id] = new Linkp2p(bw, latency); return 0; } -int GTSim::add_route(int src, int dst, int* links, int nlink){ - topo_->add_link(src, dst, links, nlink); - // topo_->create_tmplink(src, dst, links, nlink); +// if gtnets_nodes_ includes id, return true, otherwise return false. +bool GTSim::node_include(int id){ + if (gtnets_nodes_.find(id) != gtnets_nodes_.end()) return true; + else return false; +} + +// if gtnets_link_ includes id, return true, otherwise return false. +bool GTSim::link_include(int id){ + if (gtnets_links_.find(id) != gtnets_links_.end()) return true; + else return false; +} + +int GTSim::add_onehop_route(int src, int dst, int link){ + if (topo_->add_onehop_route(src, dst, link) < 0){ + fprintf(stderr, "Cannot add a route, src: %d, dst: %d, link: %d\n", + src, dst, link); + return -1; + } return 0; } -void GTSim::create_gtnets_topology(){ - //TODO: add manual routing - //TODO: is this addressing fine? +// Generate the gtnets nodes according to topo_. +void GTSim::add_nodes(){ static unsigned int address = IPAddr("192.168.0.1"); - tmp_links_ = topo_->get_links(); - map::iterator it; - - //By now, all links has two nodes. - //Connect left and right with the link. - for (it = tmp_links_.begin(); it != tmp_links_.end(); it++){ - it->second->print(); - //both nodes must be not null. TODO check it! - int linkid = it->second->id(); - int leftid = it->second->left_node()->id(); - int rightid = it->second->right_node()->id(); - - cout << "linkid: " << linkid << endl; - cout << "leftid: " << leftid << endl; - cout << "rightid: " << rightid << endl; - - - map::iterator nodeit = gtnets_nodes_.find(leftid); - // if the nodes don't exist, add one. - if (nodeit == gtnets_nodes_.end()){ - gtnets_nodes_[leftid] = new Node(); - gtnets_nodes_[leftid]->SetIPAddr(address++); - //add host-node relationships. - vector tmphosts = it->second->left_node()->hosts(); - - for (int i = 0; i < tmphosts.size(); i++){ - gtnets_hosts_[tmphosts[i]] = leftid; - cout << "host: " << tmphosts[i] << " node: " << leftid << endl; - } + vector nodes = topo_->nodes(); + vector::iterator it; + int id; + for (it = nodes.begin(); it != nodes.end(); it++){ + id = (*it)->id(); + gtnets_nodes_[id] = new Node(); + gtnets_nodes_[id]->SetIPAddr(address++); + // printf("In GTSim, add_node: %d\n", id); + } +} +void GTSim::node_connect(){ + + map links = topo_->links(); + map::iterator it; + int linkid, srcid, dstid; + for (it = links.begin(); it != links.end(); it++){ + linkid = it->second->id(); + //if link is used in a route, connect the two nodes. + if (it->second->src_node() && it->second->dst_node()){ + + srcid = it->second->src_node()->id(); + dstid = it->second->dst_node()->id(); + + gtnets_nodes_[srcid]-> + AddDuplexLink(gtnets_nodes_[dstid], *(gtnets_links_[linkid])); } - nodeit = gtnets_nodes_.find(rightid); - if (nodeit == gtnets_nodes_.end()){//new entry - gtnets_nodes_[rightid] = new Node(); - gtnets_nodes_[rightid]->SetIPAddr(address++); - - //add host-node relationships. - vector tmphosts = it->second->right_node()->hosts(); - - for (int i = 0; i < tmphosts.size(); i++){ - gtnets_hosts_[tmphosts[i]] = rightid; - cout << "host: " << tmphosts[i] << " node: " << rightid << endl; - } - } + } +} + +// Create nodes and routes from the temporary topology, GTNETS_Topolgy. +void GTSim::create_gtnets_topology(){ + add_nodes(); + node_connect(); +} + +// Add a route that includes more than one hop. All one hop +// routes must have been added. When this function is called +// for the first time, all gtnets nodes are generated. +int GTSim::add_route(int src, int dst, int* links, int nlink){ + if (is_topology_ == 0){ + create_gtnets_topology(); + // topo_->print_topology(); + is_topology_ = 1; + } + + IPAddr_t mymask = IPAddr("255.255.255.255"); - gtnets_nodes_[leftid]-> - AddDuplexLink(gtnets_nodes_[rightid], *gtnets_links_[linkid]); + int src_node = topo_->nodeid_from_hostid(src); + int dst_node = topo_->nodeid_from_hostid(dst); + + if (gtnets_nodes_.find(src_node) == gtnets_nodes_.end()){ + fprintf(stderr, "node %d not found\n", src_node); + return -1; + } + if (gtnets_nodes_.find(dst_node) == gtnets_nodes_.end()){ + fprintf(stderr, "node %d not found\n", dst_node); + return -1; + } + + Node* tmpsrc = gtnets_nodes_[src_node]; + Node* tmpdst = gtnets_nodes_[dst_node]; + + int next_node, cur_node; + + cur_node = src_node; + for (int i = 0; i < nlink; i++){ + if (gtnets_nodes_.find(cur_node) == gtnets_nodes_.end()){ + fprintf(stderr, "node %d not found\n", cur_node); + return -1; + } + next_node = topo_->peer_node_id(links[i], cur_node); + if (next_node < 0){ + fprintf(stderr, "peer node not found\n"); + return -1; + } + if (gtnets_nodes_.find(next_node) == gtnets_nodes_.end()){ + fprintf(stderr, "node %d not found\n", next_node); + return -1; + } + + //add route + Node* tmpcur = gtnets_nodes_[cur_node]; + Node* tmpnext = gtnets_nodes_[next_node]; + + tmpcur->AddRoute(tmpdst->GetIPAddr(), + mymask, + tmpcur->GetIfByNode(tmpnext), + tmpnext->GetIPAddr()); + + tmpnext->AddRoute(tmpsrc->GetIPAddr(), + mymask, + tmpnext->GetIfByNode(tmpcur), + tmpcur->GetIPAddr()); + + cur_node = next_node; + } + if (cur_node != dst_node){ + fprintf(stderr, "Route inconsistency, last: %d, dst: %d\n", + cur_node, dst_node); + return -1; } + + return 0; } + + int GTSim::create_flow(int src, int dst, long datasize, void* metadata){ + //if no route with more than one links, topology has not been generated. + //generate it here. if (is_topology_ == 0){ create_gtnets_topology(); + // topo_->print_topology(); is_topology_ = 1; } - //TODO: what if more than two flows? - //TODO: check if src and dst exists. - //TODO: should use "flowID" to name servers and clients. - gtnets_servers_[nflow_] = (TCPServer*)gtnets_nodes_[gtnets_hosts_[dst]]-> - AddApplication(TCPServer(TCPReno())); + + int src_node = topo_->nodeid_from_hostid(src); + if (src_node < 0){ + fprintf(stderr, "src %d not found\n"); + return -1; + } + int dst_node = topo_->nodeid_from_hostid(dst); + if (dst_node < 0){ + fprintf(stderr, "dst %d not found\n"); + return -1; + } + + gtnets_servers_[nflow_] = (TCPServer*)gtnets_nodes_[dst_node]-> + AddApplication(TCPServer(TCPReno())); gtnets_servers_[nflow_]->BindAndListen(80); - gtnets_clients_[nflow_] = (TCPSend*)gtnets_nodes_[gtnets_hosts_[src]]-> - AddApplication(TCPSend(metadata, gtnets_nodes_[gtnets_hosts_[dst]]->GetIPAddr(), + gtnets_clients_[nflow_] = (TCPSend*)gtnets_nodes_[src_node]-> + AddApplication(TCPSend(metadata, gtnets_nodes_[dst_node]->GetIPAddr(), 80, Constant(datasize), TCPReno())); gtnets_clients_[nflow_]->SetSendCallBack(tcp_sent_callback); gtnets_clients_[nflow_]->Start(0); @@ -164,6 +280,7 @@ Time_t GTSim::get_time_to_next_flow_completion(){ write(pfds[1], (const void*)&t, sizeof(Time_t)); exit(0); } + return t1; } @@ -184,14 +301,6 @@ int GTSim::run(double delta){ return 0; } -// Clean up. -int GTSim::finalize(){ - //TODO - is_topology_ = 0; - delete sim_; - delete topo_; - return 0; -} void static tcp_sent_callback(void* action, double completion_time){ // Schedule the flow complete event. diff --git a/src/surf/gtnets/gtnets_simulator.h b/src/surf/gtnets/gtnets_simulator.h index b5a34fd5f0..4194383559 100644 --- a/src/surf/gtnets/gtnets_simulator.h +++ b/src/surf/gtnets/gtnets_simulator.h @@ -1,4 +1,8 @@ -//Kayo Fujiwara 1/8/2007 +/* $Id$ */ +/* Copyright (c) 2007 Kayo Fujiwara. 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 _GTNETS_SIM_H #define _GTNETS_SIM_H @@ -22,6 +26,7 @@ #include "tcp-newreno.h" #include "validation.h" #include "event.h" +#include "routing-manual.h" using namespace std; @@ -33,17 +38,24 @@ public: ~GTSim(); public: int add_link(int id, double bandwidth, double latency); + int add_onehop_route(int src, int dst, int link); int add_route(int src, int dst, int* links, int nlink); + int add_router(int id); int create_flow(int src, int dst, long datasize, void* metadata); double get_time_to_next_flow_completion(); int run_until_next_flow_completion(void*** metadata, int* number_of_flows); int run(double deltat); - int finalize(); void create_gtnets_topology(); private: + void add_nodes(); + void node_connect(); + + bool node_include(int); + bool link_include(int); Simulator* sim_; - SGTopology* topo_; + GTNETS_Topology* topo_; + RoutingManual* rm_; int nnode_; int is_topology_; int nflow_; @@ -52,8 +64,7 @@ private: map gtnets_nodes_; map gtnets_servers_; map gtnets_clients_; - map tmp_links_; - map gtnets_hosts_; // + map gtnets_metadata_; }; diff --git a/src/surf/gtnets/gtnets_topology.cc b/src/surf/gtnets/gtnets_topology.cc index 16f019e837..16f97480ea 100644 --- a/src/surf/gtnets/gtnets_topology.cc +++ b/src/surf/gtnets/gtnets_topology.cc @@ -1,380 +1,449 @@ +/* $ID$ */ -//SGNode, SGTopology: tmporary classes for GTNetS topology. +/* Copyright (c) 2007 Kayo Fujiwara. 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. */ + +//GTNETS_Link, GTNETS_Node, GTNETS_Topology: +//Temporary classes for generating GTNetS topology #include "gtnets_topology.h" // -// SGNode +// GTNETS_Node // -// TODO when merging a node, remember to add the existing "hosts". -SGNode::SGNode(int id, int hostid){ - ID_ = id; - if (hostid >= 0) - hosts_.push_back(hostid); -} -SGNode::~SGNode(){ - //TODO +// Constructor +GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){} +// Copy constructor +GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){ + ID_ = node.ID_; + is_router_ = node.is_router_; + hosts_ = node.hosts_; } -void SGNode::add_link(SGLink* newlink){ - links_.push_back(newlink); -} +GTNETS_Node::~GTNETS_Node(){ - -SGLink* SGNode::other_link(int linkid){ - for (int i = 0; i < links_.size(); i++){ - if (links_[i]->id() != linkid) - return links_[i]; - } - return NULL; } -bool SGNode::has_link(SGLink* link){ - for (int i = 0; i < links_.size(); i++){ - //TODO can compare by object itself? - if ((links_[i]->id()) == (link->id())) - return true; +// hostid = network_card_id +int GTNETS_Node::add_host(int hostid){ + if (is_router_){ + fprintf(stderr, "Cannot add a host to a router node.\n"); + return -1; } - return false; + hosts_.insert(hostid); + return 0; } -void SGNode::print_hosts(){ - cout << "hosts["; - for (int i = 0; i < hosts_.size(); i++){ - cout << hosts_[i] << ","; +// Add a router. If this node already has a router/host, +// return -1. +int GTNETS_Node::add_router(int routerid){ + if (hosts_.size() > 1){ + fprintf(stderr, "Router node should have only one router.\n"); + return -1; + }else if (hosts_.size() == 1){ + if (hosts_.find(routerid) != hosts_.end()){ + //printf("the router already exists\n"); + return 0; + }else{ + fprintf(stderr, "Node %d is a different router.\n"); + return -1; + } } - cout << "] "; + is_router_ = true; + hosts_.insert(routerid); + return 0; } -void SGNode::print_links(){ - cout << "links["; - for (int i = 0; i < links_.size(); i++){ - cout << links_[i]->id() << ","; - } - cout << "]" << endl; +bool GTNETS_Node::is_router(){ + return is_router_; } -vector& SGNode::links(){ - return links_; +bool GTNETS_Node::include(int hostid){ + if (hosts_.find(hostid) == hosts_.end()) return false; + else return true; } -vector& SGNode::hosts(){ - return hosts_; + +void GTNETS_Node::print_hosts(){ + set::iterator it; + printf("["); + for (it = hosts_.begin(); it != hosts_.end(); it++){ + printf(" %d", *it); + } + printf("]"); } // -// SGLink +// GTNETS_Link // -SGLink::SGLink(int id, SGNode* left, SGNode* right) - :ID_(id), - left_node_(left), - right_node_(right){} +// Constructor +GTNETS_Link::GTNETS_Link(){ + ID_=-1; + src_node_ = 0; + dst_node_ = 0; +} +GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){} -SGLink::~SGLink(){ +// Copy constructor +GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){ + ID_ = link.ID_; + src_node_ = link.src_node_; + dst_node_ = link.dst_node_; +} +GTNETS_Link::~GTNETS_Link(){ + } -// add_left_linK: tow things. -// add the link to the corresponding node. -// add the corresponding node to the new link. -// (change from the tmp node to the correct node) -void SGLink::add_left_link(SGLink* newlink, int side){ - if (!left_node_){ - //if alllinks don't have a node, then copy it from - //tmporary link. - if (side == LEFTSIDE){ - left_node_ = newlink->left_node_; - } else if (side == RIGHTSIDE){ - left_node_ = newlink->right_node_; - } else { - cout << "should not come here. side: " << side << endl; - } - } else { - // if already exists, then add the new link to the existing node. - left_node_->add_link(newlink); +void GTNETS_Link::print_link_status(){ + printf("== LINKID: %d\n", ID_); + if (src_node_){ + printf(" [SRC] ID: %d, router?: %d, hosts[]: ", + src_node_->id(), src_node_->is_router()); + src_node_->print_hosts(); + printf("\n"); } - if (side == LEFTSIDE){ - newlink->left_node_ = left_node_; - //printf("link[%d] new left node: %d\n", link.ID, @left_node.ID) - }else if (side == RIGHTSIDE){ - newlink->right_node_ = left_node_; - //printf("link[%d] new left node: %d\n", link.ID, @left_node.ID) - }else{ - cout << "should not come here. side: " << side << endl; + if (dst_node_){ + printf(" [DST] ID: %d, router?: %d, hosts[]: ", + dst_node_->id(), dst_node_->is_router()); + dst_node_->print_hosts(); + printf("\n"); } +} +GTNETS_Node* GTNETS_Link::src_node(){ + return src_node_; } -void SGLink::add_right_link(SGLink* newlink, int side){ - if (!right_node_) { - //if alllinks doesn't have a node, then copy it from - //tmporary link. - if (side == LEFTSIDE){ - right_node_ = newlink->left_node_; - }else if (side == RIGHTSIDE){ - right_node_ = newlink->right_node_; - }else{ - cout << "should not come here. side: " << side << endl; - } - }else{ - right_node_->add_link(newlink); - } +GTNETS_Node* GTNETS_Link::dst_node(){ + return dst_node_; +} - if (side == LEFTSIDE){ - newlink->left_node_ = right_node_; - //printf("link[%d] new left node: %d\n", link.ID, @right_node.ID) - }else if (side == RIGHTSIDE){ - newlink->right_node_ = right_node_; - //printf("link[%d] new right node: %d\n", link.ID, @right_node.ID) - }else{ - cout << "should not come here. side: " << side << endl; +bool GTNETS_Link::route_exists(){ + if (src_node_ && dst_node_) return true; + else return false; +} + +// return the peer node id +int GTNETS_Link::peer_node(int cur_id){ + if (cur_id == src_node_->id()) return dst_node_->id(); + else if (cur_id == dst_node_->id()) return src_node_->id(); + else { + fprintf(stderr, "node not found\n"); + return -1; } } -bool SGLink::is_inleft(SGLink* link){ - if (!left_node_) - return false; - else - return left_node_->has_link(link); +int GTNETS_Link::add_src(GTNETS_Node* src){ + src_node_ = src; } -bool SGLink::is_inright(SGLink* link){ - if (!right_node_) - return false; - else - return right_node_->has_link(link); +int GTNETS_Link::add_dst(GTNETS_Node* dst){ + dst_node_ = dst; } -//return the pointer for the left link. -SGLink* SGLink::left_link(){ - if (!left_node_){ - return NULL; - }else{ - return left_node_->other_link(ID_); - } +// +// GTNETS_Topology +// + +// Constructor +GTNETS_Topology::GTNETS_Topology(){ + nodeID_ = 0; } -SGLink* SGLink::right_link(){ - if (!right_node_){ - return NULL; - }else{ - return right_node_->other_link(ID_); +// Destructor +GTNETS_Topology::~GTNETS_Topology(){ + map::iterator it1; + for (it1 = links_.begin(); it1 != links_.end(); it1++){ + delete it1->second; + } + vector::iterator it2; + for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){ + delete *it2; } - } -SGNode* SGLink::left_node(){ - return left_node_; -} +int GTNETS_Topology::link_size(){ + return links_.size(); +} -SGNode* SGLink::right_node(){ - return right_node_; +int GTNETS_Topology::node_size(){ + return nodes_.size(); } +int GTNETS_Topology::add_link(int id){ + map::iterator iter = links_.find(id); -void SGLink::print(){ - printf("link[%d]:\n", ID_); - if (left_node_){ - printf(" left node: %d ", left_node_->id()); - left_node_->print_hosts(); - left_node_->print_links(); - } - - if (right_node_){ - printf(" right node: %d ", right_node_->id()); - right_node_->print_hosts(); - right_node_->print_links(); + if(iter == links_.end()) { + GTNETS_Link* link= new GTNETS_Link(id); + //printf("link %d is added: %d\n", id, link->id()); + //links_.insert(make_pair(id, link)); + links_[id] = link; + return 0; + }else{ + fprintf(stderr, "Link %d already exists.\n", id); + return -1; } } +int GTNETS_Topology::add_router(int id){ + set::iterator iter = routers_.find(id); -SGTopology::SGTopology(){ - nodeID_ = 0; + if(iter == routers_.end()) { + //printf("router %d is inserted\n", id); + routers_.insert(id); + return 0; + }else{ + fprintf(stderr, "Router %d already exists.\n", id); + return -1; + } } -SGTopology::~SGTopology(){ +bool GTNETS_Topology::is_router(int id){ + set::iterator iter = routers_.find(id); + if(iter == routers_.end()) return false; + else return true; +} +//return the node id of the peer of cur_id by linkid. +int GTNETS_Topology::peer_node_id(int linkid, int cur_id){ + //printf("linkid: %d, cur_id: %d\n", linkid, cur_id); + GTNETS_Link* link = links_[linkid]; + if (!link) { + fprintf(stderr, "link %d not found\n", linkid); + return -1; + } + if ((cur_id < 0) || (cur_id > nodes_.size()-1)){ + fprintf(stderr, "node %d not found\n", cur_id); + return -1; + } + int peer = link->peer_node(nodes_[cur_id]->id()); + if (peer < 0){ + fprintf(stderr, "peer not found\n"); + return -1; + } + return peer; } +int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){ + GTNETS_Link* link; -// TODO: assume that all router-route 1-hop routes are set. -void SGTopology::add_link(int src, int dst, int* links, int nsize){ - if (nsize == 1){ - map::iterator it; - it = nodes_.find(src); - //if not exists, add one. - if (it == nodes_.end()){ - nodes_[src] = new SGNode(src, src); - } - it = nodes_.find(dst); - //if not exists, add one. - if (it == nodes_.end()){ - nodes_[dst] = new SGNode(dst, dst); - } + map::iterator iter = links_.find(linkid); - map::iterator itl; - itl = links_.find(links[0]); - //if not exists, add one. - if (itl == links_.end()){ - links_[links[0]] = new SGLink(links[0], nodes_[src], nodes_[dst]); - } + if(iter == links_.end()) { + fprintf(stderr, "Link %d not found.\n", linkid); + return -1; + }else{ + link = iter->second; } -} + // printf("add_onehop_route: src: %d, dst: %d, linkid: %d, %d\n", + // src, dst, linkid, link->id()); -//create a temporary link set. (one route) -// not used now. should clean up... -void SGTopology::create_tmplink(int src, int dst, int* links, int nsize){ - map tmplinks; + GTNETS_Node *src_node, *dst_node; + src_node = link->src_node(); + dst_node = link->dst_node(); - SGNode* n1; - SGNode* n2; - int cur = -1; - int nex; + // If not exists a route, add one. + if (!link->route_exists()){ + //check whether there exists a node for the src host/router. + int s_node_id = nodeid_from_hostid(src); + int node_id; + + if (s_node_id < 0){//not exist, create one. + s_node_id = nodeID_; + GTNETS_Node* node1 = new GTNETS_Node(s_node_id); + nodes_.push_back(node1); + hosts_[src] = nodes_[s_node_id]->id(); - for (int i = 0; i < nsize; i++){ - if (i == 0) { - nodeID_++; //new node - n1 = new SGNode(nodeID_, src); - }else - n1 = n2; //current - - cur = links[i]; - - if (i == (nsize-1)){ nodeID_++; - n2 = new SGNode(nodeID_, dst); - }else{ - nex = links[i+1]; - nodeID_++; //new node - n2 = new SGNode(nodeID_, -1); } - tmplinks[cur] = new SGLink(cur, n1, n2); - if (n1) n1->add_link(tmplinks[cur]); - if (n2) n2->add_link(tmplinks[cur]); + if (is_router(src)) + nodes_[s_node_id]->add_router(src); + else + nodes_[s_node_id]->add_host(src); + + link->add_src(nodes_[s_node_id]); + + //check whether there exists a node for the dst host/router. + int d_node_id = nodeid_from_hostid(dst); + if (d_node_id < 0){//not exist, create one. + d_node_id = nodeID_; + GTNETS_Node* node2 = new GTNETS_Node(d_node_id); + nodes_.push_back(node2); + hosts_[dst] = nodes_[d_node_id]->id(); + nodeID_++; + } + + if (is_router(dst)) + nodes_[d_node_id]->add_router(dst); + else + nodes_[d_node_id]->add_host(dst); + + link->add_dst(nodes_[d_node_id]); + + // other: has either src or dst (error) + }else if (!src_node || !dst_node){ + fprintf(stderr, "Either src or dst is null\n"); + return -1; } - for (int i = 0; i < nsize; i++){ - //tmplinks[links[i]]->print(); - merge_link(tmplinks[links[i]]); + // case 1: link has two routers + else if (src_node->is_router() && dst_node->is_router()){ + int tmpsrc1 = src_node->id(); + int tmpsrc2 = nodeid_from_hostid(src); + int tmpdst1 = dst_node->id(); + int tmpdst2 = nodeid_from_hostid(dst); + if (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) || + ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))){ + fprintf(stderr, "Route already exists\n"); + }else{ + fprintf(stderr, "Different one hop route defined\n"); + return -1; + } } - add_tmplink_to_links(tmplinks); -} + // case 2: link has one router and one host + else if (src_node->is_router() && !dst_node->is_router()){ + int newsrc, newdst; + if (is_router(src)){ + newsrc = src; + newdst = dst; + }else if (is_router(dst)){ + newsrc = dst; + newdst = src; + }else{ + fprintf(stderr, "one of nodes should be a router\n"); + return -1; + } -void SGTopology::merge_link(SGLink* link){ - map::iterator iter; - iter = links_.find(link->id()); - if (iter == links_.end()){ - //if the link has not been added to the topology.links_, then - //printf("link %d doesn't exist in alllinks. No action.\n", link->id()); - return; - }else{ - int ncommon = 0; - int comleft = -1; //if tmplink.left == @alllinks.link.left, 0, otherwise, 1. - int comright = -1; //if tmplink.right == @alllinks.link.left, 0, otherwise, 1. - //since link is from tmplinks, each link has at most two neibours. - - if (link->left_link()){ - //printf("common neibor: left_first: %d\n", link->left_link()->id()); - if (links_[link->id()]->is_inleft(link->left_link())){ - comleft = 0; - ncommon += 1; - } - if (links_[link->id()]->is_inright(link->left_link())){ - comleft = 1; - ncommon += 1; - } + if (src_node->id() != nodeid_from_hostid(newsrc)){ + fprintf(stderr, "The router should be identical\n"); + return -1; } - if (link->right_link()){ - //printf("common neibor: right_first: %d\n", link->right_link()->id()); - if (links_[link->id()]->is_inleft(link->right_link())){ - comright = 0; - ncommon += 1; - } - if (links_[link->id()]->is_inright(link->right_link())){ - comright = 1; - ncommon += 1; - } + //now, to add dst to dst_node, dst should be a host. + + if (is_router(newdst)){ + fprintf(stderr, "dst %d is not an endpoint. cannot add it to dst_node\n"); + return -1; } - //printf("common: %d, comright: %d, comleft: %d\n",ncommon, comright, comleft); + if (!dst_node->include(newdst)){ + dst_node->add_host(newdst); + hosts_[newdst] = dst_node->id(); + } + } + else if (!src_node->is_router() && dst_node->is_router()){ + int newsrc, newdst; + if (is_router(src)){ + newsrc = dst; + newdst = src; + }else if (is_router(dst)){ + newsrc = src; + newdst = dst; + }else{ + fprintf(stderr, "one of nodes should be a router\n"); + return -1; + } - if (ncommon == 0){ - //merge link.n1 with @alllink.n1, link.n2 with @alllink.n2 - if (link->left_link()) - links_[link->id()]->add_left_link(link->left_link(), RIGHTSIDE); - if (link->right_link()) - links_[link->id()]->add_right_link(link->right_link(), LEFTSIDE); - - }else if (ncommon == 1){ - printf("ncommon %d\n", links_[link->id()]->id()); - //left --> right - if ((comleft == -1) && (comright == 0)){ - if (link->left_link()) - links_[link->id()]->add_right_link(link->left_link(), RIGHTSIDE); - }else if ((comleft == -1) && (comright == 1)){ - //left --> left - if (link->left_link()) - links_[link->id()]->add_left_link(link->left_link(), RIGHTSIDE); - }else if ((comright == -1) && (comleft == 0)){ - //right --> right - if (link->right_link()) - links_[link->id()]->add_right_link(link->right_link(), LEFTSIDE); - }else if ((comright == -1) && (comleft == 1)){ - //right --> left - if (link->right_link()) - links_[link->id()]->add_left_link(link->right_link(), LEFTSIDE); - }else{ - fprintf(stderr, "should not come here\n"); - } + if (dst_node->id() != hosts_[newdst]){ + fprintf(stderr, "The router should be identical\n"); + return -1; + } - }else if (ncommon == 2){ - //no change + //now, to add dst to src_node, dst should be a host. - }else{ - fprintf(stderr, "error, common links are more than 2. %d\n", ncommon); + if (is_router(newsrc)){ + fprintf(stderr, "dst %d is not an endpoint. cannot add it to src_node\n"); + return -1; + } + + if (!src_node->include(newsrc)){ + src_node->add_host(newsrc); + hosts_[newsrc] = src_node->id(); } } -} -void SGTopology::add_tmplink_to_links(map tmplink){ - map::iterator iter; + // case 3: link has two hosts + else if (!src_node->is_router() && !dst_node->is_router()){ - for (iter = tmplink.begin(); iter != tmplink.end(); iter++){ - map::iterator alliter = links_.find(iter->first); - if (alliter == links_.end()){ - // cout << "tmplink " << iter->first << " not found in links_, adding." - // << endl; - links_[iter->first] = iter->second; + if (is_router(src) || is_router(dst)){ + fprintf(stderr, "Cannot add a router to host-host link\n"); + return -1; } - // cout << "tmplink: " << iter->second->id() << endl; + + //if both are hosts, the order doesn't matter. + if (src_node->include(src)){ + if (dst_node->include(dst)){ + //nothing + }else{ + dst_node->add_host(dst); + hosts_[dst] = dst_node->id(); + } + }else if (src_node->include(dst)){ + if (dst_node->include(src)){ + //nothing + }else{ + dst_node->add_host(src); + hosts_[src] = dst_node->id(); + } + }else if (dst_node->include(src)){ + if (src_node->include(dst)){ + //nothing + }else{ + src_node->add_host(dst); + hosts_[dst] = src_node->id(); + } + }else if (dst_node->include(dst)){ + if (src_node->include(src)){ + //nothing + }else{ + src_node->add_host(src); + hosts_[src] = src_node->id(); + } + }else{ + src_node->add_host(src); + dst_node->add_host(dst); + hosts_[src] = src_node->id(); + hosts_[dst] = dst_node->id(); + } + + } + else{ + fprintf(stderr, "Shouldn't be here\n"); + return -1; } - + return 0; } -void SGTopology::print_topology(){ - map::iterator iter; - for (iter = links_.begin(); iter != links_.end(); iter++){ - iter->second->print(); - } +int GTNETS_Topology::nodeid_from_hostid(int hostid){ + map::iterator it = hosts_.find(hostid); + if (it == hosts_.end()) + return -1; + else return it->second; } -void SGTopology::create_gtnets_topology(){ - map::iterator it; +void GTNETS_Topology::print_topology(){ + map::iterator it; for (it = links_.begin(); it != links_.end(); it++){ - + it->second->print_link_status(); } } -map& SGTopology::get_links(){ +const vector& GTNETS_Topology::nodes(){ + return nodes_; +} + +const map& GTNETS_Topology::links(){ return links_; } diff --git a/src/surf/gtnets/gtnets_topology.h b/src/surf/gtnets/gtnets_topology.h index 6202438c15..b233d7e7e7 100644 --- a/src/surf/gtnets/gtnets_topology.h +++ b/src/surf/gtnets/gtnets_topology.h @@ -1,3 +1,9 @@ +/* $ID$ */ + +/* Copyright (c) 2007 Kayo Fujiwara. 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 _GTNETS_TOPOLOGY_H @@ -5,97 +11,88 @@ #include #include +#include #include -#define LEFTSIDE 0 -#define RIGHTSIDE 1 - using namespace std; -class SGLink; +class GTNETS_Link; -class SGNode{ +class GTNETS_Node{ public: - SGNode(int id, int hostid); - ~SGNode(); - - void add_link(SGLink*); + GTNETS_Node(int); + GTNETS_Node(const GTNETS_Node& node); + ~GTNETS_Node(); - //get other link than the link with the given id. - //Note it's only for the case the node has two links. - SGLink* other_link(int); - - bool has_link(SGLink*); //TODO can do const SGLink*? - void print_links(); - void print_hosts(); - - vector& links(); - vector& hosts(); + int add_host(int); + int add_router(int); int id(){return ID_;}; + bool is_router(); + bool include(int); + void print_hosts(); private: int ID_; - bool ishost_; - vector hosts_; //simgrid hosts - vector links_; + int is_router_; + set hosts_; //simgrid hosts }; -class SGLink{ +class GTNETS_Link{ public: - SGLink(int id, SGNode* left, SGNode* right); - ~SGLink(); - - //for a temporary link set, that is, a link has at most two neibours. - SGLink* left_link(); - SGLink* right_link(); - - - SGNode* left_node(); - SGNode* right_node(); - - bool is_inleft(SGLink*); - bool is_inright(SGLink*); - - void add_left_link(SGLink*, int side); - void add_right_link(SGLink*, int side); - + GTNETS_Link(); + GTNETS_Link(int id); + GTNETS_Link(const GTNETS_Link&); + ~GTNETS_Link(); + + GTNETS_Node* src_node(); + GTNETS_Node* dst_node(); + int peer_node(int); int id(){return ID_;}; - - void print(); + void print_link_status(); + int add_src(GTNETS_Node*); + int add_dst(GTNETS_Node*); + bool route_exists(); private: int ID_; - SGNode* left_node_; - SGNode* right_node_; + GTNETS_Node* src_node_; + GTNETS_Node* dst_node_; }; - -class SGTopology{ +// To create a topology: +// 1. add links +// 2. add routers +// 3. add onehop links +class GTNETS_Topology{ public: - SGTopology(); - ~SGTopology(); - - void add_link(int src, int dst, int* links, int nsize); - - void create_tmplink(int src, int dst, int* links, int nsize); - - void merge_link(SGLink*); - - void add_tmplink_to_links(map tmplink); //??? - + GTNETS_Topology(); + ~GTNETS_Topology(); + + bool is_router(int id); + int peer_node_id(int linkid, int cur_id); + int add_link(int id); + int add_router(int id); + int add_onehop_route(int src, int dst, int link); + + int nodeid_from_hostid(int); + int link_size(); + int node_size(); void print_topology(); + const vector& nodes(); + const map& links(); - void create_gtnets_topology(); - - map& get_links(); - private: + int nodeID_; - map links_; - map nodes_; + map links_; + vector nodes_; + + map hosts_; //hostid->nodeid + + set routers_; }; #endif