1/*
2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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 are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 12 unchanged lines hidden (view full) ---

21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <algorithm>
30
31#include "mem/protocol/Protocol.hh"
32#include "mem/ruby/buffers/MessageBuffer.hh"
33#include "mem/ruby/network/simple/PerfectSwitch.hh"
34#include "mem/ruby/network/simple/SimpleNetwork.hh"
35#include "mem/ruby/profiler/Profiler.hh"
36#include "mem/ruby/slicc_interface/NetworkMessage.hh"
37#include "mem/ruby/system/System.hh"
38

--- 13 unchanged lines hidden (view full) ---

52 m_virtual_networks = network_ptr->getNumberOfVirtualNetworks();
53 m_switch_id = sid;
54 m_round_robin_start = 0;
55 m_network_ptr = network_ptr;
56 m_wakeups_wo_switch = 0;
57}
58
59void
58PerfectSwitch::addInPort(const Vector<MessageBuffer*>& in)
60PerfectSwitch::addInPort(const vector<MessageBuffer*>& in)
61{
62 assert(in.size() == m_virtual_networks);
63 NodeID port = m_in.size();
62 m_in.insertAtBottom(in);
64 m_in.push_back(in);
65 for (int j = 0; j < m_virtual_networks; j++) {
66 m_in[port][j]->setConsumer(this);
67 string desc = csprintf("[Queue from port %s %s %s to PerfectSwitch]",
68 NodeIDToString(m_switch_id), NodeIDToString(port),
69 NodeIDToString(j));
70 m_in[port][j]->setDescription(desc);
71 }
72}
73
74void
73PerfectSwitch::addOutPort(const Vector<MessageBuffer*>& out,
75PerfectSwitch::addOutPort(const vector<MessageBuffer*>& out,
76 const NetDest& routing_table_entry)
77{
78 assert(out.size() == m_virtual_networks);
79
80 // Setup link order
81 LinkOrder l;
82 l.m_value = 0;
83 l.m_link = m_out.size();
82 m_link_order.insertAtBottom(l);
84 m_link_order.push_back(l);
85
86 // Add to routing table
85 m_out.insertAtBottom(out);
86 m_routing_table.insertAtBottom(routing_table_entry);
87 m_out.push_back(out);
88 m_routing_table.push_back(routing_table_entry);
89}
90
91void
92PerfectSwitch::clearRoutingTables()
93{
94 m_routing_table.clear();
95}
96

--- 11 unchanged lines hidden (view full) ---

108 m_out[i][vnet]->clear();
109 }
110 }
111}
112
113void
114PerfectSwitch::reconfigureOutPort(const NetDest& routing_table_entry)
115{
114 m_routing_table.insertAtBottom(routing_table_entry);
116 m_routing_table.push_back(routing_table_entry);
117}
118
119PerfectSwitch::~PerfectSwitch()
120{
121}
122
123void
124PerfectSwitch::wakeup()

--- 33 unchanged lines hidden (view full) ---

158 for (int counter = 0; counter < m_in.size(); counter++) {
159 // Round robin scheduling
160 incoming++;
161 if (incoming >= m_in.size()) {
162 incoming = 0;
163 }
164
165 // temporary vectors to store the routing results
164 Vector<LinkID> output_links;
165 Vector<NetDest> output_link_destinations;
166 vector<LinkID> output_links;
167 vector<NetDest> output_link_destinations;
168
169 // Is there a message waiting?
170 while (m_in[incoming][vnet]->isReady()) {
171 DEBUG_EXPR(NETWORK_COMP, MedPrio, incoming);
172
173 // Peek at message
174 msg_ptr = m_in[incoming][vnet]->peekMsgPtr();
175 net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());

--- 27 unchanged lines hidden (view full) ---

203 }
204 int value =
205 (out_queue_length << 8) | (random() & 0xff);
206 m_link_order[out].m_link = out;
207 m_link_order[out].m_value = value;
208 }
209
210 // Look at the most empty link first
209 m_link_order.sortVector();
211 sort(m_link_order.begin(), m_link_order.end());
212 }
213 }
214
215 for (int i = 0; i < m_routing_table.size(); i++) {
216 // pick the next link to look at
217 int link = m_link_order[i].m_link;
218 NetDest dst = m_routing_table[link];
219 DEBUG_EXPR(NETWORK_COMP, MedPrio, dst);
220
221 if (!msg_dsts.intersectionIsNotEmpty(dst))
222 continue;
223
224 // Remember what link we're using
223 output_links.insertAtBottom(link);
225 output_links.push_back(link);
226
227 // Need to remember which destinations need this
228 // message in another vector. This Set is the
229 // intersection of the routing_table entry and the
230 // current destination set. The intersection must
231 // not be empty, since we are inside "if"
230 output_link_destinations.insertAtBottom(msg_dsts.AND(dst));
232 output_link_destinations.push_back(msg_dsts.AND(dst));
233
234 // Next, we update the msg_destination not to
235 // include those nodes that were already handled
236 // by this link
237 msg_dsts.removeNetDest(dst);
238 }
239
240 assert(msg_dsts.count() == 0);

--- 97 unchanged lines hidden ---