From 4ae02295d59036fa2f9d272ee288e0321bb8257a Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 7 Jan 2013 13:05:44 -0500 Subject: cpu: Unify SimpleCPU and O3 CPU serialization code The O3 CPU used to copy its thread context to a SimpleThread in order to do serialization. This was a bit of a hack involving two static SimpleThread instances and a magic constructor that was only used by the O3 CPU. This patch moves the ThreadContext serialization code into two global procedures that, in addition to the normal serialization parameters, take a ThreadContext reference as a parameter. This allows us to reuse the serialization code in all ThreadContext implementations. --- src/cpu/inorder/thread_context.cc | 15 ---------- src/cpu/inorder/thread_context.hh | 6 ---- src/cpu/o3/cpu.cc | 26 +++++------------- src/cpu/o3/thread_context.hh | 5 ---- src/cpu/o3/thread_context_impl.hh | 16 ----------- src/cpu/o3/thread_state.hh | 33 ++++++++++++++++++++++ src/cpu/simple_thread.cc | 16 ++--------- src/cpu/simple_thread.hh | 2 -- src/cpu/thread_context.cc | 58 +++++++++++++++++++++++++++++++++++++++ src/cpu/thread_context.hh | 24 ++++++++++------ 10 files changed, 116 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc index 4abfb6cca..2990430e1 100644 --- a/src/cpu/inorder/thread_context.cc +++ b/src/cpu/inorder/thread_context.cc @@ -160,21 +160,6 @@ InOrderThreadContext::regStats(const std::string &name) } } - -void -InOrderThreadContext::serialize(std::ostream &os) -{ - panic("serialize unimplemented"); -} - - -void -InOrderThreadContext::unserialize(Checkpoint *cp, const std::string §ion) -{ - panic("unserialize unimplemented"); -} - - void InOrderThreadContext::copyArchRegs(ThreadContext *src_tc) { diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh index 2191ac238..f4847d0b4 100644 --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@ -191,12 +191,6 @@ class InOrderThreadContext : public ThreadContext /** Registers statistics associated with this TC. */ void regStats(const std::string &name); - /** Serializes state. */ - void serialize(std::ostream &os); - - /** Unserializes state. */ - void unserialize(Checkpoint *cp, const std::string §ion); - /** Returns this thread's ID number. */ int getThreadNum() { return thread->threadId(); } diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 0419a6173..2613a8da3 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -1097,16 +1097,9 @@ FullO3CPU::serialize(std::ostream &os) nameOut(os, csprintf("%s.tickEvent", name())); tickEvent.serialize(os); - // Use SimpleThread's ability to checkpoint to make it easier to - // write out the registers. Also make this static so it doesn't - // get instantiated multiple times (causes a panic in statistics). - static SimpleThread temp; - - ThreadID size = thread.size(); - for (ThreadID i = 0; i < size; i++) { + for (ThreadID i = 0; i < thread.size(); i++) { nameOut(os, csprintf("%s.xc.%i", name(), i)); - temp.copyTC(thread[i]->getTC()); - temp.serialize(os); + thread[i]->serialize(os); } } @@ -1119,16 +1112,11 @@ FullO3CPU::unserialize(Checkpoint *cp, const std::string §ion) BaseCPU::unserialize(cp, section); tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); - // Use SimpleThread's ability to checkpoint to make it easier to - // read in the registers. Also make this static so it doesn't - // get instantiated multiple times (causes a panic in statistics). - static SimpleThread temp; - - ThreadID size = thread.size(); - for (ThreadID i = 0; i < size; i++) { - temp.copyTC(thread[i]->getTC()); - temp.unserialize(cp, csprintf("%s.xc.%i", section, i)); - thread[i]->getTC()->copyArchRegs(temp.getTC()); + for (ThreadID i = 0; i < thread.size(); i++) { + thread[i]->unserialize(cp, + csprintf("%s.xc.%i", section, i)); + if (thread[i]->status() == ThreadContext::Active) + activateThread(i); } } diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 1efcfff9c..4201878af 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -153,11 +153,6 @@ class O3ThreadContext : public ThreadContext /** Registers statistics associated with this TC. */ virtual void regStats(const std::string &name); - /** Serializes state. */ - virtual void serialize(std::ostream &os); - /** Unserializes state. */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); - /** Reads the last tick that this thread was activated on. */ virtual Tick readLastActivate(); /** Reads the last tick that this thread was suspended on. */ diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 4ab793538..2de6dbc1b 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -158,22 +158,6 @@ O3ThreadContext::regStats(const std::string &name) } } -template -void -O3ThreadContext::serialize(std::ostream &os) -{ - if (FullSystem && thread->kernelStats) - thread->kernelStats->serialize(os); -} - -template -void -O3ThreadContext::unserialize(Checkpoint *cp, const std::string §ion) -{ - if (FullSystem && thread->kernelStats) - thread->kernelStats->unserialize(cp, section); -} - template Tick O3ThreadContext::readLastActivate() diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index 96ccfc95c..406c798f0 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -99,6 +111,27 @@ struct O3ThreadState : public ThreadState { profilePC = 3; } + void serialize(std::ostream &os) + { + ThreadState::serialize(os); + // Use the ThreadContext serialization helper to serialize the + // TC. + ::serialize(*tc, os); + } + + void unserialize(Checkpoint *cp, const std::string §ion) + { + // Prevent squashing - we don't have any instructions in + // flight that we need to squash since we just instantiated a + // clean system. + noSquashFromTC = true; + ThreadState::unserialize(cp, section); + // Use the ThreadContext serialization helper to unserialize + // the TC. + ::unserialize(*tc, cp, section); + noSquashFromTC = false; + } + /** Pointer to the ThreadContext of this thread. */ ThreadContext *tc; diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index d2171a0e4..787680224 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -99,12 +99,6 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, kernelStats = new TheISA::Kernel::Statistics(system); } -SimpleThread::SimpleThread() - : ThreadState(NULL, -1, NULL), isa(NULL) -{ - tc = new ProxyThreadContext(this); -} - SimpleThread::~SimpleThread() { delete tc; @@ -175,10 +169,7 @@ void SimpleThread::serialize(ostream &os) { ThreadState::serialize(os); - SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); - SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); - _pcState.serialize(os); - // thread_num and cpu_id are deterministic from the config + ::serialize(*tc, os); } @@ -186,10 +177,7 @@ void SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) { ThreadState::unserialize(cp, section); - UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); - UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); - _pcState.unserialize(cp, section); - // thread_num and cpu_id are deterministic from the config + ::unserialize(*tc, cp, section); } void diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 33dcdd49d..ee54850ae 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -140,8 +140,6 @@ class SimpleThread : public ThreadState Process *_process, TheISA::TLB *_itb, TheISA::TLB *_dtb, TheISA::ISA *_isa); - SimpleThread(); - virtual ~SimpleThread(); virtual void takeOverFrom(ThreadContext *oldContext); diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc index c403667bf..4a4038297 100644 --- a/src/cpu/thread_context.cc +++ b/src/cpu/thread_context.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -78,3 +90,49 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two) } + +void +serialize(ThreadContext &tc, std::ostream &os) +{ + using namespace TheISA; + + FloatRegBits floatRegs[NumFloatRegs]; + for (int i = 0; i < NumFloatRegs; ++i) + floatRegs[i] = tc.readFloatRegBitsFlat(i); + // This is a bit ugly, but needed to maintain backwards + // compatibility. + arrayParamOut(os, "floatRegs.i", floatRegs, NumFloatRegs); + + IntReg intRegs[NumIntRegs]; + for (int i = 0; i < NumIntRegs; ++i) + intRegs[i] = tc.readIntRegFlat(i); + SERIALIZE_ARRAY(intRegs, NumIntRegs); + + tc.pcState().serialize(os); + + // thread_num and cpu_id are deterministic from the config +} + +void +unserialize(ThreadContext &tc, Checkpoint *cp, const std::string §ion) +{ + using namespace TheISA; + + FloatRegBits floatRegs[NumFloatRegs]; + // This is a bit ugly, but needed to maintain backwards + // compatibility. + arrayParamIn(cp, section, "floatRegs.i", floatRegs, NumFloatRegs); + for (int i = 0; i < NumFloatRegs; ++i) + tc.setFloatRegBitsFlat(i, floatRegs[i]); + + IntReg intRegs[NumIntRegs]; + UNSERIALIZE_ARRAY(intRegs, NumIntRegs); + for (int i = 0; i < NumIntRegs; ++i) + tc.setIntRegFlat(i, intRegs[i]); + + PCState pcState; + pcState.unserialize(cp, section); + tc.pcState(pcState); + + // thread_num and cpu_id are deterministic from the config +} diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 611924371..c54076c8a 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 ARM Limited + * Copyright (c) 2011-2012 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -177,9 +177,6 @@ class ThreadContext virtual void regStats(const std::string &name) = 0; - virtual void serialize(std::ostream &os) = 0; - virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; - virtual EndQuiesceEvent *getQuiesceEvent() = 0; // Not necessarily the best location for these... @@ -369,10 +366,6 @@ class ProxyThreadContext : public ThreadContext void regStats(const std::string &name) { actualTC->regStats(name); } - void serialize(std::ostream &os) { actualTC->serialize(os); } - void unserialize(Checkpoint *cp, const std::string §ion) - { actualTC->unserialize(cp, section); } - EndQuiesceEvent *getQuiesceEvent() { return actualTC->getQuiesceEvent(); } Tick readLastActivate() { return actualTC->readLastActivate(); } @@ -473,4 +466,19 @@ class ProxyThreadContext : public ThreadContext { actualTC->setFloatRegBitsFlat(idx, val); } }; +/** @{ */ +/** + * Thread context serialization helpers + * + * These helper functions provide a way to the data in a + * ThreadContext. They are provided as separate helper function since + * implementing them as members of the ThreadContext interface would + * be confusing when the ThreadContext is exported via a proxy. + */ + +void serialize(ThreadContext &tc, std::ostream &os); +void unserialize(ThreadContext &tc, Checkpoint *cp, const std::string §ion); + +/** @} */ + #endif -- cgit v1.2.3