Support serializing and unserializing in the O3 CPU. Also a few small fixes for...
authorKevin Lim <ktlim@umich.edu>
Fri, 7 Jul 2006 03:13:38 +0000 (23:13 -0400)
committerKevin Lim <ktlim@umich.edu>
Fri, 7 Jul 2006 03:13:38 +0000 (23:13 -0400)
src/cpu/o3/commit_impl.hh:
    Fix to clear drainPending variable on call to resume.
src/cpu/o3/cpu.cc:
src/cpu/o3/cpu.hh:
    Support serializing and unserializing in the O3 CPU.
src/cpu/o3/lsq_impl.hh:
    Be sure to say we have no stores to write back if the active thread list is empty.
src/cpu/simple_thread.cc:
src/cpu/simple_thread.hh:
    Slightly change how SimpleThread is used to copy from other ThreadContexts.

--HG--
extra : convert_revision : 92a5109b3783a989d5b451036061ef82c56d3121

src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/lsq_impl.hh
src/cpu/simple_thread.cc
src/cpu/simple_thread.hh

index b50c9a898fb5973ee488c96347ad5c1bc406e83f..39e1cf3fe4f284a02718ca0c2db391c70014207c 100644 (file)
@@ -377,6 +377,7 @@ template <class Impl>
 void
 DefaultCommit<Impl>::resume()
 {
+    drainPending = false;
 }
 
 template <class Impl>
index 3a52fe4c2a05c3e922f03280651f9a99bb2ace11..f345fe82dce3c5714ec67e1afd98dc89e531afae 100644 (file)
@@ -707,6 +707,47 @@ FullO3CPU<Impl>::haltContext(int tid)
 */
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::serialize(std::ostream &os)
+{
+    SERIALIZE_ENUM(_status);
+    BaseCPU::serialize(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;
+
+    for (int i = 0; i < thread.size(); i++) {
+        nameOut(os, csprintf("%s.xc.%i", name(), i));
+        temp.copyTC(thread[i]->getTC());
+        temp.serialize(os);
+    }
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
+{
+    UNSERIALIZE_ENUM(_status);
+    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;
+
+    for (int i = 0; i < thread.size(); i++) {
+        temp.copyTC(thread[i]->getTC());
+        temp.unserialize(cp, csprintf("%s.xc.%i", section, i));
+        thread[i]->getTC()->copyArchRegs(temp.getTC());
+    }
+}
+
 template <class Impl>
 bool
 FullO3CPU<Impl>::drain(Event *drain_event)
@@ -717,15 +758,16 @@ FullO3CPU<Impl>::drain(Event *drain_event)
     rename.drain();
     iew.drain();
     commit.drain();
-    // A bit of a hack...set the drainEvent after all the drain()
-    // calls have been made, that way if all of the stages drain
-    // immediately, the signalDrained() function knows not to call
-    // process on the drain event.
-    drainEvent = drain_event;
 
     // Wake the CPU and record activity so everything can drain out if
     // the CPU was not able to immediately drain.
-    if (_status != Drained) {
+    if (getState() != SimObject::DrainedTiming) {
+        // A bit of a hack...set the drainEvent after all the drain()
+        // calls have been made, that way if all of the stages drain
+        // immediately, the signalDrained() function knows not to call
+        // process on the drain event.
+        drainEvent = drain_event;
+
         wakeCPU();
         activityRec.activity();
 
@@ -739,14 +781,15 @@ template <class Impl>
 void
 FullO3CPU<Impl>::resume()
 {
-    if (_status == SwitchedOut)
-        return;
     fetch.resume();
     decode.resume();
     rename.resume();
     iew.resume();
     commit.resume();
 
+    if (_status == SwitchedOut || _status == Idle)
+        return;
+
     if (!tickEvent.scheduled())
         tickEvent.schedule(curTick);
     _status = Running;
@@ -760,7 +803,7 @@ FullO3CPU<Impl>::signalDrained()
         if (tickEvent.scheduled())
             tickEvent.squash();
 
-        _status = Drained;
+        changeState(SimObject::DrainedTiming);
 
         if (drainEvent) {
             drainEvent->process();
index cf374760141615b57b4873435e581cdee500131a..5b881e5580224ea8b46754ec83a7c9fda36aef53 100644 (file)
@@ -111,7 +111,6 @@ class FullO3CPU : public BaseO3CPU
         Idle,
         Halted,
         Blocked,
-        Drained,
         SwitchedOut
     };
 
@@ -266,6 +265,13 @@ class FullO3CPU : public BaseO3CPU
     /** Update The Order In Which We Process Threads. */
     void updateThreadPriority();
 
+    /** Serialize state. */
+    virtual void serialize(std::ostream &os);
+
+    /** Unserialize from a checkpoint. */
+    virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+  public:
     /** Executes a syscall on this cycle.
      *  ---------------------------------------
      *  Note: this is a virtual function. CPU-Specific
index 5173f8be1180eb5245a0e4122fc05a1d192191f0..89fd1a71da8fb9fa25358f90c7db9f8c37462ae5 100644 (file)
@@ -502,6 +502,9 @@ LSQ<Impl>::hasStoresToWB()
 {
     list<unsigned>::iterator active_threads = (*activeThreads).begin();
 
+    if ((*activeThreads).empty())
+        return false;
+
     while (active_threads != (*activeThreads).end()) {
         unsigned tid = *active_threads++;
         if (!hasStoresToWB(tid))
index 6255b335797ebb95ca560177bf2acdeb14928d35..af1db2ff27db727f1ed25ced1a813b51d67c46cd 100644 (file)
@@ -125,7 +125,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
 
 #endif
 
-SimpleThread::SimpleThread(ThreadContext *oldContext)
+SimpleThread::SimpleThread()
 #if FULL_SYSTEM
     : ThreadState(-1, -1)
 #else
@@ -134,19 +134,6 @@ SimpleThread::SimpleThread(ThreadContext *oldContext)
 {
     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()
@@ -182,6 +169,23 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
     oldContext->setStatus(ThreadContext::Unallocated);
 }
 
+void
+SimpleThread::copyTC(ThreadContext *context)
+{
+    copyState(context);
+
+#if FULL_SYSTEM
+    EndQuiesceEvent *quiesce = context->getQuiesceEvent();
+    if (quiesce) {
+        quiesceEvent = quiesce;
+    }
+    Kernel::Statistics *stats = context->getKernelStats();
+    if (stats) {
+        kernelStats = stats;
+    }
+#endif
+}
+
 void
 SimpleThread::copyState(ThreadContext *oldContext)
 {
index ff2639e10f5faff97b17989cc1dbd54a575fb92b..d36853db4c82e9105a60959ebfd5da4836513d76 100644 (file)
@@ -121,7 +121,7 @@ class SimpleThread : public ThreadState
                  MemObject *memobj);
 #endif
 
-    SimpleThread(ThreadContext *oldContext);
+    SimpleThread();
 
     virtual ~SimpleThread();
 
@@ -129,6 +129,8 @@ class SimpleThread : public ThreadState
 
     void regStats(const std::string &name);
 
+    void copyTC(ThreadContext *context);
+
     void copyState(ThreadContext *oldContext);
 
     void serialize(std::ostream &os);