Ruby: Get rid of the dead ruby tester.

None of the code in the ruby tester directory is compiled or referred to
outside of that directory. This change eliminates it. If it's needed in the
future, it can be revived from the history. In the mean time, this removes
clutter and the only use of the GEMS_ROOT scons variable.
This commit is contained in:
Gabe Black 2011-03-11 11:27:16 -08:00
parent d7b5508875
commit a78e772929
14 changed files with 0 additions and 1909 deletions

View file

@ -1,278 +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.
*/
#include <cassert>
#include "base/misc.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/tester/DeterministicDriver.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
//#include "DMAGenerator.hh"
#include "mem/ruby/tester/DetermGETXGenerator.hh"
using namespace std;
#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 = 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.resize(num_procs);
for (int i=0; i<m_last_progress_vector.size(); i++) {
m_last_progress_vector[i] = 0;
}
m_load_vector.resize(10);
for (int i=0; i<m_load_vector.size(); i++) {
m_load_vector[i] = -1; // No processor last held it
}
m_store_vector.resize(10);
for (int i=0; i<m_store_vector.size(); i++) {
m_store_vector[i] = -1; // No processor last held it
}
m_generator_vector.resize(num_procs);
int generator = string_to_SpecifiedGeneratorType(generator_type);
for (int i=0; i<m_generator_vector.size(); i++) {
switch (generator) {
case SpecifiedGeneratorType_DetermGETXGenerator:
m_generator_vector[i] = new DetermGETXGenerator(i, this);
break;
case SpecifiedGeneratorType_DetermInvGenerator:
m_generator_vector[i] = new DetermInvGenerator(i, *this);
break;
case SpecifiedGeneratorType_DetermSeriesGETSGenerator:
m_generator_vector[i] = new DetermSeriesGETSGenerator(i, *this);
break;
default:
fatal("Unexpected specified generator type");
}
}
//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; i<m_last_progress_vector.size(); i++) {
delete m_generator_vector[i];
}
}
//void DeterministicDriver::dmaHitCallback()
//{
// m_dma_generator->performCallback();
//}
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)
{
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)
{
return isAddrReady(node, m_store_vector);
}
bool DeterministicDriver::isStoreReady(NodeID node, Address addr)
{
return isAddrReady(node, m_store_vector, addr);
}
bool DeterministicDriver::isLoadReady(NodeID node)
{
return isAddrReady(node, m_load_vector);
}
bool DeterministicDriver::isLoadReady(NodeID node, Address addr)
{
return isAddrReady(node, m_load_vector, addr);
}
// searches for any address in the addr_vector
bool DeterministicDriver::isAddrReady(NodeID node, vector<NodeID> addr_vector)
{
for (int i=0; i<addr_vector.size(); i++) {
if (((addr_vector[i]+1)%m_num_procs == node) &&
(m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next
(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<NodeID> addr_vector, Address addr)
{
int addr_number = addr.getAddress()/DATA_BLOCK_BYTES;
assert((addr_number >= 0) && (addr_number < addr_vector.size()));
if (((addr_vector[addr_number]+1)%m_num_procs == node) &&
(m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next
(eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests
return true;
} else {
return false;
}
}
void DeterministicDriver::loadCompleted(NodeID node, Address addr)
{
m_loads_completed++;
setNextAddr(node, addr, m_load_vector);
}
void DeterministicDriver::storeCompleted(NodeID node, Address addr)
{
m_stores_completed++;
setNextAddr(node, addr, m_store_vector);
}
void DeterministicDriver::setNextAddr(NodeID node, Address addr, vector<NodeID>& addr_vector)
{
// mark the addr vector that this proc was the last to use the particular address
int addr_number = addr.getAddress()/DATA_BLOCK_BYTES;
addr_vector[addr_number] = node;
}
Address DeterministicDriver::getNextLoadAddr(NodeID node)
{
return getNextAddr(node, m_load_vector);
}
Address DeterministicDriver::getNextStoreAddr(NodeID node)
{
return getNextAddr(node, m_store_vector);
}
Address DeterministicDriver::getNextAddr(NodeID node, vector<NodeID> addr_vector)
{
// This method deterministically picks the next addr the node should acquirer
// The addrs cycle through according to NodeID 0->1->...->lastID->0...
Address addr;
// should only be called if we know a addr is ready for the node
assert(isAddrReady(node, addr_vector));
for (int addr_number=0; addr_number<addr_vector.size(); addr_number++) {
// is this node next in line for the addr
// POLINA: LOOK HERE!
// if ((addr_vector[addr_number] != 1) && ((addr_vector[addr_number]+1)%m_num_procs) == node) {
if (((addr_vector[addr_number]+1)%m_num_procs) == node) {
// One addr per cache line
addr.setAddress(addr_number * DATA_BLOCK_BYTES);
}
}
m_last_issue = eventQueue->getTime();
return addr;
}
void DeterministicDriver::reportDone()
{
m_done_counter++;
if ((m_done_counter == m_num_procs)) {
m_finish_time = eventQueue->getTime();
//m_dma_generator->stop();
}
}
void DeterministicDriver::recordLoadLatency(Time time)
{
m_load_latency.add(time);
}
void DeterministicDriver::recordStoreLatency(Time time)
{
m_store_latency.add(time);
}
void DeterministicDriver::printStats(ostream& out) const
{
out << endl;
out << "DeterministicDriver Stats" << endl;
out << "---------------------" << endl;
out << "finish_time: " << m_finish_time << endl;
out << "load_latency: " << m_load_latency << endl;
out << "store_latency: " << m_store_latency << endl;
}
void DeterministicDriver::print(ostream& out) const
{
}

View file

@ -1,150 +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 DETERMINISTICDRIVER_H
#define DETERMINISTICDRIVER_H
#include <map>
#include <vector>
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.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 "mem/ruby/common/Address.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/common/Driver.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/protocol/SpecifiedGeneratorType.hh"
//class DMAGenerator;
class DeterministicDriver : public Driver, public Consumer {
public:
friend class DetermGETXGenerator;
friend class DetermSeriesGETSGenerator;
friend class DetermInvGenerator;
// Constructors
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);
bool isLoadReady(NodeID node, Address addr);
void loadCompleted(NodeID node, Address addr);
void storeCompleted(NodeID node, Address addr);
Address getNextLoadAddr(NodeID node);
Address getNextStoreAddr(NodeID node);
int getLoadsCompleted() { return m_loads_completed; }
int getStoresCompleted() { return m_stores_completed; }
void reportDone();
void recordLoadLatency(Time time);
void recordStoreLatency(Time time);
// 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
Address getNextAddr(NodeID node, std::vector<NodeID> addr_vector);
bool isAddrReady(NodeID node, std::vector<NodeID> addr_vector);
bool isAddrReady(NodeID node, std::vector<NodeID> addr_vector, Address addr);
void setNextAddr(NodeID node, Address addr, std::vector<NodeID>& addr_vector);
// Data Members (m_ prefix)
std::vector<Time> m_last_progress_vector;
std::vector<SpecifiedGenerator*> m_generator_vector;
//DMAGenerator* m_dma_generator;
std::vector<NodeID> m_load_vector; // Processor last to load the addr
std::vector<NodeID> m_store_vector; // Processor last to store the addr
int last_proc;
int m_done_counter;
int m_loads_completed;
int m_stores_completed;
// enforces the previous node to have a certain # of completions
// before next node starts
map <int64_t, pair <int, Address> > requests;
Time m_think_time;
Time m_wait_time;
int m_tester_length;
int m_num_procs;
RubyEventQueue * eventQueue;
int m_numCompletionsPerNode;
Histogram m_load_latency;
Histogram m_store_latency;
Time m_finish_time;
Time m_last_issue;
};
// Output operator declaration
ostream& operator<<(ostream& out, const DeterministicDriver& obj);
// ******************* Definitions *******************
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const DeterministicDriver& obj)
{
obj.print(out);
out << flush;
return out;
}
#endif //DETERMINISTICDRIVER_H

View file

@ -1,146 +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.
*/
#include <cassert>
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/tester/RaceyDriver.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/tester/RaceyPseudoThread.hh"
RaceyDriver::RaceyDriver(int num_procs, int tester_length)
{
m_finish_time = 0;
m_done_counter = 0;
m_wakeup_thread0 = false;
m_num_procs = num_procs;
m_tester_length = tester_length;
eventQueue = new RubyEventQueue;
// racey at least need two processors
assert(m_num_procs >= 2);
// init all racey pseudo threads
m_racey_pseudo_threads.resize(m_num_procs);
for (int i=0; i<m_racey_pseudo_threads.size(); i++) {
m_racey_pseudo_threads[i] = new RaceyPseudoThread(i, *this);
}
// add this driver to the global event queue, for deadlock detection
eventQueue->scheduleEvent(this, g_DEADLOCK_THRESHOLD);
}
RaceyDriver::~RaceyDriver()
{
for (int i=0; i<m_racey_pseudo_threads.size(); i++) {
delete m_racey_pseudo_threads[i];
}
}
void RaceyDriver::go() {
// tick both queues until everyone is done
while (m_done_counter != m_num_procs) {
libruby_tick(1);
eventQueue->triggerEvents(eventQueue->getTime() + 1);
}
}
void RaceyDriver::hitCallback(int64_t request_id)
{
assert(requests.find(request_id) != requests.end());
int proc = requests[request_id].first;
Address address = requests[request_id].second.address;
uint8_t * data = new uint8_t[4];
for (int i = 0; i < 4; i++) {
data[i] = requests[request_id].second.data[i];
}
requests[request_id].second.data;
m_racey_pseudo_threads[proc]->performCallback(proc, address, data);
requests.erase(request_id);
}
integer_t RaceyDriver::getInstructionCount(int procID) const
{
// return m_racey_pseudo_threads[procID]->getInstructionCounter();
assert(0);
}
int RaceyDriver::runningThreads()
{
return m_num_procs - m_done_counter;
}
// used to wake up thread 0 whenever other thread finishes
void RaceyDriver::registerThread0Wakeup()
{
m_wakeup_thread0 = true;
}
void RaceyDriver::joinThread()
{
m_done_counter++;
if (m_done_counter == m_num_procs) {
m_finish_time = eventQueue->getTime();
}
if(m_wakeup_thread0) {
eventQueue->scheduleEvent(m_racey_pseudo_threads[0], 1);
m_wakeup_thread0 = false;
}
}
void RaceyDriver::wakeup()
{
// check for deadlock
for(int i = 0 ; i < m_racey_pseudo_threads.size(); i++) {
m_racey_pseudo_threads[i]->checkForDeadlock();
}
// schedule next wakeup
if (m_done_counter < m_num_procs) {
eventQueue->scheduleEvent(this, g_DEADLOCK_THRESHOLD);
}
}
void RaceyDriver::printStats(ostream& out) const
{
assert(m_done_counter == m_num_procs);
out << endl;
out << "RaceyDriver Stats" << endl;
out << "---------------------" << endl;
out << "execution signature: " << m_racey_pseudo_threads[0]->getSignature() << endl;
out << "finish_time: " << m_finish_time << endl;
}
void RaceyDriver::print(ostream& out) const
{
}

View file

@ -1,130 +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: The driver interface between racey pseudo threads and ruby
* memory timing simulator.
*
*/
#ifndef RACEYDRIVER_H
#define RACEYDRIVER_H
#include <map>
#include <vector>
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Driver.hh"
#include "mem/ruby/tester/RaceyPseudoThread.hh"
#include "mem/ruby/libruby.hh"
#define g_DEADLOCK_THRESHOLD 5000
struct address_data {
Address address;
uint8_t * data;
};
class RaceyDriver : public Driver, public Consumer {
public:
friend class RaceyPseudoThread;
// Constructors
RaceyDriver(int num_procs, int tester_length);
// Destructor
~RaceyDriver();
// Public Methods
int runningThreads();
void registerThread0Wakeup();
void joinThread();
bool Thread0Initialized() {
return m_racey_pseudo_threads[0]->getInitializedState();
};
void hitCallback(int64_t request_id);
void wakeup();
void printStats(ostream& out) const;
void clearStats() {}
void printConfig(ostream& out) const {}
void go();
integer_t getInstructionCount(int procID) const;
// save/load cpu states
void saveCPUStates(int cpu_id, string filename) {
m_racey_pseudo_threads[cpu_id]->saveCPUStates(filename);
};
void loadCPUStates(int cpu_id, string filename) {
m_racey_pseudo_threads[cpu_id]->loadCPUStates(filename);
};
// reset IC
void resetIC(int cpu_id) {
m_racey_pseudo_threads[cpu_id]->resetIC();
}
void print(ostream& out) const;
private:
// Private copy constructor and assignment operator
RaceyDriver(const RaceyDriver& obj);
RaceyDriver& operator=(const RaceyDriver& obj);
// Data Members (m_ prefix)
std::vector<RaceyPseudoThread*> m_racey_pseudo_threads;
int m_done_counter;
bool m_wakeup_thread0;
Time m_finish_time;
map <int64_t, pair <int, struct address_data> > requests;
RubyEventQueue * eventQueue;
int m_num_procs;
int m_tester_length;
};
// Output operator declaration
ostream& operator<<(ostream& out, const RaceyDriver& obj);
// ******************* Definitions *******************
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const RaceyDriver& obj)
{
obj.print(out);
out << flush;
return out;
}
#endif //RACEYDRIVER_H

View file

@ -1,351 +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.
*/
/*
* Description: see RaceyPseudoThread.h
*/
#include <cassert>
#include "mem/ruby/tester/RaceyPseudoThread.hh"
#include "mem/ruby/tester/RaceyDriver.hh"
#include "gzstream.hh"
RaceyPseudoThread::RaceyPseudoThread(NodeID id, RaceyDriver& driver)
: m_driver(driver), m_proc_id(id) {
resetIC(); // IC contains the committed instruction number
m_last_progress = 0;
m_done = false;
m_stop = 0;
m_driver.eventQueue->scheduleEvent(this, 1);
}
RaceyPseudoThread::~RaceyPseudoThread() {
}
void RaceyPseudoThread::checkForDeadlock() {
Time current_time = m_driver.eventQueue->getTime();
if(!m_done && (current_time - m_last_progress) > g_DEADLOCK_THRESHOLD) {
panic("Deadlock detected: m_proc_id: %d m_ic_counter: %d "
"m_last_progress: %d\n",
m_proc_id, m_ic_counter, m_last_progress);
}
}
void RaceyPseudoThread::performCallback(int proc, Address address, uint8_t * data ) {
assert(proc == m_proc_id);
DPRINTF(RubyTester, "proc: %d, address: %s\n", proc, address);
m_last_progress = m_driver.eventQueue->getTime();
if(m_read) {
int b0, b1, b2, b3;
b0 = data[0]; b0 <<= 0;
b1 = data[1]; b1 <<= 8;
b2 = data[2]; b2 <<= 16;
b3 = data[3]; b3 <<= 24;
m_value = b0 | b1 | b2 | b3;
} else {
char b0, b1, b2, b3;
b0 = (m_value>>0)&0xFF; data[0] = b0;
b1 = (m_value>>8)&0xFF; data[1] = b1;
b2 = (m_value>>16)&0xFF; data[2] = b2;
b3 = (m_value>>24)&0xFF; data[3] = b3;
}
// schedule wakeup for next requests in next cycle
m_driver.eventQueue->scheduleEvent(this, 1);
// new instruction
m_ic_counter++;
}
void RaceyPseudoThread::wakeup() {
// for debug
if(m_stop != 0) {
cout << m_proc_id << " " << m_stop << ((m_read)? " read ":" written ") << m_value;
if(0) cout << " [" << m_driver.eventQueue->getTime() << "]";
cout << endl;
}
assert(!m_done);
// Note, this function can not have ANY local variable!
switch(m_stop) {
case 0:
break;
case 1:
goto L1;
case 2:
goto L2;
case 3:
goto L3;
case 4:
goto L4;
case 5:
goto L5;
case 6:
goto L6;
case 7:
goto L7;
case 8:
goto L8;
case 9:
goto L9;
case 10:
goto L10;
default:
fatal("RaceyPseudoThread: Bad context point %u!", m_stop);
}
//
// initialization
//
if(m_proc_id == 0) {
for(m_looper = 0; m_looper < m_driver.m_num_procs; m_looper++) {
store_sig(m_looper, m_looper+1);
m_stop = 6; return;
L6: {};
}
for(m_looper = 0; m_looper < M_ELEM; m_looper++) {
store_m(m_looper, M_ELEM-m_looper);
m_stop = 7; return;
L7: {};
}
// init done
m_initialized = true;
} else {
// other processors
if(!m_driver.Thread0Initialized()) {
// wait for processors 0
m_driver.eventQueue->scheduleEvent(this, 1);
return;
}
}
cout << "Thread " << m_proc_id << " started in parallel phase" << endl;
//
// main thread body
//
for(m_looper = 0 ; m_looper < m_driver.m_tester_length; m_looper++) {
/* m_value = */ load_sig(m_proc_id);
m_stop = 1; return;
L1: {};
m_num = m_value;
m_index1 = m_num%M_ELEM;
/* m_value = */ load_m(m_index1);
m_stop = 2; return;
L2: {};
m_num = mix(m_num, m_value);
m_index2 = m_num%M_ELEM;
/* m_value = */ load_m(m_index2);
m_stop = 3; return;
L3: {};
m_num = mix(m_num, m_value);
store_m(m_index2, m_num);
m_stop = 4; return;
L4: {};
store_sig(m_proc_id, m_num);
m_stop = 5; return;
L5: {};
} // end for
//
// compute final sig
//
if(m_proc_id == 0) {
// wait for other threads
while (m_driver.runningThreads() > 1) {
m_driver.registerThread0Wakeup();
m_stop = 10; return;
L10: {};
}
/* m_value = */ load_sig(0);
m_stop = 8; return;
L8: {};
m_final_sig = m_value;
for(m_looper = 1; m_looper < m_driver.m_num_procs; m_looper++) {
/* m_value = */ load_sig(m_looper);
m_stop = 9; return;
L9: {};
m_final_sig = mix(m_value, m_final_sig);
}
} // processors 0
// done
m_driver.joinThread();
m_done = true;
}
void RaceyPseudoThread::load_sig(unsigned index) {
cout << m_proc_id << " : load_sig " << index << endl;
m_read = true;
// timestamp, threadid, action, and logical address are used only by transactional memory, should be augmented
uint8_t * read_data = new uint8_t[4];
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_proc_id);
// pc is zero, problem?
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(sig(index), read_data, 4, 0, RubyRequestType_LD, RubyAccessMode_User));
assert(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data;
request_data.address = Address(sig(index));
request_data.data = read_data;
m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data)));
/*sequencer()->makeRequest(CacheMsg(Address(sig(index)), Address(sig(index)), CacheRequestType_LD,
Address(physical_address_t(1)),
AccessModeType_UserMode, 4,
PrefetchBit_No, 0, Address(0),
0, 0 , false)); */
}
void RaceyPseudoThread::load_m(unsigned index) {
// cout << m_proc_id << " : load_m " << index << endl;
m_read = true;
uint8_t * read_data = new uint8_t[4];
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_proc_id);
// pc is zero, problem?
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m(index), read_data, 4, 0, RubyRequestType_LD, RubyAccessMode_User));
assert(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data;
request_data.address = Address(m(index));
request_data.data = read_data;
m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data)));
/*sequencer()->makeRequest(CacheMsg(Address(m(index)), Address(m(index)), CacheRequestType_LD,
Address(physical_address_t(1)),
AccessModeType_UserMode, 4,
PrefetchBit_No, 0, Address(0),
0, 0, false)); */
}
void RaceyPseudoThread::store_sig(unsigned index, unsigned value) {
cout << m_proc_id << " : store_sig " << index << " " << value << endl;
m_read = false;
m_value = value;
uint8_t * write_data = new uint8_t[4];
memcpy(write_data, &value, 4);
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_proc_id);
// pc is zero, problem?
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(sig(index), write_data, 4, 0, RubyRequestType_ST, RubyAccessMode_User));
assert(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data;
request_data.address = Address(sig(index));
request_data.data = write_data;
m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data)));
/*sequencer()->makeRequest(CacheMsg(Address(sig(index)), Address(sig(index)), CacheRequestType_ST,
Address(physical_address_t(1)),
AccessModeType_UserMode, 4,
PrefetchBit_No, 0, Address(0),
0, 0, false)); */
}
void RaceyPseudoThread::store_m(unsigned index, unsigned value) {
//cout << m_proc_id << " : store_m " << index << endl;
m_read = false;
m_value = value;
uint8_t * write_data = new uint8_t[4];
memcpy(write_data, &value, 4);
char name [] = "Sequencer_";
char port_name [13];
sprintf(port_name, "%s%d", name, m_proc_id);
// pc is zero, problem?
int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m(index), write_data, 4, 0, RubyRequestType_ST, RubyAccessMode_User));
assert(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data;
request_data.address = Address(m(index));
request_data.data = write_data;
m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data)));
/*sequencer()->makeRequest(CacheMsg(Address(m(index)), Address(m(index)), CacheRequestType_ST,
Address(physical_address_t(1)),
AccessModeType_UserMode, 4,
PrefetchBit_No, 0, Address(0),
0, 0, false)); */
}
// Save and Load context of a thread
void RaceyPseudoThread::saveCPUStates(string filename) {
ogzstream out(filename.c_str());
out.write((char*)&m_looper, sizeof(int));
out.write((char*)&m_num, sizeof(unsigned));
out.write((char*)&m_index1, sizeof(unsigned));
out.write((char*)&m_index2, sizeof(unsigned));
out.write((char*)&m_stop, sizeof(unsigned));
out.close();
}
void RaceyPseudoThread::loadCPUStates(string filename) {
igzstream out(filename.c_str());
out.read((char*)&m_looper, sizeof(int));
out.read((char*)&m_num, sizeof(unsigned));
out.read((char*)&m_index1, sizeof(unsigned));
out.read((char*)&m_index2, sizeof(unsigned));
out.read((char*)&m_stop, sizeof(unsigned));
out.close();
}
void RaceyPseudoThread::print(ostream& out) const {
out << "[Racey Pseudo Thread: " << m_proc_id << "]" << endl;
}

View file

@ -1,152 +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.
*/
/*
* Description: This implements a pseudo racey thread which drives ruby timing
* simulator with access to two shared arrays.
*
*/
#ifndef RACEYPSEUDOTHREAD_H
#define RACEYPSEUDOTHREAD_H
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/NodeID.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/libruby.hh"
class RaceyDriver;
class RaceyPseudoThread : public Consumer {
private:
// constants
static const int PRIME1 = 103072243;
static const int PRIME2 = 103995407;
static const int M_ELEM = 64;
// m and sig array's starting address,
// each signature should occupy a cacheline
static const int SIG_ARR = 0;
static const int M_ARR = 0x10000;
static const int LINESIZE = 64;
// get address of a element from the m and sig arrays
physical_address_t sig(unsigned index) {
assert(index < M_ARR/64);
return SIG_ARR + (index*64);
};
physical_address_t m(unsigned index) { return M_ARR + (index*64); };
public:
// Constructors
RaceyPseudoThread(NodeID node, RaceyDriver& driver);
// Destructor
~RaceyPseudoThread();
// Public Methods
void performCallback(int proc, Address address, uint8_t * data);
void wakeup();
integer_t getInstructionCount() { return m_ic_counter; };
unsigned getSignature() { assert(m_proc_id == 0); return m_final_sig; };
void checkForDeadlock();
// save and restore the thread state
void saveCPUStates(string filename);
void loadCPUStates(string filename);
// reset IC to zero for next checkpoint
void resetIC() { m_ic_counter = 0; };
bool getInitializedState() { return m_initialized; };
void print(ostream& out) const;
private:
// Private Methods
// mix two numbers
unsigned mix (unsigned i, unsigned j) { return (i + j * PRIME2) % PRIME1; };
// load or store the array
void load_sig(unsigned index);
void load_m(unsigned index);
void store_sig(unsigned index, unsigned value);
void store_m(unsigned index, unsigned value);
// Private copy constructor and assignment operator
RaceyPseudoThread(const RaceyPseudoThread& obj);
RaceyPseudoThread& operator=(const RaceyPseudoThread& obj);
// Data Members (m_ prefix)
RaceyDriver& m_driver;
NodeID m_proc_id;
// are we done?
bool m_done;
// [committed] instruction counter
int m_ic_counter;
// last time we made progress
Time m_last_progress;
// value of the callback block
bool m_read;
unsigned m_value;
// final signature
unsigned m_final_sig;
// local variables for the pseudo thread
int m_looper;
unsigned m_num, m_index1, m_index2, m_stop;
bool m_initialized;
};
// Output operator declaration
ostream& operator<<(ostream& out, const RaceyPseudoThread& obj);
// ******************* Definitions *******************
// Output operator definition
extern inline
ostream& operator<<(ostream& out, const RaceyPseudoThread& obj)
{
obj.print(out);
out << flush;
return out;
}
#endif //RACEYPSEUDOTHREAD_H

View file

@ -1,40 +0,0 @@
# -*- mode:python -*-
# Copyright (c) 2009 The Hewlett-Packard Development Company
# 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.
#
# Authors: Nathan Binkert
Import('*')
if not env['RUBY']:
Return()
#Source('SpecifiedGenerator.cc')
#Source('main.cc')
#Source('test_framework.cc')
#Source('RaceyDriver.cc')
#Source('RaceyPseudoThread.cc')

View file

@ -1,44 +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/SpecifiedGenerator.hh"
SpecifiedGenerator::SpecifiedGenerator()
{
}
SpecifiedGenerator::~SpecifiedGenerator()
{
}

View file

@ -1,68 +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 SPECIFIEDGENERATOR_H
#define SPECIFIEDGENERATOR_H
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/NodeID.hh"
#include "mem/ruby/common/Address.hh"
class SpecifiedGenerator : public Consumer {
public:
// Constructors
SpecifiedGenerator();
// Destructor
virtual ~SpecifiedGenerator() = 0;
// Public Methods
virtual void wakeup() = 0;
virtual void performCallback(NodeID proc, Address address) = 0;
virtual void print(ostream& out) const = 0;
protected:
// accessible by subclasses
private:
// inaccessible by subclasses
};
#endif //SPECIFIEDGENERATOR_H

View file

@ -1,39 +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/eventqueue/RubyEventQueue.hh"
class RubyEventQueue;
extern RubyEventQueue * eventQueue;

View file

@ -1,45 +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/slicc/main.hh"
#include "mem/ruby/tester/test_framework.hh"
// *******************
// *** tester main ***
// *******************
int main(int argc, char *argv[])
{
tester_main(argc, argv);
}

View file

@ -1,43 +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 MAIN_H
#define MAIN_H
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
#endif //MAIN_H

View file

@ -1,378 +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$
*
*/
using namespace std;
#include "base/misc.hh"
#include "mem/ruby/tester/test_framework.hh"
#include "mem/protocol/protocol_name.hh"
#include "mem/ruby/tester/DeterministicDriver.hh"
#include "mem/ruby/tester/RaceyDriver.hh"
#include "mem/ruby/common/Driver.hh"
#include "mem/ruby/recorder/Tracer.hh"
#include <string>
#include <map>
#include <iostream>
#include <assert.h>
#include <vector>
#include <string>
#include <sstream>
#include <sys/wait.h>
#include "mem/ruby/libruby.hh"
// FIXME: should really make this a class if can't figure out how to make a function to get the ruby parameter
static void set_defaults();
static void parseOptions(int argc, char **argv);
static void usageInstructions();
static void checkArg(char ch);
static void tester_initialize(int argc, char **argv);
static void tester_playback_trace();
static void tester_destroy();
static void hit_callback(int64_t request_id);
// Tester variables
string driver_type;
string generator_type;
Driver * m_driver_ptr;
int g_tester_length;
int num_completions;
Time g_think_time;
Time g_wait_time;
int num_procs;
static string trace_filename;
bool replaying;
void tester_main(int argc, char **argv)
{
tester_initialize(argc, argv);
if (trace_filename != "") {
// playback a trace (for multicast-mask prediction)
replaying = true;
tester_playback_trace();
}
tester_destroy();
}
vector<string> tokenizeMyString(string str, string delims)
{
vector<string> tokens;
char* pch;
char* tmp;
const char* c_delims = delims.c_str();
tmp = new char[str.length()+1];
strcpy(tmp, str.c_str());
pch = strtok(tmp, c_delims);
while (pch != NULL) {
tokens.push_back(string(pch));
pch = strtok(NULL, c_delims);
}
delete [] tmp;
return tokens;
}
vector<string> getPorts(const char* cfg_script, int cfg_script_argc, char* cfg_script_argv[])
{
stringstream cfg_output;
// first we execute the Ruby-lang configuration script
int fd[2];
int pid;
if (pipe(fd) == -1) {
perror("Error Creating Pipe");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == -1){
perror("Error forking");
exit(EXIT_FAILURE);
}
if (!pid) {
// child
close(fd[0]); // close the read end of the pipe
// replace stdout with the write pipe
if (dup2(fd[1], STDOUT_FILENO) == -1) {
perror("Error redirecting stdout");
exit(EXIT_FAILURE);
}
#define QUOTE_MACRO(x, y) QUOTE_TXT(x,y)
#define QUOTE_TXT(x, y) #x y
if (execlp("ruby", "ruby", "-I", QUOTE_MACRO(GEMS_ROOT, "/ruby/config"), QUOTE_MACRO(GEMS_ROOT, "/tests/list_ports.rb"), cfg_script, NULL)) {
perror("execlp");
exit(EXIT_FAILURE);
}
} else {
close(fd[1]);
int child_status;
if (wait(&child_status) == -1) {
perror("wait");
exit(EXIT_FAILURE);
}
if (child_status != EXIT_SUCCESS) {
exit(EXIT_FAILURE);
}
char buf[100];
int bytes_read;
while( (bytes_read = read(fd[0], buf, 100)) > 0 ) {
for (int i=0;i<bytes_read;i++) {
cfg_output << buf[i];
}
}
assert(bytes_read == 0);
close(fd[0]);
}
string line;
getline(cfg_output, line);
return tokenizeMyString(line, " ");
}
void tester_initialize(int argc, char **argv)
{
const char* cfg_file = argv[1];
set_defaults();
parseOptions(argc, argv);
libruby_init(cfg_file);
libruby_print_config(std::cout);
vector<string> port_names = getPorts(cfg_file, 0, NULL);
vector<RubyPortHandle> ports;
for (vector<string>::const_iterator it = port_names.begin(); it != port_names.end(); it++)
ports.push_back(libruby_get_port((*it).c_str(), hit_callback));
if (driver_type == "Deterministic") {
m_driver_ptr = new DeterministicDriver(generator_type, num_completions, num_procs, g_think_time, g_wait_time, g_tester_length);
}
else if (driver_type == "Racey") {
m_driver_ptr = new RaceyDriver(num_procs, g_tester_length);
}
/* else if (driver_type == "Synthetic") {
m_driver_ptr = new SyntheticDriver();
}
}*/
if (trace_filename == "") {
m_driver_ptr->go();
}
}
void tester_playback_trace()
{
replaying = true;
assert(trace_filename != "");
cout << "Reading trace from file '" << trace_filename << "'..." << endl;
Tracer * replayer = new Tracer("noname");
int read = replayer->playbackTrace(trace_filename);
cout << "(" << read << " requests read)" << endl;
if (read == 0) {
fatal("Zero items read from tracefile.");
}
}
void tester_destroy()
{
m_driver_ptr->printStats(cout);
libruby_destroy();
cerr << "Success: " << CURRENT_PROTOCOL << endl;
}
void hit_callback(int64_t request_id)
{
if (!replaying) {
m_driver_ptr->hitCallback(request_id);
}
}
// ************************************************************************
// *** Functions for parsing the command line parameters for the tester ***
// ************************************************************************
static struct option const long_options[] =
{
{"help", no_argument, NULL, 'h'},
{"number of processors", required_argument, NULL, 'p'},
{"test run length", required_argument, NULL, 'l'},
{"generator think time", required_argument, NULL, 'k'},
{"generator wait time", required_argument, NULL, 'w'},
{"driver type", required_argument, NULL, 'd'},
{"generator type", required_argument, NULL, 'g'},
{"num completions before pass", required_argument, NULL, 'n'},
{"test tracer", required_argument, NULL, 'z'},
{NULL, 0, NULL, 0}
};
// This is awkward and temporary, need the defaults config, and also need functions to
// just lookup a parameter in the configuration file
// Ideally the default values are set by libruby_init and then a function is provided to
// set values at run-time
static void set_defaults() {
replaying = false;
g_tester_length = 0;
g_think_time = 10;
g_wait_time = 10;
num_procs = 1;
trace_filename = "";
num_completions = 1;
driver_type = "Deterministic";
generator_type = "DetermSeriesGETSGenerator";
}
static void parseOptions(int argc, char **argv)
{
cout << "Parsing command line arguments:" << endl;
// construct the short arguments string
int counter = 0;
string short_options;
while (long_options[counter].name != NULL) {
short_options += char(long_options[counter].val);
if (long_options[counter].has_arg == required_argument) {
short_options += char(':');
}
counter++;
}
char c;
/* Parse command line options. */
while ((c = getopt_long (argc, argv, short_options.c_str(), long_options, (int *) 0)) != EOF) {
switch (c) {
case 0:
break;
case 'h':
usageInstructions();
break;
case 'p':
checkArg(c);
cout << " number of processors = " << optarg << endl;
num_procs = atoi( optarg );
break;
case 'l': {
checkArg(c);
g_tester_length = atoi(optarg);
cout << " length of run = " << g_tester_length << endl;
if (g_tester_length == 0) {
usageInstructions();
}
break;
}
case 'k': {
checkArg(c);
g_think_time = atoi(optarg);
break;
}
case 'w': {
checkArg(c);
g_wait_time = atoi(optarg);
break;
}
case 'd':
checkArg(c);
cout << " driver type = " << optarg << endl;
driver_type = strdup( optarg );
break;
case 'g':
checkArg(c);
cout << " generator type = " << optarg << endl;
generator_type = strdup( optarg );
break;
case 'n':
checkArg(c);
cout << " num completions before pass = " << optarg << endl;
num_completions = atoi( optarg );
break;
case 'z':
checkArg(c);
trace_filename = string(optarg);
cout << " tracefile = " << trace_filename << endl;
break;
default:
cerr << "parameter '" << c << "' unknown" << endl;
usageInstructions();
}
}
}
static void usageInstructions()
{
cerr << endl;
cerr << "Options:" << endl;
// print options
int counter = 0;
while (long_options[counter].name != NULL) {
cerr << " -" << char(long_options[counter].val);
if (long_options[counter].has_arg == required_argument) {
cerr << " <arg>";
}
cerr << " --" << long_options[counter].name;
if (long_options[counter].has_arg == required_argument) {
cerr << " <arg>";
}
cerr << endl;
counter++;
}
cerr << endl;
exit(1);
}
static void checkArg(char ch)
{
if (optarg == NULL) {
cerr << "Error: parameter '" << ch << "' missing required argument" << endl;
usageInstructions();
}
}

View file

@ -1,45 +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 TESTFRAMEWORK_H
#define TESTFRAMEWORK_H
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Tester_Globals.hh"
void tester_main(int argc, char **argv);
#endif //TESTFRAMEWORK_H