lan.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1997 University of Southern California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *      This product includes software developed by the Information Sciences
  16.  *      Institute of the University of Southern California.
  17.  * 4. Neither the name of the University nor of the Institute may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  */
  34. #include "sincos.h"
  35. #include "config.h"
  36. #include "lan.h"
  37. #include "edge.h"
  38. #include "packet.h"
  39. #include "node.h"
  40. #include "view.h"
  41. #include "psview.h"
  42. #include "paint.h"
  43. #include "netmodel.h"
  44. #include "trace.h"
  45. LanLink::LanLink(Edge *e): edge_(e)
  46. {
  47.   /*need to search through the destination node's links to find the link
  48.     that's the twin of this one (i.e, same nodes, other direction) */
  49.   int lan=e->src();
  50.   Node *n=e->neighbor();
  51.   Edge *te=n->links();
  52.   while (te!=NULL) {
  53.     if (te->dst()==lan) {
  54.       pair_=te;
  55.       break;
  56.     }
  57.     te=te->next_;
  58.   }
  59. }
  60. int LanLink::placed()
  61. {
  62.   return edge_->neighbor()->marked();
  63. }
  64. //----------------------------------------------------------------------
  65. // Lan::Lan(const char *name, NetModel *nm, double ps, double bw,
  66. //          double delay, double angle)
  67. //----------------------------------------------------------------------
  68. Lan::Lan(const char *name, NetModel *nm, double ps, double bw,
  69.          double delay, double angle) :
  70.   Animation(0,0),
  71.   nm_(nm),
  72.   links_(NULL),
  73.   ps_(ps),
  74.   bw_(bw), 
  75.   delay_(delay),
  76.   angle_(angle),
  77.   marked_(0),
  78.   max_(0) {
  79.   virtual_node_ = new VirtualNode(name, this);
  80.   name_ = new char[strlen(name) + 1];
  81.   strcpy(name_, name);
  82.   ln_ = atoi(name); /*XXX*/
  83.   paint_ = Paint::instance()->thick();
  84.   dropHash_ = new Tcl_HashTable;
  85.   // XXX: unique packet id == (src, dst, id). Its size may be changed later.
  86.   Tcl_InitHashTable(dropHash_, 3);
  87. }
  88. //----------------------------------------------------------------------
  89. //----------------------------------------------------------------------
  90. Lan::~Lan() {
  91.   if (dropHash_ != NULL) {
  92.     Tcl_DeleteHashTable(dropHash_);
  93.     delete dropHash_;
  94.   }
  95.   delete virtual_node_;
  96. }
  97. float Lan::distance(float /*x*/, float /*y*/) const 
  98. {
  99. // TODO: to be added
  100. return HUGE_VAL;
  101. }
  102. //----------------------------------------------------------------------
  103. //----------------------------------------------------------------------
  104. static int to_the_left(Edge *e, double angle, int incoming) {
  105.   double edge_angle = e->angle();
  106.   if (incoming)
  107.     edge_angle = 1.0 + edge_angle;
  108.   if (edge_angle > 2.0)
  109.     edge_angle -= 2.0;
  110.   double a = angle - edge_angle;
  111.   if (a < 0) {
  112.     a += 2.0;
  113.   }
  114.   if (a > 1.0) {
  115.     return 1;
  116.   } else {
  117.     return 0;
  118.   }
  119. }
  120. //----------------------------------------------------------------------
  121. // void Lan::add_link(Edge *e)
  122. //   - add a link to the shared bus line
  123. //----------------------------------------------------------------------
  124. void Lan::add_link(Edge *e) {
  125.   int left = 0; 
  126.   int right = 0;
  127.   double sine, cosine, left_length, right_length;
  128.   Node * source, * destination;
  129.   LanLink * ll;
  130.   ll = new LanLink(e);
  131.   source = e->getSourceNode();
  132.   destination = e->getDestinationNode();
  133.   SINCOSPI(angle_, &sine, &cosine);
  134.   ll->next(links_);
  135.   links_ = ll;
  136.   virtual_node_->add_link(e);
  137.   // Keep track of how long the "bus" is
  138.   ll = links_;
  139.   while (ll != NULL) {
  140.     if (to_the_left(ll->edge(), angle_, 0)) {
  141.       left++;
  142.     } else {
  143.       right++;
  144.     }
  145.     ll = ll->next();
  146.   }
  147.   left_length = left * (destination->size() + source->size() + size_);
  148.   right_length = right * (destination->size() + source->size() + size_);
  149.   if (max_ < left_length) {
  150.     max_ = (int) ceil(left_length);
  151.    }
  152.   if (max_ < right_length) {
  153.     max_ = (int) ceil(right_length);
  154.   }
  155. }
  156. //----------------------------------------------------------------------
  157. //----------------------------------------------------------------------
  158. void Lan::update_bb() {
  159. double s,c;
  160. SINCOSPI(angle_,&s,&c);
  161. bb_.xmin = x_ - size_*c;
  162.         bb_.xmax = x_+size_*c*(2*max_+1);
  163. bb_.ymin = y_ - size_*s;
  164.         bb_.ymax = y_+size_*s*(2*max_+1);
  165. }
  166. //----------------------------------------------------------------------
  167. //----------------------------------------------------------------------
  168. void
  169. Lan::size(double size) {
  170.   size_ = size;
  171.   update_bb();
  172. }
  173. //----------------------------------------------------------------------
  174. //----------------------------------------------------------------------
  175. void
  176. Lan::place(double x, double y) {
  177.   x_ = x;
  178.   y_ = y;
  179.   update_bb();
  180. }
  181. //----------------------------------------------------------------------
  182. //----------------------------------------------------------------------
  183. void Lan::draw(class View* nv, double time) {
  184.   double s, c;
  185.   SINCOSPI(angle_, &s, &c);
  186.   //nv->line(x_ - size_ * c, y_ - size_ * s,
  187.   //         x_ + size_ * c * (2 * max_ + 1), y_ + size_ * s * (2 * max_ + 1),
  188.   //         paint_);
  189.   nv->line(x_ - size_ * c, y_ - size_ * s,
  190.            x_ + size_ * c + c * max_, y_ + size_ * s + s * max_,
  191.            paint_);
  192. }
  193. //void Lan::draw(class PSView* nv, double /*time*/) const {
  194. /*
  195.   double s,c;
  196.   SINCOSPI(angle_,&s,&c);
  197.   nv->line(x_-size_*c, y_-size_*s, x_+size_*c*(2*max_+1), 
  198.      y_+size_*s*(2*max_+1), paint_);
  199. }
  200. */
  201. void Lan::remove_drop(const TraceEvent &e)
  202. {
  203.   int id[3];
  204.   id[0] = e.pe.src;
  205.   id[1] = e.pe.dst;
  206.   id[2] = e.pe.pkt.id;
  207.   Tcl_HashEntry *he = Tcl_FindHashEntry(dropHash_, (const char *)id);
  208.   if (he != NULL) {
  209.     TraceEvent *pe = (TraceEvent *)Tcl_GetHashValue(he);
  210.     delete pe;
  211.     Tcl_DeleteHashEntry(he);
  212.   }
  213. }
  214. void Lan::register_drop(const TraceEvent &e)
  215. {
  216. int newEntry = 1;
  217. int id[3];
  218. id[0] = e.pe.src;
  219. id[1] = e.pe.dst;
  220. id[2] = e.pe.pkt.id;
  221. Tcl_HashEntry *he = Tcl_CreateHashEntry(dropHash_, (const char *)id, 
  222. &newEntry);
  223. if (he == NULL)
  224. return;
  225. if (newEntry) {
  226.   TraceEvent *pe = new TraceEvent;
  227.   *pe = e;
  228.   Tcl_SetHashValue(he, (ClientData)pe);
  229. }
  230. }
  231. void Lan::arrive_packet(Packet *p, Edge *e, double atime) {
  232.   /*need to duplicate the packet on all other links 
  233.     except the arrival link*/
  234.   LanLink *l=links_;
  235.   PacketAttr pkt;
  236.   int id[3];
  237.   pkt.size=p->size();
  238.   pkt.id=p->id();
  239.   pkt.attr=p->attr();
  240.   strcpy(pkt.type,p->type());
  241.   strcpy(pkt.convid,p->convid());
  242.   while (l!=NULL) {
  243.     Edge *ne=l->edge();
  244.     if (l->pair()!=e) {
  245.       //       Packet *np = nm_->newPacket(pkt, ne, atime);
  246.       nm_->newPacket(pkt, ne, atime);
  247.       id[0] = ne->src();
  248.       id[1] = ne->dst();
  249.       id[2] = p->id();
  250.       Tcl_HashEntry *he = Tcl_FindHashEntry(dropHash_, (const char *)id);
  251.       if (he != NULL) {
  252. // This is a drop packet, fake a trace event and add a drop
  253. TraceEvent *pe = (TraceEvent *)Tcl_GetHashValue(he);
  254. pe->time = atime;
  255. // The fact that this trace event is still there implies that 
  256. // we are going forwards.
  257. nm_->add_drop(*pe, atime, FORWARDS);
  258. delete pe;
  259. Tcl_DeleteHashEntry(he);
  260.       }
  261.     }
  262.     l=l->next();
  263.   }
  264.   rgb *color = Paint::instance()->paint_to_rgb(p->paint());
  265.   paint_ = Paint::instance()->lookup(color->colorname, 5);
  266. }
  267. void Lan::delete_packet(Packet *) {
  268.   paint_ = Paint::instance()->thick();
  269. }
  270. //----------------------------------------------------------------------
  271. //----------------------------------------------------------------------
  272. double Lan::x(Edge *e) const {
  273.   double sine, cosine;
  274.   SINCOSPI(angle_, &sine, &cosine);
  275.   LanLink * l = links_;
  276.   int incoming =- 1;
  277.   int left = -1;
  278.   int right = -1;
  279.   Node * source, * destination;
  280.   source = e->getSourceNode();
  281.   destination = e->getDestinationNode();
  282.   while (l != NULL) {
  283.     if (to_the_left(l->edge(), angle_, 0)) {
  284.       left++;
  285.     } else {
  286.       right++;
  287.     }
  288.     if (l->pair() == e) {
  289.       incoming = 1;
  290.       break;
  291.     } else if (l->edge()==e) {
  292.       incoming = 0;
  293.       break;
  294.     }
  295.     l = l->next();
  296.   }
  297.   if (to_the_left(e, angle_, incoming)) {
  298.     return x_ + cosine * left * (destination->size() + source->size() + size_);
  299.     //return x_ + cosine * left * 2 * size_;
  300.   } else {
  301.     return x_ + cosine * right * (destination->size() + source->size() + size_);
  302.     //return x_ + cosine * right * 2 * size_; 
  303.   }
  304. }
  305. double Lan::y(Edge *e) const {
  306.   double s,c;
  307.   SINCOSPI(angle_,&s,&c);
  308.   LanLink *l=links_;
  309.   int incoming=-1;
  310.   int left=-1;
  311.   int right=-1;
  312.   while (l!=NULL) {
  313.     if (to_the_left(l->edge(), angle_,0)) {
  314.       left++;
  315.     } else {
  316.       right++;
  317.     }
  318.     if (l->pair()==e) {
  319.       incoming=1;
  320.       break;
  321.     } else if (l->edge()==e) {
  322.       incoming=0;
  323.       break;
  324.     }
  325.     l=l->next();
  326.   }
  327.   Node * destination = e->getDestinationNode();
  328.   if (to_the_left(e, angle_, incoming)) {
  329.     return y_ + s * left * destination->size();
  330.   } else {
  331.     return y_ + s * right * destination->size();
  332.   }
  333. }
  334. #ifdef NOTDEF
  335. Edge *Lan::lookupEdge(Node *n) {
  336.   LanNode *ln=nodes_;
  337.   while(ln!=NULL) {
  338.     if (ln->node()==n)
  339.     {
  340.       return ln->e1_;
  341.     }
  342.   }
  343.   return NULL;
  344. }
  345. #endif