Various serialization changes to make it possible for the O3CPU to checkpoint.
authorKevin Lim <ktlim@umich.edu>
Thu, 6 Jul 2006 21:53:26 +0000 (17:53 -0400)
committerKevin Lim <ktlim@umich.edu>
Thu, 6 Jul 2006 21:53:26 +0000 (17:53 -0400)
src/arch/alpha/regfile.hh:
    Define serialize/unserialize functions on MiscRegFile itself.
src/cpu/o3/regfile.hh:
    Remove old commented code.
src/cpu/simple_thread.cc:
src/cpu/simple_thread.hh:
    Push common serialization code to ThreadState level.  Also allow the SimpleThread to be used for checkpointing by other models.
src/cpu/thread_state.cc:
src/cpu/thread_state.hh:
    Move common serialization code into ThreadState.

--HG--
extra : convert_revision : ef64ef515355437439af967eda2e610e8c1b658b

src/arch/alpha/regfile.hh
src/cpu/o3/regfile.hh
src/cpu/simple_thread.cc
src/cpu/simple_thread.hh
src/cpu/thread_state.cc
src/cpu/thread_state.hh

index 1025412cd35ce45599ea2e6c2d41fa2284297f45..9ecad6f42915865b7fc64b8dd026319b85e9e106 100644 (file)
@@ -112,6 +112,10 @@ namespace AlphaISA
             lock_flag = 0;
             lock_addr = 0;
         }
+
+        void serialize(std::ostream &os);
+
+        void unserialize(Checkpoint *cp, const std::string &section);
 #if FULL_SYSTEM
       protected:
         typedef uint64_t InternalProcReg;
index 6972f055f1bf5e7a9d17ba07e5f80083fba230ef..b6677b4b1037e0843658241c658bd71d53eb2ef8 100644 (file)
@@ -86,10 +86,6 @@ class PhysRegFile
     //The duplication is unfortunate but it's better than having
     //different ways to access certain registers.
 
-    //Add these in later when everything else is in place
-//    void serialize(std::ostream &os);
-//    void unserialize(Checkpoint *cp, const std::string &section);
-
     /** Reads an integer register. */
     uint64_t readIntReg(PhysRegIndex reg_idx)
     {
index db28b23e8562ef9d46094982ad74935e1f7fb5b9..6255b335797ebb95ca560177bf2acdeb14928d35 100644 (file)
@@ -123,14 +123,31 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
     tc = new ProxyThreadContext<SimpleThread>(this);
 }
 
-SimpleThread::SimpleThread(RegFile *regFile)
-    : ThreadState(-1, -1, NULL, -1, NULL), cpu(NULL)
+#endif
+
+SimpleThread::SimpleThread(ThreadContext *oldContext)
+#if FULL_SYSTEM
+    : ThreadState(-1, -1)
+#else
+    : ThreadState(-1, -1, NULL, -1, NULL)
+#endif
 {
-    regs = *regFile;
     tc = new ProxyThreadContext<SimpleThread>(this);
-}
+    regs.clear();
+
+    copyState(oldContext);
 
+#if FULL_SYSTEM
+    EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
+    if (quiesce) {
+        quiesceEvent = quiesce;
+    }
+    Kernel::Statistics *stats = oldContext->getKernelStats();
+    if (stats) {
+        kernelStats = stats;
+    }
 #endif
+}
 
 SimpleThread::~SimpleThread()
 {
@@ -147,13 +164,8 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
     assert(process == oldContext->getProcessPtr());
 #endif
 
-    // copy over functional state
-    _status = oldContext->status();
-    copyArchRegs(oldContext);
-    cpuId = oldContext->readCpuId();
-#if !FULL_SYSTEM
-    funcExeInst = oldContext->readFuncExeInst();
-#else
+    copyState(oldContext);
+#if FULL_SYSTEM
     EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
     if (quiesce) {
         // Point the quiesce event's TC at this TC so that it wakes up
@@ -170,43 +182,33 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
     oldContext->setStatus(ThreadContext::Unallocated);
 }
 
+void
+SimpleThread::copyState(ThreadContext *oldContext)
+{
+    // copy over functional state
+    _status = oldContext->status();
+    copyArchRegs(oldContext);
+    cpuId = oldContext->readCpuId();
+#if !FULL_SYSTEM
+    funcExeInst = oldContext->readFuncExeInst();
+#endif
+}
+
 void
 SimpleThread::serialize(ostream &os)
 {
-    SERIALIZE_ENUM(_status);
+    ThreadState::serialize(os);
     regs.serialize(os);
     // thread_num and cpu_id are deterministic from the config
-    SERIALIZE_SCALAR(funcExeInst);
-    SERIALIZE_SCALAR(inst);
-
-#if FULL_SYSTEM
-    Tick quiesceEndTick = 0;
-    if (quiesceEvent->scheduled())
-        quiesceEndTick = quiesceEvent->when();
-    SERIALIZE_SCALAR(quiesceEndTick);
-    if (kernelStats)
-        kernelStats->serialize(os);
-#endif
 }
 
 
 void
 SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
 {
-    UNSERIALIZE_ENUM(_status);
+    ThreadState::unserialize(cp, section);
     regs.unserialize(cp, section);
     // thread_num and cpu_id are deterministic from the config
-    UNSERIALIZE_SCALAR(funcExeInst);
-    UNSERIALIZE_SCALAR(inst);
-
-#if FULL_SYSTEM
-    Tick quiesceEndTick;
-    UNSERIALIZE_SCALAR(quiesceEndTick);
-    if (quiesceEndTick)
-        quiesceEvent->schedule(quiesceEndTick);
-    if (kernelStats)
-        kernelStats->unserialize(cp, section);
-#endif
 }
 
 #if FULL_SYSTEM
index de65e9891efbbd1c2ba74be1b936968ab74d3c4f..ff2639e10f5faff97b17989cc1dbd54a575fb92b 100644 (file)
@@ -119,16 +119,18 @@ class SimpleThread : public ThreadState
 #else
     SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
                  MemObject *memobj);
-    // Constructor to use SimpleThread to pass reg file around.  Not
-    // used for anything else.
-    SimpleThread(RegFile *regFile);
 #endif
+
+    SimpleThread(ThreadContext *oldContext);
+
     virtual ~SimpleThread();
 
     virtual void takeOverFrom(ThreadContext *oldContext);
 
     void regStats(const std::string &name);
 
+    void copyState(ThreadContext *oldContext);
+
     void serialize(std::ostream &os);
     void unserialize(Checkpoint *cp, const std::string &section);
 
index 872678a41cecc0fd38c646a0e4f9758d38a2f484..6a96560f194e63cf3238be1a56d59f099c43dcf5 100644 (file)
 #include "base/output.hh"
 #include "cpu/profile.hh"
 #include "cpu/thread_state.hh"
+#include "sim/serialize.hh"
+
+#if FULL_SYSTEM
+#include "cpu/quiesce_event.hh"
+#include "kern/kernel_stats.hh"
+#endif
 
 #if FULL_SYSTEM
 ThreadState::ThreadState(int _cpuId, int _tid)
@@ -49,6 +55,43 @@ ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
     numLoad = 0;
 }
 
+void
+ThreadState::serialize(std::ostream &os)
+{
+    SERIALIZE_ENUM(_status);
+    // thread_num and cpu_id are deterministic from the config
+    SERIALIZE_SCALAR(funcExeInst);
+    SERIALIZE_SCALAR(inst);
+
+#if FULL_SYSTEM
+    Tick quiesceEndTick = 0;
+    if (quiesceEvent->scheduled())
+        quiesceEndTick = quiesceEvent->when();
+    SERIALIZE_SCALAR(quiesceEndTick);
+    if (kernelStats)
+        kernelStats->serialize(os);
+#endif
+}
+
+void
+ThreadState::unserialize(Checkpoint *cp, const std::string &section)
+{
+
+    UNSERIALIZE_ENUM(_status);
+    // thread_num and cpu_id are deterministic from the config
+    UNSERIALIZE_SCALAR(funcExeInst);
+    UNSERIALIZE_SCALAR(inst);
+
+#if FULL_SYSTEM
+    Tick quiesceEndTick;
+    UNSERIALIZE_SCALAR(quiesceEndTick);
+    if (quiesceEndTick)
+        quiesceEvent->schedule(quiesceEndTick);
+    if (kernelStats)
+        kernelStats->unserialize(cp, section);
+#endif
+}
+
 #if FULL_SYSTEM
 
 void
index cb1449ac5cb12b64fe7196eaa9ccbc5d902b5e45..b03a2e2bb83ee2e1d4cc0b2734f63fc7724696bc 100644 (file)
@@ -49,6 +49,8 @@ namespace Kernel {
 };
 #endif
 
+class Checkpoint;
+
 /**
  *  Struct for holding general thread state that is needed across CPU
  *  models.  This includes things such as pointers to the process,
@@ -65,6 +67,10 @@ struct ThreadState {
                 short _asid, MemObject *mem);
 #endif
 
+    void serialize(std::ostream &os);
+
+    void unserialize(Checkpoint *cp, const std::string &section);
+
     void setCpuId(int id) { cpuId = id; }
 
     int readCpuId() { return cpuId; }