Fix so that O3CPU doesnt segfault on exit.
authorKorey Sewell <ksewell@umich.edu>
Fri, 7 Jul 2006 08:06:26 +0000 (04:06 -0400)
committerKorey Sewell <ksewell@umich.edu>
Fri, 7 Jul 2006 08:06:26 +0000 (04:06 -0400)
Major thing was to not execute commit if there are no active threads in CPU.

src/cpu/o3/alpha/thread_context.hh:
    call deallocate instead of deallocateContext
src/cpu/o3/commit_impl.hh:
    dont run commit stage if there are no instructions
src/cpu/o3/cpu.cc:
    add deallocate event, deactivateThread function, and edit deallocateContext.
src/cpu/o3/cpu.hh:
    add deallocate event and add optional delay to deallocateContext
src/cpu/o3/thread_context.hh:
    optional delay for deallocate
src/cpu/o3/thread_context_impl.hh:
    edit DPRINTFs to say Thread Context instead of Alpha TC
src/cpu/thread_context.hh:
    optional delay
src/sim/syscall_emul.hh:
    name stuff

--HG--
extra : convert_revision : f4033e1f66b3043d30ad98dcc70d8b193dea70b6

src/cpu/o3/alpha/thread_context.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/thread_context.hh
src/sim/syscall_emul.hh

index 78b0ee78826e2d3543eb5bed2cbbf5fe0d540a99..ad52b0d2e82ad38b868b8013c5801bfd7aa8aa52 100644 (file)
@@ -70,18 +70,19 @@ class AlphaTC : public O3ThreadContext<Impl>
     { panic("Not supported on Alpha!"); }
 
 
-    // This function exits the thread context in the CPU and returns
-    // 1 if the CPU has no more active threads (meaning it's OK to exit);
-    // Used in syscall-emulation mode when a thread executes the 'exit'
-    // syscall.
+    /** This function exits the thread context in the CPU and returns
+     * 1 if the CPU has no more active threads (meaning it's OK to exit);
+     * Used in syscall-emulation mode when a thread executes the 'exit'
+     * syscall.
+     */
     virtual int exit()
     {
-        this->cpu->deallocateContext(this->thread->readTid());
+        this->deallocate();
 
         // If there are still threads executing in the system
         if (this->cpu->numActiveThreads())
-            return 0;
+            return 0; // don't exit simulation
         else
-            return 1;
+            return 1; // exit simulation
     }
 };
index 06b8e8a954c53ac197d64f7730cc9c9325ece97e..53d247e9780dcdfd3df9674f86fed29f773315f4 100644 (file)
@@ -562,6 +562,9 @@ DefaultCommit<Impl>::tick()
         return;
     }
 
+    if ((*activeThreads).size() <= 0)
+        return;
+
     list<unsigned>::iterator threads = (*activeThreads).begin();
 
     // Check if any of the threads are done squashing.  Change the
index c88146fa6ef0fdc1184781b0e9efd3e9cfde97c8..0a564169ae88f1d1302b5adb62e1fc811f77febd 100644 (file)
@@ -114,6 +114,36 @@ FullO3CPU<Impl>::ActivateThreadEvent::description()
     return "FullO3CPU \"Activate Thread\" event";
 }
 
+template <class Impl>
+FullO3CPU<Impl>::DeallocateContextEvent::DeallocateContextEvent()
+    : Event(&mainEventQueue, CPU_Tick_Pri)
+{
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::DeallocateContextEvent::init(int thread_num,
+                                           FullO3CPU<Impl> *thread_cpu)
+{
+    tid = thread_num;
+    cpu = thread_cpu;
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::DeallocateContextEvent::process()
+{
+    cpu->deactivateThread(tid);
+    cpu->removeThread(tid);
+}
+
+template <class Impl>
+const char *
+FullO3CPU<Impl>::DeallocateContextEvent::description()
+{
+    return "FullO3CPU \"Deallocate Context\" event";
+}
+
 template <class Impl>
 FullO3CPU<Impl>::FullO3CPU(Params *params)
     : BaseO3CPU(params),
@@ -459,6 +489,118 @@ FullO3CPU<Impl>::init()
     commit.setThreads(thread);
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::activateThread(unsigned tid)
+{
+    list<unsigned>::iterator isActive = find(
+        activeThreads.begin(), activeThreads.end(), tid);
+
+    if (isActive == activeThreads.end()) {
+        DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
+                tid);
+
+        activeThreads.push_back(tid);
+    }
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::deactivateThread(unsigned tid)
+{
+    //Remove From Active List, if Active
+    list<unsigned>::iterator thread_it =
+        find(activeThreads.begin(), activeThreads.end(), tid);
+
+    if (thread_it != activeThreads.end()) {
+        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
+                tid);
+        activeThreads.erase(thread_it);
+    }
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::activateContext(int tid, int delay)
+{
+    // Needs to set each stage to running as well.
+    if (delay){
+        DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
+                "on cycle %d\n", tid, curTick + cycles(delay));
+        scheduleActivateThreadEvent(tid, delay);
+    } else {
+        activateThread(tid);
+    }
+
+    if(lastActivatedCycle < curTick) {
+        scheduleTickEvent(delay);
+
+        // Be sure to signal that there's some activity so the CPU doesn't
+        // deschedule itself.
+        activityRec.activity();
+        fetch.wakeFromQuiesce();
+
+        lastActivatedCycle = curTick;
+
+        _status = Running;
+    }
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::deallocateContext(int tid, int delay)
+{
+    // Schedule removal of thread data from CPU
+    if (delay){
+        DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate "
+                "on cycle %d\n", tid, curTick + cycles(delay));
+        scheduleDeallocateContextEvent(tid, delay);
+    } else {
+        deactivateThread(tid);
+        removeThread(tid);
+    }
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::suspendContext(int tid)
+{
+    DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
+    unscheduleTickEvent();
+    _status = Idle;
+/*
+    //Remove From Active List, if Active
+    list<unsigned>::iterator isActive = find(
+        activeThreads.begin(), activeThreads.end(), tid);
+
+    if (isActive != activeThreads.end()) {
+        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
+                tid);
+        activeThreads.erase(isActive);
+    }
+*/
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::haltContext(int tid)
+{
+    DPRINTF(O3CPU,"[tid:%i]: Halting Thread Context", tid);
+/*
+    //Remove From Active List, if Active
+    list<unsigned>::iterator isActive = find(
+        activeThreads.begin(), activeThreads.end(), tid);
+
+    if (isActive != activeThreads.end()) {
+        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
+                tid);
+        activeThreads.erase(isActive);
+
+        removeThread(tid);
+    }
+*/
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::insertThread(unsigned tid)
@@ -511,7 +653,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::removeThread(unsigned tid)
 {
-    DPRINTF(O3CPU,"[tid:%i] Removing thread from CPU.");
+    DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.");
 
     // Copy Thread Data From RegFile
     // If thread is suspended, it might be re-allocated
@@ -537,6 +679,8 @@ FullO3CPU<Impl>::removeThread(unsigned tid)
     fetch.squash(0,tid);
     decode.squash(tid);
     rename.squash(tid);
+    iew.squash(tid);
+    commit.rob->squash(commit.rob->readHeadInst(tid)->seqNum, tid);
 
     assert(iew.ldstQueue.getCount(tid) == 0);
 
@@ -600,113 +744,12 @@ FullO3CPU<Impl>::activateWhenReady(int tid)
         //blocks fetch
         contextSwitch = true;
 
+        //@todo: dont always add to waitlist
         //do waitlist
         cpuWaitList.push_back(tid);
     }
 }
 
-template <class Impl>
-void
-FullO3CPU<Impl>::activateThread(unsigned int tid)
-{
-    list<unsigned>::iterator isActive = find(
-        activeThreads.begin(), activeThreads.end(), tid);
-
-    if (isActive == activeThreads.end()) {
-        DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
-                tid);
-
-        activeThreads.push_back(tid);
-    }
-}
-
-
-template <class Impl>
-void
-FullO3CPU<Impl>::activateContext(int tid, int delay)
-{
-    // Needs to set each stage to running as well.
-    if (delay){
-        DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
-                "on cycle %d\n", tid, curTick + cycles(delay));
-        scheduleActivateThreadEvent(tid, delay);
-    } else {
-        activateThread(tid);
-    }
-
-    if(lastActivatedCycle < curTick) {
-        scheduleTickEvent(delay);
-
-        // Be sure to signal that there's some activity so the CPU doesn't
-        // deschedule itself.
-        activityRec.activity();
-        fetch.wakeFromQuiesce();
-
-        lastActivatedCycle = curTick;
-
-        _status = Running;
-    }
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::suspendContext(int tid)
-{
-    DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
-    unscheduleTickEvent();
-    _status = Idle;
-/*
-    //Remove From Active List, if Active
-    list<unsigned>::iterator isActive = find(
-        activeThreads.begin(), activeThreads.end(), tid);
-
-    if (isActive != activeThreads.end()) {
-        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
-                tid);
-        activeThreads.erase(isActive);
-    }
-*/
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::deallocateContext(int tid)
-{
-    DPRINTF(O3CPU,"[tid:%i]: Deallocating Thread Context", tid);
-
-    //Remove From Active List, if Active
-    list<unsigned>::iterator thread_it =
-        find(activeThreads.begin(), activeThreads.end(), tid);
-
-    if (thread_it != activeThreads.end()) {
-        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
-                tid);
-        activeThreads.erase(thread_it);
-
-        removeThread(tid);
-    }
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::haltContext(int tid)
-{
-    DPRINTF(O3CPU,"[tid:%i]: Halting Thread Context", tid);
-/*
-    //Remove From Active List, if Active
-    list<unsigned>::iterator isActive = find(
-        activeThreads.begin(), activeThreads.end(), tid);
-
-    if (isActive != activeThreads.end()) {
-        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
-                tid);
-        activeThreads.erase(isActive);
-
-        removeThread(tid);
-    }
-*/
-}
-
 template <class Impl>
 void
 FullO3CPU<Impl>::switchOut()
index bd045160192dcd04a7b3c0e3671a79ba5eb690a5..476b5ffb33e0e6e085a9421277b6b80467bf6a3a 100644 (file)
@@ -197,6 +197,49 @@ class FullO3CPU : public BaseO3CPU
     /** The tick event used for scheduling CPU ticks. */
     ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
 
+    class DeallocateContextEvent : public Event
+    {
+      private:
+        /** Number of Thread to Activate */
+        int tid;
+
+        /** Pointer to the CPU. */
+        FullO3CPU<Impl> *cpu;
+
+      public:
+        /** Constructs the event. */
+        DeallocateContextEvent();
+
+        /** Initialize Event */
+        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
+
+        /** Processes the event, calling activateThread() on the CPU. */
+        void process();
+
+        /** Returns the description of the event. */
+        const char *description();
+    };
+
+    /** Schedule cpu to deallocate thread context.*/
+    void scheduleDeallocateContextEvent(int tid, int delay)
+    {
+        // Schedule thread to activate, regardless of its current state.
+        if (deallocateContextEvent[tid].squashed())
+            deallocateContextEvent[tid].reschedule(curTick + cycles(delay));
+        else if (!deallocateContextEvent[tid].scheduled())
+            deallocateContextEvent[tid].schedule(curTick + cycles(delay));
+    }
+
+    /** Unschedule thread deallocation in CPU */
+    void unscheduleDeallocateContextEvent(int tid)
+    {
+        if (deallocateContextEvent[tid].scheduled())
+            deallocateContextEvent[tid].squash();
+    }
+
+    /** The tick event used for scheduling CPU ticks. */
+    DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
+
   public:
     /** Constructs a CPU with the given parameters. */
     FullO3CPU(Params *params);
@@ -219,7 +262,10 @@ class FullO3CPU : public BaseO3CPU
     { return activeThreads.size(); }
 
     /** Add Thread to Active Threads List */
-    void activateThread(unsigned int tid);
+    void activateThread(unsigned tid);
+
+    /** Remove Thread from Active Threads List */
+    void deactivateThread(unsigned tid);
 
     /** Setup CPU to insert a thread's context */
     void insertThread(unsigned tid);
@@ -247,7 +293,7 @@ class FullO3CPU : public BaseO3CPU
     /** Remove Thread from Active Threads List &&
      *  Remove Thread Context from CPU.
      */
-    void deallocateContext(int tid);
+    void deallocateContext(int tid, int delay = 1);
 
     /** Remove Thread from Active Threads List &&
      *  Remove Thread Context from CPU.
index d097ee63eb97142716aaf3375d1c3aabdcadf977..df8d1a6d8bd68d0c1d1d3f081cb2c2474c79841f 100755 (executable)
@@ -112,7 +112,7 @@ class O3ThreadContext : public ThreadContext
     virtual void suspend();
 
     /** Set the status to Unallocated. */
-    virtual void deallocate();
+    virtual void deallocate(int delay = 0);
 
     /** Set the status to Halted. */
     virtual void halt();
index cfb71f623889f73dd4ce90ed698e756b995fbb42..bf8cbf850d74438c0bc99cde93135d06ad617385 100755 (executable)
@@ -115,7 +115,8 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::activate(int delay)
 {
-    DPRINTF(O3CPU, "Calling activate on AlphaTC\n");
+    DPRINTF(O3CPU, "Calling activate on Thread Context %d\n",
+            getThreadNum());
 
     if (thread->status() == ThreadContext::Active)
         return;
@@ -139,7 +140,8 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::suspend()
 {
-    DPRINTF(O3CPU, "Calling suspend on AlphaTC\n");
+    DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n",
+            getThreadNum());
 
     if (thread->status() == ThreadContext::Suspended)
         return;
@@ -163,22 +165,24 @@ O3ThreadContext<Impl>::suspend()
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::deallocate()
+O3ThreadContext<Impl>::deallocate(int delay)
 {
-    DPRINTF(O3CPU, "Calling deallocate on AlphaTC\n");
+    DPRINTF(O3CPU, "Calling deallocate on Thread Context %d\n",
+            getThreadNum());
 
     if (thread->status() == ThreadContext::Unallocated)
         return;
 
     thread->setStatus(ThreadContext::Unallocated);
-    cpu->deallocateContext(thread->readTid());
+    cpu->deallocateContext(thread->readTid(), delay);
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::halt()
 {
-    DPRINTF(O3CPU, "Calling halt on AlphaTC\n");
+    DPRINTF(O3CPU, "Calling halt on Thread Context %d\n",
+            getThreadNum());
 
     if (thread->status() == ThreadContext::Halted)
         return;
index 70d70514419b29ac9e63f00f75235c853fcf17b9..e019e22bc33d516594f1d3c6367f23aab30d669a 100644 (file)
@@ -143,7 +143,7 @@ class ThreadContext
     virtual void suspend() = 0;
 
     /// Set the status to Unallocated.
-    virtual void deallocate() = 0;
+    virtual void deallocate(int delay = 0) = 0;
 
     /// Set the status to Halted.
     virtual void halt() = 0;
@@ -318,7 +318,7 @@ class ProxyThreadContext : public ThreadContext
     void suspend() { actualTC->suspend(); }
 
     /// Set the status to Unallocated.
-    void deallocate() { actualTC->deallocate(); }
+    void deallocate(int delay = 0) { actualTC->deallocate(); }
 
     /// Set the status to Halted.
     void halt() { actualTC->halt(); }
index a3990e2fd1300168dc0bac0fcd2e2f7a46041e59..a3ff006efbad33750df310314f1ef6963101ae44 100644 (file)
@@ -27,7 +27,6 @@
  *
  * Authors: Steve Reinhardt
  *          Kevin Lim
- *          Korey Sewell
  */
 
 #ifndef __SIM_SYSCALL_EMUL_HH__