diff options
Diffstat (limited to 'src/mem/ruby/tester/RaceyPseudoThread.cc')
-rw-r--r-- | src/mem/ruby/tester/RaceyPseudoThread.cc | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/src/mem/ruby/tester/RaceyPseudoThread.cc b/src/mem/ruby/tester/RaceyPseudoThread.cc deleted file mode 100644 index ae01585e6..000000000 --- a/src/mem/ruby/tester/RaceyPseudoThread.cc +++ /dev/null @@ -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; -} - |