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
|
@ -346,8 +346,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
|
||||||
// we're actually at the correct cycle or we need to wait a little while
|
// we're actually at the correct cycle or we need to wait a little while
|
||||||
// more
|
// more
|
||||||
int ticks;
|
int ticks;
|
||||||
if ( tc->status() == ThreadContext::Halted ||
|
if ( tc->status() == ThreadContext::Halted)
|
||||||
tc->status() == ThreadContext::Unallocated)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
|
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
|
||||||
|
|
|
@ -121,9 +121,6 @@ class CheckerThreadContext : public ThreadContext
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend() { actualTC->suspend(); }
|
void suspend() { actualTC->suspend(); }
|
||||||
|
|
||||||
/// Set the status to Unallocated.
|
|
||||||
void deallocate(int delay = 0) { actualTC->deallocate(delay); }
|
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt() { actualTC->halt(); }
|
void halt() { actualTC->halt(); }
|
||||||
|
|
||||||
|
|
|
@ -340,12 +340,6 @@ class InOrderCPU : public BaseCPU
|
||||||
virtual void disableMultiThreading(unsigned tid, unsigned vpe);
|
virtual void disableMultiThreading(unsigned tid, unsigned vpe);
|
||||||
void disableThreads(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. */
|
/** Activate a Thread When CPU Resources are Available. */
|
||||||
void activateWhenReady(int tid);
|
void activateWhenReady(int tid);
|
||||||
|
|
||||||
|
|
|
@ -573,12 +573,6 @@ InOrderDynInst::disableMultiThreading(unsigned vpe)
|
||||||
this->cpu->disableMultiThreading(threadNumber, vpe);
|
this->cpu->disableMultiThreading(threadNumber, vpe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
InOrderDynInst::setThreadRescheduleCondition(uint32_t cond)
|
|
||||||
{
|
|
||||||
this->cpu->setThreadRescheduleCondition(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Fault
|
inline Fault
|
||||||
InOrderDynInst::read(Addr addr, T &data, unsigned flags)
|
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 enableMultiThreading(unsigned vpe);
|
||||||
virtual void disableMultiThreading(unsigned vpe);
|
virtual void disableMultiThreading(unsigned vpe);
|
||||||
|
|
||||||
virtual void setThreadRescheduleCondition(uint32_t cond);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// PROGRAM COUNTERS - PC/NPC/NPC
|
// PROGRAM COUNTERS - PC/NPC/NPC
|
||||||
|
|
|
@ -46,7 +46,7 @@ InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
|
||||||
copyArchRegs(old_context);
|
copyArchRegs(old_context);
|
||||||
|
|
||||||
thread->funcExeInst = old_context->readFuncExeInst();
|
thread->funcExeInst = old_context->readFuncExeInst();
|
||||||
old_context->setStatus(ThreadContext::Unallocated);
|
old_context->setStatus(ThreadContext::Halted);
|
||||||
thread->inSyscall = false;
|
thread->inSyscall = false;
|
||||||
thread->trapPending = false;
|
thread->trapPending = false;
|
||||||
}
|
}
|
||||||
|
@ -79,19 +79,6 @@ InOrderThreadContext::suspend(int delay)
|
||||||
cpu->suspendContext(thread->readTid(), 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
|
void
|
||||||
InOrderThreadContext::halt(int delay)
|
InOrderThreadContext::halt(int delay)
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,9 +118,6 @@ class InOrderThreadContext : public ThreadContext
|
||||||
/** Set the status to Suspended. */
|
/** Set the status to Suspended. */
|
||||||
virtual void suspend(int delay = 0);
|
virtual void suspend(int delay = 0);
|
||||||
|
|
||||||
/** Set the status to Unallocated. */
|
|
||||||
virtual void deallocate(int delay = 1);
|
|
||||||
|
|
||||||
/** Set the status to Halted. */
|
/** Set the status to Halted. */
|
||||||
virtual void halt(int delay = 0);
|
virtual void halt(int delay = 0);
|
||||||
|
|
||||||
|
@ -244,32 +241,6 @@ class InOrderThreadContext : public ThreadContext
|
||||||
virtual void changeRegFileContext(unsigned param,
|
virtual void changeRegFileContext(unsigned param,
|
||||||
unsigned val)
|
unsigned val)
|
||||||
{ panic("Not supported!"); }
|
{ 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
|
#endif
|
||||||
|
|
|
@ -122,9 +122,6 @@ class O3ThreadContext : public ThreadContext
|
||||||
/** Set the status to Suspended. */
|
/** Set the status to Suspended. */
|
||||||
virtual void suspend(int delay = 0);
|
virtual void suspend(int delay = 0);
|
||||||
|
|
||||||
/** Set the status to Unallocated. */
|
|
||||||
virtual void deallocate(int delay = 0);
|
|
||||||
|
|
||||||
/** Set the status to Halted. */
|
/** Set the status to Halted. */
|
||||||
virtual void halt(int delay = 0);
|
virtual void halt(int delay = 0);
|
||||||
|
|
||||||
|
@ -273,22 +270,6 @@ class O3ThreadContext : public ThreadContext
|
||||||
#endif
|
#endif
|
||||||
this->cpu->setNextNPC(val, this->thread->threadId());
|
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
|
#endif
|
||||||
|
|
|
@ -84,7 +84,7 @@ O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
|
||||||
cpu->lockFlag = false;
|
cpu->lockFlag = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
old_context->setStatus(ThreadContext::Unallocated);
|
old_context->setStatus(ThreadContext::Halted);
|
||||||
|
|
||||||
thread->inSyscall = false;
|
thread->inSyscall = false;
|
||||||
thread->trapPending = false;
|
thread->trapPending = false;
|
||||||
|
@ -104,11 +104,6 @@ O3ThreadContext<Impl>::activate(int delay)
|
||||||
thread->lastActivate = curTick;
|
thread->lastActivate = curTick;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (thread->status() == ThreadContext::Unallocated) {
|
|
||||||
cpu->activateWhenReady(thread->threadId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread->setStatus(ThreadContext::Active);
|
thread->setStatus(ThreadContext::Active);
|
||||||
|
|
||||||
// status() == Suspended
|
// status() == Suspended
|
||||||
|
@ -142,20 +137,6 @@ O3ThreadContext<Impl>::suspend(int delay)
|
||||||
cpu->suspendContext(thread->threadId());
|
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>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::halt(int delay)
|
O3ThreadContext<Impl>::halt(int delay)
|
||||||
|
|
|
@ -148,9 +148,6 @@ class OzoneCPU : public BaseCPU
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend();
|
void suspend();
|
||||||
|
|
||||||
/// Set the status to Unallocated.
|
|
||||||
void deallocate(int delay = 0);
|
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt();
|
void halt();
|
||||||
|
|
||||||
|
|
|
@ -737,14 +737,6 @@ OzoneCPU<Impl>::OzoneTC::suspend()
|
||||||
cpu->suspendContext(thread->threadId());
|
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.
|
/// Set the status to Halted.
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
|
@ -799,7 +791,7 @@ OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
|
||||||
cpu->lockFlag = false;
|
cpu->lockFlag = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
old_context->setStatus(ThreadContext::Unallocated);
|
old_context->setStatus(ThreadContext::Halted);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -81,7 +81,7 @@ BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
|
||||||
p->itb, p->dtb, /* asid */ 0);
|
p->itb, p->dtb, /* asid */ 0);
|
||||||
#endif // !FULL_SYSTEM
|
#endif // !FULL_SYSTEM
|
||||||
|
|
||||||
thread->setStatus(ThreadContext::Unallocated);
|
thread->setStatus(ThreadContext::Halted);
|
||||||
|
|
||||||
tc = thread->getTC();
|
tc = thread->getTC();
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
|
||||||
|
|
||||||
storeCondFailures = 0;
|
storeCondFailures = 0;
|
||||||
|
|
||||||
oldContext->setStatus(ThreadContext::Unallocated);
|
oldContext->setStatus(ThreadContext::Halted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -253,15 +253,6 @@ SimpleThread::suspend()
|
||||||
cpu->suspendContext(_threadId);
|
cpu->suspendContext(_threadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SimpleThread::deallocate()
|
|
||||||
{
|
|
||||||
if (status() == ThreadContext::Unallocated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_status = ThreadContext::Unallocated;
|
|
||||||
cpu->deallocateContext(_threadId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SimpleThread::halt()
|
SimpleThread::halt()
|
||||||
|
|
|
@ -208,9 +208,6 @@ class SimpleThread : public ThreadState
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend();
|
void suspend();
|
||||||
|
|
||||||
/// Set the status to Unallocated.
|
|
||||||
void deallocate();
|
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt();
|
void halt();
|
||||||
|
|
||||||
|
|
|
@ -87,14 +87,9 @@ class ThreadContext
|
||||||
typedef TheISA::MiscRegFile MiscRegFile;
|
typedef TheISA::MiscRegFile MiscRegFile;
|
||||||
typedef TheISA::MiscReg MiscReg;
|
typedef TheISA::MiscReg MiscReg;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Status
|
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
|
/// Running. Instructions should be executed only when
|
||||||
/// the context is in this state.
|
/// the context is in this state.
|
||||||
Active,
|
Active,
|
||||||
|
@ -154,9 +149,6 @@ class ThreadContext
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
virtual void suspend(int delay = 0) = 0;
|
virtual void suspend(int delay = 0) = 0;
|
||||||
|
|
||||||
/// Set the status to Unallocated.
|
|
||||||
virtual void deallocate(int delay = 0) = 0;
|
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
virtual void halt(int delay = 0) = 0;
|
virtual void halt(int delay = 0) = 0;
|
||||||
|
|
||||||
|
@ -337,9 +329,6 @@ class ProxyThreadContext : public ThreadContext
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend(int delay = 0) { actualTC->suspend(); }
|
void suspend(int delay = 0) { actualTC->suspend(); }
|
||||||
|
|
||||||
/// Set the status to Unallocated.
|
|
||||||
void deallocate(int delay = 0) { actualTC->deallocate(); }
|
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt(int delay = 0) { actualTC->halt(); }
|
void halt(int delay = 0) { actualTC->halt(); }
|
||||||
|
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ class Tru64 : public OperatingSystem
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
assert(tc->status() == ThreadContext::Active);
|
assert(tc->status() == ThreadContext::Active);
|
||||||
tc->deallocate();
|
tc->halt();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,7 @@ Process::findFreeContext()
|
||||||
ThreadContext *tc;
|
ThreadContext *tc;
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
tc = system->getThreadContext(contextIds[i]);
|
tc = system->getThreadContext(contextIds[i]);
|
||||||
if (tc->status() == ThreadContext::Unallocated) {
|
if (tc->status() == ThreadContext::Halted) {
|
||||||
// inactive context, free to use
|
// inactive context, free to use
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
#include "sim/sim_exit.hh"
|
#include "sim/sim_exit.hh"
|
||||||
|
|
||||||
|
@ -91,9 +92,13 @@ SyscallReturn
|
||||||
exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
exitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc)
|
||||||
{
|
{
|
||||||
if (tc->exit()) {
|
if (process->system->numRunningContexts() == 1) {
|
||||||
|
// Last running context... exit simulator
|
||||||
exitSimLoop("target called exit()",
|
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;
|
return 1;
|
||||||
|
|
|
@ -211,6 +211,17 @@ System::registerThreadContext(ThreadContext *tc, int assigned)
|
||||||
return id;
|
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
|
void
|
||||||
System::startup()
|
System::startup()
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,12 +96,14 @@ class System : public SimObject
|
||||||
|
|
||||||
int numContexts()
|
int numContexts()
|
||||||
{
|
{
|
||||||
if (_numContexts != threadContexts.size())
|
assert(_numContexts == threadContexts.size());
|
||||||
panic("cpu array not fully populated!");
|
|
||||||
|
|
||||||
return _numContexts;
|
return _numContexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return number of running (non-halted) thread contexts in
|
||||||
|
* system. These threads could be Active or Suspended. */
|
||||||
|
int numRunningContexts();
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
Platform *platform;
|
Platform *platform;
|
||||||
uint64_t init_param;
|
uint64_t init_param;
|
||||||
|
|
Loading…
Reference in a new issue