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:
parent
9b66e82897
commit
8882dc1283
20 changed files with 33 additions and 147 deletions
|
@ -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) -
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -1074,7 +1074,7 @@ class Tru64 : public OperatingSystem
|
|||
ThreadContext *tc)
|
||||
{
|
||||
assert(tc->status() == ThreadContext::Active);
|
||||
tc->deallocate();
|
||||
tc->halt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue