X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/7c878c7f73356568b2cf6c801d90e44a08a1e233..33c343e90884708b2c9b64af35a9b39f4caf13a7:/src/surf/gtnets/gtnets_simulator.cc diff --git a/src/surf/gtnets/gtnets_simulator.cc b/src/surf/gtnets/gtnets_simulator.cc index 498bb370a0..8d5c3ab7fd 100644 --- a/src/surf/gtnets/gtnets_simulator.cc +++ b/src/surf/gtnets/gtnets_simulator.cc @@ -1,9 +1,22 @@ -//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 +#include + +using namespace std; -void static tcp_sent_callback(int id, double completion_time); +static vector meta_flows; +static int* meta_nflow; +static int meta_flg = 0; + + +void static tcp_sent_callback(void* action, double completion_time); // Constructor. // TODO: check the default values. @@ -12,128 +25,240 @@ GTSim::GTSim(){ is_topology_ = 0; nflow_ = 0; sim_ = new Simulator(); - topo_ = new SGTopology(); + topo_ = new GTNETS_Topology(); + sim_->verbose=false; // Set default values. TCP::DefaultAdvWin(wsize); TCP::DefaultSegSize(1000); 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(); + is_topology_ = 1; + } + + IPAddr_t mymask = IPAddr("255.255.255.255"); + + 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]; - gtnets_nodes_[leftid]-> - AddDuplexLink(gtnets_nodes_[rightid], *gtnets_links_[linkid]); + 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(); 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(nflow_, 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); + + gtnets_action_to_flow_[metadata] = nflow_; nflow_++; return 0; @@ -143,50 +268,63 @@ Time_t GTSim::get_time_to_next_flow_completion(){ int status; Time_t t1; int pfds[2]; + int soon_pid=-1; + meta_flg=0; + + //remain needs to be updated in the future + Count_t remain; pipe(pfds); t1 = 0; - if (fork() != 0){ + + if ( (soon_pid=fork()) != 0){ read(pfds[0], &t1, sizeof(Time_t)); - waitpid(-1, &status, 0); + waitpid(soon_pid, &status, 0); }else{ Time_t t; t = sim_->RunUntilNextCompletion(); write(pfds[1], (const void*)&t, sizeof(Time_t)); exit(0); } + return t1; } +double GTSim::gtnets_get_flow_rx(void *metadata){ + int flow_id = gtnets_action_to_flow_[metadata]; + return gtnets_servers_[flow_id]->totRx; +} + int GTSim::run_until_next_flow_completion(void ***metadata, int *number_of_flows){ + + meta_flows.clear(); + meta_nflow = number_of_flows; + meta_flg = 1; + Time_t t1 = sim_->RunUntilNextCompletion(); - sim_->Run(t1); - //TODO set metadata and number of flows. + + *metadata = (meta_flows.empty() ? NULL : &meta_flows[0]); return 0; } int GTSim::run(double delta){ + meta_flg=0; sim_->Run(delta); return 0; } -// Clean up. -int GTSim::finalize(){ - //TODO - is_topology_ = 0; - delete sim_; - delete topo_; - return 0; -} -void static tcp_sent_callback(int id, double completion_time){ +void static tcp_sent_callback(void* action, double completion_time){ // Schedule the flow complete event. SimulatorEvent* e = new SimulatorEvent(SimulatorEvent::FLOW_COMPLETE); Simulator::instance->Schedule(e, 0, Simulator::instance); - //TODO: set metadata - printf("In tcp_sent_callback: flow id: %d, time: %f\n", id, completion_time); + if (meta_flg){ + meta_flows.push_back(action); + (*meta_nflow)++; + } } +