Fix so that O3CPU doesnt segfault on exit.
Major thing was to not execute commit if there are no active threads in CPU. src/cpu/o3/alpha/thread_context.hh: call deallocate instead of deallocateContext src/cpu/o3/commit_impl.hh: dont run commit stage if there are no instructions src/cpu/o3/cpu.cc: add deallocate event, deactivateThread function, and edit deallocateContext. src/cpu/o3/cpu.hh: add deallocate event and add optional delay to deallocateContext src/cpu/o3/thread_context.hh: optional delay for deallocate src/cpu/o3/thread_context_impl.hh: edit DPRINTFs to say Thread Context instead of Alpha TC src/cpu/thread_context.hh: optional delay src/sim/syscall_emul.hh: name stuff --HG-- extra : convert_revision : f4033e1f66b3043d30ad98dcc70d8b193dea70b6
This commit is contained in:
parent
e60f998e29
commit
c355df5bfe
8 changed files with 218 additions and 122 deletions
|
@ -70,18 +70,19 @@ class AlphaTC : public O3ThreadContext<Impl>
|
|||
{ 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.
|
||||
/** 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());
|
||||
this->deallocate();
|
||||
|
||||
// If there are still threads executing in the system
|
||||
if (this->cpu->numActiveThreads())
|
||||
return 0;
|
||||
return 0; // don't exit simulation
|
||||
else
|
||||
return 1;
|
||||
return 1; // exit simulation
|
||||
}
|
||||
};
|
||||
|
|
|
@ -562,6 +562,9 @@ DefaultCommit<Impl>::tick()
|
|||
return;
|
||||
}
|
||||
|
||||
if ((*activeThreads).size() <= 0)
|
||||
return;
|
||||
|
||||
list<unsigned>::iterator threads = (*activeThreads).begin();
|
||||
|
||||
// Check if any of the threads are done squashing. Change the
|
||||
|
|
|
@ -114,6 +114,36 @@ FullO3CPU<Impl>::ActivateThreadEvent::description()
|
|||
return "FullO3CPU \"Activate Thread\" event";
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::DeallocateContextEvent::DeallocateContextEvent()
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::DeallocateContextEvent::init(int thread_num,
|
||||
FullO3CPU<Impl> *thread_cpu)
|
||||
{
|
||||
tid = thread_num;
|
||||
cpu = thread_cpu;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::DeallocateContextEvent::process()
|
||||
{
|
||||
cpu->deactivateThread(tid);
|
||||
cpu->removeThread(tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
const char *
|
||||
FullO3CPU<Impl>::DeallocateContextEvent::description()
|
||||
{
|
||||
return "FullO3CPU \"Deallocate Context\" event";
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::FullO3CPU(Params *params)
|
||||
: BaseO3CPU(params),
|
||||
|
@ -459,6 +489,118 @@ FullO3CPU<Impl>::init()
|
|||
commit.setThreads(thread);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::activateThread(unsigned tid)
|
||||
{
|
||||
list<unsigned>::iterator isActive = find(
|
||||
activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (isActive == activeThreads.end()) {
|
||||
DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
|
||||
tid);
|
||||
|
||||
activeThreads.push_back(tid);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::deactivateThread(unsigned tid)
|
||||
{
|
||||
//Remove From Active List, if Active
|
||||
list<unsigned>::iterator thread_it =
|
||||
find(activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (thread_it != activeThreads.end()) {
|
||||
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
|
||||
tid);
|
||||
activeThreads.erase(thread_it);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::activateContext(int tid, int delay)
|
||||
{
|
||||
// Needs to set each stage to running as well.
|
||||
if (delay){
|
||||
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
|
||||
"on cycle %d\n", tid, curTick + cycles(delay));
|
||||
scheduleActivateThreadEvent(tid, delay);
|
||||
} else {
|
||||
activateThread(tid);
|
||||
}
|
||||
|
||||
if(lastActivatedCycle < curTick) {
|
||||
scheduleTickEvent(delay);
|
||||
|
||||
// Be sure to signal that there's some activity so the CPU doesn't
|
||||
// deschedule itself.
|
||||
activityRec.activity();
|
||||
fetch.wakeFromQuiesce();
|
||||
|
||||
lastActivatedCycle = curTick;
|
||||
|
||||
_status = Running;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::deallocateContext(int tid, int delay)
|
||||
{
|
||||
// Schedule removal of thread data from CPU
|
||||
if (delay){
|
||||
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate "
|
||||
"on cycle %d\n", tid, curTick + cycles(delay));
|
||||
scheduleDeallocateContextEvent(tid, delay);
|
||||
} else {
|
||||
deactivateThread(tid);
|
||||
removeThread(tid);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::suspendContext(int tid)
|
||||
{
|
||||
DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
|
||||
unscheduleTickEvent();
|
||||
_status = Idle;
|
||||
/*
|
||||
//Remove From Active List, if Active
|
||||
list<unsigned>::iterator isActive = find(
|
||||
activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (isActive != activeThreads.end()) {
|
||||
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
|
||||
tid);
|
||||
activeThreads.erase(isActive);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::haltContext(int tid)
|
||||
{
|
||||
DPRINTF(O3CPU,"[tid:%i]: Halting Thread Context", tid);
|
||||
/*
|
||||
//Remove From Active List, if Active
|
||||
list<unsigned>::iterator isActive = find(
|
||||
activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (isActive != activeThreads.end()) {
|
||||
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
|
||||
tid);
|
||||
activeThreads.erase(isActive);
|
||||
|
||||
removeThread(tid);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::insertThread(unsigned tid)
|
||||
|
@ -511,7 +653,7 @@ template <class Impl>
|
|||
void
|
||||
FullO3CPU<Impl>::removeThread(unsigned tid)
|
||||
{
|
||||
DPRINTF(O3CPU,"[tid:%i] Removing thread from CPU.");
|
||||
DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.");
|
||||
|
||||
// Copy Thread Data From RegFile
|
||||
// If thread is suspended, it might be re-allocated
|
||||
|
@ -537,6 +679,8 @@ FullO3CPU<Impl>::removeThread(unsigned tid)
|
|||
fetch.squash(0,tid);
|
||||
decode.squash(tid);
|
||||
rename.squash(tid);
|
||||
iew.squash(tid);
|
||||
commit.rob->squash(commit.rob->readHeadInst(tid)->seqNum, tid);
|
||||
|
||||
assert(iew.ldstQueue.getCount(tid) == 0);
|
||||
|
||||
|
@ -600,113 +744,12 @@ FullO3CPU<Impl>::activateWhenReady(int tid)
|
|||
//blocks fetch
|
||||
contextSwitch = true;
|
||||
|
||||
//@todo: dont always add to waitlist
|
||||
//do waitlist
|
||||
cpuWaitList.push_back(tid);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::activateThread(unsigned int tid)
|
||||
{
|
||||
list<unsigned>::iterator isActive = find(
|
||||
activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (isActive == activeThreads.end()) {
|
||||
DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
|
||||
tid);
|
||||
|
||||
activeThreads.push_back(tid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::activateContext(int tid, int delay)
|
||||
{
|
||||
// Needs to set each stage to running as well.
|
||||
if (delay){
|
||||
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
|
||||
"on cycle %d\n", tid, curTick + cycles(delay));
|
||||
scheduleActivateThreadEvent(tid, delay);
|
||||
} else {
|
||||
activateThread(tid);
|
||||
}
|
||||
|
||||
if(lastActivatedCycle < curTick) {
|
||||
scheduleTickEvent(delay);
|
||||
|
||||
// Be sure to signal that there's some activity so the CPU doesn't
|
||||
// deschedule itself.
|
||||
activityRec.activity();
|
||||
fetch.wakeFromQuiesce();
|
||||
|
||||
lastActivatedCycle = curTick;
|
||||
|
||||
_status = Running;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::suspendContext(int tid)
|
||||
{
|
||||
DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
|
||||
unscheduleTickEvent();
|
||||
_status = Idle;
|
||||
/*
|
||||
//Remove From Active List, if Active
|
||||
list<unsigned>::iterator isActive = find(
|
||||
activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (isActive != activeThreads.end()) {
|
||||
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
|
||||
tid);
|
||||
activeThreads.erase(isActive);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::deallocateContext(int tid)
|
||||
{
|
||||
DPRINTF(O3CPU,"[tid:%i]: Deallocating Thread Context", tid);
|
||||
|
||||
//Remove From Active List, if Active
|
||||
list<unsigned>::iterator thread_it =
|
||||
find(activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (thread_it != activeThreads.end()) {
|
||||
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
|
||||
tid);
|
||||
activeThreads.erase(thread_it);
|
||||
|
||||
removeThread(tid);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::haltContext(int tid)
|
||||
{
|
||||
DPRINTF(O3CPU,"[tid:%i]: Halting Thread Context", tid);
|
||||
/*
|
||||
//Remove From Active List, if Active
|
||||
list<unsigned>::iterator isActive = find(
|
||||
activeThreads.begin(), activeThreads.end(), tid);
|
||||
|
||||
if (isActive != activeThreads.end()) {
|
||||
DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
|
||||
tid);
|
||||
activeThreads.erase(isActive);
|
||||
|
||||
removeThread(tid);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::switchOut()
|
||||
|
|
|
@ -197,6 +197,49 @@ class FullO3CPU : public BaseO3CPU
|
|||
/** The tick event used for scheduling CPU ticks. */
|
||||
ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
|
||||
|
||||
class DeallocateContextEvent : public Event
|
||||
{
|
||||
private:
|
||||
/** Number of Thread to Activate */
|
||||
int tid;
|
||||
|
||||
/** 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();
|
||||
|
||||
/** Returns the description of the event. */
|
||||
const char *description();
|
||||
};
|
||||
|
||||
/** Schedule cpu to deallocate thread context.*/
|
||||
void scheduleDeallocateContextEvent(int tid, int delay)
|
||||
{
|
||||
// Schedule thread to activate, regardless of its current state.
|
||||
if (deallocateContextEvent[tid].squashed())
|
||||
deallocateContextEvent[tid].reschedule(curTick + cycles(delay));
|
||||
else if (!deallocateContextEvent[tid].scheduled())
|
||||
deallocateContextEvent[tid].schedule(curTick + cycles(delay));
|
||||
}
|
||||
|
||||
/** Unschedule thread deallocation in CPU */
|
||||
void unscheduleDeallocateContextEvent(int tid)
|
||||
{
|
||||
if (deallocateContextEvent[tid].scheduled())
|
||||
deallocateContextEvent[tid].squash();
|
||||
}
|
||||
|
||||
/** The tick event used for scheduling CPU ticks. */
|
||||
DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
|
||||
|
||||
public:
|
||||
/** Constructs a CPU with the given parameters. */
|
||||
FullO3CPU(Params *params);
|
||||
|
@ -219,7 +262,10 @@ class FullO3CPU : public BaseO3CPU
|
|||
{ return activeThreads.size(); }
|
||||
|
||||
/** Add Thread to Active Threads List */
|
||||
void activateThread(unsigned int tid);
|
||||
void activateThread(unsigned tid);
|
||||
|
||||
/** Remove Thread from Active Threads List */
|
||||
void deactivateThread(unsigned tid);
|
||||
|
||||
/** Setup CPU to insert a thread's context */
|
||||
void insertThread(unsigned tid);
|
||||
|
@ -247,7 +293,7 @@ class FullO3CPU : public BaseO3CPU
|
|||
/** Remove Thread from Active Threads List &&
|
||||
* Remove Thread Context from CPU.
|
||||
*/
|
||||
void deallocateContext(int tid);
|
||||
void deallocateContext(int tid, int delay = 1);
|
||||
|
||||
/** Remove Thread from Active Threads List &&
|
||||
* Remove Thread Context from CPU.
|
||||
|
|
|
@ -112,7 +112,7 @@ class O3ThreadContext : public ThreadContext
|
|||
virtual void suspend();
|
||||
|
||||
/** Set the status to Unallocated. */
|
||||
virtual void deallocate();
|
||||
virtual void deallocate(int delay = 0);
|
||||
|
||||
/** Set the status to Halted. */
|
||||
virtual void halt();
|
||||
|
|
|
@ -115,7 +115,8 @@ template <class Impl>
|
|||
void
|
||||
O3ThreadContext<Impl>::activate(int delay)
|
||||
{
|
||||
DPRINTF(O3CPU, "Calling activate on AlphaTC\n");
|
||||
DPRINTF(O3CPU, "Calling activate on Thread Context %d\n",
|
||||
getThreadNum());
|
||||
|
||||
if (thread->status() == ThreadContext::Active)
|
||||
return;
|
||||
|
@ -139,7 +140,8 @@ template <class Impl>
|
|||
void
|
||||
O3ThreadContext<Impl>::suspend()
|
||||
{
|
||||
DPRINTF(O3CPU, "Calling suspend on AlphaTC\n");
|
||||
DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n",
|
||||
getThreadNum());
|
||||
|
||||
if (thread->status() == ThreadContext::Suspended)
|
||||
return;
|
||||
|
@ -163,22 +165,24 @@ O3ThreadContext<Impl>::suspend()
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::deallocate()
|
||||
O3ThreadContext<Impl>::deallocate(int delay)
|
||||
{
|
||||
DPRINTF(O3CPU, "Calling deallocate on AlphaTC\n");
|
||||
DPRINTF(O3CPU, "Calling deallocate on Thread Context %d\n",
|
||||
getThreadNum());
|
||||
|
||||
if (thread->status() == ThreadContext::Unallocated)
|
||||
return;
|
||||
|
||||
thread->setStatus(ThreadContext::Unallocated);
|
||||
cpu->deallocateContext(thread->readTid());
|
||||
cpu->deallocateContext(thread->readTid(), delay);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
O3ThreadContext<Impl>::halt()
|
||||
{
|
||||
DPRINTF(O3CPU, "Calling halt on AlphaTC\n");
|
||||
DPRINTF(O3CPU, "Calling halt on Thread Context %d\n",
|
||||
getThreadNum());
|
||||
|
||||
if (thread->status() == ThreadContext::Halted)
|
||||
return;
|
||||
|
|
|
@ -143,7 +143,7 @@ class ThreadContext
|
|||
virtual void suspend() = 0;
|
||||
|
||||
/// Set the status to Unallocated.
|
||||
virtual void deallocate() = 0;
|
||||
virtual void deallocate(int delay = 0) = 0;
|
||||
|
||||
/// Set the status to Halted.
|
||||
virtual void halt() = 0;
|
||||
|
@ -318,7 +318,7 @@ class ProxyThreadContext : public ThreadContext
|
|||
void suspend() { actualTC->suspend(); }
|
||||
|
||||
/// Set the status to Unallocated.
|
||||
void deallocate() { actualTC->deallocate(); }
|
||||
void deallocate(int delay = 0) { actualTC->deallocate(); }
|
||||
|
||||
/// Set the status to Halted.
|
||||
void halt() { actualTC->halt(); }
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
*
|
||||
* Authors: Steve Reinhardt
|
||||
* Kevin Lim
|
||||
* Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __SIM_SYSCALL_EMUL_HH__
|
||||
|
|
Loading…
Reference in a new issue