56a57,61
>
> for(int i = 0;i < m_virtual_networks;++i)
> {
> m_pending_message_count.push_back(0);
> }
64a70
>
70a77,78
> m_in[port][j]->setIncomingLink(port);
> m_in[port][j]->setVnet(j);
157,163c165,172
< // for all input ports, use round robin scheduling
< for (int counter = 0; counter < m_in.size(); counter++) {
< // Round robin scheduling
< incoming++;
< if (incoming >= m_in.size()) {
< incoming = 0;
< }
---
> if(m_pending_message_count[vnet] > 0) {
> // for all input ports, use round robin scheduling
> for (int counter = 0; counter < m_in.size(); counter++) {
> // Round robin scheduling
> incoming++;
> if (incoming >= m_in.size()) {
> incoming = 0;
> }
165,167c174,176
< // temporary vectors to store the routing results
< vector<LinkID> output_links;
< vector<NetDest> output_link_destinations;
---
> // temporary vectors to store the routing results
> vector<LinkID> output_links;
> vector<NetDest> output_link_destinations;
169,171c178,180
< // Is there a message waiting?
< while (m_in[incoming][vnet]->isReady()) {
< DPRINTF(RubyNetwork, "incoming: %d\n", incoming);
---
> // Is there a message waiting?
> while (m_in[incoming][vnet]->isReady()) {
> DPRINTF(RubyNetwork, "incoming: %d\n", incoming);
173,176c182,185
< // Peek at message
< msg_ptr = m_in[incoming][vnet]->peekMsgPtr();
< net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());
< DPRINTF(RubyNetwork, "Message: %s\n", (*net_msg_ptr));
---
> // Peek at message
> msg_ptr = m_in[incoming][vnet]->peekMsgPtr();
> net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());
> DPRINTF(RubyNetwork, "Message: %s\n", (*net_msg_ptr));
178,181c187,190
< output_links.clear();
< output_link_destinations.clear();
< NetDest msg_dsts =
< net_msg_ptr->getInternalDestination();
---
> output_links.clear();
> output_link_destinations.clear();
> NetDest msg_dsts =
> net_msg_ptr->getInternalDestination();
183,185c192,194
< // Unfortunately, the token-protocol sends some
< // zero-destination messages, so this assert isn't valid
< // assert(msg_dsts.count() > 0);
---
> // Unfortunately, the token-protocol sends some
> // zero-destination messages, so this assert isn't valid
> // assert(msg_dsts.count() > 0);
187,188c196,197
< assert(m_link_order.size() == m_routing_table.size());
< assert(m_link_order.size() == m_out.size());
---
> assert(m_link_order.size() == m_routing_table.size());
> assert(m_link_order.size() == m_out.size());
190,202c199,204
< if (m_network_ptr->getAdaptiveRouting()) {
< if (m_network_ptr->isVNetOrdered(vnet)) {
< // Don't adaptively route
< for (int out = 0; out < m_out.size(); out++) {
< m_link_order[out].m_link = out;
< m_link_order[out].m_value = 0;
< }
< } else {
< // Find how clogged each link is
< for (int out = 0; out < m_out.size(); out++) {
< int out_queue_length = 0;
< for (int v = 0; v < m_virtual_networks; v++) {
< out_queue_length += m_out[out][v]->getSize();
---
> if (m_network_ptr->getAdaptiveRouting()) {
> if (m_network_ptr->isVNetOrdered(vnet)) {
> // Don't adaptively route
> for (int out = 0; out < m_out.size(); out++) {
> m_link_order[out].m_link = out;
> m_link_order[out].m_value = 0;
204,208c206,217
< int value =
< (out_queue_length << 8) | (random() & 0xff);
< m_link_order[out].m_link = out;
< m_link_order[out].m_value = value;
< }
---
> } else {
> // Find how clogged each link is
> for (int out = 0; out < m_out.size(); out++) {
> int out_queue_length = 0;
> for (int v = 0; v < m_virtual_networks; v++) {
> out_queue_length += m_out[out][v]->getSize();
> }
> int value =
> (out_queue_length << 8) | (random() & 0xff);
> m_link_order[out].m_link = out;
> m_link_order[out].m_value = value;
> }
210,211c219,221
< // Look at the most empty link first
< sort(m_link_order.begin(), m_link_order.end());
---
> // Look at the most empty link first
> sort(m_link_order.begin(), m_link_order.end());
> }
213d222
< }
215,219c224,228
< for (int i = 0; i < m_routing_table.size(); i++) {
< // pick the next link to look at
< int link = m_link_order[i].m_link;
< NetDest dst = m_routing_table[link];
< DPRINTF(RubyNetwork, "dst: %s\n", dst);
---
> for (int i = 0; i < m_routing_table.size(); i++) {
> // pick the next link to look at
> int link = m_link_order[i].m_link;
> NetDest dst = m_routing_table[link];
> DPRINTF(RubyNetwork, "dst: %s\n", dst);
221,222c230,231
< if (!msg_dsts.intersectionIsNotEmpty(dst))
< continue;
---
> if (!msg_dsts.intersectionIsNotEmpty(dst))
> continue;
224,225c233,234
< // Remember what link we're using
< output_links.push_back(link);
---
> // Remember what link we're using
> output_links.push_back(link);
227,232c236,241
< // Need to remember which destinations need this
< // message in another vector. This Set is the
< // intersection of the routing_table entry and the
< // current destination set. The intersection must
< // not be empty, since we are inside "if"
< output_link_destinations.push_back(msg_dsts.AND(dst));
---
> // Need to remember which destinations need this
> // message in another vector. This Set is the
> // intersection of the routing_table entry and the
> // current destination set. The intersection must
> // not be empty, since we are inside "if"
> output_link_destinations.push_back(msg_dsts.AND(dst));
234,238c243,247
< // Next, we update the msg_destination not to
< // include those nodes that were already handled
< // by this link
< msg_dsts.removeNetDest(dst);
< }
---
> // Next, we update the msg_destination not to
> // include those nodes that were already handled
> // by this link
> msg_dsts.removeNetDest(dst);
> }
240,241c249,250
< assert(msg_dsts.count() == 0);
< //assert(output_links.size() > 0);
---
> assert(msg_dsts.count() == 0);
> //assert(output_links.size() > 0);
243,252c252,261
< // Check for resources - for all outgoing queues
< bool enough = true;
< for (int i = 0; i < output_links.size(); i++) {
< int outgoing = output_links[i];
< if (!m_out[outgoing][vnet]->areNSlotsAvailable(1))
< enough = false;
< DPRINTF(RubyNetwork, "Checking if node is blocked\n"
< "outgoing: %d, vnet: %d, enough: %d\n",
< outgoing, vnet, enough);
< }
---
> // Check for resources - for all outgoing queues
> bool enough = true;
> for (int i = 0; i < output_links.size(); i++) {
> int outgoing = output_links[i];
> if (!m_out[outgoing][vnet]->areNSlotsAvailable(1))
> enough = false;
> DPRINTF(RubyNetwork, "Checking if node is blocked\n"
> "outgoing: %d, vnet: %d, enough: %d\n",
> outgoing, vnet, enough);
> }
254,261c263,270
< // There were not enough resources
< if (!enough) {
< g_eventQueue_ptr->scheduleEvent(this, 1);
< DPRINTF(RubyNetwork, "Can't deliver message since a node "
< "is blocked\n"
< "Message: %s\n", (*net_msg_ptr));
< break; // go to next incoming port
< }
---
> // There were not enough resources
> if (!enough) {
> g_eventQueue_ptr->scheduleEvent(this, 1);
> DPRINTF(RubyNetwork, "Can't deliver message since a node "
> "is blocked\n"
> "Message: %s\n", (*net_msg_ptr));
> break; // go to next incoming port
> }
263c272
< MsgPtr unmodified_msg_ptr;
---
> MsgPtr unmodified_msg_ptr;
265,271c274,280
< if (output_links.size() > 1) {
< // If we are sending this message down more than
< // one link (size>1), we need to make a copy of
< // the message so each branch can have a different
< // internal destination we need to create an
< // unmodified MsgPtr because the MessageBuffer
< // enqueue func will modify the message
---
> if (output_links.size() > 1) {
> // If we are sending this message down more than
> // one link (size>1), we need to make a copy of
> // the message so each branch can have a different
> // internal destination we need to create an
> // unmodified MsgPtr because the MessageBuffer
> // enqueue func will modify the message
273,283c282
< // This magic line creates a private copy of the
< // message
< unmodified_msg_ptr = msg_ptr->clone();
< }
<
< // Enqueue it - for all outgoing queues
< for (int i=0; i<output_links.size(); i++) {
< int outgoing = output_links[i];
<
< if (i > 0) {
< // create a private copy of the unmodified
---
> // This magic line creates a private copy of the
285c284
< msg_ptr = unmodified_msg_ptr->clone();
---
> unmodified_msg_ptr = msg_ptr->clone();
288,293c287,289
< // Change the internal destination set of the
< // message so it knows which destinations this
< // link is responsible for.
< net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());
< net_msg_ptr->getInternalDestination() =
< output_link_destinations[i];
---
> // Enqueue it - for all outgoing queues
> for (int i=0; i<output_links.size(); i++) {
> int outgoing = output_links[i];
295,299c291,295
< // Enqeue msg
< DPRINTF(RubyNetwork, "Switch: %d enqueuing net msg from "
< "inport[%d][%d] to outport [%d][%d] time: %lld.\n",
< m_switch_id, incoming, vnet, outgoing, vnet,
< g_eventQueue_ptr->getTime());
---
> if (i > 0) {
> // create a private copy of the unmodified
> // message
> msg_ptr = unmodified_msg_ptr->clone();
> }
301,302c297,302
< m_out[outgoing][vnet]->enqueue(msg_ptr);
< }
---
> // Change the internal destination set of the
> // message so it knows which destinations this
> // link is responsible for.
> net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());
> net_msg_ptr->getInternalDestination() =
> output_link_destinations[i];
304,305c304,316
< // Dequeue msg
< m_in[incoming][vnet]->pop();
---
> // Enqeue msg
> DPRINTF(RubyNetwork, "Switch: %d enqueuing net msg from "
> "inport[%d][%d] to outport [%d][%d] time: %lld.\n",
> m_switch_id, incoming, vnet, outgoing, vnet,
> g_eventQueue_ptr->getTime());
>
> m_out[outgoing][vnet]->enqueue(msg_ptr);
> }
>
> // Dequeue msg
> m_in[incoming][vnet]->pop();
> m_pending_message_count[vnet]--;
> }
311a323,328
> PerfectSwitch::storeEventInfo(int info)
> {
> m_pending_message_count[info]++;
> }
>
> void