diff --git a/src/cpu/o3/alpha/thread_context.hh b/src/cpu/o3/alpha/thread_context.hh index 57190d65e..78b0ee788 100644 --- a/src/cpu/o3/alpha/thread_context.hh +++ b/src/cpu/o3/alpha/thread_context.hh @@ -37,21 +37,21 @@ class AlphaTC : public O3ThreadContext public: #if FULL_SYSTEM /** Returns a pointer to the ITB. */ - virtual AlphaITB *getITBPtr() { return cpu->itb; } + virtual AlphaITB *getITBPtr() { return this->cpu->itb; } /** Returns a pointer to the DTB. */ - virtual AlphaDTB *getDTBPtr() { return cpu->dtb; } + virtual AlphaDTB *getDTBPtr() { return this->cpu->dtb; } /** Returns pointer to the quiesce event. */ virtual EndQuiesceEvent *getQuiesceEvent() { - return thread->quiesceEvent; + return this->thread->quiesceEvent; } /** Returns if the thread is currently in PAL mode, based on * the PC's value. */ virtual bool inPalMode() - { return TheISA::PcPAL(cpu->readPC(thread->readTid())); } + { return TheISA::PcPAL(this->cpu->readPC(this->thread->readTid())); } #endif virtual uint64_t readNextNPC() @@ -68,4 +68,20 @@ class AlphaTC : public O3ThreadContext virtual void changeRegFileContext(TheISA::RegFile::ContextParam param, TheISA::RegFile::ContextVal val) { 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. + virtual int exit() + { + this->cpu->deallocateContext(this->thread->readTid()); + + // If there are still threads executing in the system + if (this->cpu->numActiveThreads()) + return 0; + else + return 1; + } }; diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 2a9ecff4e..1cff6142d 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -214,6 +214,10 @@ class FullO3CPU : public BaseO3CPU /** Initialize the CPU */ void init(); + /** Returns the Number of Active Threads in the CPU */ + int numActiveThreads() + { return activeThreads.size(); } + /** Add Thread to Active Threads List */ void activateThread(unsigned int tid); diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index d60867029..d097ee63e 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -34,6 +34,13 @@ #include "cpu/o3/isa_specific.hh" +class EndQuiesceEvent; +namespace Kernel { + class Statistics; +}; + +class TranslatingPort; + /** * Derived ThreadContext class for use with the O3CPU. It * provides the interface for any external objects to access a diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index fccabaf36..cfb71f623 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -30,6 +30,7 @@ */ #include "cpu/o3/thread_context.hh" +#include "cpu/quiesce_event.hh" using namespace TheISA; diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 3c79e1116..70d705144 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -247,6 +247,11 @@ class ThreadContext // Same with st cond failures. virtual Counter readFuncExeInst() = 0; + + // 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 calls the exit syscall. + virtual int exit() { return 1; }; #endif virtual void changeRegFileContext(RegFile::ContextParam param, diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 848b6f869..e72890612 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -27,7 +27,6 @@ * * Authors: Steve Reinhardt * Ali Saidi - * Korey Sewell */ #include @@ -92,7 +91,9 @@ SyscallReturn exitFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc) { - exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff); + if (tc->exit()) { + exitSimLoop("target called exit()", tc->getSyscallArg(0) & 0xff); + } return 1; }