alpha,arm,mips,power,x86,cpu,sim: Cleanup activate/deactivate
activate(), suspend(), and halt() used on thread contexts had an optional delay parameter. However this parameter was often ignored. Also, when used, the delay was seemily arbitrarily set to 0 or 1 cycle (no other delays were ever specified). This patch removes the delay parameter and 'Events' associated with them across all ISAs and cores. Unused activate logic is also removed.
This commit is contained in:
parent
2b0438a11e
commit
e1403fc2af
|
@ -68,7 +68,7 @@ void zeroRegisters(TC *tc);
|
||||||
// Alpha IPR register accessors
|
// Alpha IPR register accessors
|
||||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||||
inline void startupCPU(ThreadContext *tc, int cpuId)
|
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{ tc->activate(Cycles(0)); }
|
{ tc->activate(); }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
|
@ -104,7 +104,7 @@ void zeroRegisters(TC *tc);
|
||||||
|
|
||||||
inline void startupCPU(ThreadContext *tc, int cpuId)
|
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
|
@ -96,7 +96,7 @@ restoreThread(TC *tc)
|
||||||
|
|
||||||
// TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
|
// TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
|
||||||
tc->pcState(restartPC);
|
tc->pcState(restartPC);
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
|
|
||||||
warn("%i: Restoring thread %i in %s @ PC %x",
|
warn("%i: Restoring thread %i in %s @ PC %x",
|
||||||
curTick(), tc->threadId(), tc->getCpuPtr()->name(), restartPC);
|
curTick(), tc->threadId(), tc->getCpuPtr()->name(), restartPC);
|
||||||
|
|
|
@ -231,7 +231,7 @@ zeroRegisters(CPU *cpu)
|
||||||
void
|
void
|
||||||
startupCPU(ThreadContext *tc, int cpuId)
|
startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -59,7 +59,7 @@ void zeroRegisters(TC *tc);
|
||||||
inline void
|
inline void
|
||||||
startupCPU(ThreadContext *tc, int cpuId)
|
startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -77,7 +77,7 @@ startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
// Other CPUs will get activated by IPIs
|
// Other CPUs will get activated by IPIs
|
||||||
if (cpuId == 0 || !FullSystem)
|
if (cpuId == 0 || !FullSystem)
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
|
@ -203,12 +203,12 @@ void initCPU(ThreadContext *tc, int cpuId)
|
||||||
void startupCPU(ThreadContext *tc, int cpuId)
|
void startupCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
if (cpuId == 0 || !FullSystem) {
|
if (cpuId == 0 || !FullSystem) {
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
} else {
|
} else {
|
||||||
// This is an application processor (AP). It should be initialized to
|
// This is an application processor (AP). It should be initialized to
|
||||||
// look like only the BIOS POST has run on it and put then put it into
|
// look like only the BIOS POST has run on it and put then put it into
|
||||||
// a halted state.
|
// a halted state.
|
||||||
tc->suspend(Cycles(0));
|
tc->suspend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,10 +251,8 @@ class BaseCPU : public MemObject
|
||||||
/// Provide access to the tracer pointer
|
/// Provide access to the tracer pointer
|
||||||
Trace::InstTracer * getTracer() { return tracer; }
|
Trace::InstTracer * getTracer() { return tracer; }
|
||||||
|
|
||||||
/// Notify the CPU that the indicated context is now active. The
|
/// Notify the CPU that the indicated context is now active.
|
||||||
/// delay parameter indicates the number of ticks to wait before
|
virtual void activateContext(ThreadID thread_num) {}
|
||||||
/// executing (typically 0 or 1).
|
|
||||||
virtual void activateContext(ThreadID thread_num, Cycles delay) {}
|
|
||||||
|
|
||||||
/// Notify the CPU that the indicated context is now suspended.
|
/// Notify the CPU that the indicated context is now suspended.
|
||||||
virtual void suspendContext(ThreadID thread_num) {}
|
virtual void suspendContext(ThreadID thread_num) {}
|
||||||
|
@ -285,8 +283,6 @@ class BaseCPU : public MemObject
|
||||||
virtual void startup();
|
virtual void startup();
|
||||||
virtual void regStats();
|
virtual void regStats();
|
||||||
|
|
||||||
virtual void activateWhenReady(ThreadID tid) {};
|
|
||||||
|
|
||||||
void registerThreadContexts();
|
void registerThreadContexts();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -157,16 +157,14 @@ class CheckerThreadContext : public ThreadContext
|
||||||
checkerTC->setStatus(new_status);
|
checkerTC->setStatus(new_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the status to Active. Optional delay indicates number of
|
/// Set the status to Active.
|
||||||
/// cycles to wait before beginning execution.
|
void activate() { actualTC->activate(); }
|
||||||
void activate(Cycles delay = Cycles(1))
|
|
||||||
{ actualTC->activate(delay); }
|
|
||||||
|
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend(Cycles delay) { actualTC->suspend(delay); }
|
void suspend() { actualTC->suspend(); }
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt(Cycles delay) { actualTC->halt(delay); }
|
void halt() { actualTC->halt(); }
|
||||||
|
|
||||||
void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
|
void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
|
||||||
|
|
||||||
|
|
|
@ -1090,11 +1090,11 @@ InOrderCPU::activateThreadInPipeline(ThreadID tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::deactivateContext(ThreadID tid, Cycles delay)
|
InOrderCPU::deactivateContext(ThreadID tid)
|
||||||
{
|
{
|
||||||
DPRINTF(InOrderCPU,"[tid:%i]: Deactivating ...\n", tid);
|
DPRINTF(InOrderCPU,"[tid:%i]: Deactivating ...\n", tid);
|
||||||
|
|
||||||
scheduleCpuEvent(DeactivateThread, NoFault, tid, dummyInst[tid], delay);
|
scheduleCpuEvent(DeactivateThread, NoFault, tid, dummyInst[tid]);
|
||||||
|
|
||||||
// Be sure to signal that there's some activity so the CPU doesn't
|
// Be sure to signal that there's some activity so the CPU doesn't
|
||||||
// deschedule itself.
|
// deschedule itself.
|
||||||
|
@ -1172,12 +1172,12 @@ InOrderCPU::tickThreadStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::activateContext(ThreadID tid, Cycles delay)
|
InOrderCPU::activateContext(ThreadID tid)
|
||||||
{
|
{
|
||||||
DPRINTF(InOrderCPU,"[tid:%i]: Activating ...\n", tid);
|
DPRINTF(InOrderCPU,"[tid:%i]: Activating ...\n", tid);
|
||||||
|
|
||||||
|
|
||||||
scheduleCpuEvent(ActivateThread, NoFault, tid, dummyInst[tid], delay);
|
scheduleCpuEvent(ActivateThread, NoFault, tid, dummyInst[tid]);
|
||||||
|
|
||||||
// Be sure to signal that there's some activity so the CPU doesn't
|
// Be sure to signal that there's some activity so the CPU doesn't
|
||||||
// deschedule itself.
|
// deschedule itself.
|
||||||
|
@ -1187,12 +1187,12 @@ InOrderCPU::activateContext(ThreadID tid, Cycles delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::activateNextReadyContext(Cycles delay)
|
InOrderCPU::activateNextReadyContext()
|
||||||
{
|
{
|
||||||
DPRINTF(InOrderCPU,"Activating next ready thread\n");
|
DPRINTF(InOrderCPU,"Activating next ready thread\n");
|
||||||
|
|
||||||
scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst[0],
|
scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst[0],
|
||||||
delay, ActivateNextReadyThread_Pri);
|
Cycles(0), ActivateNextReadyThread_Pri);
|
||||||
|
|
||||||
// Be sure to signal that there's some activity so the CPU doesn't
|
// Be sure to signal that there's some activity so the CPU doesn't
|
||||||
// deschedule itself.
|
// deschedule itself.
|
||||||
|
|
|
@ -498,7 +498,7 @@ class InOrderCPU : public BaseCPU
|
||||||
void trap(const Fault &fault, ThreadID tid, DynInstPtr inst);
|
void trap(const Fault &fault, ThreadID tid, DynInstPtr inst);
|
||||||
|
|
||||||
/** Schedule thread activation on the CPU */
|
/** Schedule thread activation on the CPU */
|
||||||
void activateContext(ThreadID tid, Cycles delay = Cycles(0));
|
void activateContext(ThreadID tid);
|
||||||
|
|
||||||
/** Add Thread to Active Threads List. */
|
/** Add Thread to Active Threads List. */
|
||||||
void activateThread(ThreadID tid);
|
void activateThread(ThreadID tid);
|
||||||
|
@ -507,13 +507,13 @@ class InOrderCPU : public BaseCPU
|
||||||
void activateThreadInPipeline(ThreadID tid);
|
void activateThreadInPipeline(ThreadID tid);
|
||||||
|
|
||||||
/** Schedule Thread Activation from Ready List */
|
/** Schedule Thread Activation from Ready List */
|
||||||
void activateNextReadyContext(Cycles delay = Cycles(0));
|
void activateNextReadyContext();
|
||||||
|
|
||||||
/** Add Thread From Ready List to Active Threads List. */
|
/** Add Thread From Ready List to Active Threads List. */
|
||||||
void activateNextReadyThread();
|
void activateNextReadyThread();
|
||||||
|
|
||||||
/** Schedule a thread deactivation on the CPU */
|
/** Schedule a thread deactivation on the CPU */
|
||||||
void deactivateContext(ThreadID tid, Cycles delay = Cycles(0));
|
void deactivateContext(ThreadID tid);
|
||||||
|
|
||||||
/** Remove from Active Thread List */
|
/** Remove from Active Thread List */
|
||||||
void deactivateThread(ThreadID tid);
|
void deactivateThread(ThreadID tid);
|
||||||
|
|
|
@ -103,7 +103,7 @@ InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderThreadContext::activate(Cycles delay)
|
InOrderThreadContext::activate()
|
||||||
{
|
{
|
||||||
DPRINTF(InOrderCPU, "Calling activate on Thread Context %d\n",
|
DPRINTF(InOrderCPU, "Calling activate on Thread Context %d\n",
|
||||||
getThreadNum());
|
getThreadNum());
|
||||||
|
@ -113,12 +113,12 @@ InOrderThreadContext::activate(Cycles delay)
|
||||||
|
|
||||||
thread->setStatus(ThreadContext::Active);
|
thread->setStatus(ThreadContext::Active);
|
||||||
|
|
||||||
cpu->activateContext(thread->threadId(), delay);
|
cpu->activateContext(thread->threadId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderThreadContext::suspend(Cycles delay)
|
InOrderThreadContext::suspend()
|
||||||
{
|
{
|
||||||
DPRINTF(InOrderCPU, "Calling suspend on Thread Context %d\n",
|
DPRINTF(InOrderCPU, "Calling suspend on Thread Context %d\n",
|
||||||
getThreadNum());
|
getThreadNum());
|
||||||
|
@ -131,7 +131,7 @@ InOrderThreadContext::suspend(Cycles delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderThreadContext::halt(Cycles delay)
|
InOrderThreadContext::halt()
|
||||||
{
|
{
|
||||||
DPRINTF(InOrderCPU, "Calling halt on Thread Context %d\n",
|
DPRINTF(InOrderCPU, "Calling halt on Thread Context %d\n",
|
||||||
getThreadNum());
|
getThreadNum());
|
||||||
|
|
|
@ -179,15 +179,14 @@ class InOrderThreadContext : public ThreadContext
|
||||||
void setStatus(Status new_status)
|
void setStatus(Status new_status)
|
||||||
{ thread->setStatus(new_status); }
|
{ thread->setStatus(new_status); }
|
||||||
|
|
||||||
/** Set the status to Active. Optional delay indicates number of
|
/** Set the status to Active. */
|
||||||
* cycles to wait before beginning execution. */
|
void activate();
|
||||||
void activate(Cycles delay = Cycles(1));
|
|
||||||
|
|
||||||
/** Set the status to Suspended. */
|
/** Set the status to Suspended. */
|
||||||
void suspend(Cycles delay = Cycles(0));
|
void suspend();
|
||||||
|
|
||||||
/** Set the status to Halted. */
|
/** Set the status to Halted. */
|
||||||
void halt(Cycles delay = Cycles(0));
|
void halt();
|
||||||
|
|
||||||
/** Takes over execution of a thread from another CPU. */
|
/** Takes over execution of a thread from another CPU. */
|
||||||
void takeOverFrom(ThreadContext *old_context);
|
void takeOverFrom(ThreadContext *old_context);
|
||||||
|
@ -279,8 +278,8 @@ class InOrderThreadContext : public ThreadContext
|
||||||
int flattenMiscIndex(int reg)
|
int flattenMiscIndex(int reg)
|
||||||
{ return cpu->isa[thread->threadId()]->flattenMiscIndex(reg); }
|
{ return cpu->isa[thread->threadId()]->flattenMiscIndex(reg); }
|
||||||
|
|
||||||
void activateContext(Cycles delay)
|
void activateContext()
|
||||||
{ cpu->activateContext(thread->threadId(), delay); }
|
{ cpu->activateContext(thread->threadId()); }
|
||||||
|
|
||||||
void deallocateContext()
|
void deallocateContext()
|
||||||
{ cpu->deallocateContext(thread->threadId()); }
|
{ cpu->deallocateContext(thread->threadId()); }
|
||||||
|
|
|
@ -430,9 +430,9 @@ BaseKvmCPU::wakeup()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseKvmCPU::activateContext(ThreadID thread_num, Cycles delay)
|
BaseKvmCPU::activateContext(ThreadID thread_num)
|
||||||
{
|
{
|
||||||
DPRINTF(Kvm, "ActivateContext %d (%d cycles)\n", thread_num, delay);
|
DPRINTF(Kvm, "ActivateContext %d\n", thread_num);
|
||||||
|
|
||||||
assert(thread_num == 0);
|
assert(thread_num == 0);
|
||||||
assert(thread);
|
assert(thread);
|
||||||
|
@ -442,7 +442,7 @@ BaseKvmCPU::activateContext(ThreadID thread_num, Cycles delay)
|
||||||
|
|
||||||
numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend);
|
numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend);
|
||||||
|
|
||||||
schedule(tickEvent, clockEdge(delay));
|
schedule(tickEvent, clockEdge(Cycles(0)));
|
||||||
_status = Running;
|
_status = Running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ class BaseKvmCPU : public BaseCPU
|
||||||
MasterPort &getInstPort() { return instPort; }
|
MasterPort &getInstPort() { return instPort; }
|
||||||
|
|
||||||
void wakeup();
|
void wakeup();
|
||||||
void activateContext(ThreadID thread_num, Cycles delay);
|
void activateContext(ThreadID thread_num);
|
||||||
void suspendContext(ThreadID thread_num);
|
void suspendContext(ThreadID thread_num);
|
||||||
void deallocateContext(ThreadID thread_num);
|
void deallocateContext(ThreadID thread_num);
|
||||||
void haltContext(ThreadID thread_num);
|
void haltContext(ThreadID thread_num);
|
||||||
|
|
|
@ -63,7 +63,6 @@ MinorCPU::MinorCPU(MinorCPUParams *params) :
|
||||||
}
|
}
|
||||||
|
|
||||||
threads.push_back(thread);
|
threads.push_back(thread);
|
||||||
threadActivateEvents.push_back(new ThreadActivateEvent(*this, 0));
|
|
||||||
|
|
||||||
thread->setStatus(ThreadContext::Halted);
|
thread->setStatus(ThreadContext::Halted);
|
||||||
|
|
||||||
|
@ -87,7 +86,6 @@ MinorCPU::~MinorCPU()
|
||||||
|
|
||||||
for (ThreadID thread_id = 0; thread_id < threads.size(); thread_id++) {
|
for (ThreadID thread_id = 0; thread_id < threads.size(); thread_id++) {
|
||||||
delete threads[thread_id];
|
delete threads[thread_id];
|
||||||
delete threadActivateEvents[thread_id];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +190,9 @@ MinorCPU::startup()
|
||||||
|
|
||||||
for (auto i = threads.begin(); i != threads.end(); i ++)
|
for (auto i = threads.begin(); i != threads.end(); i ++)
|
||||||
(*i)->startup();
|
(*i)->startup();
|
||||||
|
|
||||||
|
/* CPU state setup, activate initial context */
|
||||||
|
activateContext(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
|
@ -275,31 +276,20 @@ MinorCPU::takeOverFrom(BaseCPU *old_cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MinorCPU::activateContext(ThreadID thread_id, Cycles delay)
|
MinorCPU::activateContext(ThreadID thread_id)
|
||||||
{
|
{
|
||||||
DPRINTF(MinorCPU, "ActivateContext thread: %d delay: %d\n",
|
DPRINTF(MinorCPU, "ActivateContext thread: %d", thread_id);
|
||||||
thread_id, delay);
|
|
||||||
|
|
||||||
if (!threadActivateEvents[thread_id]->scheduled()) {
|
|
||||||
schedule(threadActivateEvents[thread_id], clockEdge(delay));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MinorCPU::ThreadActivateEvent::process()
|
|
||||||
{
|
|
||||||
DPRINTFS(MinorCPU, (&cpu), "Activating thread: %d\n", thread_id);
|
|
||||||
|
|
||||||
/* Do some cycle accounting. lastStopped is reset to stop the
|
/* Do some cycle accounting. lastStopped is reset to stop the
|
||||||
* wakeup call on the pipeline from adding the quiesce period
|
* wakeup call on the pipeline from adding the quiesce period
|
||||||
* to BaseCPU::numCycles */
|
* to BaseCPU::numCycles */
|
||||||
cpu.stats.quiesceCycles += cpu.pipeline->cyclesSinceLastStopped();
|
stats.quiesceCycles += pipeline->cyclesSinceLastStopped();
|
||||||
cpu.pipeline->resetLastStopped();
|
pipeline->resetLastStopped();
|
||||||
|
|
||||||
/* Wake up the thread, wakeup the pipeline tick */
|
/* Wake up the thread, wakeup the pipeline tick */
|
||||||
cpu.threads[thread_id]->activate();
|
threads[thread_id]->activate();
|
||||||
cpu.wakeupOnEvent(Minor::Pipeline::CPUStageId);
|
wakeupOnEvent(Minor::Pipeline::CPUStageId);
|
||||||
cpu.pipeline->wakeupFetch();
|
pipeline->wakeupFetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -78,23 +78,6 @@ typedef SimpleThread MinorThread;
|
||||||
class MinorCPU : public BaseCPU
|
class MinorCPU : public BaseCPU
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/** Event for delayed wakeup of a thread */
|
|
||||||
class ThreadActivateEvent : public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MinorCPU &cpu;
|
|
||||||
ThreadID thread_id;
|
|
||||||
|
|
||||||
ThreadActivateEvent(MinorCPU &cpu_, ThreadID thread_id_) :
|
|
||||||
cpu(cpu_), thread_id(thread_id_)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void process();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Events to wakeup each thread */
|
|
||||||
std::vector<ThreadActivateEvent *> threadActivateEvents;
|
|
||||||
|
|
||||||
/** pipeline is a container for the clockable pipeline stage objects.
|
/** pipeline is a container for the clockable pipeline stage objects.
|
||||||
* Elements of pipeline call TheISA to implement the model. */
|
* Elements of pipeline call TheISA to implement the model. */
|
||||||
Minor::Pipeline *pipeline;
|
Minor::Pipeline *pipeline;
|
||||||
|
@ -184,7 +167,7 @@ class MinorCPU : public BaseCPU
|
||||||
void takeOverFrom(BaseCPU *old_cpu);
|
void takeOverFrom(BaseCPU *old_cpu);
|
||||||
|
|
||||||
/** Thread activation interface from BaseCPU. */
|
/** Thread activation interface from BaseCPU. */
|
||||||
void activateContext(ThreadID thread_id, Cycles delay);
|
void activateContext(ThreadID thread_id);
|
||||||
void suspendContext(ThreadID thread_id);
|
void suspendContext(ThreadID thread_id);
|
||||||
|
|
||||||
/** Interface for stages to signal that they have become active after
|
/** Interface for stages to signal that they have become active after
|
||||||
|
|
|
@ -147,67 +147,6 @@ FullO3CPU<Impl>::TickEvent::description() const
|
||||||
return "FullO3CPU tick";
|
return "FullO3CPU tick";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
FullO3CPU<Impl>::ActivateThreadEvent::ActivateThreadEvent()
|
|
||||||
: Event(CPU_Switch_Pri)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::ActivateThreadEvent::init(int thread_num,
|
|
||||||
FullO3CPU<Impl> *thread_cpu)
|
|
||||||
{
|
|
||||||
tid = thread_num;
|
|
||||||
cpu = thread_cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::ActivateThreadEvent::process()
|
|
||||||
{
|
|
||||||
cpu->activateThread(tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
const char *
|
|
||||||
FullO3CPU<Impl>::ActivateThreadEvent::description() const
|
|
||||||
{
|
|
||||||
return "FullO3CPU \"Activate Thread\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
FullO3CPU<Impl>::DeallocateContextEvent::DeallocateContextEvent()
|
|
||||||
: Event(CPU_Tick_Pri), tid(0), remove(false), cpu(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::DeallocateContextEvent::init(int thread_num,
|
|
||||||
FullO3CPU<Impl> *thread_cpu)
|
|
||||||
{
|
|
||||||
tid = thread_num;
|
|
||||||
cpu = thread_cpu;
|
|
||||||
remove = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::DeallocateContextEvent::process()
|
|
||||||
{
|
|
||||||
cpu->deactivateThread(tid);
|
|
||||||
if (remove)
|
|
||||||
cpu->removeThread(tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
const char *
|
|
||||||
FullO3CPU<Impl>::DeallocateContextEvent::description() const
|
|
||||||
{
|
|
||||||
return "FullO3CPU \"Deallocate Context\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||||
: BaseO3CPU(params),
|
: BaseO3CPU(params),
|
||||||
|
@ -346,9 +285,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||||
|
|
||||||
renameMap[tid].init(®File, TheISA::ZeroReg, fpZeroReg,
|
renameMap[tid].init(®File, TheISA::ZeroReg, fpZeroReg,
|
||||||
&freeList);
|
&freeList);
|
||||||
|
|
||||||
activateThreadEvent[tid].init(tid, this);
|
|
||||||
deallocateContextEvent[tid].init(tid, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize rename map to assign physical registers to the
|
// Initialize rename map to assign physical registers to the
|
||||||
|
@ -389,7 +325,6 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
|
||||||
globalSeqNum[tid] = 1;
|
globalSeqNum[tid] = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
contextSwitch = false;
|
|
||||||
DPRINTF(O3CPU, "Creating O3CPU object.\n");
|
DPRINTF(O3CPU, "Creating O3CPU object.\n");
|
||||||
|
|
||||||
// Setup any thread state.
|
// Setup any thread state.
|
||||||
|
@ -613,9 +548,6 @@ FullO3CPU<Impl>::tick()
|
||||||
|
|
||||||
commit.tick();
|
commit.tick();
|
||||||
|
|
||||||
if (!FullSystem)
|
|
||||||
doContextSwitch();
|
|
||||||
|
|
||||||
// Now advance the time buffers
|
// Now advance the time buffers
|
||||||
timeBuffer.advance();
|
timeBuffer.advance();
|
||||||
|
|
||||||
|
@ -761,18 +693,12 @@ FullO3CPU<Impl>::totalOps() const
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::activateContext(ThreadID tid, Cycles delay)
|
FullO3CPU<Impl>::activateContext(ThreadID tid)
|
||||||
{
|
{
|
||||||
assert(!switchedOut());
|
assert(!switchedOut());
|
||||||
|
|
||||||
// Needs to set each stage to running as well.
|
// Needs to set each stage to running as well.
|
||||||
if (delay){
|
activateThread(tid);
|
||||||
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
|
|
||||||
"on cycle %d\n", tid, clockEdge(delay));
|
|
||||||
scheduleActivateThreadEvent(tid, delay);
|
|
||||||
} else {
|
|
||||||
activateThread(tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't want to wake the CPU if it is drained. In that case,
|
// We don't want to wake the CPU if it is drained. In that case,
|
||||||
// we just want to flag the thread as active and schedule the tick
|
// we just want to flag the thread as active and schedule the tick
|
||||||
|
@ -783,7 +709,7 @@ FullO3CPU<Impl>::activateContext(ThreadID tid, Cycles delay)
|
||||||
// If we are time 0 or if the last activation time is in the past,
|
// If we are time 0 or if the last activation time is in the past,
|
||||||
// schedule the next tick and wake up the fetch unit
|
// schedule the next tick and wake up the fetch unit
|
||||||
if (lastActivatedCycle == 0 || lastActivatedCycle < curTick()) {
|
if (lastActivatedCycle == 0 || lastActivatedCycle < curTick()) {
|
||||||
scheduleTickEvent(delay);
|
scheduleTickEvent(Cycles(0));
|
||||||
|
|
||||||
// Be sure to signal that there's some activity so the CPU doesn't
|
// Be sure to signal that there's some activity so the CPU doesn't
|
||||||
// deschedule itself.
|
// deschedule itself.
|
||||||
|
@ -803,22 +729,12 @@ FullO3CPU<Impl>::activateContext(ThreadID tid, Cycles delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
bool
|
void
|
||||||
FullO3CPU<Impl>::scheduleDeallocateContext(ThreadID tid, bool remove,
|
FullO3CPU<Impl>::deallocateContext(ThreadID tid, bool remove)
|
||||||
Cycles delay)
|
|
||||||
{
|
{
|
||||||
// Schedule removal of thread data from CPU
|
deactivateThread(tid);
|
||||||
if (delay){
|
if (remove)
|
||||||
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate "
|
removeThread(tid);
|
||||||
"on tick %d\n", tid, clockEdge(delay));
|
|
||||||
scheduleDeallocateContextEvent(tid, remove, delay);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
deactivateThread(tid);
|
|
||||||
if (remove)
|
|
||||||
removeThread(tid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -827,10 +743,10 @@ FullO3CPU<Impl>::suspendContext(ThreadID tid)
|
||||||
{
|
{
|
||||||
DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
|
DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
|
||||||
assert(!switchedOut());
|
assert(!switchedOut());
|
||||||
bool deallocated = scheduleDeallocateContext(tid, false, Cycles(1));
|
deallocateContext(tid, false);
|
||||||
|
|
||||||
// If this was the last thread then unschedule the tick event.
|
// If this was the last thread then unschedule the tick event.
|
||||||
if ((activeThreads.size() == 1 && !deallocated) ||
|
if (activeThreads.size() == 0)
|
||||||
activeThreads.size() == 0)
|
|
||||||
unscheduleTickEvent();
|
unscheduleTickEvent();
|
||||||
|
|
||||||
DPRINTF(Quiesce, "Suspending Context\n");
|
DPRINTF(Quiesce, "Suspending Context\n");
|
||||||
|
@ -845,7 +761,7 @@ FullO3CPU<Impl>::haltContext(ThreadID tid)
|
||||||
//For now, this is the same as deallocate
|
//For now, this is the same as deallocate
|
||||||
DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
|
DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
|
||||||
assert(!switchedOut());
|
assert(!switchedOut());
|
||||||
scheduleDeallocateContext(tid, true, Cycles(1));
|
deallocateContext(tid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -896,7 +812,7 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
|
||||||
|
|
||||||
src_tc->setStatus(ThreadContext::Active);
|
src_tc->setStatus(ThreadContext::Active);
|
||||||
|
|
||||||
activateContext(tid, Cycles(1));
|
activateContext(tid);
|
||||||
|
|
||||||
//Reset ROB/IQ/LSQ Entries
|
//Reset ROB/IQ/LSQ Entries
|
||||||
commit.rob->resetEntries();
|
commit.rob->resetEntries();
|
||||||
|
@ -973,77 +889,6 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::activateWhenReady(ThreadID tid)
|
|
||||||
{
|
|
||||||
DPRINTF(O3CPU,"[tid:%i]: Checking if resources are available for incoming"
|
|
||||||
"(e.g. PhysRegs/ROB/IQ/LSQ) \n",
|
|
||||||
tid);
|
|
||||||
|
|
||||||
bool ready = true;
|
|
||||||
|
|
||||||
// Should these all be '<' not '>='? This seems backwards...
|
|
||||||
if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"Phys. Int. Regs.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
} else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"Phys. Float. Regs.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
} else if (freeList.numFreeCCRegs() >= TheISA::NumCCRegs) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"Phys. CC. Regs.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
} else if (commit.rob->numFreeEntries() >=
|
|
||||||
commit.rob->entryAmount(activeThreads.size() + 1)) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"ROB entries.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
} else if (iew.instQueue.numFreeEntries() >=
|
|
||||||
iew.instQueue.entryAmount(activeThreads.size() + 1)) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"IQ entries.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
} else if (iew.ldstQueue.numFreeLoadEntries() >=
|
|
||||||
iew.ldstQueue.entryAmount(activeThreads.size() + 1)) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"LQ entries.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
} else if (iew.ldstQueue.numFreeStoreEntries() >=
|
|
||||||
iew.ldstQueue.entryAmount(activeThreads.size() + 1)) {
|
|
||||||
DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough "
|
|
||||||
"SQ entries.\n",
|
|
||||||
tid);
|
|
||||||
ready = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ready) {
|
|
||||||
insertThread(tid);
|
|
||||||
|
|
||||||
contextSwitch = false;
|
|
||||||
|
|
||||||
cpuWaitList.remove(tid);
|
|
||||||
} else {
|
|
||||||
suspendContext(tid);
|
|
||||||
|
|
||||||
//blocks fetch
|
|
||||||
contextSwitch = true;
|
|
||||||
|
|
||||||
//@todo: dont always add to waitlist
|
|
||||||
//do waitlist
|
|
||||||
cpuWaitList.push_back(tid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
Fault
|
Fault
|
||||||
FullO3CPU<Impl>::hwrei(ThreadID tid)
|
FullO3CPU<Impl>::hwrei(ThreadID tid)
|
||||||
|
@ -1243,19 +1088,6 @@ FullO3CPU<Impl>::isDrained() const
|
||||||
{
|
{
|
||||||
bool drained(true);
|
bool drained(true);
|
||||||
|
|
||||||
for (ThreadID i = 0; i < thread.size(); ++i) {
|
|
||||||
if (activateThreadEvent[i].scheduled()) {
|
|
||||||
DPRINTF(Drain, "CPU not drained, tread %i has a "
|
|
||||||
"pending activate event\n", i);
|
|
||||||
drained = false;
|
|
||||||
}
|
|
||||||
if (deallocateContextEvent[i].scheduled()) {
|
|
||||||
DPRINTF(Drain, "CPU not drained, tread %i has a "
|
|
||||||
"pending deallocate context event\n", i);
|
|
||||||
drained = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!instList.empty() || !removeList.empty()) {
|
if (!instList.empty() || !removeList.empty()) {
|
||||||
DPRINTF(Drain, "Main CPU structures not drained.\n");
|
DPRINTF(Drain, "Main CPU structures not drained.\n");
|
||||||
drained = false;
|
drained = false;
|
||||||
|
@ -1830,24 +1662,6 @@ FullO3CPU<Impl>::getFreeTid()
|
||||||
return InvalidThreadID;
|
return InvalidThreadID;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
void
|
|
||||||
FullO3CPU<Impl>::doContextSwitch()
|
|
||||||
{
|
|
||||||
if (contextSwitch) {
|
|
||||||
|
|
||||||
//ADD CODE TO DEACTIVE THREAD HERE (???)
|
|
||||||
|
|
||||||
ThreadID size = cpuWaitList.size();
|
|
||||||
for (ThreadID tid = 0; tid < size; tid++) {
|
|
||||||
activateWhenReady(tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpuWaitList.size() == 0)
|
|
||||||
contextSwitch = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::updateThreadPriority()
|
FullO3CPU<Impl>::updateThreadPriority()
|
||||||
|
|
|
@ -229,116 +229,6 @@ class FullO3CPU : public BaseO3CPU
|
||||||
tickEvent.squash();
|
tickEvent.squash();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActivateThreadEvent : public Event
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/** Number of Thread to Activate */
|
|
||||||
ThreadID tid;
|
|
||||||
|
|
||||||
/** Pointer to the CPU. */
|
|
||||||
FullO3CPU<Impl> *cpu;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Constructs the event. */
|
|
||||||
ActivateThreadEvent();
|
|
||||||
|
|
||||||
/** 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() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Schedule thread to activate , regardless of its current state. */
|
|
||||||
void
|
|
||||||
scheduleActivateThreadEvent(ThreadID tid, Cycles delay)
|
|
||||||
{
|
|
||||||
// Schedule thread to activate, regardless of its current state.
|
|
||||||
if (activateThreadEvent[tid].squashed())
|
|
||||||
reschedule(activateThreadEvent[tid],
|
|
||||||
clockEdge(delay));
|
|
||||||
else if (!activateThreadEvent[tid].scheduled()) {
|
|
||||||
Tick when = clockEdge(delay);
|
|
||||||
|
|
||||||
// Check if the deallocateEvent is also scheduled, and make
|
|
||||||
// sure they do not happen at same time causing a sleep that
|
|
||||||
// is never woken from.
|
|
||||||
if (deallocateContextEvent[tid].scheduled() &&
|
|
||||||
deallocateContextEvent[tid].when() == when) {
|
|
||||||
when++;
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule(activateThreadEvent[tid], when);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Unschedule actiavte thread event, regardless of its current state. */
|
|
||||||
void
|
|
||||||
unscheduleActivateThreadEvent(ThreadID tid)
|
|
||||||
{
|
|
||||||
if (activateThreadEvent[tid].scheduled())
|
|
||||||
activateThreadEvent[tid].squash();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The tick event used for scheduling CPU ticks. */
|
|
||||||
ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
|
|
||||||
|
|
||||||
class DeallocateContextEvent : public Event
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/** Number of Thread to deactivate */
|
|
||||||
ThreadID tid;
|
|
||||||
|
|
||||||
/** Should the thread be removed from the CPU? */
|
|
||||||
bool remove;
|
|
||||||
|
|
||||||
/** 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();
|
|
||||||
|
|
||||||
/** Sets whether the thread should also be removed from the CPU. */
|
|
||||||
void setRemove(bool _remove) { remove = _remove; }
|
|
||||||
|
|
||||||
/** Returns the description of the event. */
|
|
||||||
const char *description() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Schedule cpu to deallocate thread context.*/
|
|
||||||
void
|
|
||||||
scheduleDeallocateContextEvent(ThreadID tid, bool remove, Cycles delay)
|
|
||||||
{
|
|
||||||
// Schedule thread to activate, regardless of its current state.
|
|
||||||
if (deallocateContextEvent[tid].squashed())
|
|
||||||
reschedule(deallocateContextEvent[tid],
|
|
||||||
clockEdge(delay));
|
|
||||||
else if (!deallocateContextEvent[tid].scheduled())
|
|
||||||
schedule(deallocateContextEvent[tid],
|
|
||||||
clockEdge(delay));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Unschedule thread deallocation in CPU */
|
|
||||||
void
|
|
||||||
unscheduleDeallocateContextEvent(ThreadID tid)
|
|
||||||
{
|
|
||||||
if (deallocateContextEvent[tid].scheduled())
|
|
||||||
deallocateContextEvent[tid].squash();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The tick event used for scheduling CPU ticks. */
|
|
||||||
DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the pipeline has drained and signal the DrainManager.
|
* Check if the pipeline has drained and signal the DrainManager.
|
||||||
*
|
*
|
||||||
|
@ -430,7 +320,7 @@ class FullO3CPU : public BaseO3CPU
|
||||||
virtual Counter totalOps() const;
|
virtual Counter totalOps() const;
|
||||||
|
|
||||||
/** Add Thread to Active Threads List. */
|
/** Add Thread to Active Threads List. */
|
||||||
void activateContext(ThreadID tid, Cycles delay);
|
void activateContext(ThreadID tid);
|
||||||
|
|
||||||
/** Remove Thread from Active Threads List */
|
/** Remove Thread from Active Threads List */
|
||||||
void suspendContext(ThreadID tid);
|
void suspendContext(ThreadID tid);
|
||||||
|
@ -438,20 +328,13 @@ class FullO3CPU : public BaseO3CPU
|
||||||
/** Remove Thread from Active Threads List &&
|
/** Remove Thread from Active Threads List &&
|
||||||
* Possibly Remove Thread Context from CPU.
|
* Possibly Remove Thread Context from CPU.
|
||||||
*/
|
*/
|
||||||
bool scheduleDeallocateContext(ThreadID tid, bool remove,
|
void deallocateContext(ThreadID tid, bool remove);
|
||||||
Cycles delay = Cycles(1));
|
|
||||||
|
|
||||||
/** Remove Thread from Active Threads List &&
|
/** Remove Thread from Active Threads List &&
|
||||||
* Remove Thread Context from CPU.
|
* Remove Thread Context from CPU.
|
||||||
*/
|
*/
|
||||||
void haltContext(ThreadID tid);
|
void haltContext(ThreadID tid);
|
||||||
|
|
||||||
/** Activate a Thread When CPU Resources are Available. */
|
|
||||||
void activateWhenReady(ThreadID tid);
|
|
||||||
|
|
||||||
/** Add or Remove a Thread Context in the CPU. */
|
|
||||||
void doContextSwitch();
|
|
||||||
|
|
||||||
/** Update The Order In Which We Process Threads. */
|
/** Update The Order In Which We Process Threads. */
|
||||||
void updateThreadPriority();
|
void updateThreadPriority();
|
||||||
|
|
||||||
|
@ -792,9 +675,6 @@ class FullO3CPU : public BaseO3CPU
|
||||||
/** Pointers to all of the threads in the CPU. */
|
/** Pointers to all of the threads in the CPU. */
|
||||||
std::vector<Thread *> thread;
|
std::vector<Thread *> thread;
|
||||||
|
|
||||||
/** Is there a context switch pending? */
|
|
||||||
bool contextSwitch;
|
|
||||||
|
|
||||||
/** Threads Scheduled to Enter CPU */
|
/** Threads Scheduled to Enter CPU */
|
||||||
std::list<int> cpuWaitList;
|
std::list<int> cpuWaitList;
|
||||||
|
|
||||||
|
|
|
@ -811,10 +811,7 @@ DefaultFetch<Impl>::checkStall(ThreadID tid) const
|
||||||
{
|
{
|
||||||
bool ret_val = false;
|
bool ret_val = false;
|
||||||
|
|
||||||
if (cpu->contextSwitch) {
|
if (stalls[tid].drain) {
|
||||||
DPRINTF(Fetch,"[tid:%i]: Stalling for a context switch.\n",tid);
|
|
||||||
ret_val = true;
|
|
||||||
} else if (stalls[tid].drain) {
|
|
||||||
assert(cpu->isDraining());
|
assert(cpu->isDraining());
|
||||||
DPRINTF(Fetch,"[tid:%i]: Drain stall detected.\n",tid);
|
DPRINTF(Fetch,"[tid:%i]: Drain stall detected.\n",tid);
|
||||||
ret_val = true;
|
ret_val = true;
|
||||||
|
@ -970,9 +967,8 @@ DefaultFetch<Impl>::tick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there was activity this cycle, inform the CPU of it.
|
// If there was activity this cycle, inform the CPU of it.
|
||||||
if (wroteToTimeBuffer || cpu->contextSwitch) {
|
if (wroteToTimeBuffer) {
|
||||||
DPRINTF(Activity, "Activity this cycle.\n");
|
DPRINTF(Activity, "Activity this cycle.\n");
|
||||||
|
|
||||||
cpu->activityThisCycle();
|
cpu->activityThisCycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,15 +136,14 @@ class O3ThreadContext : public ThreadContext
|
||||||
virtual void setStatus(Status new_status)
|
virtual void setStatus(Status new_status)
|
||||||
{ thread->setStatus(new_status); }
|
{ thread->setStatus(new_status); }
|
||||||
|
|
||||||
/** Set the status to Active. Optional delay indicates number of
|
/** Set the status to Active. */
|
||||||
* cycles to wait before beginning execution. */
|
virtual void activate();
|
||||||
virtual void activate(Cycles delay = Cycles(1));
|
|
||||||
|
|
||||||
/** Set the status to Suspended. */
|
/** Set the status to Suspended. */
|
||||||
virtual void suspend(Cycles delay = Cycles(0));
|
virtual void suspend();
|
||||||
|
|
||||||
/** Set the status to Halted. */
|
/** Set the status to Halted. */
|
||||||
virtual void halt(Cycles delay = Cycles(0));
|
virtual void halt();
|
||||||
|
|
||||||
/** Dumps the function profiling information.
|
/** Dumps the function profiling information.
|
||||||
* @todo: Implement.
|
* @todo: Implement.
|
||||||
|
|
|
@ -84,7 +84,7 @@ O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::activate(Cycles delay)
|
O3ThreadContext<Impl>::activate()
|
||||||
{
|
{
|
||||||
DPRINTF(O3CPU, "Calling activate on Thread Context %d\n",
|
DPRINTF(O3CPU, "Calling activate on Thread Context %d\n",
|
||||||
threadId());
|
threadId());
|
||||||
|
@ -96,12 +96,12 @@ O3ThreadContext<Impl>::activate(Cycles delay)
|
||||||
thread->setStatus(ThreadContext::Active);
|
thread->setStatus(ThreadContext::Active);
|
||||||
|
|
||||||
// status() == Suspended
|
// status() == Suspended
|
||||||
cpu->activateContext(thread->threadId(), delay);
|
cpu->activateContext(thread->threadId());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::suspend(Cycles delay)
|
O3ThreadContext<Impl>::suspend()
|
||||||
{
|
{
|
||||||
DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n",
|
DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n",
|
||||||
threadId());
|
threadId());
|
||||||
|
@ -118,10 +118,9 @@ O3ThreadContext<Impl>::suspend(Cycles delay)
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
O3ThreadContext<Impl>::halt(Cycles delay)
|
O3ThreadContext<Impl>::halt()
|
||||||
{
|
{
|
||||||
DPRINTF(O3CPU, "Calling halt on Thread Context %d\n",
|
DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", threadId());
|
||||||
threadId());
|
|
||||||
|
|
||||||
if (thread->status() == ThreadContext::Halted)
|
if (thread->status() == ThreadContext::Halted)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -222,9 +222,9 @@ AtomicSimpleCPU::verifyMemoryMode() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AtomicSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
AtomicSimpleCPU::activateContext(ThreadID thread_num)
|
||||||
{
|
{
|
||||||
DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);
|
DPRINTF(SimpleCPU, "ActivateContext %d\n", thread_num);
|
||||||
|
|
||||||
assert(thread_num == 0);
|
assert(thread_num == 0);
|
||||||
assert(thread);
|
assert(thread);
|
||||||
|
@ -236,7 +236,7 @@ AtomicSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
||||||
numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend);
|
numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend);
|
||||||
|
|
||||||
//Make sure ticks are still on multiples of cycles
|
//Make sure ticks are still on multiples of cycles
|
||||||
schedule(tickEvent, clockEdge(delay));
|
schedule(tickEvent, clockEdge(Cycles(0)));
|
||||||
_status = BaseSimpleCPU::Running;
|
_status = BaseSimpleCPU::Running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
|
|
||||||
void verifyMemoryMode() const;
|
void verifyMemoryMode() const;
|
||||||
|
|
||||||
virtual void activateContext(ThreadID thread_num, Cycles delay);
|
virtual void activateContext(ThreadID thread_num);
|
||||||
virtual void suspendContext(ThreadID thread_num);
|
virtual void suspendContext(ThreadID thread_num);
|
||||||
|
|
||||||
Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
|
Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
|
||||||
|
|
|
@ -200,9 +200,9 @@ TimingSimpleCPU::verifyMemoryMode() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
TimingSimpleCPU::activateContext(ThreadID thread_num)
|
||||||
{
|
{
|
||||||
DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);
|
DPRINTF(SimpleCPU, "ActivateContext %d\n", thread_num);
|
||||||
|
|
||||||
assert(thread_num == 0);
|
assert(thread_num == 0);
|
||||||
assert(thread);
|
assert(thread);
|
||||||
|
@ -213,7 +213,7 @@ TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
||||||
_status = BaseSimpleCPU::Running;
|
_status = BaseSimpleCPU::Running;
|
||||||
|
|
||||||
// kick things off by initiating the fetch of the next instruction
|
// kick things off by initiating the fetch of the next instruction
|
||||||
schedule(fetchEvent, clockEdge(delay));
|
schedule(fetchEvent, clockEdge(Cycles(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||||
|
|
||||||
void verifyMemoryMode() const;
|
void verifyMemoryMode() const;
|
||||||
|
|
||||||
virtual void activateContext(ThreadID thread_num, Cycles delay);
|
virtual void activateContext(ThreadID thread_num);
|
||||||
virtual void suspendContext(ThreadID thread_num);
|
virtual void suspendContext(ThreadID thread_num);
|
||||||
|
|
||||||
Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
|
Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
|
||||||
|
|
|
@ -159,22 +159,14 @@ SimpleThread::dumpFuncProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimpleThread::activate(Cycles delay)
|
SimpleThread::activate()
|
||||||
{
|
{
|
||||||
if (status() == ThreadContext::Active)
|
if (status() == ThreadContext::Active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lastActivate = curTick();
|
lastActivate = curTick();
|
||||||
|
|
||||||
// if (status() == ThreadContext::Unallocated) {
|
|
||||||
// cpu->activateWhenReady(_threadId);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
_status = ThreadContext::Active;
|
_status = ThreadContext::Active;
|
||||||
|
baseCpu->activateContext(_threadId);
|
||||||
// status() == Suspended
|
|
||||||
baseCpu->activateContext(_threadId, delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -211,9 +211,8 @@ class SimpleThread : public ThreadState
|
||||||
|
|
||||||
void setStatus(Status newStatus) { _status = newStatus; }
|
void setStatus(Status newStatus) { _status = newStatus; }
|
||||||
|
|
||||||
/// Set the status to Active. Optional delay indicates number of
|
/// Set the status to Active.
|
||||||
/// cycles to wait before beginning execution.
|
void activate();
|
||||||
void activate(Cycles delay = Cycles(1));
|
|
||||||
|
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend();
|
void suspend();
|
||||||
|
|
|
@ -165,15 +165,14 @@ class ThreadContext
|
||||||
|
|
||||||
virtual void setStatus(Status new_status) = 0;
|
virtual void setStatus(Status new_status) = 0;
|
||||||
|
|
||||||
/// Set the status to Active. Optional delay indicates number of
|
/// Set the status to Active.
|
||||||
/// cycles to wait before beginning execution.
|
virtual void activate() = 0;
|
||||||
virtual void activate(Cycles delay = Cycles(1)) = 0;
|
|
||||||
|
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
virtual void suspend(Cycles delay = Cycles(0)) = 0;
|
virtual void suspend() = 0;
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
virtual void halt(Cycles delay = Cycles(0)) = 0;
|
virtual void halt() = 0;
|
||||||
|
|
||||||
virtual void dumpFuncProfile() = 0;
|
virtual void dumpFuncProfile() = 0;
|
||||||
|
|
||||||
|
@ -362,16 +361,14 @@ class ProxyThreadContext : public ThreadContext
|
||||||
|
|
||||||
void setStatus(Status new_status) { actualTC->setStatus(new_status); }
|
void setStatus(Status new_status) { actualTC->setStatus(new_status); }
|
||||||
|
|
||||||
/// Set the status to Active. Optional delay indicates number of
|
/// Set the status to Active.
|
||||||
/// cycles to wait before beginning execution.
|
void activate() { actualTC->activate(); }
|
||||||
void activate(Cycles delay = Cycles(1))
|
|
||||||
{ actualTC->activate(delay); }
|
|
||||||
|
|
||||||
/// Set the status to Suspended.
|
/// Set the status to Suspended.
|
||||||
void suspend(Cycles delay = Cycles(0)) { actualTC->suspend(); }
|
void suspend() { actualTC->suspend(); }
|
||||||
|
|
||||||
/// Set the status to Halted.
|
/// Set the status to Halted.
|
||||||
void halt(Cycles delay = Cycles(0)) { actualTC->halt(); }
|
void halt() { actualTC->halt(); }
|
||||||
|
|
||||||
void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
|
void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ Process::initState()
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
|
|
||||||
// mark this context as active so it will start ticking.
|
// mark this context as active so it will start ticking.
|
||||||
tc->activate(Cycles(0));
|
tc->activate();
|
||||||
|
|
||||||
pTable->initState(tc);
|
pTable->initState(tc);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue