From 92de70b69aaf3f399a855057b556ed198139e5d8 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 6 Jul 2009 15:49:47 -0700 Subject: ruby: Import the latest ruby changes from gems. This was done with an automated process, so there could be things that were done in this tree in the past that didn't make it. One known regression is that atomic memory operations do not seem to work properly anymore. --- src/mem/ruby/tester/BarrierGenerator.cc | 333 ----------------- src/mem/ruby/tester/BarrierGenerator.hh | 138 -------- src/mem/ruby/tester/Check.cc | 310 ---------------- src/mem/ruby/tester/Check.hh | 107 ------ src/mem/ruby/tester/CheckTable.cc | 128 ------- src/mem/ruby/tester/CheckTable.hh | 93 ----- src/mem/ruby/tester/DetermGETXGenerator.cc | 72 ++-- src/mem/ruby/tester/DetermGETXGenerator.hh | 17 +- src/mem/ruby/tester/DetermInvGenerator.cc | 100 +++--- src/mem/ruby/tester/DetermInvGenerator.hh | 11 +- src/mem/ruby/tester/DetermSeriesGETSGenerator.cc | 56 ++- src/mem/ruby/tester/DetermSeriesGETSGenerator.hh | 11 +- src/mem/ruby/tester/DeterministicDriver.cc | 145 ++++---- src/mem/ruby/tester/DeterministicDriver.hh | 54 ++- src/mem/ruby/tester/Driver_Tester.cc | 44 +++ src/mem/ruby/tester/Driver_Tester.hh | 82 +++++ src/mem/ruby/tester/EventQueue_Tester.hh | 118 ++++++ src/mem/ruby/tester/Global_Tester.hh | 74 ++++ src/mem/ruby/tester/Instruction.cc | 51 --- src/mem/ruby/tester/Instruction.hh | 57 --- src/mem/ruby/tester/RaceyDriver.cc | 67 ++-- src/mem/ruby/tester/RaceyDriver.hh | 32 +- src/mem/ruby/tester/RaceyPseudoThread.cc | 353 ++++++++++++++++++ src/mem/ruby/tester/RaceyPseudoThread.hh | 151 ++++++++ src/mem/ruby/tester/RequestGenerator.cc | 220 ------------ src/mem/ruby/tester/RequestGenerator.hh | 102 ------ src/mem/ruby/tester/SpecifiedGenerator.cc | 4 - src/mem/ruby/tester/SpecifiedGenerator.hh | 8 +- src/mem/ruby/tester/SyntheticDriver.cc | 286 --------------- src/mem/ruby/tester/SyntheticDriver.hh | 118 ------ src/mem/ruby/tester/Tester.cc | 112 ------ src/mem/ruby/tester/Tester.hh | 93 ----- src/mem/ruby/tester/main.cc | 9 +- src/mem/ruby/tester/main.hh | 9 +- src/mem/ruby/tester/test_framework.cc | 433 +++++++++++------------ src/mem/ruby/tester/test_framework.hh | 4 +- 36 files changed, 1333 insertions(+), 2669 deletions(-) delete mode 100644 src/mem/ruby/tester/BarrierGenerator.cc delete mode 100644 src/mem/ruby/tester/BarrierGenerator.hh delete mode 100644 src/mem/ruby/tester/Check.cc delete mode 100644 src/mem/ruby/tester/Check.hh delete mode 100644 src/mem/ruby/tester/CheckTable.cc delete mode 100644 src/mem/ruby/tester/CheckTable.hh create mode 100644 src/mem/ruby/tester/Driver_Tester.cc create mode 100644 src/mem/ruby/tester/Driver_Tester.hh create mode 100644 src/mem/ruby/tester/EventQueue_Tester.hh create mode 100644 src/mem/ruby/tester/Global_Tester.hh delete mode 100644 src/mem/ruby/tester/Instruction.cc delete mode 100644 src/mem/ruby/tester/Instruction.hh create mode 100644 src/mem/ruby/tester/RaceyPseudoThread.cc create mode 100644 src/mem/ruby/tester/RaceyPseudoThread.hh delete mode 100644 src/mem/ruby/tester/RequestGenerator.cc delete mode 100644 src/mem/ruby/tester/RequestGenerator.hh delete mode 100644 src/mem/ruby/tester/SyntheticDriver.cc delete mode 100644 src/mem/ruby/tester/SyntheticDriver.hh delete mode 100644 src/mem/ruby/tester/Tester.cc delete mode 100644 src/mem/ruby/tester/Tester.hh (limited to 'src/mem/ruby/tester') diff --git a/src/mem/ruby/tester/BarrierGenerator.cc b/src/mem/ruby/tester/BarrierGenerator.cc deleted file mode 100644 index 9dbcf39fd..000000000 --- a/src/mem/ruby/tester/BarrierGenerator.cc +++ /dev/null @@ -1,333 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id: BarrierGenerator.C 1.3 2005/01/19 13:12:35-06:00 mikem@maya.cs.wisc.edu $ - * - */ - -#include "mem/ruby/tester/BarrierGenerator.hh" -#include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/config/RubyConfig.hh" -#include "mem/ruby/common/SubBlock.hh" -#include "mem/ruby/tester/SyntheticDriver.hh" -#include "mem/protocol/Chip.hh" - -BarrierGenerator::BarrierGenerator(NodeID node, SyntheticDriver& driver) : - m_driver(driver) -{ - m_status = BarrierGeneratorStatus_Thinking; - m_last_transition = 0; - m_node = node; - m_counter = 0; - proc_counter = 0; - m_local_sense = false; - - m_total_think = 0; - m_think_periods = 0; - - g_eventQueue_ptr->scheduleEvent(this, 1+(random() % 200)); -} - -BarrierGenerator::~BarrierGenerator() -{ -} - -void BarrierGenerator::wakeup() -{ - DEBUG_EXPR(TESTER_COMP, MedPrio, m_node); - DEBUG_EXPR(TESTER_COMP, MedPrio, m_status); - - if (m_status == BarrierGeneratorStatus_Thinking) { - m_barrier_done = false; - m_local_sense = !m_local_sense; - m_status = BarrierGeneratorStatus_Test_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateTest(); // Test - } else if (m_status == BarrierGeneratorStatus_Test_Waiting) { - m_status = BarrierGeneratorStatus_Test_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateTest(); // Test - } else if (m_status == BarrierGeneratorStatus_Release_Waiting) { - m_status = BarrierGeneratorStatus_Release_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateRelease(); // Test - } else if (m_status == BarrierGeneratorStatus_StoreBarrierCounter_Waiting) { - m_status = BarrierGeneratorStatus_StoreBarrierCounter_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateStoreCtr(); - } else if (m_status == BarrierGeneratorStatus_StoreFlag_Waiting) { - m_status = BarrierGeneratorStatus_StoreFlag_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateStoreFlag(); - } else if (m_status == BarrierGeneratorStatus_Holding) { - m_status = BarrierGeneratorStatus_Release_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateRelease(); // Release - } else if (m_status == BarrierGeneratorStatus_Before_Swap) { - m_status = BarrierGeneratorStatus_Swap_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateSwap(); - } else if (m_status == BarrierGeneratorStatus_SpinFlag_Ready) { - m_status = BarrierGeneratorStatus_SpinFlag_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); - initiateLoadFlag(); - } else { - WARN_EXPR(m_status); - ERROR_MSG("Invalid status"); - } -} - -void BarrierGenerator::performCallback(NodeID proc, SubBlock& data) -{ - Address address = data.getAddress(); - assert(proc == m_node); - - DEBUG_EXPR(TESTER_COMP, LowPrio, proc); - DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); - DEBUG_EXPR(TESTER_COMP, LowPrio, address); - DEBUG_EXPR(TESTER_COMP, LowPrio, data); - - if (m_status == BarrierGeneratorStatus_Test_Pending) { - uint8 dat = data.readByte(); - uint8 lock = dat >> 7; - if (lock == 1) { - // Locked - keep spinning - m_status = BarrierGeneratorStatus_Test_Waiting; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); - } else { - // Unlocked - try the swap - m_driver.recordTestLatency(g_eventQueue_ptr->getTime() - m_last_transition); - m_status = BarrierGeneratorStatus_Before_Swap; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); - } - } else if (m_status == BarrierGeneratorStatus_Swap_Pending) { - m_driver.recordSwapLatency(g_eventQueue_ptr->getTime() - m_last_transition); - uint8 dat = data.readByte(); - uint8 lock = dat >> 7; - if (lock == 1) { - // We failed to aquire the lock - m_status = BarrierGeneratorStatus_Test_Waiting; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); - } else { - // We acquired the lock - dat = dat | 0x80; - data.writeByte(dat); - m_status = BarrierGeneratorStatus_StoreBarrierCounter_Waiting; - m_last_transition = g_eventQueue_ptr->getTime(); - DEBUG_MSG(TESTER_COMP, HighPrio, "Acquired"); - DEBUG_EXPR(TESTER_COMP, HighPrio, proc); - DEBUG_EXPR(TESTER_COMP, HighPrio, g_eventQueue_ptr->getTime()); - // g_eventQueue_ptr->scheduleEvent(this, holdTime()); - - g_eventQueue_ptr->scheduleEvent(this, 1); - - // initiateLoadCtr(); - } - } else if (m_status == BarrierGeneratorStatus_StoreBarrierCounter_Pending) { - - // if value == p, reset counter and set local sense flag - uint8 ctr = data.readByte(); - //uint8 sense = ctr >> 4; - ctr = ctr & 0x0F; - - ctr++; - data.writeByte( ctr | 0x80); // store counter and lock - - //cout << m_node << " incremented Barrier_ctr to " << (int)ctr << ", " << data << "\n"; - - if (ctr == (uint8) 16) { - - data.writeByte( 0x0 ); - m_status = BarrierGeneratorStatus_StoreFlag_Waiting; - m_barrier_done = true; - - g_eventQueue_ptr->scheduleEvent(this, 1); - } - else { - - m_status = BarrierGeneratorStatus_Release_Waiting; - g_eventQueue_ptr->scheduleEvent(this, 1); - } - } else if (m_status == BarrierGeneratorStatus_StoreFlag_Pending) { - - // write flag - if (m_local_sense) { - data.writeByte( 0x01 ); - } - else { - data.writeByte( 0x00 ); - } - - m_status = BarrierGeneratorStatus_Release_Waiting; - g_eventQueue_ptr->scheduleEvent(this, 1); - - } else if (m_status == BarrierGeneratorStatus_Release_Pending) { - m_driver.recordReleaseLatency(g_eventQueue_ptr->getTime() - m_last_transition); - // We're releasing the lock - uint8 dat = data.readByte(); - dat = dat & 0x7F; - data.writeByte(dat); - - if (m_barrier_done) { - m_counter++; - proc_counter++; - if (m_counter < g_tester_length) { - m_status = BarrierGeneratorStatus_Thinking; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); - } else { - - m_driver.reportDone(proc_counter, m_node); - m_last_transition = g_eventQueue_ptr->getTime(); - } - } - else { - m_status = BarrierGeneratorStatus_SpinFlag_Ready; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); - } - } else if (m_status == BarrierGeneratorStatus_SpinFlag_Pending) { - - uint8 sense = data.readByte(); - - - if (sense != m_local_sense) { - m_status = BarrierGeneratorStatus_SpinFlag_Ready; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); - } - else { - m_counter++; - proc_counter++; - if (m_counter < g_tester_length) { - m_status = BarrierGeneratorStatus_Thinking; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); - } else { - m_driver.reportDone(proc_counter, m_node); - m_status = BarrierGeneratorStatus_Done; - m_last_transition = g_eventQueue_ptr->getTime(); - } - } - - } else { - WARN_EXPR(m_status); - ERROR_MSG("Invalid status"); - } -} - -int BarrierGenerator::thinkTime() -{ - int ret; - float ratio = g_think_fudge_factor; - - // return 400; - - if (ratio == 0) { - return g_think_time; - } - - int r = random(); - int x = (int) ( (float)g_think_time*ratio*2.0); - int mod = r % x; - - - int rand = ( mod+1 - ((float)g_think_time*ratio) ); - - ret = (g_think_time + rand); - - m_total_think += ret; - m_think_periods++; - - return ret; -} - -int BarrierGenerator::waitTime() const -{ - return g_wait_time; -} - - -void BarrierGenerator::initiateTest() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Test"); - sequencer()->makeRequest(CacheMsg(Address(0x40), CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - -void BarrierGenerator::initiateSwap() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Swap"); - sequencer()->makeRequest(CacheMsg(Address(0x40), CacheRequestType_ATOMIC, Address(2), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - -void BarrierGenerator::initiateRelease() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Release"); - sequencer()->makeRequest(CacheMsg(Address(0x40), CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - -void BarrierGenerator::initiateLoadCtr() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating load of barrier counter"); - sequencer()->makeRequest(CacheMsg(Address(0x40), CacheRequestType_LD, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - -void BarrierGenerator::initiateStoreCtr() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating load of barrier counter"); - sequencer()->makeRequest(CacheMsg(Address(0x40), CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - -void BarrierGenerator::initiateStoreFlag() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating load of barrier counter"); - sequencer()->makeRequest(CacheMsg(Address(0x00), CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - -void BarrierGenerator::initiateLoadFlag() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating load of barrier counter"); - sequencer()->makeRequest(CacheMsg(Address(0x00), CacheRequestType_LD, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, false)); -} - - -Sequencer* BarrierGenerator::sequencer() const -{ - return g_system_ptr->getChip(m_node/RubyConfig::numberOfProcsPerChip())->getSequencer(m_node%RubyConfig::numberOfProcsPerChip()); -} - -void BarrierGenerator::print(ostream& out) const -{ -} - diff --git a/src/mem/ruby/tester/BarrierGenerator.hh b/src/mem/ruby/tester/BarrierGenerator.hh deleted file mode 100644 index e0fa497da..000000000 --- a/src/mem/ruby/tester/BarrierGenerator.hh +++ /dev/null @@ -1,138 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: - * - */ - -#ifndef BARRIERGENERATOR_H -#define BARRIERGENERATOR_H - -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/common/Address.hh" - -class Sequencer; -class SubBlock; -class SyntheticDriver; - - -enum BarrierGeneratorStatus { - BarrierGeneratorStatus_FIRST, - BarrierGeneratorStatus_Thinking = BarrierGeneratorStatus_FIRST, - BarrierGeneratorStatus_Test_Pending, - BarrierGeneratorStatus_Test_Waiting, - BarrierGeneratorStatus_Before_Swap, - BarrierGeneratorStatus_Swap_Pending, - BarrierGeneratorStatus_Holding, - BarrierGeneratorStatus_Release_Pending, - BarrierGeneratorStatus_Release_Waiting, - BarrierGeneratorStatus_StoreFlag_Waiting, - BarrierGeneratorStatus_StoreFlag_Pending, - BarrierGeneratorStatus_Done, - BarrierGeneratorStatus_SpinFlag_Ready, - BarrierGeneratorStatus_SpinFlag_Pending, - BarrierGeneratorStatus_LoadBarrierCounter_Pending, - BarrierGeneratorStatus_StoreBarrierCounter_Pending, - BarrierGeneratorStatus_StoreBarrierCounter_Waiting, - BarrierGeneratorStatus_NUM -}; - - -// UNCOMMENT THIS FOR A SINGLE WORK QUEUE -// static int m_counter; - -class BarrierGenerator : public Consumer { -public: - // Constructors - BarrierGenerator(NodeID node, SyntheticDriver& driver); - - // Destructor - ~BarrierGenerator(); - - // Public Methods - void wakeup(); - void performCallback(NodeID proc, SubBlock& data); - - void print(ostream& out) const; -private: - // Private Methods - int thinkTime() ; - int waitTime() const; - void initiateTest(); - void initiateSwap(); - void initiateRelease(); - void initiateLoadCtr(); - void initiateStoreCtr(); - void initiateLoadFlag(); - void initiateStoreFlag(); - Sequencer* sequencer() const; - - // Private copy constructor and assignment operator - BarrierGenerator(const BarrierGenerator& obj); - BarrierGenerator& operator=(const BarrierGenerator& obj); - - // Data Members (m_ prefix) - SyntheticDriver& m_driver; - NodeID m_node; - BarrierGeneratorStatus m_status; - int proc_counter; - - int m_counter; - - bool m_local_sense; - bool m_barrier_done; - - Time m_last_transition; - Address m_address; - - int m_total_think; - int m_think_periods; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const BarrierGenerator& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const BarrierGenerator& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //REQUESTGENERATOR_H - diff --git a/src/mem/ruby/tester/Check.cc b/src/mem/ruby/tester/Check.cc deleted file mode 100644 index 7896b572a..000000000 --- a/src/mem/ruby/tester/Check.cc +++ /dev/null @@ -1,310 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -#include "mem/ruby/tester/Check.hh" -#include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/common/SubBlock.hh" -#include "mem/protocol/Chip.hh" -#include "mem/packet.hh" - -Check::Check(const Address& address, const Address& pc) -{ - m_status = TesterStatus_Idle; - - pickValue(); - pickInitiatingNode(); - changeAddress(address); - m_pc = pc; - m_access_mode = AccessModeType(random() % AccessModeType_NUM); - m_store_count = 0; -} - -void Check::initiate() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating"); - DEBUG_EXPR(TESTER_COMP, MedPrio, *this); - - // current CMP protocol doesn't support prefetches - if (!Protocol::m_CMP && (random() & 0xf) == 0) { // 1 in 16 chance - initiatePrefetch(); // Prefetch from random processor - } - - if(m_status == TesterStatus_Idle) { - initiateAction(); - } else if(m_status == TesterStatus_Ready) { - initiateCheck(); - } else { - // Pending - do nothing - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating action/check - failed: action/check is pending\n"); - } -} - -void Check::initiatePrefetch(Sequencer* targetSequencer_ptr) -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating prefetch"); - - CacheRequestType type; - if ((random() & 0x7) != 0) { // 1 in 8 chance - if ((random() & 0x1) == 0) { // 50% chance - type = CacheRequestType_LD; - } else { - type = CacheRequestType_IFETCH; - } - } else { - type = CacheRequestType_ST; - } - - Addr data_addr = m_address.getAddress(); - Addr pc_addr = m_pc.getAddress(); - Request request(0, data_addr, 0, Flags(Request::PREFETCH), pc_addr, 0, 0); - MemCmd::Command command; - if (type == CacheRequestType_IFETCH) { - command = MemCmd::ReadReq; - request.setFlags(Request::INST_FETCH); - } else if (type == CacheRequestType_LD || type == CacheRequestType_IFETCH) { - command = MemCmd::ReadReq; - } else if (type == CacheRequestType_ST) { - command = MemCmd::WriteReq; - } else if (type == CacheRequestType_ATOMIC) { - command = MemCmd::SwapReq; // TODO -- differentiate between atomic types - } else { - panic("Cannot convert request to packet"); - } - - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID - - assert(targetSequencer_ptr != NULL); - if (targetSequencer_ptr->isReady(&pkt)) { - targetSequencer_ptr->makeRequest(&pkt); - } -} - -void Check::initiatePrefetch() -{ - // Any sequencer can issue a prefetch for this address - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(random() % RubyConfig::numberOfChips())->getSequencer(random() % RubyConfig::numberOfProcsPerChip()); - assert(targetSequencer_ptr != NULL); - initiatePrefetch(targetSequencer_ptr); -} - -void Check::initiateAction() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Action"); - assert(m_status == TesterStatus_Idle); - - CacheRequestType type = CacheRequestType_ST; - if ((random() & 0x1) == 0) { // 50% chance - type = CacheRequestType_ATOMIC; - } - - Addr data_addr = m_address.getAddress()+m_store_count; - Addr pc_addr = m_pc.getAddress(); - Request request(0, data_addr, 1, Flags(), pc_addr, 0, 0); - MemCmd::Command command; - if (type == CacheRequestType_IFETCH) { - command = MemCmd::ReadReq; - request.setFlags(Request::INST_FETCH); - } else if (type == CacheRequestType_LD || type == CacheRequestType_IFETCH) { - command = MemCmd::ReadReq; - } else if (type == CacheRequestType_ST) { - command = MemCmd::WriteReq; - } else if (type == CacheRequestType_ATOMIC) { - command = MemCmd::SwapReq; // TODO -- differentiate between atomic types - } else { - panic("Cannot convert request to packet"); - } - - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID - - Sequencer* sequencer_ptr = initiatingSequencer(); - if (sequencer_ptr->isReady(&pkt) == false) { - DEBUG_MSG(TESTER_COMP, MedPrio, "failed to initiate action - sequencer not ready\n"); - } else { - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating action - successful\n"); - DEBUG_EXPR(TESTER_COMP, MedPrio, m_status); - m_status = TesterStatus_Action_Pending; - - sequencer_ptr->makeRequest(&pkt); - } - DEBUG_EXPR(TESTER_COMP, MedPrio, m_status); -} - -void Check::initiateCheck() -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Check"); - assert(m_status == TesterStatus_Ready); - - CacheRequestType type = CacheRequestType_LD; - if ((random() & 0x1) == 0) { // 50% chance - type = CacheRequestType_IFETCH; - } - - - Addr data_addr = m_address.getAddress()+m_store_count; - Addr pc_addr = m_pc.getAddress(); - Request request(0, data_addr, CHECK_SIZE, Flags(), pc_addr, 0, 0); - MemCmd::Command command; - if (type == CacheRequestType_IFETCH) { - command = MemCmd::ReadReq; - request.setFlags(Request::INST_FETCH); - } else if (type == CacheRequestType_LD || type == CacheRequestType_IFETCH) { - command = MemCmd::ReadReq; - } else if (type == CacheRequestType_ST) { - command = MemCmd::WriteReq; - } else if (type == CacheRequestType_ATOMIC) { - command = MemCmd::SwapReq; // TODO -- differentiate between atomic types - } else { - panic("Cannot convert request to packet"); - } - - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID - - Sequencer* sequencer_ptr = initiatingSequencer(); - if (sequencer_ptr->isReady(&pkt) == false) { - DEBUG_MSG(TESTER_COMP, MedPrio, "failed to initiate check - sequencer not ready\n"); - } else { - DEBUG_MSG(TESTER_COMP, MedPrio, "initiating check - successful\n"); - DEBUG_MSG(TESTER_COMP, MedPrio, m_status); - m_status = TesterStatus_Check_Pending; - - sequencer_ptr->makeRequest(&pkt); - } - DEBUG_MSG(TESTER_COMP, MedPrio, m_status); -} - -void Check::performCallback(NodeID proc, SubBlock& data) -{ - Address address = data.getAddress(); - // assert(getAddress() == address); // This isn't exactly right since we now have multi-byte checks - assert(getAddress().getLineAddress() == address.getLineAddress()); - - DEBUG_MSG(TESTER_COMP, MedPrio, "Callback"); - DEBUG_EXPR(TESTER_COMP, MedPrio, *this); - - if (m_status == TesterStatus_Action_Pending) { - DEBUG_MSG(TESTER_COMP, MedPrio, "Action callback"); - // Perform store - data.setByte(0, m_value+m_store_count); // We store one byte at a time - m_store_count++; - - if (m_store_count == CHECK_SIZE) { - m_status = TesterStatus_Ready; - } else { - m_status = TesterStatus_Idle; - } - } else if (m_status == TesterStatus_Check_Pending) { - DEBUG_MSG(TESTER_COMP, MedPrio, "Check callback"); - // Perform load/check - for(int byte_number=0; byte_numbergetTime()); - ERROR_MSG("Action/check failure"); - } - } - DEBUG_MSG(TESTER_COMP, HighPrio, "Action/check success:"); - DEBUG_EXPR(TESTER_COMP, HighPrio, *this); - DEBUG_EXPR(TESTER_COMP, MedPrio, data); - - m_status = TesterStatus_Idle; - pickValue(); - - } else { - WARN_EXPR(*this); - WARN_EXPR(proc); - WARN_EXPR(data); - WARN_EXPR(m_status); - WARN_EXPR(g_eventQueue_ptr->getTime()); - ERROR_MSG("Unexpected TesterStatus"); - } - - DEBUG_EXPR(TESTER_COMP, MedPrio, proc); - DEBUG_EXPR(TESTER_COMP, MedPrio, data); - DEBUG_EXPR(TESTER_COMP, MedPrio, getAddress().getLineAddress()); - DEBUG_MSG(TESTER_COMP, MedPrio, "Callback done"); - DEBUG_EXPR(TESTER_COMP, MedPrio, *this); -} - -void Check::changeAddress(const Address& address) -{ - assert((m_status == TesterStatus_Idle) || (m_status == TesterStatus_Ready)); - m_status = TesterStatus_Idle; - m_address = address; - m_store_count = 0; -} - -Sequencer* Check::initiatingSequencer() const -{ - return g_system_ptr->getChip(m_initiatingNode/RubyConfig::numberOfProcsPerChip())->getSequencer(m_initiatingNode%RubyConfig::numberOfProcsPerChip()); -} - -void Check::pickValue() -{ - assert(m_status == TesterStatus_Idle); - m_status = TesterStatus_Idle; - // DEBUG_MSG(TESTER_COMP, MedPrio, m_status); - DEBUG_MSG(TESTER_COMP, MedPrio, *this); - m_value = random() & 0xff; // One byte - // DEBUG_MSG(TESTER_COMP, MedPrio, m_value); - DEBUG_MSG(TESTER_COMP, MedPrio, *this); - m_store_count = 0; -} - -void Check::pickInitiatingNode() -{ - assert((m_status == TesterStatus_Idle) || (m_status == TesterStatus_Ready)); - m_status = TesterStatus_Idle; - DEBUG_MSG(TESTER_COMP, MedPrio, m_status); - m_initiatingNode = (random() % RubyConfig::numberOfProcessors()); - DEBUG_MSG(TESTER_COMP, MedPrio, m_initiatingNode); - m_store_count = 0; -} - -void Check::print(ostream& out) const -{ - out << "[" - << m_address << ", value: " - << (int) m_value << ", status: " - << m_status << ", initiating node: " - << m_initiatingNode << ", store_count: " - << m_store_count - << "]" << flush; -} diff --git a/src/mem/ruby/tester/Check.hh b/src/mem/ruby/tester/Check.hh deleted file mode 100644 index 8f08b3f40..000000000 --- a/src/mem/ruby/tester/Check.hh +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: - * - */ - -#ifndef CHECK_H -#define CHECK_H - -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/protocol/TesterStatus.hh" -#include "mem/protocol/AccessModeType.hh" -class Sequencer; -class SubBlock; - -const int CHECK_SIZE_BITS = 2; -const int CHECK_SIZE = (1<; - physical_address_t physical = 0; - Address address; - - const int size1 = 32; - const int size2 = 100; - - // The first set is to get some false sharing - physical = 1000; - for (int i=0; iexist(Address(address.getAddress()+i))) { - // A mapping for this byte already existed, discard the entire check - return; - } - } - - Check* check_ptr = new Check(address, Address(100+m_check_vector.size())); - for (int i=0; iadd(Address(address.getAddress()+i), check_ptr); - } - m_check_vector.insertAtBottom(check_ptr); -} - -Check* CheckTable::getRandomCheck() -{ - return m_check_vector[random() % m_check_vector.size()]; -} - -Check* CheckTable::getCheck(const Address& address) -{ - DEBUG_MSG(TESTER_COMP, MedPrio, "Looking for check by address"); - DEBUG_EXPR(TESTER_COMP, MedPrio, address); - - if (m_lookup_map_ptr->exist(address)) { - Check* check = m_lookup_map_ptr->lookup(address); - assert(check != NULL); - return check; - } else { - return NULL; - } -} - -void CheckTable::print(ostream& out) const -{ -} diff --git a/src/mem/ruby/tester/CheckTable.hh b/src/mem/ruby/tester/CheckTable.hh deleted file mode 100644 index a7f486315..000000000 --- a/src/mem/ruby/tester/CheckTable.hh +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: - * - */ - -#ifndef CHECKTABLE_H -#define CHECKTABLE_H - -#include "mem/ruby/common/Global.hh" -#include "mem/gems_common/Vector.hh" - -class Address; -class Check; -template class Map; - -class CheckTable { -public: - // Constructors - CheckTable(); - - // Destructor - ~CheckTable(); - - // Public Methods - - Check* getRandomCheck(); - Check* getCheck(const Address& address); - - // bool isPresent(const Address& address) const; - // void removeCheckFromTable(const Address& address); - // bool isTableFull() const; - // Need a method to select a check or retrieve a check - - void print(ostream& out) const; -private: - // Private Methods - void addCheck(const Address& address); - - // Private copy constructor and assignment operator - CheckTable(const CheckTable& obj); - CheckTable& operator=(const CheckTable& obj); - - // Data Members (m_ prefix) - Vector m_check_vector; - Map* m_lookup_map_ptr; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const CheckTable& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const CheckTable& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //CHECKTABLE_H diff --git a/src/mem/ruby/tester/DetermGETXGenerator.cc b/src/mem/ruby/tester/DetermGETXGenerator.cc index e4d8addd2..6692fb80c 100644 --- a/src/mem/ruby/tester/DetermGETXGenerator.cc +++ b/src/mem/ruby/tester/DetermGETXGenerator.cc @@ -37,26 +37,23 @@ #include "mem/ruby/tester/DetermGETXGenerator.hh" #include "mem/protocol/DetermGETXGeneratorStatus.hh" -#include "mem/protocol/LockStatus.hh" -#include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/config/RubyConfig.hh" -#include "mem/ruby/common/SubBlock.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/protocol/Chip.hh" -#include "mem/packet.hh" +#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/tester/SpecifiedGenerator.hh" +//#include "DMAController.hh" +#include "mem/ruby/libruby.hh" -DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver& driver) : - m_driver(driver) + +DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver * driver) { m_status = DetermGETXGeneratorStatus_Thinking; m_last_transition = 0; m_node = node; m_address = Address(9999); // initialize to null value m_counter = 0; - + parent_driver = driver; // don't know exactly when this node needs to request so just guess randomly - g_eventQueue_ptr->scheduleEvent(this, 1+(random() % 200)); + parent_driver->eventQueue->scheduleEvent(this, 1+(random() % 200)); } DetermGETXGenerator::~DetermGETXGenerator() @@ -70,13 +67,13 @@ void DetermGETXGenerator::wakeup() // determine if this node is next for the GETX round robin request if (m_status == DetermGETXGeneratorStatus_Thinking) { - if (m_driver.isStoreReady(m_node)) { + if (parent_driver->isStoreReady(m_node)) { pickAddress(); m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = parent_driver->eventQueue->getTime(); initiateStore(); // GETX } else { // I'll check again later - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); + parent_driver->eventQueue->scheduleEvent(this, thinkTime()); } } else { WARN_EXPR(m_status); @@ -85,31 +82,28 @@ void DetermGETXGenerator::wakeup() } -void DetermGETXGenerator::performCallback(NodeID proc, SubBlock& data) +void DetermGETXGenerator::performCallback(NodeID proc, Address address) { - Address address = data.getAddress(); assert(proc == m_node); assert(address == m_address); DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - DEBUG_EXPR(TESTER_COMP, LowPrio, data); if (m_status == DetermGETXGeneratorStatus_Store_Pending) { - m_driver.recordStoreLatency(g_eventQueue_ptr->getTime() - m_last_transition); - data.writeByte(m_node); - m_driver.storeCompleted(m_node, data.getAddress()); // advance the store queue + parent_driver->recordStoreLatency(parent_driver->eventQueue->getTime() - m_last_transition); + parent_driver->storeCompleted(m_node, address); // advance the store queue m_counter++; - if (m_counter < g_tester_length) { + if (m_counter < parent_driver->m_tester_length) { m_status = DetermGETXGeneratorStatus_Thinking; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); + m_last_transition = parent_driver->eventQueue->getTime(); + parent_driver->eventQueue->scheduleEvent(this, waitTime()); } else { - m_driver.reportDone(); + parent_driver->reportDone(); m_status = DetermGETXGeneratorStatus_Done; - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = parent_driver->eventQueue->getTime(); } } else { @@ -120,38 +114,40 @@ void DetermGETXGenerator::performCallback(NodeID proc, SubBlock& data) int DetermGETXGenerator::thinkTime() const { - return g_think_time; + return parent_driver->m_think_time; } int DetermGETXGenerator::waitTime() const { - return g_wait_time; + return parent_driver->m_wait_time; } void DetermGETXGenerator::pickAddress() { assert(m_status == DetermGETXGeneratorStatus_Thinking); - m_address = m_driver.getNextStoreAddr(m_node); + m_address = parent_driver->getNextStoreAddr(m_node); } void DetermGETXGenerator::initiateStore() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); - Addr data_addr = m_address.getAddress(); - Request request(0, data_addr, 1, Flags(), 3, 0, 0); - MemCmd::Command command; - command = MemCmd::WriteReq; + uint8_t *write_data = new uint8_t[64]; + for(int i=0; i < 64; i++) { + write_data[i] = m_node; + } + + char name [] = "Sequencer_"; + char port_name [13]; + sprintf(port_name, "%s%d", name, m_node); - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor)); - sequencer()->makeRequest(&pkt); -} + // delete [] write_data; -Sequencer* DetermGETXGenerator::sequencer() const -{ - return g_system_ptr->getChip(m_node/RubyConfig::numberOfProcsPerChip())->getSequencer(m_node%RubyConfig::numberOfProcsPerChip()); + ASSERT(parent_driver->requests.find(request_id) == parent_driver->requests.end()); + parent_driver->requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } void DetermGETXGenerator::print(ostream& out) const diff --git a/src/mem/ruby/tester/DetermGETXGenerator.hh b/src/mem/ruby/tester/DetermGETXGenerator.hh index 1f5b67653..82e616e4b 100644 --- a/src/mem/ruby/tester/DetermGETXGenerator.hh +++ b/src/mem/ruby/tester/DetermGETXGenerator.hh @@ -40,28 +40,26 @@ #ifndef DETERMGETXGENERATOR_H #define DETERMGETXGENERATOR_H -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Global_Tester.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/protocol/DetermGETXGeneratorStatus.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/common/Address.hh" +#include "Address_Tester.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" -class Sequencer; -class SubBlock; class DeterministicDriver; +class DMAController; class DetermGETXGenerator : public SpecifiedGenerator { public: // Constructors - DetermGETXGenerator(NodeID node, DeterministicDriver& driver); + DetermGETXGenerator(NodeID node, DeterministicDriver * driver); // Destructor ~DetermGETXGenerator(); // Public Methods void wakeup(); - void performCallback(NodeID proc, SubBlock& data); + void performCallback(NodeID proc, Address address); void print(ostream& out) const; private: @@ -69,20 +67,21 @@ private: int thinkTime() const; int waitTime() const; void initiateStore(); + void initiateDMA(); void pickAddress(); - Sequencer* sequencer() const; + DMAController* dma() const; // copy constructor and assignment operator DetermGETXGenerator(const DetermGETXGenerator& obj); DetermGETXGenerator& operator=(const DetermGETXGenerator& obj); + DeterministicDriver * parent_driver; // Data Members (m_ prefix) DetermGETXGeneratorStatus m_status; int m_counter; Address m_address; NodeID m_node; - DeterministicDriver& m_driver; Time m_last_transition; }; diff --git a/src/mem/ruby/tester/DetermInvGenerator.cc b/src/mem/ruby/tester/DetermInvGenerator.cc index bafaa18ae..eebe18057 100644 --- a/src/mem/ruby/tester/DetermInvGenerator.cc +++ b/src/mem/ruby/tester/DetermInvGenerator.cc @@ -38,13 +38,10 @@ #include "mem/ruby/tester/DetermInvGenerator.hh" #include "mem/protocol/DetermInvGeneratorStatus.hh" -#include "mem/protocol/LockStatus.hh" -#include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/config/RubyConfig.hh" -#include "mem/ruby/common/SubBlock.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/protocol/Chip.hh" +#include "mem/ruby/tester/Global_Tester.hh" +//#include "DMAController.hh" +#include "mem/ruby/libruby.hh" DetermInvGenerator::DetermInvGenerator(NodeID node, DeterministicDriver& driver) : m_driver(driver) @@ -54,9 +51,8 @@ DetermInvGenerator::DetermInvGenerator(NodeID node, DeterministicDriver& driver) m_node = node; m_address = Address(9999); // initiate to a NULL value m_counter = 0; - // don't know exactly when this node needs to request so just guess randomly - g_eventQueue_ptr->scheduleEvent(this, 1+(random() % 200)); + m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200)); } DetermInvGenerator::~DetermInvGenerator() @@ -74,23 +70,23 @@ void DetermInvGenerator::wakeup() if (m_driver.isLoadReady(m_node) && m_counter == m_driver.getStoresCompleted()) { pickLoadAddress(); m_status = DetermInvGeneratorStatus_Load_Pending; // Load Pending - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = m_driver.eventQueue->getTime(); initiateLoad(); // GETS } else { // I'll check again later - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); + m_driver.eventQueue->scheduleEvent(this, thinkTime()); } } else if (m_status == DetermInvGeneratorStatus_Load_Complete) { if (m_driver.isStoreReady(m_node, m_address)) { // do a store in this transaction or start the next one if (m_driver.isLoadReady((0), m_address)) { // everyone is in S for this address i.e. back to node 0 m_status = DetermInvGeneratorStatus_Store_Pending; - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = m_driver.eventQueue->getTime(); initiateStore(); // GETX } else { // I'm next, I just have to wait for all loads to complete - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); + m_driver.eventQueue->scheduleEvent(this, thinkTime()); } } else { // I'm not next to store, go back to thinking m_status = DetermInvGeneratorStatus_Thinking; - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); + m_driver.eventQueue->scheduleEvent(this, thinkTime()); } } else { WARN_EXPR(m_status); @@ -99,48 +95,48 @@ void DetermInvGenerator::wakeup() } -void DetermInvGenerator::performCallback(NodeID proc, SubBlock& data) +void DetermInvGenerator::performCallback(NodeID proc, Address address) { - Address address = data.getAddress(); assert(proc == m_node); assert(address == m_address); DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - DEBUG_EXPR(TESTER_COMP, LowPrio, data); if (m_status == DetermInvGeneratorStatus_Load_Pending) { - m_driver.recordLoadLatency(g_eventQueue_ptr->getTime() - m_last_transition); - m_driver.loadCompleted(m_node, data.getAddress()); + m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition); + //NodeID firstByte = data.readByte(); // dummy read + + m_driver.loadCompleted(m_node, address); if (!m_driver.isStoreReady(m_node, m_address)) { // if we don't have to store, we are done for this transaction m_counter++; } - if (m_counter < g_tester_length) { + if (m_counter < m_driver.m_tester_length) { m_status = DetermInvGeneratorStatus_Load_Complete; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); + m_last_transition = m_driver.eventQueue->getTime(); + m_driver.eventQueue->scheduleEvent(this, waitTime()); } else { m_driver.reportDone(); m_status = DetermInvGeneratorStatus_Done; - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = m_driver.eventQueue->getTime(); } } else if (m_status == DetermInvGeneratorStatus_Store_Pending) { - m_driver.recordStoreLatency(g_eventQueue_ptr->getTime() - m_last_transition); - data.writeByte(m_node); - m_driver.storeCompleted(m_node, data.getAddress()); // advance the store queue + m_driver.recordStoreLatency(m_driver.eventQueue->getTime() - m_last_transition); + //data.writeByte(m_node); + m_driver.storeCompleted(m_node, address); // advance the store queue m_counter++; - if (m_counter < g_tester_length) { + if (m_counter < m_driver.m_tester_length) { m_status = DetermInvGeneratorStatus_Thinking; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); + m_last_transition = m_driver.eventQueue->getTime(); + m_driver.eventQueue->scheduleEvent(this, waitTime()); } else { m_driver.reportDone(); m_status = DetermInvGeneratorStatus_Done; - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = m_driver.eventQueue->getTime(); } } else { WARN_EXPR(m_status); @@ -150,23 +146,22 @@ void DetermInvGenerator::performCallback(NodeID proc, SubBlock& data) DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - DEBUG_EXPR(TESTER_COMP, LowPrio, data); } int DetermInvGenerator::thinkTime() const { - return g_think_time; + return m_driver.m_think_time; } int DetermInvGenerator::waitTime() const { - return g_wait_time; + return m_driver.m_wait_time; } int DetermInvGenerator::holdTime() const { - return g_hold_time; + assert(0); } void DetermInvGenerator::pickLoadAddress() @@ -179,35 +174,42 @@ void DetermInvGenerator::pickLoadAddress() void DetermInvGenerator::initiateLoad() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load"); + // sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); + uint8_t * read_data = new uint8_t[64]; - Addr data_addr = m_address.getAddress(); - Request request(0, data_addr, 1, Flags(), 1, 0, 0); - MemCmd::Command command; - command = MemCmd::ReadReq; + char name [] = "Sequencer_"; + char port_name [13]; + sprintf(port_name, "%s%d", name, m_node); - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), read_data, 64, 0, RubyRequestType_LD, RubyAccessMode_Supervisor)); - sequencer()->makeRequest(&pkt); + //delete [] read_data; + + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); + m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } void DetermInvGenerator::initiateStore() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); + // sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); + uint8_t *write_data = new uint8_t[64]; + for(int i=0; i < 64; i++) { + write_data[i] = m_node; + } - Addr data_addr = m_address.getAddress(); - Request request(0, data_addr, 1, Flags(), 3, 0, 0); - MemCmd::Command command; - command = MemCmd::WriteReq; + char name [] = "Sequencer_"; + char port_name [13]; + sprintf(port_name, "%s%d", name, m_node); - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor)); - sequencer()->makeRequest(&pkt); -} + //delete [] write_data; + + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); + m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address))); -Sequencer* DetermInvGenerator::sequencer() const -{ - return g_system_ptr->getChip(m_node/RubyConfig::numberOfProcsPerChip())->getSequencer(m_node%RubyConfig::numberOfProcsPerChip()); } void DetermInvGenerator::print(ostream& out) const diff --git a/src/mem/ruby/tester/DetermInvGenerator.hh b/src/mem/ruby/tester/DetermInvGenerator.hh index 4f0712fbe..6127c3af4 100644 --- a/src/mem/ruby/tester/DetermInvGenerator.hh +++ b/src/mem/ruby/tester/DetermInvGenerator.hh @@ -41,15 +41,12 @@ #ifndef DETERMINVGENERATOR_H #define DETERMINVGENERATOR_H -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Global_Tester.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/protocol/DetermInvGeneratorStatus.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/common/Address.hh" +#include "Address_Tester.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" -class Sequencer; -class SubBlock; class DeterministicDriver; class DetermInvGenerator : public SpecifiedGenerator { @@ -62,7 +59,7 @@ public: // Public Methods void wakeup(); - void performCallback(NodeID proc, SubBlock& data); + void performCallback(NodeID proc, Address address); void print(ostream& out) const; private: @@ -75,8 +72,6 @@ private: void pickLoadAddress(); void pickStoreAddress(); - Sequencer* sequencer() const; - // copy constructor and assignment operator DetermInvGenerator(const DetermInvGenerator& obj); DetermInvGenerator& operator=(const DetermInvGenerator& obj); diff --git a/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc b/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc index 5adc7aa5c..38688f10d 100644 --- a/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc +++ b/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc @@ -34,13 +34,7 @@ #include "mem/ruby/tester/DetermSeriesGETSGenerator.hh" #include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh" -#include "mem/protocol/LockStatus.hh" -#include "mem/ruby/system/Sequencer.hh" -#include "mem/ruby/system/System.hh" -#include "mem/ruby/config/RubyConfig.hh" -#include "mem/ruby/common/SubBlock.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/protocol/Chip.hh" DetermSeriesGETSGenerator::DetermSeriesGETSGenerator(NodeID node, DeterministicDriver& driver) : m_driver(driver) @@ -51,8 +45,9 @@ DetermSeriesGETSGenerator::DetermSeriesGETSGenerator(NodeID node, DeterministicD m_address = Address(9999); // initialize to null value m_counter = 0; + // don't know exactly when this node needs to request so just guess randomly - g_eventQueue_ptr->scheduleEvent(this, 1+(random() % 200)); + m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200)); } DetermSeriesGETSGenerator::~DetermSeriesGETSGenerator() @@ -69,10 +64,10 @@ void DetermSeriesGETSGenerator::wakeup() if (m_driver.isLoadReady(m_node)) { pickAddress(); m_status = DetermSeriesGETSGeneratorStatus_Load_Pending; // Load Pending - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = m_driver.eventQueue->getTime(); initiateLoad(); // SeriesGETS } else { // I'll check again later - g_eventQueue_ptr->scheduleEvent(this, thinkTime()); + m_driver.eventQueue->scheduleEvent(this, thinkTime()); } } else { WARN_EXPR(m_status); @@ -81,32 +76,30 @@ void DetermSeriesGETSGenerator::wakeup() } -void DetermSeriesGETSGenerator::performCallback(NodeID proc, SubBlock& data) +void DetermSeriesGETSGenerator::performCallback(NodeID proc, Address address) { - Address address = data.getAddress(); assert(proc == m_node); assert(address == m_address); DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - DEBUG_EXPR(TESTER_COMP, LowPrio, data); if (m_status == DetermSeriesGETSGeneratorStatus_Load_Pending) { - m_driver.recordLoadLatency(g_eventQueue_ptr->getTime() - m_last_transition); - data.writeByte(m_node); - m_driver.loadCompleted(m_node, data.getAddress()); // advance the load queue + m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition); + //data.writeByte(m_node); + m_driver.loadCompleted(m_node, address); // advance the load queue m_counter++; // do we still have more requests to complete before the next proc starts? - if (m_counter < g_tester_length*g_NUM_COMPLETIONS_BEFORE_PASS) { + if (m_counter < m_driver.m_tester_length*m_driver.m_numCompletionsPerNode) { m_status = DetermSeriesGETSGeneratorStatus_Thinking; - m_last_transition = g_eventQueue_ptr->getTime(); - g_eventQueue_ptr->scheduleEvent(this, waitTime()); + m_last_transition = m_driver.eventQueue->getTime(); + m_driver.eventQueue->scheduleEvent(this, waitTime()); } else { m_driver.reportDone(); m_status = DetermSeriesGETSGeneratorStatus_Done; - m_last_transition = g_eventQueue_ptr->getTime(); + m_last_transition = m_driver.eventQueue->getTime(); } } else { @@ -117,12 +110,12 @@ void DetermSeriesGETSGenerator::performCallback(NodeID proc, SubBlock& data) int DetermSeriesGETSGenerator::thinkTime() const { - return g_think_time; + return m_driver.m_think_time; } int DetermSeriesGETSGenerator::waitTime() const { - return g_wait_time; + return m_driver.m_wait_time; } void DetermSeriesGETSGenerator::pickAddress() @@ -135,21 +128,20 @@ void DetermSeriesGETSGenerator::pickAddress() void DetermSeriesGETSGenerator::initiateLoad() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load"); + //sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_IFETCH, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); - Addr data_addr = m_address.getAddress(); - Request request(0, data_addr, 1, Flags(), 3, 0, 0); - MemCmd::Command command; - command = MemCmd::ReadReq; - request.setFlags(Request::INST_FETCH); + uint8_t *read_data = new uint8_t[64]; - Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + char name [] = "Sequencer_"; + char port_name [13]; + sprintf(port_name, "%s%d", name, m_node); - sequencer()->makeRequest(&pkt); -} + int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), read_data, 64, 0, RubyRequestType_LD, RubyAccessMode_Supervisor)); -Sequencer* DetermSeriesGETSGenerator::sequencer() const -{ - return g_system_ptr->getChip(m_node/RubyConfig::numberOfProcsPerChip())->getSequencer(m_node%RubyConfig::numberOfProcsPerChip()); + //delete [] read_data; + + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); + m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } void DetermSeriesGETSGenerator::print(ostream& out) const diff --git a/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh b/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh index 1e44dc3bc..225e45a11 100644 --- a/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh +++ b/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh @@ -42,15 +42,12 @@ #ifndef DETERMSERIESGETSGENERATOR_H #define DETERMSERIESGETSGENERATOR_H -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Global_Tester.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh" -#include "mem/ruby/system/NodeID.hh" -#include "mem/ruby/common/Address.hh" +#include "Address_Tester.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" -class Sequencer; -class SubBlock; class DeterministicDriver; class DetermSeriesGETSGenerator : public SpecifiedGenerator { @@ -63,7 +60,7 @@ public: // Public Methods void wakeup(); - void performCallback(NodeID proc, SubBlock& data); + void performCallback(NodeID proc, Address address); void print(ostream& out) const; private: @@ -73,8 +70,6 @@ private: void initiateLoad(); void pickAddress(); - Sequencer* sequencer() const; - // copy constructor and assignment operator DetermSeriesGETSGenerator(const DetermSeriesGETSGenerator& obj); DetermSeriesGETSGenerator& operator=(const DetermSeriesGETSGenerator& obj); diff --git a/src/mem/ruby/tester/DeterministicDriver.cc b/src/mem/ruby/tester/DeterministicDriver.cc index 762672118..54b5f5e0d 100644 --- a/src/mem/ruby/tester/DeterministicDriver.cc +++ b/src/mem/ruby/tester/DeterministicDriver.cc @@ -32,67 +32,79 @@ * */ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" +#include "mem/ruby/tester/Global_Tester.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/ruby/eventqueue/RubyEventQueue.hh" -#include "mem/ruby/tester/SpecifiedGenerator.hh" +#include "mem/ruby/tester/EventQueue_Tester.hh" +//#include "DMAGenerator.hh" #include "mem/ruby/tester/DetermGETXGenerator.hh" -#include "mem/ruby/tester/DetermInvGenerator.hh" -#include "mem/ruby/tester/DetermSeriesGETSGenerator.hh" -#include "mem/ruby/common/SubBlock.hh" -#include "mem/protocol/Chip.hh" -#include "mem/packet.hh" -DeterministicDriver::DeterministicDriver(RubySystem* sys_ptr) +#define DATA_BLOCK_BYTES 64 + +DeterministicDriver::DeterministicDriver(string generator_type, int num_completions, int num_procs, Time g_think_time, Time g_wait_time, int g_tester_length) { + eventQueue = new RubyEventQueue; m_finish_time = 0; m_last_issue = -11; m_done_counter = 0; m_loads_completed = 0; m_stores_completed = 0; - m_numCompletionsPerNode = g_NUM_COMPLETIONS_BEFORE_PASS; + m_numCompletionsPerNode = num_completions; + m_num_procs = num_procs; + m_think_time = g_think_time; + m_wait_time = g_wait_time; + m_tester_length = g_tester_length; + - m_last_progress_vector.setSize(RubyConfig::numberOfProcessors()); + m_last_progress_vector.setSize(num_procs); for (int i=0; ischeduleEvent(this, 1); + //m_dma_generator = new DMAGenerator(0, this); } + +void DeterministicDriver::go() +{ + // tick both queues until everyone is done + while (m_done_counter != m_num_procs) { + libruby_tick(1); + eventQueue->triggerEvents(eventQueue->getTime() + 1); + } +} + + DeterministicDriver::~DeterministicDriver() { for (int i=0; iperformCallback(); +//} + +void DeterministicDriver::wakeup() { + assert(0); + // this shouldn't be called as we are not scheduling the driver ever +} + +void DeterministicDriver::hitCallback(int64_t request_id) { - NodeID proc = pkt->req->contextId(); - SubBlock data(Address(pkt->getAddr()), pkt->req->getSize()); - if (pkt->hasData()) { - for (int i = 0; i < pkt->req->getSize(); i++) { - data.setByte(i, *(pkt->getPtr()+i)); - } - } - m_generator_vector[proc]->performCallback(proc, data); - m_last_progress_vector[proc] = g_eventQueue_ptr->getTime(); + ASSERT(requests.find(request_id) != requests.end()); + int proc = requests[request_id].first; + Address address = requests[request_id].second; + + m_generator_vector[proc]->performCallback(proc, address); + + m_last_progress_vector[proc] = eventQueue->getTime(); + + requests.erase(request_id); } bool DeterministicDriver::isStoreReady(NodeID node) @@ -121,6 +142,8 @@ bool DeterministicDriver::isStoreReady(NodeID node) bool DeterministicDriver::isStoreReady(NodeID node, Address addr) { + int addr_number = addr.getAddress()/DATA_BLOCK_BYTES; + return isAddrReady(node, m_store_vector, addr); } @@ -138,25 +161,26 @@ bool DeterministicDriver::isLoadReady(NodeID node, Address addr) bool DeterministicDriver::isAddrReady(NodeID node, Vector addr_vector) { for (int i=0; i= m_numCompletionsPerNode*node) && // is this node next - (g_eventQueue_ptr->getTime() >= m_last_issue + 10)) { // controll rate of requests + (eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests return true; } } + return false; } // test for a particular addr bool DeterministicDriver::isAddrReady(NodeID node, Vector addr_vector, Address addr) { - int addr_number = addr.getAddress()/RubyConfig::dataBlockBytes(); + int addr_number = addr.getAddress()/DATA_BLOCK_BYTES; ASSERT ((addr_number >= 0) && (addr_number < addr_vector.size())); - if (((addr_vector[addr_number]+1)%RubyConfig::numberOfProcessors() == node) && + if (((addr_vector[addr_number]+1)%m_num_procs == node) && (m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next - (g_eventQueue_ptr->getTime() >= m_last_issue + 10)) { // controll rate of requests + (eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests return true; } else { return false; @@ -178,7 +202,7 @@ void DeterministicDriver::storeCompleted(NodeID node, Address addr) void DeterministicDriver::setNextAddr(NodeID node, Address addr, Vector& addr_vector) { // mark the addr vector that this proc was the last to use the particular address - int addr_number = addr.getAddress()/RubyConfig::dataBlockBytes(); + int addr_number = addr.getAddress()/DATA_BLOCK_BYTES; addr_vector[addr_number] = node; } @@ -204,17 +228,16 @@ Address DeterministicDriver::getNextAddr(NodeID node, Vector addr_vector ASSERT(isAddrReady(node, addr_vector)); for (int addr_number=0; addr_number0; addr_number--) { // is this node next in line for the addr - if (((addr_vector[addr_number]+1)%RubyConfig::numberOfProcessors()) == node) { + if ((addr_vector[addr_number] != 1) && ((addr_vector[addr_number]+1)%m_num_procs) == node) { // One addr per cache line - addr.setAddress(addr_number * RubyConfig::dataBlockBytes()); + addr.setAddress(addr_number * DATA_BLOCK_BYTES); } } - m_last_issue = g_eventQueue_ptr->getTime(); + m_last_issue = eventQueue->getTime(); return addr; } @@ -223,9 +246,9 @@ Address DeterministicDriver::getNextAddr(NodeID node, Vector addr_vector void DeterministicDriver::reportDone() { m_done_counter++; - if ((m_done_counter == RubyConfig::numberOfProcessors())) { - //|| (m_done_counter == g_tester_length)) { - m_finish_time = g_eventQueue_ptr->getTime(); + if ((m_done_counter == m_num_procs)) { + m_finish_time = eventQueue->getTime(); + //m_dma_generator->stop(); } } @@ -239,36 +262,6 @@ void DeterministicDriver::recordStoreLatency(Time time) m_store_latency.add(time); } -void DeterministicDriver::wakeup() -{ - // checkForDeadlock(); - if (m_done_counter < RubyConfig::numberOfProcessors()) { - g_eventQueue_ptr->scheduleEvent(this, g_DEADLOCK_THRESHOLD); - } -} - -void DeterministicDriver::checkForDeadlock() -{ - int size = m_last_progress_vector.size(); - Time current_time = g_eventQueue_ptr->getTime(); - for (int processor=0; processor g_DEADLOCK_THRESHOLD) { - WARN_EXPR(processor); -#ifndef NDEBUG - Sequencer* seq_ptr = g_system_ptr->getChip(processor/RubyConfig::numberOfProcsPerChip())->getSequencer(processor%RubyConfig::numberOfProcsPerChip()); -#endif - assert(seq_ptr != NULL); - // if (seq_ptr->isRequestPending()) { - // WARN_EXPR(seq_ptr->pendingAddress()); - // } - WARN_EXPR(current_time); - WARN_EXPR(m_last_progress_vector[processor]); - WARN_EXPR(current_time - m_last_progress_vector[processor]); - ERROR_MSG("Deadlock detected."); - } - } -} - void DeterministicDriver::printStats(ostream& out) const { out << endl; diff --git a/src/mem/ruby/tester/DeterministicDriver.hh b/src/mem/ruby/tester/DeterministicDriver.hh index 710da7922..288ad5a15 100644 --- a/src/mem/ruby/tester/DeterministicDriver.hh +++ b/src/mem/ruby/tester/DeterministicDriver.hh @@ -36,25 +36,35 @@ #ifndef DETERMINISTICDRIVER_H #define DETERMINISTICDRIVER_H - -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/common/Driver.hh" -#include "mem/ruby/common/Histogram.hh" -#include "mem/protocol/CacheRequestType.hh" - -class RubySystem; -class SpecifiedGenerator; -class Packet; - -class DeterministicDriver : public Driver, public Consumer { +#include +#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Histogram.hh" // includes global, but doesn't use anything, so it should be fine +#include "mem/protocol/CacheRequestType.hh" // includes global, but doesn't use anything, so it should be fine +#include "Address_Tester.hh" // we redefined the address +#include "mem/ruby/tester/DetermGETXGenerator.hh" // this is our file +#include "mem/ruby/tester/DetermSeriesGETSGenerator.hh" // this is our file +#include "mem/ruby/tester/DetermInvGenerator.hh" // this is our file +#include "mem/ruby/libruby.hh" +#include "mem/ruby/tester/Driver_Tester.hh" +#include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/tester/EventQueue_Tester.hh" +#include "mem/protocol/SpecifiedGeneratorType.hh" + +//class DMAGenerator; + +class DeterministicDriver : public Driver_Tester, public Consumer { public: + friend class DetermGETXGenerator; + friend class DetermSeriesGETSGenerator; + friend class DetermInvGenerator; // Constructors - DeterministicDriver(RubySystem* sys_ptr); + DeterministicDriver(string generator_type, int num_completions, int num_procs, Time g_think_time, Time g_wait_time, int g_tester_length); // Destructor ~DeterministicDriver(); // Public Methods + void go(); bool isStoreReady(NodeID node); bool isLoadReady(NodeID node); bool isStoreReady(NodeID node, Address addr); @@ -70,37 +80,47 @@ public: void recordLoadLatency(Time time); void recordStoreLatency(Time time); - void hitCallback(Packet* pkt); +// void dmaHitCallback(); + void hitCallback(int64_t request_id); void wakeup(); void printStats(ostream& out) const; void clearStats() {} void printConfig(ostream& out) const {} void print(ostream& out) const; + // Public copy constructor and assignment operator + DeterministicDriver(const DeterministicDriver& obj); + DeterministicDriver& operator=(const DeterministicDriver& obj); + private: // Private Methods - void checkForDeadlock(); Address getNextAddr(NodeID node, Vector addr_vector); bool isAddrReady(NodeID node, Vector addr_vector); bool isAddrReady(NodeID node, Vector addr_vector, Address addr); void setNextAddr(NodeID node, Address addr, Vector& addr_vector); - // Private copy constructor and assignment operator - DeterministicDriver(const DeterministicDriver& obj); - DeterministicDriver& operator=(const DeterministicDriver& obj); // Data Members (m_ prefix) Vector