Sequencer.cc (7454:3a3e8e8cce1b) Sequencer.cc (7455:586f99bf0dc4)
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;

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

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 "base/str.hh"
30#include "cpu/rubytest/RubyTester.hh"
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;

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

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 "base/str.hh"
30#include "cpu/rubytest/RubyTester.hh"
31#include "mem/gems_common/Map.hh"
32#include "mem/protocol/CacheMsg.hh"
33#include "mem/protocol/Protocol.hh"
34#include "mem/protocol/Protocol.hh"
35#include "mem/ruby/buffers/MessageBuffer.hh"
36#include "mem/ruby/common/Global.hh"
37#include "mem/ruby/common/SubBlock.hh"
38#include "mem/ruby/libruby.hh"
39#include "mem/ruby/profiler/Profiler.hh"

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

87Sequencer::wakeup()
88{
89 // Check for deadlock of any of the requests
90 Time current_time = g_eventQueue_ptr->getTime();
91
92 // Check across all outstanding requests
93 int total_outstanding = 0;
94
31#include "mem/protocol/CacheMsg.hh"
32#include "mem/protocol/Protocol.hh"
33#include "mem/protocol/Protocol.hh"
34#include "mem/ruby/buffers/MessageBuffer.hh"
35#include "mem/ruby/common/Global.hh"
36#include "mem/ruby/common/SubBlock.hh"
37#include "mem/ruby/libruby.hh"
38#include "mem/ruby/profiler/Profiler.hh"

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

86Sequencer::wakeup()
87{
88 // Check for deadlock of any of the requests
89 Time current_time = g_eventQueue_ptr->getTime();
90
91 // Check across all outstanding requests
92 int total_outstanding = 0;
93
95 std::vector<Address> keys = m_readRequestTable.keys();
96 for (int i = 0; i < keys.size(); i++) {
97 SequencerRequest* request = m_readRequestTable.lookup(keys[i]);
98 if (current_time - request->issue_time >= m_deadlock_threshold) {
99 WARN_MSG("Possible Deadlock detected");
100 WARN_EXPR(request);
101 WARN_EXPR(m_version);
102 WARN_EXPR(request->ruby_request.paddr);
103 WARN_EXPR(keys.size());
104 WARN_EXPR(current_time);
105 WARN_EXPR(request->issue_time);
106 WARN_EXPR(current_time - request->issue_time);
107 ERROR_MSG("Aborting");
108 }
94 RequestTable::iterator read = m_readRequestTable.begin();
95 RequestTable::iterator read_end = m_readRequestTable.end();
96 for (; read != read_end; ++read) {
97 SequencerRequest* request = read->second;
98 if (current_time - request->issue_time < m_deadlock_threshold)
99 continue;
100
101 WARN_MSG("Possible Deadlock detected");
102 WARN_EXPR(request);
103 WARN_EXPR(m_version);
104 WARN_EXPR(request->ruby_request.paddr);
105 WARN_EXPR(m_readRequestTable.size());
106 WARN_EXPR(current_time);
107 WARN_EXPR(request->issue_time);
108 WARN_EXPR(current_time - request->issue_time);
109 ERROR_MSG("Aborting");
109 }
110
110 }
111
111 keys = m_writeRequestTable.keys();
112 for (int i = 0; i < keys.size(); i++) {
113 SequencerRequest* request = m_writeRequestTable.lookup(keys[i]);
114 if (current_time - request->issue_time >= m_deadlock_threshold) {
115 WARN_MSG("Possible Deadlock detected");
116 WARN_EXPR(request);
117 WARN_EXPR(m_version);
118 WARN_EXPR(current_time);
119 WARN_EXPR(request->issue_time);
120 WARN_EXPR(current_time - request->issue_time);
121 WARN_EXPR(keys.size());
122 ERROR_MSG("Aborting");
123 }
112 RequestTable::iterator write = m_writeRequestTable.begin();
113 RequestTable::iterator write_end = m_writeRequestTable.end();
114 for (; write != write_end; ++write) {
115 SequencerRequest* request = write->second;
116 if (current_time - request->issue_time < m_deadlock_threshold)
117 continue;
118
119 WARN_MSG("Possible Deadlock detected");
120 WARN_EXPR(request);
121 WARN_EXPR(m_version);
122 WARN_EXPR(current_time);
123 WARN_EXPR(request->issue_time);
124 WARN_EXPR(current_time - request->issue_time);
125 WARN_EXPR(m_writeRequestTable.size());
126 ERROR_MSG("Aborting");
124 }
125
126 total_outstanding += m_writeRequestTable.size();
127 total_outstanding += m_readRequestTable.size();
128
129 assert(m_outstanding_count == total_outstanding);
130
131 if (m_outstanding_count > 0) {

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

155{
156#if 0
157 int total_demand = 0;
158 out << "Sequencer Stats Version " << m_version << endl;
159 out << "Current time = " << g_eventQueue_ptr->getTime() << endl;
160 out << "---------------" << endl;
161 out << "outstanding requests" << endl;
162
127 }
128
129 total_outstanding += m_writeRequestTable.size();
130 total_outstanding += m_readRequestTable.size();
131
132 assert(m_outstanding_count == total_outstanding);
133
134 if (m_outstanding_count > 0) {

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

158{
159#if 0
160 int total_demand = 0;
161 out << "Sequencer Stats Version " << m_version << endl;
162 out << "Current time = " << g_eventQueue_ptr->getTime() << endl;
163 out << "---------------" << endl;
164 out << "outstanding requests" << endl;
165
163 std::vector<Address> rkeys = m_readRequestTable.keys();
164 int read_size = rkeys.size();
165 out << "proc " << m_version << " Read Requests = " << read_size << endl;
166 out << "proc " << m_Read
167 << " version Requests = " << m_readRequestTable.size() << endl;
166
167 // print the request table
168
169 // print the request table
168 for (int i = 0; i < read_size; ++i) {
169 SequencerRequest *request = m_readRequestTable.lookup(rkeys[i]);
170 RequestTable::iterator read = m_readRequestTable.begin();
171 RequestTable::iterator read_end = m_readRequestTable.end();
172 for (; read != read_end; ++read) {
173 SequencerRequest* request = read->second;
170 out << "\tRequest[ " << i << " ] = " << request->type
171 << " Address " << rkeys[i]
172 << " Posted " << request->issue_time
173 << " PF " << PrefetchBit_No << endl;
174 total_demand++;
175 }
176
174 out << "\tRequest[ " << i << " ] = " << request->type
175 << " Address " << rkeys[i]
176 << " Posted " << request->issue_time
177 << " PF " << PrefetchBit_No << endl;
178 total_demand++;
179 }
180
177 std::vector<Address> wkeys = m_writeRequestTable.keys();
178 int write_size = wkeys.size();
179 out << "proc " << m_version << " Write Requests = " << write_size << endl;
181 out << "proc " << m_version
182 << " Write Requests = " << m_writeRequestTable.size << endl;
180
181 // print the request table
183
184 // print the request table
182 for (int i = 0; i < write_size; ++i){
183 CacheMsg &request = m_writeRequestTable.lookup(wkeys[i]);
185 RequestTable::iterator write = m_writeRequestTable.begin();
186 RequestTable::iterator write_end = m_writeRequestTable.end();
187 for (; write != write_end; ++write) {
188 SequencerRequest* request = write->second;
184 out << "\tRequest[ " << i << " ] = " << request.getType()
185 << " Address " << wkeys[i]
186 << " Posted " << request.getTime()
187 << " PF " << request.getPrefetch() << endl;
188 if (request.getPrefetch() == PrefetchBit_No) {
189 total_demand++;
190 }
191 }

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

226
227 Address line_addr(request->ruby_request.paddr);
228 line_addr.makeLineAddress();
229 if ((request->ruby_request.type == RubyRequestType_ST) ||
230 (request->ruby_request.type == RubyRequestType_RMW_Read) ||
231 (request->ruby_request.type == RubyRequestType_RMW_Write) ||
232 (request->ruby_request.type == RubyRequestType_Locked_Read) ||
233 (request->ruby_request.type == RubyRequestType_Locked_Write)) {
189 out << "\tRequest[ " << i << " ] = " << request.getType()
190 << " Address " << wkeys[i]
191 << " Posted " << request.getTime()
192 << " PF " << request.getPrefetch() << endl;
193 if (request.getPrefetch() == PrefetchBit_No) {
194 total_demand++;
195 }
196 }

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

231
232 Address line_addr(request->ruby_request.paddr);
233 line_addr.makeLineAddress();
234 if ((request->ruby_request.type == RubyRequestType_ST) ||
235 (request->ruby_request.type == RubyRequestType_RMW_Read) ||
236 (request->ruby_request.type == RubyRequestType_RMW_Write) ||
237 (request->ruby_request.type == RubyRequestType_Locked_Read) ||
238 (request->ruby_request.type == RubyRequestType_Locked_Write)) {
234 if (m_writeRequestTable.exist(line_addr)) {
235 m_writeRequestTable.lookup(line_addr) = request;
239 pair<RequestTable::iterator, bool> r =
240 m_writeRequestTable.insert(RequestTable::value_type(line_addr, 0));
241 bool success = r.second;
242 RequestTable::iterator i = r.first;
243 if (!success) {
244 i->second = request;
236 // return true;
237
238 // drh5: isn't this an error? do you lose the initial request?
239 assert(0);
240 }
245 // return true;
246
247 // drh5: isn't this an error? do you lose the initial request?
248 assert(0);
249 }
241 m_writeRequestTable.allocate(line_addr);
242 m_writeRequestTable.lookup(line_addr) = request;
250 i->second = request;
243 m_outstanding_count++;
244 } else {
251 m_outstanding_count++;
252 } else {
245 if (m_readRequestTable.exist(line_addr)) {
246 m_readRequestTable.lookup(line_addr) = request;
253 pair<RequestTable::iterator, bool> r =
254 m_readRequestTable.insert(RequestTable::value_type(line_addr, 0));
255 bool success = r.second;
256 RequestTable::iterator i = r.first;
257 if (!success) {
258 i->second = request;
247 // return true;
248
249 // drh5: isn't this an error? do you lose the initial request?
250 assert(0);
251 }
259 // return true;
260
261 // drh5: isn't this an error? do you lose the initial request?
262 assert(0);
263 }
252 m_readRequestTable.allocate(line_addr);
253 m_readRequestTable.lookup(line_addr) = request;
264 i->second = request;
254 m_outstanding_count++;
255 }
256
257 g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count);
258
259 total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size();
260 assert(m_outstanding_count == total_outstanding);
261
262 return false;
263}
264
265void
265 m_outstanding_count++;
266 }
267
268 g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count);
269
270 total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size();
271 assert(m_outstanding_count == total_outstanding);
272
273 return false;
274}
275
276void
277Sequencer::markRemoved()
278{
279 m_outstanding_count--;
280 assert(m_outstanding_count ==
281 m_writeRequestTable.size() + m_readRequestTable.size());
282}
283
284void
266Sequencer::removeRequest(SequencerRequest* srequest)
267{
268 assert(m_outstanding_count ==
269 m_writeRequestTable.size() + m_readRequestTable.size());
270
271 const RubyRequest & ruby_request = srequest->ruby_request;
272 Address line_addr(ruby_request.paddr);
273 line_addr.makeLineAddress();
274 if ((ruby_request.type == RubyRequestType_ST) ||
275 (ruby_request.type == RubyRequestType_RMW_Read) ||
276 (ruby_request.type == RubyRequestType_RMW_Write) ||
277 (ruby_request.type == RubyRequestType_Locked_Read) ||
278 (ruby_request.type == RubyRequestType_Locked_Write)) {
285Sequencer::removeRequest(SequencerRequest* srequest)
286{
287 assert(m_outstanding_count ==
288 m_writeRequestTable.size() + m_readRequestTable.size());
289
290 const RubyRequest & ruby_request = srequest->ruby_request;
291 Address line_addr(ruby_request.paddr);
292 line_addr.makeLineAddress();
293 if ((ruby_request.type == RubyRequestType_ST) ||
294 (ruby_request.type == RubyRequestType_RMW_Read) ||
295 (ruby_request.type == RubyRequestType_RMW_Write) ||
296 (ruby_request.type == RubyRequestType_Locked_Read) ||
297 (ruby_request.type == RubyRequestType_Locked_Write)) {
279 m_writeRequestTable.deallocate(line_addr);
298 m_writeRequestTable.erase(line_addr);
280 } else {
299 } else {
281 m_readRequestTable.deallocate(line_addr);
300 m_readRequestTable.erase(line_addr);
282 }
301 }
283 m_outstanding_count--;
284
302
285 assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size());
303 markRemoved();
286}
287
288void
289Sequencer::writeCallback(const Address& address, DataBlock& data)
290{
291 assert(address == line_address(address));
304}
305
306void
307Sequencer::writeCallback(const Address& address, DataBlock& data)
308{
309 assert(address == line_address(address));
292 assert(m_writeRequestTable.exist(line_address(address)));
310 assert(m_writeRequestTable.count(line_address(address)));
293
311
294 SequencerRequest* request = m_writeRequestTable.lookup(address);
312 RequestTable::iterator i = m_writeRequestTable.find(address);
313 assert(i != m_writeRequestTable.end());
314 SequencerRequest* request = i->second;
295
315
296 removeRequest(request);
316 m_writeRequestTable.erase(i);
317 markRemoved();
297
298 assert((request->ruby_request.type == RubyRequestType_ST) ||
299 (request->ruby_request.type == RubyRequestType_RMW_Read) ||
300 (request->ruby_request.type == RubyRequestType_RMW_Write) ||
301 (request->ruby_request.type == RubyRequestType_Locked_Read) ||
302 (request->ruby_request.type == RubyRequestType_Locked_Write));
303
304 if (request->ruby_request.type == RubyRequestType_Locked_Read) {

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

311
312 hitCallback(request, data);
313}
314
315void
316Sequencer::readCallback(const Address& address, DataBlock& data)
317{
318 assert(address == line_address(address));
318
319 assert((request->ruby_request.type == RubyRequestType_ST) ||
320 (request->ruby_request.type == RubyRequestType_RMW_Read) ||
321 (request->ruby_request.type == RubyRequestType_RMW_Write) ||
322 (request->ruby_request.type == RubyRequestType_Locked_Read) ||
323 (request->ruby_request.type == RubyRequestType_Locked_Write));
324
325 if (request->ruby_request.type == RubyRequestType_Locked_Read) {

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

332
333 hitCallback(request, data);
334}
335
336void
337Sequencer::readCallback(const Address& address, DataBlock& data)
338{
339 assert(address == line_address(address));
319 assert(m_readRequestTable.exist(line_address(address)));
340 assert(m_readRequestTable.count(line_address(address)));
320
341
321 SequencerRequest* request = m_readRequestTable.lookup(address);
322 removeRequest(request);
342 RequestTable::iterator i = m_readRequestTable.find(address);
343 assert(i != m_readRequestTable.end());
344 SequencerRequest* request = i->second;
323
345
346 m_readRequestTable.erase(i);
347 markRemoved();
348
324 assert((request->ruby_request.type == RubyRequestType_LD) ||
325 (request->ruby_request.type == RubyRequestType_RMW_Read) ||
326 (request->ruby_request.type == RubyRequestType_IFETCH));
327
328 hitCallback(request, data);
329}
330
331void

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

404 delete srequest;
405}
406
407// Returns true if the sequencer already has a load or store outstanding
408RequestStatus
409Sequencer::getRequestStatus(const RubyRequest& request)
410{
411 bool is_outstanding_store =
349 assert((request->ruby_request.type == RubyRequestType_LD) ||
350 (request->ruby_request.type == RubyRequestType_RMW_Read) ||
351 (request->ruby_request.type == RubyRequestType_IFETCH));
352
353 hitCallback(request, data);
354}
355
356void

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

429 delete srequest;
430}
431
432// Returns true if the sequencer already has a load or store outstanding
433RequestStatus
434Sequencer::getRequestStatus(const RubyRequest& request)
435{
436 bool is_outstanding_store =
412 m_writeRequestTable.exist(line_address(Address(request.paddr)));
437 !!m_writeRequestTable.count(line_address(Address(request.paddr)));
413 bool is_outstanding_load =
438 bool is_outstanding_load =
414 m_readRequestTable.exist(line_address(Address(request.paddr)));
439 !!m_readRequestTable.count(line_address(Address(request.paddr)));
415 if (is_outstanding_store) {
416 if ((request.type == RubyRequestType_LD) ||
417 (request.type == RubyRequestType_IFETCH) ||
418 (request.type == RubyRequestType_RMW_Read)) {
419 m_store_waiting_on_load_cycles++;
420 } else {
421 m_store_waiting_on_store_cycles++;
422 }

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

436 }
437
438 return RequestStatus_Ready;
439}
440
441bool
442Sequencer::empty() const
443{
440 if (is_outstanding_store) {
441 if ((request.type == RubyRequestType_LD) ||
442 (request.type == RubyRequestType_IFETCH) ||
443 (request.type == RubyRequestType_RMW_Read)) {
444 m_store_waiting_on_load_cycles++;
445 } else {
446 m_store_waiting_on_store_cycles++;
447 }

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

461 }
462
463 return RequestStatus_Ready;
464}
465
466bool
467Sequencer::empty() const
468{
444 return m_writeRequestTable.size() == 0 && m_readRequestTable.size() == 0;
469 return m_writeRequestTable.empty() && m_readRequestTable.empty();
445}
446
447RequestStatus
448Sequencer::makeRequest(const RubyRequest &request)
449{
450 assert(Address(request.paddr).getOffset() + request.len <=
451 RubySystem::getBlockSizeBytes());
452 RequestStatus status = getRequestStatus(request);

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

575{
576 CacheMemory *cache =
577 (type == CacheRequestType_IFETCH) ? m_instCache_ptr : m_dataCache_ptr;
578
579 return cache->tryCacheAccess(line_address(addr), type, data_ptr);
580}
581#endif
582
470}
471
472RequestStatus
473Sequencer::makeRequest(const RubyRequest &request)
474{
475 assert(Address(request.paddr).getOffset() + request.len <=
476 RubySystem::getBlockSizeBytes());
477 RequestStatus status = getRequestStatus(request);

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

600{
601 CacheMemory *cache =
602 (type == CacheRequestType_IFETCH) ? m_instCache_ptr : m_dataCache_ptr;
603
604 return cache->tryCacheAccess(line_address(addr), type, data_ptr);
605}
606#endif
607
608template <class KEY, class VALUE>
609std::ostream &
610operator<<(ostream &out, const m5::hash_map<KEY, VALUE> &map)
611{
612 typename m5::hash_map<KEY, VALUE>::const_iterator i = map.begin();
613 typename m5::hash_map<KEY, VALUE>::const_iterator end = map.end();
614
615 out << "[";
616 for (; i != end; ++i)
617 out << " " << i->first << "=" << i->second;
618 out << " ]";
619
620 return out;
621}
622
583void
584Sequencer::print(ostream& out) const
585{
586 out << "[Sequencer: " << m_version
587 << ", outstanding requests: " << m_outstanding_count
588 << ", read request table: " << m_readRequestTable
589 << ", write request table: " << m_writeRequestTable
590 << "]";

--- 12 unchanged lines hidden ---
623void
624Sequencer::print(ostream& out) const
625{
626 out << "[Sequencer: " << m_version
627 << ", outstanding requests: " << m_outstanding_count
628 << ", read request table: " << m_readRequestTable
629 << ", write request table: " << m_writeRequestTable
630 << "]";

--- 12 unchanged lines hidden ---