InvalidateGenerator.cc revision 6145
1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * 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 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/* 31 * $Id$ 32 * 33 */ 34 35// This Deterministic Generator generates GETX requests for all nodes in the system 36// The GETX requests are generated one at a time in round-robin fashion 0...1...2...etc. 37 38#include "DetermGETXGenerator.hh" 39#include "DetermGETXGeneratorStatus.hh" 40#include "LockStatus.hh" 41#include "Sequencer.hh" 42#include "System.hh" 43#include "RubyConfig.hh" 44#include "SubBlock.hh" 45#include "DeterministicDriver.hh" 46#include "Chip.hh" 47 48DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver& driver) : 49 m_driver(driver) 50{ 51 m_status = DetermGETXGeneratorStatus_Thinking; 52 m_last_transition = 0; 53 m_node = node; 54 m_address = Address(9999); // initialize to null value 55 m_counter = 0; 56 57 // don't know exactly when this node needs to request so just guess randomly 58 g_eventQueue_ptr->scheduleEvent(this, 1+(random() % 200)); 59} 60 61DetermGETXGenerator::~DetermGETXGenerator() 62{ 63} 64 65void DetermGETXGenerator::wakeup() 66{ 67 DEBUG_EXPR(TESTER_COMP, MedPrio, m_node); 68 DEBUG_EXPR(TESTER_COMP, MedPrio, m_status); 69 70 // determine if this node is next for the GETX round robin request 71 if (m_status == DetermGETXGeneratorStatus_Thinking) { 72 if (m_driver.isStoreReady(m_node)) { 73 pickAddress(); 74 m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending 75 m_last_transition = g_eventQueue_ptr->getTime(); 76 initiateStore(); // GETX 77 } else { // I'll check again later 78 g_eventQueue_ptr->scheduleEvent(this, thinkTime()); 79 } 80 } else { 81 WARN_EXPR(m_status); 82 ERROR_MSG("Invalid status"); 83 } 84 85} 86 87void DetermGETXGenerator::performCallback(NodeID proc, SubBlock& data) 88{ 89 Address address = data.getAddress(); 90 assert(proc == m_node); 91 assert(address == m_address); 92 93 DEBUG_EXPR(TESTER_COMP, LowPrio, proc); 94 DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); 95 DEBUG_EXPR(TESTER_COMP, LowPrio, address); 96 DEBUG_EXPR(TESTER_COMP, LowPrio, data); 97 98 if (m_status == DetermGETXGeneratorStatus_Store_Pending) { 99 m_driver.recordStoreLatency(g_eventQueue_ptr->getTime() - m_last_transition); 100 data.writeByte(m_node); 101 m_driver.storeCompleted(m_node, data.getAddress()); // advance the store queue 102 103 m_counter++; 104 if (m_counter < g_tester_length) { 105 m_status = DetermGETXGeneratorStatus_Thinking; 106 m_last_transition = g_eventQueue_ptr->getTime(); 107 g_eventQueue_ptr->scheduleEvent(this, waitTime()); 108 } else { 109 m_driver.reportDone(); 110 m_status = DetermGETXGeneratorStatus_Done; 111 m_last_transition = g_eventQueue_ptr->getTime(); 112 } 113 114 } else { 115 WARN_EXPR(m_status); 116 ERROR_MSG("Invalid status"); 117 } 118} 119 120int DetermGETXGenerator::thinkTime() const 121{ 122 return g_think_time; 123} 124 125int DetermGETXGenerator::waitTime() const 126{ 127 return g_wait_time; 128} 129 130void DetermGETXGenerator::pickAddress() 131{ 132 assert(m_status == DetermGETXGeneratorStatus_Thinking); 133 134 m_address = m_driver.getNextStoreAddr(m_node); 135} 136 137void DetermGETXGenerator::initiateStore() 138{ 139 DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); 140 sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */, 0, false)); 141} 142 143Sequencer* DetermGETXGenerator::sequencer() const 144{ 145 return g_system_ptr->getChip(m_node/RubyConfig::numberOfProcsPerChip())->getSequencer(m_node%RubyConfig::numberOfProcsPerChip()); 146} 147 148void DetermGETXGenerator::print(ostream& out) const 149{ 150} 151 152