Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/newmem
into zizzer.eecs.umich.edu:/.automount/zooks/y/ksewell/research/m5-sim/newmem-o3 --HG-- extra : convert_revision : 9098d989832e2a5818b80771e3c02170c5c8cd5b
This commit is contained in:
commit
cdf27a0a86
|
@ -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
|
||||
}
|
||||
};
|
||||
|
|
|
@ -578,6 +578,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
|
||||
|
@ -591,7 +594,7 @@ DefaultCommit<Impl>::tick()
|
|||
commitStatus[tid] = Running;
|
||||
} else {
|
||||
DPRINTF(Commit,"[tid:%u]: Still Squashing, cannot commit any"
|
||||
"insts this cycle.\n", tid);
|
||||
" insts this cycle.\n", tid);
|
||||
rob->doSquash(tid);
|
||||
toIEW->commitInfo[tid].robSquashing = true;
|
||||
wroteToTimeBuffer = true;
|
||||
|
|
|
@ -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),
|
||||
|
@ -472,6 +502,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)
|
||||
|
@ -524,7 +666,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.\n", tid);
|
||||
|
||||
// Copy Thread Data From RegFile
|
||||
// If thread is suspended, it might be re-allocated
|
||||
|
@ -550,6 +692,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);
|
||||
|
||||
|
@ -613,113 +757,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>::serialize(std::ostream &os)
|
||||
|
|
|
@ -199,6 +199,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);
|
||||
|
@ -224,7 +267,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);
|
||||
|
@ -252,7 +298,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.
|
||||
|
|
|
@ -308,7 +308,7 @@ class ROB
|
|||
|
||||
private:
|
||||
/** The sequence number of the squashed instruction. */
|
||||
InstSeqNum squashedSeqNum;
|
||||
InstSeqNum squashedSeqNum[Impl::MaxThreads];
|
||||
|
||||
/** Is the ROB done squashing. */
|
||||
bool doneSquashing[Impl::MaxThreads];
|
||||
|
|
|
@ -41,10 +41,10 @@ ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth,
|
|||
: numEntries(_numEntries),
|
||||
squashWidth(_squashWidth),
|
||||
numInstsInROB(0),
|
||||
squashedSeqNum(0),
|
||||
numThreads(_numThreads)
|
||||
{
|
||||
for (int tid=0; tid < numThreads; tid++) {
|
||||
squashedSeqNum[tid] = 0;
|
||||
doneSquashing[tid] = true;
|
||||
threadEntries[tid] = 0;
|
||||
}
|
||||
|
@ -352,11 +352,11 @@ void
|
|||
ROB<Impl>::doSquash(unsigned tid)
|
||||
{
|
||||
DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n",
|
||||
tid, squashedSeqNum);
|
||||
tid, squashedSeqNum[tid]);
|
||||
|
||||
assert(squashIt[tid] != instList[tid].end());
|
||||
|
||||
if ((*squashIt[tid])->seqNum < squashedSeqNum) {
|
||||
if ((*squashIt[tid])->seqNum < squashedSeqNum[tid]) {
|
||||
DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n",
|
||||
tid);
|
||||
|
||||
|
@ -371,7 +371,7 @@ ROB<Impl>::doSquash(unsigned tid)
|
|||
for (int numSquashed = 0;
|
||||
numSquashed < squashWidth &&
|
||||
squashIt[tid] != instList[tid].end() &&
|
||||
(*squashIt[tid])->seqNum > squashedSeqNum;
|
||||
(*squashIt[tid])->seqNum > squashedSeqNum[tid];
|
||||
++numSquashed)
|
||||
{
|
||||
DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %#x, seq num %i.\n",
|
||||
|
@ -408,7 +408,7 @@ ROB<Impl>::doSquash(unsigned tid)
|
|||
|
||||
|
||||
// Check if ROB is done squashing.
|
||||
if ((*squashIt[tid])->seqNum <= squashedSeqNum) {
|
||||
if ((*squashIt[tid])->seqNum <= squashedSeqNum[tid]) {
|
||||
DPRINTF(ROB, "[tid:%u]: Done squashing instructions.\n",
|
||||
tid);
|
||||
|
||||
|
@ -520,7 +520,7 @@ ROB<Impl>::squash(InstSeqNum squash_num,unsigned tid)
|
|||
|
||||
doneSquashing[tid] = false;
|
||||
|
||||
squashedSeqNum = squash_num;
|
||||
squashedSeqNum[tid] = squash_num;
|
||||
|
||||
if (!instList[tid].empty()) {
|
||||
InstIt tail_thread = instList[tid].end();
|
||||
|
@ -544,6 +544,7 @@ ROB<Impl>::readHeadInst()
|
|||
}
|
||||
}
|
||||
*/
|
||||
|
||||
template <class Impl>
|
||||
typename Impl::DynInstPtr
|
||||
ROB<Impl>::readHeadInst(unsigned tid)
|
||||
|
@ -558,6 +559,7 @@ ROB<Impl>::readHeadInst(unsigned tid)
|
|||
return dummyInst;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
template <class Impl>
|
||||
uint64_t
|
||||
|
|
|
@ -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