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:
Korey Sewell 2006-07-07 04:06:26 -04:00
parent e60f998e29
commit c355df5bfe
8 changed files with 218 additions and 122 deletions

View file

@ -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
}
};

View file

@ -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

View file

@ -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()

View file

@ -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.

View file

@ -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();

View file

@ -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;

View file

@ -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(); }

View file

@ -27,7 +27,6 @@
*
* Authors: Steve Reinhardt
* Kevin Lim
* Korey Sewell
*/
#ifndef __SIM_SYSCALL_EMUL_HH__