From 2f30950143cc70bc42a3c8a4111d7cf8198ec881 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 May 2009 10:38:43 -0700 Subject: ruby: Import ruby and slicc from GEMS We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother. --- src/mem/ruby/tester/RequestGenerator.cc | 196 ++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/mem/ruby/tester/RequestGenerator.cc (limited to 'src/mem/ruby/tester/RequestGenerator.cc') diff --git a/src/mem/ruby/tester/RequestGenerator.cc b/src/mem/ruby/tester/RequestGenerator.cc new file mode 100644 index 000000000..71a183315 --- /dev/null +++ b/src/mem/ruby/tester/RequestGenerator.cc @@ -0,0 +1,196 @@ + +/* + * 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 "RequestGenerator.hh" +#include "RequestGeneratorStatus.hh" +#include "LockStatus.hh" +#include "Sequencer.hh" +#include "System.hh" +#include "RubyConfig.hh" +#include "SubBlock.hh" +#include "SyntheticDriver.hh" +#include "Chip.hh" + +RequestGenerator::RequestGenerator(NodeID node, SyntheticDriver& driver) : + m_driver(driver) +{ + m_status = RequestGeneratorStatus_Thinking; + m_last_transition = 0; + m_node = node; + pickAddress(); + m_counter = 0; + + //g_eventQueue_ptr->scheduleEvent(this, 1+(random() % 200)); +} + +RequestGenerator::~RequestGenerator() +{ +} + +void RequestGenerator::wakeup() +{ + DEBUG_EXPR(TESTER_COMP, MedPrio, m_node); + DEBUG_EXPR(TESTER_COMP, MedPrio, m_status); + + if (m_status == RequestGeneratorStatus_Thinking) { + m_status = RequestGeneratorStatus_Test_Pending; + m_last_transition = g_eventQueue_ptr->getTime(); + initiateTest(); // Test + } else if (m_status == RequestGeneratorStatus_Holding) { + m_status = RequestGeneratorStatus_Release_Pending; + m_last_transition = g_eventQueue_ptr->getTime(); + initiateRelease(); // Release + } else if (m_status == RequestGeneratorStatus_Before_Swap) { + m_status = RequestGeneratorStatus_Swap_Pending; + m_last_transition = g_eventQueue_ptr->getTime(); + initiateSwap(); + } else { + WARN_EXPR(m_status); + ERROR_MSG("Invalid status"); + } +} + +void RequestGenerator::performCallback(NodeID proc, SubBlock& data) +{ + 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 == RequestGeneratorStatus_Test_Pending) { + // m_driver.recordTestLatency(g_eventQueue_ptr->getTime() - m_last_transition); + if (data.readByte() == LockStatus_Locked) { + // Locked - keep spinning + m_status = RequestGeneratorStatus_Thinking; + 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 = RequestGeneratorStatus_Before_Swap; + m_last_transition = g_eventQueue_ptr->getTime(); + g_eventQueue_ptr->scheduleEvent(this, waitTime()); + } + } else if (m_status == RequestGeneratorStatus_Swap_Pending) { + m_driver.recordSwapLatency(g_eventQueue_ptr->getTime() - m_last_transition); + if (data.readByte() == LockStatus_Locked) { + // We failed to aquire the lock + m_status = RequestGeneratorStatus_Thinking; + m_last_transition = g_eventQueue_ptr->getTime(); + g_eventQueue_ptr->scheduleEvent(this, waitTime()); + } else { + // We acquired the lock + data.writeByte(LockStatus_Locked); + m_status = RequestGeneratorStatus_Holding; + 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()); + } + } else if (m_status == RequestGeneratorStatus_Release_Pending) { + m_driver.recordReleaseLatency(g_eventQueue_ptr->getTime() - m_last_transition); + // We're releasing the lock + data.writeByte(LockStatus_Unlocked); + + m_counter++; + if (m_counter < g_tester_length) { + m_status = RequestGeneratorStatus_Thinking; + m_last_transition = g_eventQueue_ptr->getTime(); + pickAddress(); + g_eventQueue_ptr->scheduleEvent(this, thinkTime()); + } else { + m_driver.reportDone(); + m_status = RequestGeneratorStatus_Done; + m_last_transition = g_eventQueue_ptr->getTime(); + } + } else { + WARN_EXPR(m_status); + ERROR_MSG("Invalid status"); + } +} + +int RequestGenerator::thinkTime() const +{ + return g_think_time; +} + +int RequestGenerator::waitTime() const +{ + return g_wait_time; +} + +int RequestGenerator::holdTime() const +{ + return g_hold_time; +} + +void RequestGenerator::pickAddress() +{ + assert(m_status == RequestGeneratorStatus_Thinking); + m_address = m_driver.pickAddress(m_node); +} + +void RequestGenerator::initiateTest() +{ + DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Test"); + sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */, 0, false)); +} + +void RequestGenerator::initiateSwap() +{ + DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Swap"); + sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ATOMIC, Address(2), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */, 0, false)); +} + +void RequestGenerator::initiateRelease() +{ + DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Release"); + 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)); +} + +Sequencer* RequestGenerator::sequencer() const +{ + return g_system_ptr->getChip(m_node/RubyConfig::numberOfProcsPerChip())->getSequencer(m_node%RubyConfig::numberOfProcsPerChip()); +} + +void RequestGenerator::print(ostream& out) const +{ + out << "[RequestGenerator]" << endl; +} + -- cgit v1.2.3 From 6ceaffd7240993761785c0d2f5e4f92bd94fbf32 Mon Sep 17 00:00:00 2001 From: Derek Hower Date: Mon, 11 May 2009 10:38:45 -0700 Subject: ruby: Cleaned up sequencer. Removed LogTM specific code. --- src/mem/ruby/tester/RequestGenerator.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mem/ruby/tester/RequestGenerator.cc') diff --git a/src/mem/ruby/tester/RequestGenerator.cc b/src/mem/ruby/tester/RequestGenerator.cc index 71a183315..b216e06fe 100644 --- a/src/mem/ruby/tester/RequestGenerator.cc +++ b/src/mem/ruby/tester/RequestGenerator.cc @@ -169,19 +169,19 @@ void RequestGenerator::pickAddress() void RequestGenerator::initiateTest() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Test"); - sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */, 0, false)); + sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */)); } void RequestGenerator::initiateSwap() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Swap"); - sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ATOMIC, Address(2), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */, 0, false)); + sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ATOMIC, Address(2), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */)); } void RequestGenerator::initiateRelease() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Release"); - 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)); + sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */)); } Sequencer* RequestGenerator::sequencer() const -- cgit v1.2.3 From 24da30e317cdbf4b628141d69b2d17dac5ae3822 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 May 2009 10:38:45 -0700 Subject: ruby: Make ruby #includes use full paths to the files they're including. This basically means changing all #include statements and changing autogenerated code so that it generates the correct paths. Because slicc generates #includes, I had to hard code the include paths to mem/protocol. --- src/mem/ruby/tester/RequestGenerator.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/mem/ruby/tester/RequestGenerator.cc') diff --git a/src/mem/ruby/tester/RequestGenerator.cc b/src/mem/ruby/tester/RequestGenerator.cc index b216e06fe..c1772f905 100644 --- a/src/mem/ruby/tester/RequestGenerator.cc +++ b/src/mem/ruby/tester/RequestGenerator.cc @@ -32,15 +32,15 @@ * */ -#include "RequestGenerator.hh" -#include "RequestGeneratorStatus.hh" -#include "LockStatus.hh" -#include "Sequencer.hh" -#include "System.hh" -#include "RubyConfig.hh" -#include "SubBlock.hh" -#include "SyntheticDriver.hh" -#include "Chip.hh" +#include "mem/ruby/tester/RequestGenerator.hh" +#include "mem/protocol/RequestGeneratorStatus.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/SyntheticDriver.hh" +#include "mem/protocol/Chip.hh" RequestGenerator::RequestGenerator(NodeID node, SyntheticDriver& driver) : m_driver(driver) -- cgit v1.2.3 From 93f2f69657d0a2420a2c86b71505e6d27e6e2a38 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Mon, 11 May 2009 10:38:46 -0700 Subject: ruby: Working M5 interface and updated Ruby interface. This changeset also includes a lot of work from Derek Hower RubyMemory is now both a driver for Ruby and a port for M5. Changed makeRequest/hitCallback interface. Brought packets (superficially) into the sequencer. Modified tester infrastructure to be packet based. and Ruby can be used together through the example ruby_se.py script. SPARC parallel applications work, and the timing *seems* right from combined M5/Ruby debug traces. To run, % build/ALPHA_SE/m5.debug configs/example/ruby_se.py -c tests/test-progs/hello/bin/alpha/linux/hello -n 4 -t --- src/mem/ruby/tester/RequestGenerator.cc | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'src/mem/ruby/tester/RequestGenerator.cc') diff --git a/src/mem/ruby/tester/RequestGenerator.cc b/src/mem/ruby/tester/RequestGenerator.cc index c1772f905..4ee24544f 100644 --- a/src/mem/ruby/tester/RequestGenerator.cc +++ b/src/mem/ruby/tester/RequestGenerator.cc @@ -169,19 +169,43 @@ void RequestGenerator::pickAddress() void RequestGenerator::initiateTest() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Test"); - sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */)); + + Addr data_addr = m_address.getAddress(); + Request request(0, data_addr, 1, Flags(), 1, 0, 0); + MemCmd::Command command; + command = MemCmd::ReadReq; + + Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + + sequencer()->makeRequest(&pkt); } void RequestGenerator::initiateSwap() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Swap"); - sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ATOMIC, Address(2), AccessModeType_UserMode, 1, PrefetchBit_No, 0, Address(0), 0 /* only 1 SMT thread */)); + + Addr data_addr = m_address.getAddress(); + Request request(0, data_addr, 1, Flags(), 2, 0, 0); + MemCmd::Command command; + command = MemCmd::SwapReq; + + Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + + sequencer()->makeRequest(&pkt); } void RequestGenerator::initiateRelease() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Release"); - sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, 0, 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::WriteReq; + + Packet pkt(&request, command, 0); // TODO -- make dest a real NodeID + + sequencer()->makeRequest(&pkt); } Sequencer* RequestGenerator::sequencer() const -- cgit v1.2.3