Deleted Added
sdiff udiff text old ( 7454:3a3e8e8cce1b ) new ( 7455:586f99bf0dc4 )
full compact
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
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 }
109 }
110
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 }
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
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
167 // print the request table
168 for (int i = 0; i < read_size; ++i) {
169 SequencerRequest *request = m_readRequestTable.lookup(rkeys[i]);
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
177 std::vector<Address> wkeys = m_writeRequestTable.keys();
178 int write_size = wkeys.size();
179 out << "proc " << m_version << " Write Requests = " << write_size << endl;
180
181 // print the request table
182 for (int i = 0; i < write_size; ++i){
183 CacheMsg &request = m_writeRequestTable.lookup(wkeys[i]);
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)) {
234 if (m_writeRequestTable.exist(line_addr)) {
235 m_writeRequestTable.lookup(line_addr) = request;
236 // return true;
237
238 // drh5: isn't this an error? do you lose the initial request?
239 assert(0);
240 }
241 m_writeRequestTable.allocate(line_addr);
242 m_writeRequestTable.lookup(line_addr) = request;
243 m_outstanding_count++;
244 } else {
245 if (m_readRequestTable.exist(line_addr)) {
246 m_readRequestTable.lookup(line_addr) = request;
247 // return true;
248
249 // drh5: isn't this an error? do you lose the initial request?
250 assert(0);
251 }
252 m_readRequestTable.allocate(line_addr);
253 m_readRequestTable.lookup(line_addr) = 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
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)) {
279 m_writeRequestTable.deallocate(line_addr);
280 } else {
281 m_readRequestTable.deallocate(line_addr);
282 }
283 m_outstanding_count--;
284
285 assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size());
286}
287
288void
289Sequencer::writeCallback(const Address& address, DataBlock& data)
290{
291 assert(address == line_address(address));
292 assert(m_writeRequestTable.exist(line_address(address)));
293
294 SequencerRequest* request = m_writeRequestTable.lookup(address);
295
296 removeRequest(request);
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));
319 assert(m_readRequestTable.exist(line_address(address)));
320
321 SequencerRequest* request = m_readRequestTable.lookup(address);
322 removeRequest(request);
323
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 =
412 m_writeRequestTable.exist(line_address(Address(request.paddr)));
413 bool is_outstanding_load =
414 m_readRequestTable.exist(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{
444 return m_writeRequestTable.size() == 0 && m_readRequestTable.size() == 0;
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
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 ---