Get rid of the Unallocated thread context state.

Basically merge it in with Halted.
Also had to get rid of a few other functions that
called ThreadContext::deallocate(), including:
 - InOrderCPU's setThreadRescheduleCondition.
 - ThreadContext::exit().  This function was there to avoid terminating
   simulation when one thread out of a multi-thread workload exits, but we
   need to find a better (non-cpu-centric) way.
This commit is contained in:
Steve Reinhardt 2009-04-15 13:13:47 -07:00
parent 9b66e82897
commit 8882dc1283
20 changed files with 33 additions and 147 deletions

View file

@ -346,8 +346,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
// we're actually at the correct cycle or we need to wait a little while
// more
int ticks;
if ( tc->status() == ThreadContext::Halted ||
tc->status() == ThreadContext::Unallocated)
if ( tc->status() == ThreadContext::Halted)
return;
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -

View file

@ -121,9 +121,6 @@ class CheckerThreadContext : public ThreadContext
/// Set the status to Suspended.
void suspend() { actualTC->suspend(); }
/// Set the status to Unallocated.
void deallocate(int delay = 0) { actualTC->deallocate(delay); }
/// Set the status to Halted.
void halt() { actualTC->halt(); }

View file

@ -340,12 +340,6 @@ class InOrderCPU : public BaseCPU
virtual void disableMultiThreading(unsigned tid, unsigned vpe);
void disableThreads(unsigned tid, unsigned vpe);
// Sets a thread-rescheduling condition.
void setThreadRescheduleCondition(uint32_t tid)
{
//@TODO: IMPLEMENT ME
}
/** Activate a Thread When CPU Resources are Available. */
void activateWhenReady(int tid);

View file

@ -573,12 +573,6 @@ InOrderDynInst::disableMultiThreading(unsigned vpe)
this->cpu->disableMultiThreading(threadNumber, vpe);
}
void
InOrderDynInst::setThreadRescheduleCondition(uint32_t cond)
{
this->cpu->setThreadRescheduleCondition(cond);
}
template<class T>
inline Fault
InOrderDynInst::read(Addr addr, T &data, unsigned flags)

View file

@ -481,8 +481,6 @@ class InOrderDynInst : public FastAlloc, public RefCounted
virtual void enableMultiThreading(unsigned vpe);
virtual void disableMultiThreading(unsigned vpe);
virtual void setThreadRescheduleCondition(uint32_t cond);
////////////////////////////////////////////////////////////
//
// PROGRAM COUNTERS - PC/NPC/NPC

View file

@ -46,7 +46,7 @@ InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
copyArchRegs(old_context);
thread->funcExeInst = old_context->readFuncExeInst();
old_context->setStatus(ThreadContext::Unallocated);
old_context->setStatus(ThreadContext::Halted);
thread->inSyscall = false;
thread->trapPending = false;
}
@ -79,19 +79,6 @@ InOrderThreadContext::suspend(int delay)
cpu->suspendContext(thread->readTid(), delay);
}
void
InOrderThreadContext::deallocate(int delay)
{
DPRINTF(InOrderCPU, "Calling deallocate on Thread Context %d\n",
getThreadNum());
if (thread->status() == ThreadContext::Unallocated)
return;
thread->setStatus(ThreadContext::Unallocated);
cpu->deallocateContext(thread->readTid(), delay);
}
void
InOrderThreadContext::halt(int delay)
{

View file

@ -118,9 +118,6 @@ class InOrderThreadContext : public ThreadContext
/** Set the status to Suspended. */
virtual void suspend(int delay = 0);
/** Set the status to Unallocated. */
virtual void deallocate(int delay = 1);
/** Set the status to Halted. */
virtual void halt(int delay = 0);
@ -244,32 +241,6 @@ class InOrderThreadContext : public ThreadContext
virtual void changeRegFileContext(unsigned param,
unsigned val)
{ panic("Not supported!"); }
/** 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->deallocate();
// If there are still threads executing in the system (for now
// this single cpu)
if (this->cpu->numActiveThreads() - 1 > 0)
return 0; // don't exit simulation
else
return 1; // exit simulation
}
virtual void setThreadRescheduleCondition(uint64_t cond)
{
this->deallocate();
this->setStatus(ThreadContext::Suspended);
activateContext(cond);
}
};
#endif

View file

@ -122,9 +122,6 @@ class O3ThreadContext : public ThreadContext
/** Set the status to Suspended. */
virtual void suspend(int delay = 0);
/** Set the status to Unallocated. */
virtual void deallocate(int delay = 0);
/** Set the status to Halted. */
virtual void halt(int delay = 0);
@ -273,22 +270,6 @@ class O3ThreadContext : public ThreadContext
#endif
this->cpu->setNextNPC(val, this->thread->threadId());
}
/** 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->deallocate();
// If there are still threads executing in the system
if (this->cpu->numActiveThreads())
return 0; // don't exit simulation
else
return 1; // exit simulation
}
};
#endif

View file

@ -84,7 +84,7 @@ O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
cpu->lockFlag = false;
#endif
old_context->setStatus(ThreadContext::Unallocated);
old_context->setStatus(ThreadContext::Halted);
thread->inSyscall = false;
thread->trapPending = false;
@ -104,11 +104,6 @@ O3ThreadContext<Impl>::activate(int delay)
thread->lastActivate = curTick;
#endif
if (thread->status() == ThreadContext::Unallocated) {
cpu->activateWhenReady(thread->threadId());
return;
}
thread->setStatus(ThreadContext::Active);
// status() == Suspended
@ -142,20 +137,6 @@ O3ThreadContext<Impl>::suspend(int delay)
cpu->suspendContext(thread->threadId());
}
template <class Impl>
void
O3ThreadContext<Impl>::deallocate(int delay)
{
DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n",
threadId(), delay);
if (thread->status() == ThreadContext::Unallocated)
return;
thread->setStatus(ThreadContext::Unallocated);
cpu->deallocateContext(thread->threadId(), true, delay);
}
template <class Impl>
void
O3ThreadContext<Impl>::halt(int delay)

View file

@ -148,9 +148,6 @@ class OzoneCPU : public BaseCPU
/// Set the status to Suspended.
void suspend();
/// Set the status to Unallocated.
void deallocate(int delay = 0);
/// Set the status to Halted.
void halt();

View file

@ -737,14 +737,6 @@ OzoneCPU<Impl>::OzoneTC::suspend()
cpu->suspendContext(thread->threadId());
}
/// Set the status to Unallocated.
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::deallocate(int delay)
{
cpu->deallocateContext(thread->threadId(), delay);
}
/// Set the status to Halted.
template <class Impl>
void
@ -799,7 +791,7 @@ OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
cpu->lockFlag = false;
#endif
old_context->setStatus(ThreadContext::Unallocated);
old_context->setStatus(ThreadContext::Halted);
}
template <class Impl>

View file

@ -81,7 +81,7 @@ BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
p->itb, p->dtb, /* asid */ 0);
#endif // !FULL_SYSTEM
thread->setStatus(ThreadContext::Unallocated);
thread->setStatus(ThreadContext::Halted);
tc = thread->getTC();

View file

@ -152,7 +152,7 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
storeCondFailures = 0;
oldContext->setStatus(ThreadContext::Unallocated);
oldContext->setStatus(ThreadContext::Halted);
}
void
@ -253,15 +253,6 @@ SimpleThread::suspend()
cpu->suspendContext(_threadId);
}
void
SimpleThread::deallocate()
{
if (status() == ThreadContext::Unallocated)
return;
_status = ThreadContext::Unallocated;
cpu->deallocateContext(_threadId);
}
void
SimpleThread::halt()

View file

@ -208,9 +208,6 @@ class SimpleThread : public ThreadState
/// Set the status to Suspended.
void suspend();
/// Set the status to Unallocated.
void deallocate();
/// Set the status to Halted.
void halt();

View file

@ -87,14 +87,9 @@ class ThreadContext
typedef TheISA::MiscRegFile MiscRegFile;
typedef TheISA::MiscReg MiscReg;
public:
enum Status
{
/// Initialized but not running yet. All CPUs start in
/// this state, but most transition to Active on cycle 1.
/// In MP or SMT systems, non-primary contexts will stay
/// in this state until a thread is assigned to them.
Unallocated,
/// Running. Instructions should be executed only when
/// the context is in this state.
Active,
@ -154,9 +149,6 @@ class ThreadContext
/// Set the status to Suspended.
virtual void suspend(int delay = 0) = 0;
/// Set the status to Unallocated.
virtual void deallocate(int delay = 0) = 0;
/// Set the status to Halted.
virtual void halt(int delay = 0) = 0;
@ -337,9 +329,6 @@ class ProxyThreadContext : public ThreadContext
/// Set the status to Suspended.
void suspend(int delay = 0) { actualTC->suspend(); }
/// Set the status to Unallocated.
void deallocate(int delay = 0) { actualTC->deallocate(); }
/// Set the status to Halted.
void halt(int delay = 0) { actualTC->halt(); }

View file

@ -1074,7 +1074,7 @@ class Tru64 : public OperatingSystem
ThreadContext *tc)
{
assert(tc->status() == ThreadContext::Active);
tc->deallocate();
tc->halt();
return 0;
}

View file

@ -221,7 +221,7 @@ Process::findFreeContext()
ThreadContext *tc;
for (int i = 0; i < size; ++i) {
tc = system->getThreadContext(contextIds[i]);
if (tc->status() == ThreadContext::Unallocated) {
if (tc->status() == ThreadContext::Halted) {
// inactive context, free to use
return tc;
}

View file

@ -42,6 +42,7 @@
#include "cpu/base.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/system.hh"
#include "sim/sim_exit.hh"
@ -91,9 +92,13 @@ SyscallReturn
exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
if (tc->exit()) {
if (process->system->numRunningContexts() == 1) {
// Last running context... exit simulator
exitSimLoop("target called exit()",
process->getSyscallArg(tc, 0) & 0xff);
process->getSyscallArg(tc, 0) & 0xff);
} else {
// other running threads... just halt this one
tc->halt();
}
return 1;

View file

@ -211,6 +211,17 @@ System::registerThreadContext(ThreadContext *tc, int assigned)
return id;
}
int
System::numRunningContexts()
{
int running = 0;
for (int i = 0; i < _numContexts; ++i) {
if (threadContexts[i]->status() != ThreadContext::Halted)
++running;
}
return running;
}
void
System::startup()
{

View file

@ -89,19 +89,21 @@ class System : public SimObject
std::vector<ThreadContext *> threadContexts;
int _numContexts;
ThreadContext * getThreadContext(int tid)
ThreadContext *getThreadContext(int tid)
{
return threadContexts[tid];
}
int numContexts()
{
if (_numContexts != threadContexts.size())
panic("cpu array not fully populated!");
assert(_numContexts == threadContexts.size());
return _numContexts;
}
/** Return number of running (non-halted) thread contexts in
* system. These threads could be Active or Suspended. */
int numRunningContexts();
#if FULL_SYSTEM
Platform *platform;
uint64_t init_param;