eventq: convert all usage of events to use the new API.
For now, there is still a single global event queue, but this is necessary for making the steps towards a parallelized m5.
This commit is contained in:
@@ -33,10 +33,12 @@
|
||||
#include "arch/alpha/regfile.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
void
|
||||
RegFile::serialize(std::ostream &os)
|
||||
RegFile::serialize(EventManager *em, ostream &os)
|
||||
{
|
||||
intRegFile.serialize(os);
|
||||
floatRegFile.serialize(os);
|
||||
@@ -49,7 +51,7 @@ RegFile::serialize(std::ostream &os)
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
//XXX These should be implemented by someone who knows the alpha stuff better
|
||||
|
||||
class Checkpoint;
|
||||
class EventManager;
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA {
|
||||
@@ -202,8 +203,9 @@ class RegFile {
|
||||
intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
void serialize(EventManager *em, std::ostream &os);
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
|
||||
void
|
||||
changeContext(RegContextParam param, RegContextVal val)
|
||||
|
||||
10
src/arch/mips/regfile/misc_regfile.cc
Executable file → Normal file
10
src/arch/mips/regfile/misc_regfile.cc
Executable file → Normal file
@@ -567,7 +567,7 @@ MiscRegFile::scheduleCP0Update(int delay)
|
||||
|
||||
//schedule UPDATE
|
||||
CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);
|
||||
cp0_event->schedule(curTick + cpu->ticks(delay));
|
||||
cpu->schedule(cp0_event, curTick + cpu->ticks(delay));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,8 +601,7 @@ MiscRegFile::updateCPU()
|
||||
}
|
||||
|
||||
MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu),
|
||||
cp0EventType(e_type)
|
||||
: Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
|
||||
{ }
|
||||
|
||||
void
|
||||
@@ -627,10 +626,7 @@ MiscRegFile::CP0Event::description() const
|
||||
void
|
||||
MiscRegFile::CP0Event::scheduleEvent(int delay)
|
||||
{
|
||||
if (squashed())
|
||||
reschedule(curTick + cpu->ticks(delay));
|
||||
else if (!scheduled())
|
||||
schedule(curTick + cpu->ticks(delay));
|
||||
cpu->reschedule(this, curTick + cpu->ticks(delay), true);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -193,7 +193,7 @@ RegFile::setNextNPC(Addr val)
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::serialize(std::ostream &os)
|
||||
RegFile::serialize(EventManager *em, std::ostream &os)
|
||||
{
|
||||
intRegFile.serialize(os);
|
||||
//SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
|
||||
@@ -207,7 +207,8 @@ RegFile::serialize(std::ostream &os)
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
RegFile::unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
//UNSERIALIZE_ARRAY(floatRegFile);
|
||||
|
||||
@@ -41,8 +41,9 @@
|
||||
//#include "cpu/base.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class BaseCPU;
|
||||
class Checkpoint;
|
||||
class EventManager;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
@@ -99,8 +100,9 @@ namespace MipsISA
|
||||
Addr readNextNPC();
|
||||
void setNextNPC(Addr val);
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
void serialize(EventManager *em, std::ostream &os);
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
|
||||
void changeContext(RegContextParam param, RegContextVal val)
|
||||
{
|
||||
|
||||
@@ -593,7 +593,8 @@ void MiscRegFile::setReg(int miscReg,
|
||||
setRegNoEffect(miscReg, new_val);
|
||||
}
|
||||
|
||||
void MiscRegFile::serialize(std::ostream & os)
|
||||
void
|
||||
MiscRegFile::serialize(EventManager *em, std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(asi);
|
||||
SERIALIZE_SCALAR(tick);
|
||||
@@ -670,7 +671,9 @@ void MiscRegFile::serialize(std::ostream & os)
|
||||
#endif
|
||||
}
|
||||
|
||||
void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
|
||||
void
|
||||
MiscRegFile::unserialize(EventManager *em, Checkpoint *cp,
|
||||
const string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(asi);
|
||||
UNSERIALIZE_SCALAR(tick);
|
||||
@@ -729,15 +732,15 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
|
||||
|
||||
if (tick_cmp) {
|
||||
tickCompare = new TickCompareEvent(this, tc);
|
||||
tickCompare->schedule(tick_cmp);
|
||||
em->schedule(tickCompare, tick_cmp);
|
||||
}
|
||||
if (stick_cmp) {
|
||||
sTickCompare = new STickCompareEvent(this, tc);
|
||||
sTickCompare->schedule(stick_cmp);
|
||||
em->schedule(sTickCompare, stick_cmp);
|
||||
}
|
||||
if (hstick_cmp) {
|
||||
hSTickCompare = new HSTickCompareEvent(this, tc);
|
||||
hSTickCompare->schedule(hstick_cmp);
|
||||
em->schedule(hSTickCompare, hstick_cmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,9 +288,10 @@ namespace SparcISA
|
||||
return priContext | (uint32_t)partId << 13;
|
||||
}
|
||||
|
||||
void serialize(std::ostream & os);
|
||||
void serialize(EventManager *em, std::ostream & os);
|
||||
|
||||
void unserialize(Checkpoint * cp, const std::string & section);
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string & section);
|
||||
|
||||
void copyMiscRegs(ThreadContext * tc);
|
||||
|
||||
|
||||
@@ -219,21 +219,23 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg)
|
||||
//return intRegFile.flattenIndex(reg);
|
||||
}
|
||||
|
||||
void RegFile::serialize(std::ostream &os)
|
||||
void
|
||||
RegFile::serialize(EventManager *em, ostream &os)
|
||||
{
|
||||
intRegFile.serialize(os);
|
||||
floatRegFile.serialize(os);
|
||||
miscRegFile.serialize(os);
|
||||
miscRegFile.serialize(em, os);
|
||||
SERIALIZE_SCALAR(pc);
|
||||
SERIALIZE_SCALAR(npc);
|
||||
SERIALIZE_SCALAR(nnpc);
|
||||
}
|
||||
|
||||
void RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
void
|
||||
RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
miscRegFile.unserialize(cp, section);
|
||||
miscRegFile.unserialize(em, cp, section);
|
||||
UNSERIALIZE_SCALAR(pc);
|
||||
UNSERIALIZE_SCALAR(npc);
|
||||
UNSERIALIZE_SCALAR(nnpc);
|
||||
|
||||
@@ -112,8 +112,9 @@ namespace SparcISA
|
||||
|
||||
void setIntReg(int intReg, const IntReg &val);
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
void serialize(EventManager *em, std::ostream &os);
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -84,12 +84,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||
tickCompare = new TickCompareEvent(this, tc);
|
||||
setRegNoEffect(miscReg, val);
|
||||
if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
|
||||
tickCompare->deschedule();
|
||||
cpu->deschedule(tickCompare);
|
||||
time = (tick_cmpr & mask(63)) - (tick & mask(63));
|
||||
if (!(tick_cmpr & ~mask(63)) && time > 0) {
|
||||
if (tickCompare->scheduled())
|
||||
tickCompare->deschedule();
|
||||
tickCompare->schedule(time * cpu->ticks(1));
|
||||
cpu->deschedule(tickCompare);
|
||||
cpu->schedule(tickCompare, curTick + time * cpu->ticks(1));
|
||||
}
|
||||
panic("writing to TICK compare register %#X\n", val);
|
||||
break;
|
||||
@@ -99,13 +99,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||
sTickCompare = new STickCompareEvent(this, tc);
|
||||
setRegNoEffect(miscReg, val);
|
||||
if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
|
||||
sTickCompare->deschedule();
|
||||
cpu->deschedule(sTickCompare);
|
||||
time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
|
||||
cpu->instCount();
|
||||
if (!(stick_cmpr & ~mask(63)) && time > 0) {
|
||||
if (sTickCompare->scheduled())
|
||||
sTickCompare->deschedule();
|
||||
sTickCompare->schedule(time * cpu->ticks(1) + curTick);
|
||||
cpu->deschedule(sTickCompare);
|
||||
cpu->schedule(sTickCompare, curTick + time * cpu->ticks(1));
|
||||
}
|
||||
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
|
||||
break;
|
||||
@@ -169,13 +169,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||
hSTickCompare = new HSTickCompareEvent(this, tc);
|
||||
setRegNoEffect(miscReg, val);
|
||||
if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
|
||||
hSTickCompare->deschedule();
|
||||
cpu->deschedule(hSTickCompare);
|
||||
time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
|
||||
cpu->instCount();
|
||||
if (!(hstick_cmpr & ~mask(63)) && time > 0) {
|
||||
if (hSTickCompare->scheduled())
|
||||
hSTickCompare->deschedule();
|
||||
hSTickCompare->schedule(curTick + time * cpu->ticks(1));
|
||||
cpu->deschedule(hSTickCompare);
|
||||
cpu->schedule(hSTickCompare, curTick + time * cpu->ticks(1));
|
||||
}
|
||||
DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
|
||||
break;
|
||||
@@ -296,12 +296,14 @@ MiscRegFile::processTickCompare(ThreadContext *tc)
|
||||
void
|
||||
MiscRegFile::processSTickCompare(ThreadContext *tc)
|
||||
{
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
// since our microcode instructions take two cycles we need to check if
|
||||
// we're actually at the correct cycle or we need to wait a little while
|
||||
// more
|
||||
int ticks;
|
||||
ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
|
||||
tc->getCpuPtr()->instCount();
|
||||
cpu->instCount();
|
||||
assert(ticks >= 0 && "stick compare missed interrupt cycle");
|
||||
|
||||
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
|
||||
@@ -311,12 +313,14 @@ MiscRegFile::processSTickCompare(ThreadContext *tc)
|
||||
setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
|
||||
}
|
||||
} else
|
||||
sTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
|
||||
cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1));
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::processHSTickCompare(ThreadContext *tc)
|
||||
{
|
||||
BaseCPU *cpu = tc->getCpuPtr();
|
||||
|
||||
// since our microcode instructions take two cycles we need to check if
|
||||
// we're actually at the correct cycle or we need to wait a little while
|
||||
// more
|
||||
@@ -326,7 +330,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
|
||||
return;
|
||||
|
||||
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
|
||||
tc->getCpuPtr()->instCount();
|
||||
cpu->instCount();
|
||||
assert(ticks >= 0 && "hstick compare missed interrupt cycle");
|
||||
|
||||
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
|
||||
@@ -337,6 +341,6 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc)
|
||||
}
|
||||
// Need to do something to cause interrupt to happen here !!! @todo
|
||||
} else
|
||||
hSTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick);
|
||||
cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1));
|
||||
}
|
||||
|
||||
|
||||
@@ -115,10 +115,8 @@ namespace X86ISA
|
||||
class ApicTimerEvent : public Event
|
||||
{
|
||||
public:
|
||||
ApicTimerEvent() : Event(&mainEventQueue)
|
||||
{}
|
||||
|
||||
void process()
|
||||
void
|
||||
process()
|
||||
{
|
||||
warn("Local APIC timer event doesn't do anything!\n");
|
||||
}
|
||||
|
||||
@@ -228,7 +228,8 @@ int X86ISA::flattenFloatIndex(ThreadContext * tc, int reg)
|
||||
return reg;
|
||||
}
|
||||
|
||||
void RegFile::serialize(std::ostream &os)
|
||||
void
|
||||
RegFile::serialize(EventManager *em, std::ostream &os)
|
||||
{
|
||||
intRegFile.serialize(os);
|
||||
floatRegFile.serialize(os);
|
||||
@@ -237,7 +238,8 @@ void RegFile::serialize(std::ostream &os)
|
||||
SERIALIZE_SCALAR(nextRip);
|
||||
}
|
||||
|
||||
void RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
void
|
||||
RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include <string>
|
||||
|
||||
class Checkpoint;
|
||||
class EventManager;
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
@@ -139,8 +140,9 @@ namespace X86ISA
|
||||
|
||||
void setIntReg(int intReg, const IntReg &val);
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
void serialize(EventManager *em, std::ostream &os);
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -60,13 +60,12 @@ vector<BaseCPU *> BaseCPU::cpuList;
|
||||
// been initialized
|
||||
int maxThreadsPerCPU = 1;
|
||||
|
||||
CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
|
||||
BaseCPU *_cpu)
|
||||
: Event(q, Event::Progress_Event_Pri), interval(ival),
|
||||
lastNumInst(0), cpu(_cpu)
|
||||
CPUProgressEvent::CPUProgressEvent(BaseCPU *_cpu, Tick ival)
|
||||
: Event(Event::Progress_Event_Pri), interval(ival), lastNumInst(0),
|
||||
cpu(_cpu)
|
||||
{
|
||||
if (interval)
|
||||
schedule(curTick + interval);
|
||||
cpu->schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -84,7 +83,7 @@ CPUProgressEvent::process()
|
||||
curTick, cpu->name(), temp - lastNumInst);
|
||||
#endif
|
||||
lastNumInst = temp;
|
||||
schedule(curTick + interval);
|
||||
cpu->schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -121,22 +120,26 @@ BaseCPU::BaseCPU(Params *p)
|
||||
//
|
||||
// set up instruction-count-based termination events, if any
|
||||
//
|
||||
if (p->max_insts_any_thread != 0)
|
||||
for (int i = 0; i < number_of_threads; ++i)
|
||||
schedExitSimLoop("a thread reached the max instruction count",
|
||||
p->max_insts_any_thread, 0,
|
||||
comInstEventQueue[i]);
|
||||
if (p->max_insts_any_thread != 0) {
|
||||
const char *cause = "a thread reached the max instruction count";
|
||||
for (int i = 0; i < number_of_threads; ++i) {
|
||||
Event *event = new SimLoopExitEvent(cause, 0);
|
||||
comInstEventQueue[i]->schedule(event, p->max_insts_any_thread);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->max_insts_all_threads != 0) {
|
||||
const char *cause = "all threads reached the max instruction count";
|
||||
|
||||
// allocate & initialize shared downcounter: each event will
|
||||
// decrement this when triggered; simulation will terminate
|
||||
// when counter reaches 0
|
||||
int *counter = new int;
|
||||
*counter = number_of_threads;
|
||||
for (int i = 0; i < number_of_threads; ++i)
|
||||
new CountedExitEvent(comInstEventQueue[i],
|
||||
"all threads reached the max instruction count",
|
||||
p->max_insts_all_threads, *counter);
|
||||
for (int i = 0; i < number_of_threads; ++i) {
|
||||
Event *event = new CountedExitEvent(cause, *counter);
|
||||
comInstEventQueue[i]->schedule(event, p->max_insts_any_thread);
|
||||
}
|
||||
}
|
||||
|
||||
// allocate per-thread load-based event queues
|
||||
@@ -147,22 +150,25 @@ BaseCPU::BaseCPU(Params *p)
|
||||
//
|
||||
// set up instruction-count-based termination events, if any
|
||||
//
|
||||
if (p->max_loads_any_thread != 0)
|
||||
for (int i = 0; i < number_of_threads; ++i)
|
||||
schedExitSimLoop("a thread reached the max load count",
|
||||
p->max_loads_any_thread, 0,
|
||||
comLoadEventQueue[i]);
|
||||
if (p->max_loads_any_thread != 0) {
|
||||
const char *cause = "a thread reached the max load count";
|
||||
for (int i = 0; i < number_of_threads; ++i) {
|
||||
Event *event = new SimLoopExitEvent(cause, 0);
|
||||
comLoadEventQueue[i]->schedule(event, p->max_loads_any_thread);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->max_loads_all_threads != 0) {
|
||||
const char *cause = "all threads reached the max load count";
|
||||
// allocate & initialize shared downcounter: each event will
|
||||
// decrement this when triggered; simulation will terminate
|
||||
// when counter reaches 0
|
||||
int *counter = new int;
|
||||
*counter = number_of_threads;
|
||||
for (int i = 0; i < number_of_threads; ++i)
|
||||
new CountedExitEvent(comLoadEventQueue[i],
|
||||
"all threads reached the max load count",
|
||||
p->max_loads_all_threads, *counter);
|
||||
for (int i = 0; i < number_of_threads; ++i) {
|
||||
Event *event = new CountedExitEvent(cause, *counter);
|
||||
comLoadEventQueue[i]->schedule(event, p->max_loads_all_threads);
|
||||
}
|
||||
}
|
||||
|
||||
functionTracingEnabled = false;
|
||||
@@ -174,9 +180,9 @@ BaseCPU::BaseCPU(Params *p)
|
||||
if (p->function_trace_start == 0) {
|
||||
functionTracingEnabled = true;
|
||||
} else {
|
||||
new EventWrapper<BaseCPU,
|
||||
&BaseCPU::enableFunctionTrace>(
|
||||
this, p->function_trace_start, true);
|
||||
typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap;
|
||||
Event *event = new wrap(this, true);
|
||||
schedule(event, p->function_trace_start);
|
||||
}
|
||||
}
|
||||
#if FULL_SYSTEM
|
||||
@@ -209,13 +215,13 @@ BaseCPU::startup()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (!params()->defer_registration && profileEvent)
|
||||
profileEvent->schedule(curTick);
|
||||
schedule(profileEvent, curTick);
|
||||
#endif
|
||||
|
||||
if (params()->progress_interval) {
|
||||
new CPUProgressEvent(&mainEventQueue,
|
||||
ticks(params()->progress_interval),
|
||||
this);
|
||||
Tick num_ticks = ticks(params()->progress_interval);
|
||||
Event *event = new CPUProgressEvent(this, num_ticks);
|
||||
schedule(event, curTick + num_ticks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +306,7 @@ BaseCPU::switchOut()
|
||||
// panic("This CPU doesn't support sampling!");
|
||||
#if FULL_SYSTEM
|
||||
if (profileEvent && profileEvent->scheduled())
|
||||
profileEvent->deschedule();
|
||||
deschedule(profileEvent);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -336,7 +342,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
|
||||
threadContexts[i]->profileClear();
|
||||
|
||||
if (profileEvent)
|
||||
profileEvent->schedule(curTick);
|
||||
schedule(profileEvent, curTick);
|
||||
#endif
|
||||
|
||||
// Connect new CPU to old CPU's memory only if new CPU isn't
|
||||
@@ -358,7 +364,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
|
||||
|
||||
#if FULL_SYSTEM
|
||||
BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval)
|
||||
: Event(&mainEventQueue), cpu(_cpu), interval(_interval)
|
||||
: cpu(_cpu), interval(_interval)
|
||||
{ }
|
||||
|
||||
void
|
||||
@@ -369,7 +375,7 @@ BaseCPU::ProfileEvent::process()
|
||||
tc->profileSample();
|
||||
}
|
||||
|
||||
schedule(curTick + interval);
|
||||
cpu->schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -65,7 +65,7 @@ class CPUProgressEvent : public Event
|
||||
BaseCPU *cpu;
|
||||
|
||||
public:
|
||||
CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu);
|
||||
CPUProgressEvent(BaseCPU *_cpu, Tick ival);
|
||||
|
||||
void process();
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ class CpuEvent : public Event
|
||||
ThreadContext *tc;
|
||||
|
||||
public:
|
||||
CpuEvent(EventQueue *q, ThreadContext *_tc, Priority p = Default_Pri)
|
||||
: Event(q, p), tc(_tc)
|
||||
CpuEvent(ThreadContext *_tc, Priority p = Default_Pri)
|
||||
: Event(p), tc(_tc)
|
||||
{ cpuEventList.push_back(this); }
|
||||
|
||||
/** delete the cpu event from the global list. */
|
||||
@@ -81,9 +81,8 @@ class CpuEventWrapper : public CpuEvent
|
||||
T *object;
|
||||
|
||||
public:
|
||||
CpuEventWrapper(T *obj, ThreadContext *_tc,
|
||||
EventQueue *q = &mainEventQueue, Priority p = Default_Pri)
|
||||
: CpuEvent(q, _tc, p), object(obj)
|
||||
CpuEventWrapper(T *obj, ThreadContext *_tc, Priority p = Default_Pri)
|
||||
: CpuEvent(_tc, p), object(obj)
|
||||
{ }
|
||||
void process() { (object->*F)(tc); }
|
||||
};
|
||||
|
||||
@@ -152,7 +152,7 @@ MemTest::MemTest(const Params *p)
|
||||
// set up counters
|
||||
noResponseCycles = 0;
|
||||
numReads = 0;
|
||||
tickEvent.schedule(0);
|
||||
schedule(tickEvent, 0);
|
||||
|
||||
id = TESTER_ALLOCATOR++;
|
||||
|
||||
@@ -262,7 +262,7 @@ void
|
||||
MemTest::tick()
|
||||
{
|
||||
if (!tickEvent.scheduled())
|
||||
tickEvent.schedule(curTick + ticks(1));
|
||||
schedule(tickEvent, curTick + ticks(1));
|
||||
|
||||
if (++noResponseCycles >= 500000) {
|
||||
cerr << name() << ": deadlocked at cycle " << curTick << endl;
|
||||
|
||||
@@ -74,10 +74,10 @@ class MemTest : public MemObject
|
||||
{
|
||||
private:
|
||||
MemTest *cpu;
|
||||
|
||||
public:
|
||||
TickEvent(MemTest *c)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) {}
|
||||
void process() {cpu->tick();}
|
||||
TickEvent(MemTest *c) : Event(CPU_Tick_Pri), cpu(c) {}
|
||||
void process() { cpu->tick(); }
|
||||
virtual const char *description() const { return "MemTest tick"; }
|
||||
};
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
template <class Impl>
|
||||
DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
|
||||
unsigned _tid)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), commit(_commit), tid(_tid)
|
||||
: Event(CPU_Tick_Pri), commit(_commit), tid(_tid)
|
||||
{
|
||||
this->setFlags(Event::AutoDelete);
|
||||
}
|
||||
@@ -462,7 +462,7 @@ DefaultCommit<Impl>::generateTrapEvent(unsigned tid)
|
||||
|
||||
TrapEvent *trap = new TrapEvent(this, tid);
|
||||
|
||||
trap->schedule(curTick + trapLatency);
|
||||
cpu->schedule(trap, curTick + trapLatency);
|
||||
trapInFlight[tid] = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ BaseO3CPU::regStats()
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
|
||||
: Event(CPU_Tick_Pri), cpu(c)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ FullO3CPU<Impl>::TickEvent::description() const
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::ActivateThreadEvent::ActivateThreadEvent()
|
||||
: Event(&mainEventQueue, CPU_Switch_Pri)
|
||||
: Event(CPU_Switch_Pri)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ FullO3CPU<Impl>::ActivateThreadEvent::description() const
|
||||
|
||||
template <class Impl>
|
||||
FullO3CPU<Impl>::DeallocateContextEvent::DeallocateContextEvent()
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), tid(0), remove(false), cpu(NULL)
|
||||
: Event(CPU_Tick_Pri), tid(0), remove(false), cpu(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ FullO3CPU<Impl>::tick()
|
||||
lastRunningCycle = curTick;
|
||||
timesIdled++;
|
||||
} else {
|
||||
tickEvent.schedule(nextCycle(curTick + ticks(1)));
|
||||
schedule(tickEvent, nextCycle(curTick + ticks(1)));
|
||||
DPRINTF(O3CPU, "Scheduling next tick!\n");
|
||||
}
|
||||
}
|
||||
@@ -584,7 +584,6 @@ FullO3CPU<Impl>::tick()
|
||||
#if !FULL_SYSTEM
|
||||
updateThreadPriority();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
@@ -1121,7 +1120,7 @@ FullO3CPU<Impl>::resume()
|
||||
#endif
|
||||
|
||||
if (!tickEvent.scheduled())
|
||||
tickEvent.schedule(nextCycle());
|
||||
schedule(tickEvent, nextCycle());
|
||||
_status = Running;
|
||||
}
|
||||
|
||||
@@ -1214,11 +1213,11 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||
ThreadContext *tc = threadContexts[i];
|
||||
if (tc->status() == ThreadContext::Active && _status != Running) {
|
||||
_status = Running;
|
||||
tickEvent.schedule(nextCycle());
|
||||
schedule(tickEvent, nextCycle());
|
||||
}
|
||||
}
|
||||
if (!tickEvent.scheduled())
|
||||
tickEvent.schedule(nextCycle());
|
||||
schedule(tickEvent, nextCycle());
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
@@ -1687,7 +1686,7 @@ FullO3CPU<Impl>::wakeCPU()
|
||||
idleCycles += tickToCycles((curTick - 1) - lastRunningCycle);
|
||||
numCycles += tickToCycles((curTick - 1) - lastRunningCycle);
|
||||
|
||||
tickEvent.schedule(nextCycle());
|
||||
schedule(tickEvent, nextCycle());
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -148,9 +148,9 @@ class FullO3CPU : public BaseO3CPU
|
||||
void scheduleTickEvent(int delay)
|
||||
{
|
||||
if (tickEvent.squashed())
|
||||
tickEvent.reschedule(nextCycle(curTick + ticks(delay)));
|
||||
reschedule(tickEvent, nextCycle(curTick + ticks(delay)));
|
||||
else if (!tickEvent.scheduled())
|
||||
tickEvent.schedule(nextCycle(curTick + ticks(delay)));
|
||||
schedule(tickEvent, nextCycle(curTick + ticks(delay)));
|
||||
}
|
||||
|
||||
/** Unschedule tick event, regardless of its current state. */
|
||||
@@ -188,11 +188,11 @@ class FullO3CPU : public BaseO3CPU
|
||||
{
|
||||
// Schedule thread to activate, regardless of its current state.
|
||||
if (activateThreadEvent[tid].squashed())
|
||||
activateThreadEvent[tid].
|
||||
reschedule(nextCycle(curTick + ticks(delay)));
|
||||
reschedule(activateThreadEvent[tid],
|
||||
nextCycle(curTick + ticks(delay)));
|
||||
else if (!activateThreadEvent[tid].scheduled())
|
||||
activateThreadEvent[tid].
|
||||
schedule(nextCycle(curTick + ticks(delay)));
|
||||
schedule(activateThreadEvent[tid],
|
||||
nextCycle(curTick + ticks(delay)));
|
||||
}
|
||||
|
||||
/** Unschedule actiavte thread event, regardless of its current state. */
|
||||
@@ -246,11 +246,11 @@ class FullO3CPU : public BaseO3CPU
|
||||
{
|
||||
// Schedule thread to activate, regardless of its current state.
|
||||
if (deallocateContextEvent[tid].squashed())
|
||||
deallocateContextEvent[tid].
|
||||
reschedule(nextCycle(curTick + ticks(delay)));
|
||||
reschedule(deallocateContextEvent[tid],
|
||||
nextCycle(curTick + ticks(delay)));
|
||||
else if (!deallocateContextEvent[tid].scheduled())
|
||||
deallocateContextEvent[tid].
|
||||
schedule(nextCycle(curTick + ticks(delay)));
|
||||
schedule(deallocateContextEvent[tid],
|
||||
nextCycle(curTick + ticks(delay)));
|
||||
}
|
||||
|
||||
/** Unschedule thread deallocation in CPU */
|
||||
|
||||
@@ -82,7 +82,7 @@ class DefaultFetch
|
||||
public:
|
||||
/** Default constructor. */
|
||||
IcachePort(DefaultFetch<Impl> *_fetch)
|
||||
: Port(_fetch->name() + "-iport"), fetch(_fetch)
|
||||
: Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch)
|
||||
{ }
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
@@ -41,10 +41,9 @@
|
||||
|
||||
template <class Impl>
|
||||
InstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst,
|
||||
int fu_idx,
|
||||
InstructionQueue<Impl> *iq_ptr)
|
||||
: Event(&mainEventQueue, Stat_Event_Pri),
|
||||
inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
|
||||
int fu_idx, InstructionQueue<Impl> *iq_ptr)
|
||||
: Event(Stat_Event_Pri), inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr),
|
||||
freeFU(false)
|
||||
{
|
||||
this->setFlags(Event::AutoDelete);
|
||||
}
|
||||
@@ -754,7 +753,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
|
||||
FUCompletion *execution = new FUCompletion(issuing_inst,
|
||||
idx, this);
|
||||
|
||||
execution->schedule(curTick + cpu->ticks(op_latency - 1));
|
||||
cpu->schedule(execution, curTick + cpu->ticks(op_latency - 1));
|
||||
|
||||
// @todo: Enforce that issue_latency == 1 or op_latency
|
||||
if (issue_latency > 1) {
|
||||
|
||||
@@ -298,7 +298,7 @@ class LSQ {
|
||||
public:
|
||||
/** Default constructor. */
|
||||
DcachePort(LSQ *_lsq)
|
||||
: Port(_lsq->name() + "-dport"), lsq(_lsq)
|
||||
: Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
|
||||
{ }
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
@@ -584,7 +584,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
|
||||
// We'll say this has a 1 cycle load-store forwarding latency
|
||||
// for now.
|
||||
// @todo: Need to make this a parameter.
|
||||
wb->schedule(curTick);
|
||||
cpu->schedule(wb, curTick);
|
||||
|
||||
++lsqForwLoads;
|
||||
return NoFault;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
template<class Impl>
|
||||
LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt,
|
||||
LSQUnit *lsq_ptr)
|
||||
: Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
|
||||
: inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
|
||||
{
|
||||
this->setFlags(Event::AutoDelete);
|
||||
}
|
||||
@@ -684,7 +684,7 @@ LSQUnit<Impl>::writebackStores()
|
||||
"Instantly completing it.\n",
|
||||
inst->seqNum);
|
||||
WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this);
|
||||
wb->schedule(curTick + 1);
|
||||
cpu->schedule(wb, curTick + 1);
|
||||
completeStore(storeWBIdx);
|
||||
incrStIdx(storeWBIdx);
|
||||
continue;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "cpu/quiesce_event.hh"
|
||||
|
||||
EndQuiesceEvent::EndQuiesceEvent(ThreadContext *_tc)
|
||||
: Event(&mainEventQueue), tc(_tc)
|
||||
: tc(_tc)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
AtomicSimpleCPU::TickEvent::TickEvent(AtomicSimpleCPU *c)
|
||||
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
|
||||
: Event(CPU_Tick_Pri), cpu(c)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -201,9 +201,8 @@ AtomicSimpleCPU::resume()
|
||||
|
||||
changeState(SimObject::Running);
|
||||
if (thread->status() == ThreadContext::Active) {
|
||||
if (!tickEvent.scheduled()) {
|
||||
tickEvent.schedule(nextCycle());
|
||||
}
|
||||
if (!tickEvent.scheduled())
|
||||
schedule(tickEvent, nextCycle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +229,7 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||
ThreadContext *tc = threadContexts[i];
|
||||
if (tc->status() == ThreadContext::Active && _status != Running) {
|
||||
_status = Running;
|
||||
tickEvent.schedule(nextCycle());
|
||||
schedule(tickEvent, nextCycle());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -260,7 +259,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
|
||||
numCycles += tickToCycles(thread->lastActivate - thread->lastSuspend);
|
||||
|
||||
//Make sure ticks are still on multiples of cycles
|
||||
tickEvent.schedule(nextCycle(curTick + ticks(delay)));
|
||||
schedule(tickEvent, nextCycle(curTick + ticks(delay)));
|
||||
_status = Running;
|
||||
}
|
||||
|
||||
@@ -278,7 +277,7 @@ AtomicSimpleCPU::suspendContext(int thread_num)
|
||||
// tick event may not be scheduled if this gets called from inside
|
||||
// an instruction's execution, e.g. "quiesce"
|
||||
if (tickEvent.scheduled())
|
||||
tickEvent.deschedule();
|
||||
deschedule(tickEvent);
|
||||
|
||||
notIdleFraction--;
|
||||
_status = Idle;
|
||||
@@ -794,7 +793,7 @@ AtomicSimpleCPU::tick()
|
||||
latency = ticks(1);
|
||||
|
||||
if (_status != Idle)
|
||||
tickEvent.schedule(curTick + latency);
|
||||
schedule(tickEvent, curTick + latency);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ void
|
||||
TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
|
||||
{
|
||||
pkt = _pkt;
|
||||
Event::schedule(t);
|
||||
cpu->schedule(this, t);
|
||||
}
|
||||
|
||||
TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
|
||||
@@ -165,7 +165,7 @@ TimingSimpleCPU::resume()
|
||||
// Delete the old event if it existed.
|
||||
if (fetchEvent) {
|
||||
if (fetchEvent->scheduled())
|
||||
fetchEvent->deschedule();
|
||||
deschedule(fetchEvent);
|
||||
|
||||
delete fetchEvent;
|
||||
}
|
||||
@@ -186,7 +186,7 @@ TimingSimpleCPU::switchOut()
|
||||
// If we've been scheduled to resume but are then told to switch out,
|
||||
// we'll need to cancel it.
|
||||
if (fetchEvent && fetchEvent->scheduled())
|
||||
fetchEvent->deschedule();
|
||||
deschedule(fetchEvent);
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,8 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
|
||||
_status = Running;
|
||||
|
||||
// kick things off by initiating the fetch of the next instruction
|
||||
fetchEvent = new FetchEvent(this, nextCycle(curTick + ticks(delay)));
|
||||
fetchEvent = new FetchEvent(this);
|
||||
schedule(fetchEvent, nextCycle(curTick + ticks(delay)));
|
||||
}
|
||||
|
||||
|
||||
@@ -819,10 +820,11 @@ TimingSimpleCPU::DcachePort::recvRetry()
|
||||
}
|
||||
}
|
||||
|
||||
TimingSimpleCPU::IprEvent::IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
|
||||
: Event(&mainEventQueue), pkt(_pkt), cpu(_cpu)
|
||||
TimingSimpleCPU::IprEvent::IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu,
|
||||
Tick t)
|
||||
: pkt(_pkt), cpu(_cpu)
|
||||
{
|
||||
schedule(t);
|
||||
cpu->schedule(this, t);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -80,8 +80,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||
PacketPtr pkt;
|
||||
TimingSimpleCPU *cpu;
|
||||
|
||||
TickEvent(TimingSimpleCPU *_cpu)
|
||||
:Event(&mainEventQueue), cpu(_cpu) {}
|
||||
TickEvent(TimingSimpleCPU *_cpu) : cpu(_cpu) {}
|
||||
const char *description() const { return "Timing CPU tick"; }
|
||||
void schedule(PacketPtr _pkt, Tick t);
|
||||
};
|
||||
|
||||
@@ -189,7 +189,7 @@ void
|
||||
SimpleThread::serialize(ostream &os)
|
||||
{
|
||||
ThreadState::serialize(os);
|
||||
regs.serialize(os);
|
||||
regs.serialize(cpu, os);
|
||||
// thread_num and cpu_id are deterministic from the config
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ void
|
||||
SimpleThread::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
ThreadState::unserialize(cp, section);
|
||||
regs.unserialize(cp, section);
|
||||
regs.unserialize(cpu, cp, section);
|
||||
// thread_num and cpu_id are deterministic from the config
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
Tick quiesceEndTick;
|
||||
UNSERIALIZE_SCALAR(quiesceEndTick);
|
||||
if (quiesceEndTick)
|
||||
quiesceEvent->schedule(quiesceEndTick);
|
||||
baseCpu->schedule(quiesceEvent, quiesceEndTick);
|
||||
if (kernelStats)
|
||||
kernelStats->unserialize(cp, section);
|
||||
#endif
|
||||
|
||||
@@ -56,14 +56,15 @@ using namespace std;
|
||||
//Should this be AlphaISA?
|
||||
using namespace TheISA;
|
||||
|
||||
TsunamiIO::TsunamiRTC::TsunamiRTC(const string &n, const TsunamiIOParams *p) :
|
||||
MC146818(n, p->time, p->year_is_bcd, p->frequency), tsunami(p->tsunami)
|
||||
TsunamiIO::RTC::RTC(const string &n, const TsunamiIOParams *p)
|
||||
: MC146818(p->tsunami, n, p->time, p->year_is_bcd, p->frequency),
|
||||
tsunami(p->tsunami)
|
||||
{
|
||||
}
|
||||
|
||||
TsunamiIO::TsunamiIO(const Params *p)
|
||||
: BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"),
|
||||
rtc(p->name + ".rtc", p)
|
||||
: BasicPioDevice(p), tsunami(p->tsunami),
|
||||
pitimer(this, p->name + "pitimer"), rtc(p->name + ".rtc", p)
|
||||
{
|
||||
pioSize = 0x100;
|
||||
|
||||
|
||||
@@ -56,11 +56,11 @@ class TsunamiIO : public BasicPioDevice
|
||||
|
||||
protected:
|
||||
|
||||
class TsunamiRTC : public MC146818
|
||||
class RTC : public MC146818
|
||||
{
|
||||
public:
|
||||
Tsunami * tsunami;
|
||||
TsunamiRTC(const std::string &n, const TsunamiIOParams *p);
|
||||
Tsunami *tsunami;
|
||||
RTC(const std::string &n, const TsunamiIOParams *p);
|
||||
|
||||
protected:
|
||||
void handleEvent()
|
||||
@@ -94,7 +94,7 @@ class TsunamiIO : public BasicPioDevice
|
||||
/** Intel 8253 Periodic Interval Timer */
|
||||
Intel8254Timer pitimer;
|
||||
|
||||
TsunamiRTC rtc;
|
||||
RTC rtc;
|
||||
|
||||
uint8_t rtcAddr;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ using namespace std;
|
||||
|
||||
EtherBus::EtherBus(const Params *p)
|
||||
: EtherObject(p), ticksPerByte(p->speed), loopback(p->loopback),
|
||||
event(&mainEventQueue, this), sender(0), dump(p->dump)
|
||||
event(this), sender(0), dump(p->dump)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt)
|
||||
int delay = (int)ceil(((double)pkt->length * ticksPerByte) + 1.0);
|
||||
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
|
||||
delay, ticksPerByte);
|
||||
event.schedule(curTick + delay);
|
||||
schedule(event, curTick + delay);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,7 @@ class EtherBus : public EtherObject
|
||||
EtherBus *bus;
|
||||
|
||||
public:
|
||||
DoneEvent(EventQueue *q, EtherBus *b)
|
||||
: Event(q), bus(b) {}
|
||||
DoneEvent(EtherBus *b) : bus(b) {}
|
||||
virtual void process() { bus->txDone(); }
|
||||
virtual const char *description() const
|
||||
{ return "ethernet bus completion"; }
|
||||
|
||||
@@ -135,7 +135,7 @@ class LinkDelayEvent : public Event
|
||||
public:
|
||||
// non-scheduling version for createForUnserialize()
|
||||
LinkDelayEvent();
|
||||
LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when);
|
||||
LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt);
|
||||
|
||||
void process();
|
||||
|
||||
@@ -153,7 +153,8 @@ EtherLink::Link::txDone()
|
||||
|
||||
if (linkDelay > 0) {
|
||||
DPRINTF(Ethernet, "packet delayed: delay=%d\n", linkDelay);
|
||||
new LinkDelayEvent(this, packet, curTick + linkDelay);
|
||||
Event *event = new LinkDelayEvent(this, packet);
|
||||
parent->schedule(event, curTick + linkDelay);
|
||||
} else {
|
||||
txComplete(packet);
|
||||
}
|
||||
@@ -182,7 +183,7 @@ EtherLink::Link::transmit(EthPacketPtr pkt)
|
||||
|
||||
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
|
||||
delay, ticksPerByte);
|
||||
doneEvent.schedule(curTick + delay);
|
||||
parent->schedule(doneEvent, curTick + delay);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -220,23 +221,22 @@ EtherLink::Link::unserialize(const string &base, Checkpoint *cp,
|
||||
if (event_scheduled) {
|
||||
Tick event_time;
|
||||
paramIn(cp, section, base + ".event_time", event_time);
|
||||
doneEvent.schedule(event_time);
|
||||
parent->schedule(doneEvent, event_time);
|
||||
}
|
||||
}
|
||||
|
||||
LinkDelayEvent::LinkDelayEvent()
|
||||
: Event(&mainEventQueue), link(NULL)
|
||||
: link(NULL)
|
||||
{
|
||||
setFlags(AutoSerialize);
|
||||
setFlags(AutoDelete);
|
||||
}
|
||||
|
||||
LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when)
|
||||
: Event(&mainEventQueue), link(l), packet(p)
|
||||
LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p)
|
||||
: link(l), packet(p)
|
||||
{
|
||||
setFlags(AutoSerialize);
|
||||
setFlags(AutoDelete);
|
||||
schedule(when);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -246,7 +246,7 @@ EtherTap::process(int revent)
|
||||
DPRINTF(Ethernet, "bus busy...buffer for retransmission\n");
|
||||
packetBuffer.push(packet);
|
||||
if (!txEvent.scheduled())
|
||||
txEvent.schedule(curTick + retryTime);
|
||||
schedule(txEvent, curTick + retryTime);
|
||||
} else if (dump) {
|
||||
dump->dump(packet);
|
||||
}
|
||||
@@ -269,7 +269,7 @@ EtherTap::retransmit()
|
||||
}
|
||||
|
||||
if (!packetBuffer.empty() && !txEvent.scheduled())
|
||||
txEvent.schedule(curTick + retryTime);
|
||||
schedule(txEvent, curTick + retryTime);
|
||||
}
|
||||
|
||||
EtherInt*
|
||||
|
||||
@@ -90,8 +90,7 @@ class EtherTap : public EtherObject
|
||||
EtherTap *tap;
|
||||
|
||||
public:
|
||||
TxEvent(EtherTap *_tap)
|
||||
: Event(&mainEventQueue), tap(_tap) {}
|
||||
TxEvent(EtherTap *_tap) : tap(_tap) {}
|
||||
void process() { tap->retransmit(); }
|
||||
virtual const char *description() const
|
||||
{ return "EtherTap retransmit"; }
|
||||
|
||||
@@ -592,7 +592,7 @@ IGbE::postInterrupt(IntTypes t, bool now)
|
||||
|
||||
if (regs.itr.interval() == 0 || now || lastInterrupt + itr_interval <= curTick) {
|
||||
if (interEvent.scheduled()) {
|
||||
interEvent.deschedule();
|
||||
deschedule(interEvent);
|
||||
}
|
||||
cpuPostInt();
|
||||
} else {
|
||||
@@ -601,7 +601,7 @@ IGbE::postInterrupt(IntTypes t, bool now)
|
||||
DPRINTF(EthernetIntr, "EINT: Scheduling timer interrupt for tick %d\n",
|
||||
int_time);
|
||||
if (!interEvent.scheduled()) {
|
||||
interEvent.schedule(int_time);
|
||||
schedule(interEvent, int_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -628,24 +628,24 @@ IGbE::cpuPostInt()
|
||||
|
||||
|
||||
if (interEvent.scheduled()) {
|
||||
interEvent.deschedule();
|
||||
deschedule(interEvent);
|
||||
}
|
||||
|
||||
if (rdtrEvent.scheduled()) {
|
||||
regs.icr.rxt0(1);
|
||||
rdtrEvent.deschedule();
|
||||
deschedule(rdtrEvent);
|
||||
}
|
||||
if (radvEvent.scheduled()) {
|
||||
regs.icr.rxt0(1);
|
||||
radvEvent.deschedule();
|
||||
deschedule(radvEvent);
|
||||
}
|
||||
if (tadvEvent.scheduled()) {
|
||||
regs.icr.txdw(1);
|
||||
tadvEvent.deschedule();
|
||||
deschedule(tadvEvent);
|
||||
}
|
||||
if (tidvEvent.scheduled()) {
|
||||
regs.icr.txdw(1);
|
||||
tidvEvent.deschedule();
|
||||
deschedule(tidvEvent);
|
||||
}
|
||||
|
||||
regs.icr.int_assert(1);
|
||||
@@ -677,7 +677,7 @@ IGbE::chkInterrupt()
|
||||
if (!(regs.icr() & regs.imr)) {
|
||||
DPRINTF(Ethernet, "Mask cleaned all interrupts\n");
|
||||
if (interEvent.scheduled())
|
||||
interEvent.deschedule();
|
||||
deschedule(interEvent);
|
||||
if (regs.icr.int_assert())
|
||||
cpuClearInt();
|
||||
}
|
||||
@@ -691,7 +691,8 @@ IGbE::chkInterrupt()
|
||||
if (!interEvent.scheduled()) {
|
||||
DPRINTF(Ethernet, "Scheduling for %d\n", curTick + Clock::Int::ns
|
||||
* 256 * regs.itr.interval());
|
||||
interEvent.schedule(curTick + Clock::Int::ns * 256 * regs.itr.interval());
|
||||
schedule(interEvent,
|
||||
curTick + Clock::Int::ns * 256 * regs.itr.interval());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,16 +800,16 @@ IGbE::RxDescCache::pktComplete()
|
||||
if (igbe->regs.rdtr.delay()) {
|
||||
DPRINTF(EthernetSM, "RXS: Scheduling DTR for %d\n",
|
||||
igbe->regs.rdtr.delay() * igbe->intClock());
|
||||
igbe->rdtrEvent.reschedule(curTick + igbe->regs.rdtr.delay() *
|
||||
igbe->intClock(),true);
|
||||
igbe->reschedule(igbe->rdtrEvent,
|
||||
curTick + igbe->regs.rdtr.delay() * igbe->intClock(), true);
|
||||
}
|
||||
|
||||
if (igbe->regs.radv.idv()) {
|
||||
DPRINTF(EthernetSM, "RXS: Scheduling ADV for %d\n",
|
||||
igbe->regs.radv.idv() * igbe->intClock());
|
||||
if (!igbe->radvEvent.scheduled()) {
|
||||
igbe->radvEvent.schedule(curTick + igbe->regs.radv.idv() *
|
||||
igbe->intClock());
|
||||
igbe->schedule(igbe->radvEvent,
|
||||
curTick + igbe->regs.radv.idv() * igbe->intClock());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,15 +1041,15 @@ IGbE::TxDescCache::pktComplete()
|
||||
DPRINTF(EthernetDesc, "Descriptor had IDE set\n");
|
||||
if (igbe->regs.tidv.idv()) {
|
||||
DPRINTF(EthernetDesc, "setting tidv\n");
|
||||
igbe->tidvEvent.reschedule(curTick + igbe->regs.tidv.idv() *
|
||||
igbe->intClock(), true);
|
||||
igbe->reschedule(igbe->tidvEvent,
|
||||
curTick + igbe->regs.tidv.idv() * igbe->intClock(), true);
|
||||
}
|
||||
|
||||
if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) {
|
||||
DPRINTF(EthernetDesc, "setting tadv\n");
|
||||
if (!igbe->tadvEvent.scheduled()) {
|
||||
igbe->tadvEvent.schedule(curTick + igbe->regs.tadv.idv() *
|
||||
igbe->intClock());
|
||||
igbe->schedule(igbe->tadvEvent,
|
||||
curTick + igbe->regs.tadv.idv() * igbe->intClock());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1126,9 +1127,9 @@ IGbE::TxDescCache::hasOutstandingEvents()
|
||||
void
|
||||
IGbE::restartClock()
|
||||
{
|
||||
if (!tickEvent.scheduled() && (rxTick || txTick || txFifoTick) && getState() ==
|
||||
SimObject::Running)
|
||||
tickEvent.schedule((curTick/ticks(1)) * ticks(1) + ticks(1));
|
||||
if (!tickEvent.scheduled() && (rxTick || txTick || txFifoTick) &&
|
||||
getState() == SimObject::Running)
|
||||
schedule(tickEvent, (curTick / ticks(1)) * ticks(1) + ticks(1));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
@@ -1147,7 +1148,7 @@ IGbE::drain(Event *de)
|
||||
rxTick = false;
|
||||
|
||||
if (tickEvent.scheduled())
|
||||
tickEvent.deschedule();
|
||||
deschedule(tickEvent);
|
||||
|
||||
if (count)
|
||||
changeState(Draining);
|
||||
@@ -1432,7 +1433,7 @@ IGbE::tick()
|
||||
|
||||
|
||||
if (rxTick || txTick || txFifoTick)
|
||||
tickEvent.schedule(curTick + ticks(1));
|
||||
schedule(tickEvent, curTick + ticks(1));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1538,19 +1539,19 @@ IGbE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
UNSERIALIZE_SCALAR(inter_time);
|
||||
|
||||
if (rdtr_time)
|
||||
rdtrEvent.schedule(rdtr_time);
|
||||
schedule(rdtrEvent, rdtr_time);
|
||||
|
||||
if (radv_time)
|
||||
radvEvent.schedule(radv_time);
|
||||
schedule(radvEvent, radv_time);
|
||||
|
||||
if (tidv_time)
|
||||
tidvEvent.schedule(tidv_time);
|
||||
schedule(tidvEvent, tidv_time);
|
||||
|
||||
if (tadv_time)
|
||||
tadvEvent.schedule(tadv_time);
|
||||
schedule(tadvEvent, tadv_time);
|
||||
|
||||
if (inter_time)
|
||||
interEvent.schedule(inter_time);
|
||||
schedule(interEvent, inter_time);
|
||||
|
||||
txDescCache.unserialize(cp, csprintf("%s.TxDescCache", section));
|
||||
|
||||
|
||||
@@ -293,14 +293,14 @@ class IGbE : public EtherDevice
|
||||
wbOut = max_to_wb;
|
||||
|
||||
assert(!wbDelayEvent.scheduled());
|
||||
wbDelayEvent.schedule(igbe->wbDelay + curTick);
|
||||
igbe->schedule(wbDelayEvent, curTick + igbe->wbDelay);
|
||||
}
|
||||
|
||||
void writeback1()
|
||||
{
|
||||
// If we're draining delay issuing this DMA
|
||||
if (igbe->drainEvent) {
|
||||
wbDelayEvent.schedule(igbe->wbDelay + curTick);
|
||||
igbe->schedule(wbDelayEvent, curTick + igbe->wbDelay);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -356,14 +356,14 @@ class IGbE : public EtherDevice
|
||||
curFetching = max_to_fetch;
|
||||
|
||||
assert(!fetchDelayEvent.scheduled());
|
||||
fetchDelayEvent.schedule(igbe->fetchDelay + curTick);
|
||||
igbe->schedule(fetchDelayEvent, curTick + igbe->fetchDelay);
|
||||
}
|
||||
|
||||
void fetchDescriptors1()
|
||||
{
|
||||
// If we're draining delay issuing this DMA
|
||||
if (igbe->drainEvent) {
|
||||
fetchDelayEvent.schedule(igbe->fetchDelay + curTick);
|
||||
igbe->schedule(fetchDelayEvent, curTick + igbe->fetchDelay);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -557,9 +557,9 @@ class IGbE : public EtherDevice
|
||||
UNSERIALIZE_SCALAR(fetch_delay);
|
||||
UNSERIALIZE_SCALAR(wb_delay);
|
||||
if (fetch_delay)
|
||||
fetchDelayEvent.schedule(fetch_delay);
|
||||
igbe->schedule(fetchDelayEvent, fetch_delay);
|
||||
if (wb_delay)
|
||||
wbDelayEvent.schedule(wb_delay);
|
||||
igbe->schedule(wbDelayEvent, wb_delay);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ IdeDisk::doDmaTransfer()
|
||||
dmaState, devState);
|
||||
|
||||
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
|
||||
dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
|
||||
schedule(dmaTransferEvent, curTick + DMA_BACKOFF_PERIOD);
|
||||
return;
|
||||
} else
|
||||
ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent,
|
||||
@@ -349,7 +349,7 @@ IdeDisk::doDmaDataRead()
|
||||
DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
|
||||
diskDelay, totalDiskDelay);
|
||||
|
||||
dmaReadWaitEvent.schedule(curTick + totalDiskDelay);
|
||||
schedule(dmaReadWaitEvent, curTick + totalDiskDelay);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -395,7 +395,7 @@ IdeDisk::doDmaRead()
|
||||
|
||||
}
|
||||
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
|
||||
dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
|
||||
schedule(dmaReadWaitEvent, curTick + DMA_BACKOFF_PERIOD);
|
||||
return;
|
||||
} else if (!dmaReadCG->done()) {
|
||||
assert(dmaReadCG->complete() < MAX_DMA_SIZE);
|
||||
@@ -457,7 +457,7 @@ IdeDisk::doDmaDataWrite()
|
||||
cmdBytesLeft -= SectorSize;
|
||||
}
|
||||
|
||||
dmaWriteWaitEvent.schedule(curTick + totalDiskDelay);
|
||||
schedule(dmaWriteWaitEvent, curTick + totalDiskDelay);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -470,7 +470,7 @@ IdeDisk::doDmaWrite()
|
||||
curPrd.getByteCount(), TheISA::PageBytes);
|
||||
}
|
||||
if (ctrl->dmaPending() || ctrl->getState() != SimObject::Running) {
|
||||
dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD);
|
||||
schedule(dmaWriteWaitEvent, curTick + DMA_BACKOFF_PERIOD);
|
||||
return;
|
||||
} else if (!dmaWriteCG->done()) {
|
||||
assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
|
||||
@@ -545,7 +545,7 @@ IdeDisk::startDma(const uint32_t &prdTableBase)
|
||||
dmaState = Dma_Transfer;
|
||||
|
||||
// schedule dma transfer (doDmaTransfer)
|
||||
dmaTransferEvent.schedule(curTick + 1);
|
||||
schedule(dmaTransferEvent, curTick + 1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1073,12 +1073,12 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion)
|
||||
|
||||
switch (event) {
|
||||
case None : break;
|
||||
case Transfer : dmaTransferEvent.schedule(reschedule); break;
|
||||
case ReadWait : dmaReadWaitEvent.schedule(reschedule); break;
|
||||
case WriteWait : dmaWriteWaitEvent.schedule(reschedule); break;
|
||||
case PrdRead : dmaPrdReadEvent.schedule(reschedule); break;
|
||||
case DmaRead : dmaReadEvent.schedule(reschedule); break;
|
||||
case DmaWrite : dmaWriteEvent.schedule(reschedule); break;
|
||||
case Transfer : schedule(dmaTransferEvent, reschedule); break;
|
||||
case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
|
||||
case WriteWait : schedule(dmaWriteWaitEvent, reschedule); break;
|
||||
case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
|
||||
case DmaRead : schedule(dmaReadEvent, reschedule); break;
|
||||
case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
|
||||
}
|
||||
|
||||
// Unserialize device registers
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
Intel8254Timer::Intel8254Timer(const string &name)
|
||||
: _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"),
|
||||
counter2(name + ".counter2")
|
||||
Intel8254Timer::Intel8254Timer(EventManager *em, const string &name)
|
||||
: EventManager(em), _name(name),
|
||||
counter0(this, name + ".counter0"),
|
||||
counter1(this, name + ".counter1"),
|
||||
counter2(this, name + ".counter2")
|
||||
{
|
||||
counter[0] = &counter0;
|
||||
counter[1] = &counter0;
|
||||
@@ -80,10 +82,10 @@ Intel8254Timer::unserialize(const string &base, Checkpoint *cp,
|
||||
counter2.unserialize(base + ".counter2", cp, section);
|
||||
}
|
||||
|
||||
Intel8254Timer::Counter::Counter(const string &name)
|
||||
Intel8254Timer::Counter::Counter(Intel8254Timer *p, const string &name)
|
||||
: _name(name), event(this), count(0), latched_count(0), period(0),
|
||||
mode(0), output_high(false), latch_on(false), read_byte(LSB),
|
||||
write_byte(LSB)
|
||||
write_byte(LSB), parent(p)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -140,7 +142,7 @@ Intel8254Timer::Counter::write(const uint8_t data)
|
||||
count = (count & 0xFF00) | data;
|
||||
|
||||
if (event.scheduled())
|
||||
event.deschedule();
|
||||
parent->deschedule(event);
|
||||
output_high = false;
|
||||
write_byte = MSB;
|
||||
break;
|
||||
@@ -226,11 +228,10 @@ Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
|
||||
Tick event_tick;
|
||||
paramIn(cp, section, base + ".event_tick", event_tick);
|
||||
if (event_tick)
|
||||
event.schedule(event_tick);
|
||||
parent->schedule(event, event_tick);
|
||||
}
|
||||
|
||||
Intel8254Timer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
|
||||
: Event(&mainEventQueue)
|
||||
{
|
||||
interval = (Tick)(Clock::Float::s / 1193180.0);
|
||||
counter = c_ptr;
|
||||
@@ -260,7 +261,7 @@ Intel8254Timer::Counter::CounterEvent::setTo(int clocks)
|
||||
panic("Timer can't be set to go off instantly.\n");
|
||||
DPRINTF(Intel8254Timer, "Timer set to curTick + %d\n",
|
||||
clocks * interval);
|
||||
schedule(curTick + clocks * interval);
|
||||
counter->parent->schedule(this, curTick + clocks * interval);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
||||
@@ -33,16 +33,16 @@
|
||||
#ifndef __DEV_8254_HH__
|
||||
#define __DEV_8254_HH__
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "base/bitunion.hh"
|
||||
#include "sim/eventq.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
/** Programmable Interval Timer (Intel 8254) */
|
||||
class Intel8254Timer
|
||||
class Intel8254Timer : public EventManager
|
||||
{
|
||||
BitUnion8(CtrlReg)
|
||||
Bitfield<7, 6> sel;
|
||||
@@ -129,8 +129,11 @@ class Intel8254Timer
|
||||
/** Determine which byte of a 16-bit count value to read/write */
|
||||
uint8_t read_byte, write_byte;
|
||||
|
||||
/** Pointer to container */
|
||||
Intel8254Timer *parent;
|
||||
|
||||
public:
|
||||
Counter(const std::string &name);
|
||||
Counter(Intel8254Timer *p, const std::string &name);
|
||||
|
||||
/** Latch the current count (if one is not already latched) */
|
||||
void latchCount();
|
||||
@@ -183,7 +186,7 @@ class Intel8254Timer
|
||||
Counter counter1;
|
||||
Counter counter2;
|
||||
|
||||
Intel8254Timer(const std::string &name);
|
||||
Intel8254Timer(EventManager *em, const std::string &name);
|
||||
|
||||
/** Write control word */
|
||||
void writeControl(const CtrlReg data);
|
||||
|
||||
@@ -117,7 +117,7 @@ DmaPort::recvTiming(PacketPtr pkt)
|
||||
else if (backoffTime < device->maxBackoffDelay)
|
||||
backoffTime <<= 1;
|
||||
|
||||
backoffEvent.reschedule(curTick + backoffTime, true);
|
||||
reschedule(backoffEvent, curTick + backoffTime, true);
|
||||
|
||||
DPRINTF(DMA, "Backoff time set to %d ticks\n", backoffTime);
|
||||
|
||||
@@ -139,7 +139,7 @@ DmaPort::recvTiming(PacketPtr pkt)
|
||||
assert(state->totBytes >= state->numBytes);
|
||||
if (state->totBytes == state->numBytes) {
|
||||
if (state->delay)
|
||||
state->completionEvent->schedule(state->delay + curTick);
|
||||
schedule(state->completionEvent, curTick + state->delay);
|
||||
else
|
||||
state->completionEvent->process();
|
||||
delete state;
|
||||
@@ -209,7 +209,7 @@ DmaPort::recvRetry()
|
||||
if (transmitList.size() && backoffTime && !inRetry) {
|
||||
DPRINTF(DMA, "Scheduling backoff for %d\n", curTick+backoffTime);
|
||||
if (!backoffEvent.scheduled())
|
||||
backoffEvent.schedule(backoffTime+curTick);
|
||||
schedule(backoffEvent, backoffTime + curTick);
|
||||
}
|
||||
DPRINTF(DMA, "TransmitList: %d, backoffTime: %d inRetry: %d es: %d\n",
|
||||
transmitList.size(), backoffTime, inRetry,
|
||||
@@ -297,7 +297,7 @@ DmaPort::sendDma()
|
||||
!backoffEvent.scheduled()) {
|
||||
DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
|
||||
backoffTime+curTick);
|
||||
backoffEvent.schedule(backoffTime+curTick);
|
||||
schedule(backoffEvent, backoffTime + curTick);
|
||||
}
|
||||
} else if (state == Enums::atomic) {
|
||||
transmitList.pop_front();
|
||||
@@ -317,7 +317,7 @@ DmaPort::sendDma()
|
||||
|
||||
if (state->totBytes == state->numBytes) {
|
||||
assert(!state->completionEvent->scheduled());
|
||||
state->completionEvent->schedule(curTick + lat + state->delay);
|
||||
schedule(state->completionEvent, curTick + lat + state->delay);
|
||||
delete state;
|
||||
delete pkt->req;
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
MC146818::MC146818(const string &n, const struct tm time,
|
||||
bool bcd, Tick frequency)
|
||||
: _name(n), event(this, frequency)
|
||||
MC146818::MC146818(EventManager *em, const string &n, const struct tm time,
|
||||
bool bcd, Tick frequency)
|
||||
: EventManager(em), _name(n), event(this, frequency)
|
||||
{
|
||||
memset(clock_data, 0, sizeof(clock_data));
|
||||
stat_regA = RTCA_32768HZ | RTCA_1024HZ;
|
||||
@@ -75,6 +75,10 @@ MC146818::MC146818(const string &n, const struct tm time,
|
||||
DPRINTFN("Real-time clock set to %s", asctime(&time));
|
||||
}
|
||||
|
||||
MC146818::~MC146818()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MC146818::writeData(const uint8_t addr, const uint8_t data)
|
||||
{
|
||||
@@ -96,7 +100,7 @@ MC146818::writeData(const uint8_t addr, const uint8_t data)
|
||||
event.scheduleIntr();
|
||||
} else {
|
||||
if (event.scheduled())
|
||||
event.deschedule();
|
||||
deschedule(event);
|
||||
}
|
||||
stat_regB = data;
|
||||
break;
|
||||
@@ -153,27 +157,27 @@ MC146818::unserialize(const string &base, Checkpoint *cp,
|
||||
// We're not unserializing the event here, but we need to
|
||||
// rescehedule the event since curTick was moved forward by the
|
||||
// checkpoint
|
||||
event.reschedule(curTick + event.interval);
|
||||
reschedule(event, curTick + event.interval);
|
||||
}
|
||||
|
||||
MC146818::RTCEvent::RTCEvent(MC146818 * _parent, Tick i)
|
||||
: Event(&mainEventQueue), parent(_parent), interval(i)
|
||||
: parent(_parent), interval(i)
|
||||
{
|
||||
DPRINTF(MC146818, "RTC Event Initilizing\n");
|
||||
schedule(curTick + interval);
|
||||
parent->schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
void
|
||||
MC146818::RTCEvent::scheduleIntr()
|
||||
{
|
||||
schedule(curTick + interval);
|
||||
parent->schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
void
|
||||
MC146818::RTCEvent::process()
|
||||
{
|
||||
DPRINTF(MC146818, "RTC Timer Interrupt\n");
|
||||
schedule(curTick + interval);
|
||||
parent->schedule(this, curTick + interval);
|
||||
parent->handleEvent();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "sim/eventq.hh"
|
||||
|
||||
/** Real-Time Clock (MC146818) */
|
||||
class MC146818
|
||||
class MC146818 : public EventManager
|
||||
{
|
||||
protected:
|
||||
virtual void handleEvent()
|
||||
@@ -96,11 +96,9 @@ class MC146818
|
||||
uint8_t stat_regB;
|
||||
|
||||
public:
|
||||
virtual ~MC146818()
|
||||
{}
|
||||
|
||||
MC146818(const std::string &name, const struct tm time,
|
||||
MC146818(EventManager *em, const std::string &name, const struct tm time,
|
||||
bool bcd, Tick frequency);
|
||||
virtual ~MC146818();
|
||||
|
||||
/** RTC write data */
|
||||
void writeData(const uint8_t addr, const uint8_t data);
|
||||
|
||||
@@ -945,7 +945,8 @@ NSGigE::cpuIntrPost(Tick when)
|
||||
|
||||
if (intrEvent)
|
||||
intrEvent->squash();
|
||||
intrEvent = new IntrEvent(this, intrTick, true);
|
||||
intrEvent = new IntrEvent(this, true);
|
||||
schedule(intrEvent, intrTick);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1442,7 +1443,7 @@ NSGigE::rxKick()
|
||||
NsRxStateStrings[rxState]);
|
||||
|
||||
if (clock && !rxKickEvent.scheduled())
|
||||
rxKickEvent.schedule(rxKickTick);
|
||||
schedule(rxKickEvent, rxKickTick);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1492,7 +1493,7 @@ NSGigE::transmit()
|
||||
|
||||
if (!txFifo.empty() && !txEvent.scheduled()) {
|
||||
DPRINTF(Ethernet, "reschedule transmit\n");
|
||||
txEvent.schedule(curTick + retryTime);
|
||||
schedule(txEvent, curTick + retryTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1885,7 +1886,7 @@ NSGigE::txKick()
|
||||
NsTxStateStrings[txState]);
|
||||
|
||||
if (clock && !txKickEvent.scheduled())
|
||||
txKickEvent.schedule(txKickTick);
|
||||
schedule(txKickEvent, txKickTick);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1999,7 +2000,7 @@ NSGigE::transferDone()
|
||||
|
||||
DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
|
||||
|
||||
txEvent.reschedule(curTick + ticks(1), true);
|
||||
reschedule(txEvent, curTick + ticks(1), true);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2400,7 +2401,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
this->txDmaState = (DmaState) txDmaState;
|
||||
UNSERIALIZE_SCALAR(txKickTick);
|
||||
if (txKickTick)
|
||||
txKickEvent.schedule(txKickTick);
|
||||
schedule(txKickEvent, txKickTick);
|
||||
|
||||
/*
|
||||
* unserialize rx state machine
|
||||
@@ -2418,7 +2419,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
this->rxDmaState = (DmaState) rxDmaState;
|
||||
UNSERIALIZE_SCALAR(rxKickTick);
|
||||
if (rxKickTick)
|
||||
rxKickEvent.schedule(rxKickTick);
|
||||
schedule(rxKickEvent, rxKickTick);
|
||||
|
||||
/*
|
||||
* Unserialize EEPROM state machine
|
||||
@@ -2438,7 +2439,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
Tick transmitTick;
|
||||
UNSERIALIZE_SCALAR(transmitTick);
|
||||
if (transmitTick)
|
||||
txEvent.schedule(curTick + transmitTick);
|
||||
schedule(txEvent, curTick + transmitTick);
|
||||
|
||||
/*
|
||||
* unserialize receive address filter settings
|
||||
@@ -2459,7 +2460,8 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
Tick intrEventTick;
|
||||
UNSERIALIZE_SCALAR(intrEventTick);
|
||||
if (intrEventTick) {
|
||||
intrEvent = new IntrEvent(this, intrEventTick, true);
|
||||
intrEvent = new IntrEvent(this, true);
|
||||
schedule(intrEvent, intrEventTick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ using namespace std;
|
||||
|
||||
PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid,
|
||||
int funcid, Platform *p)
|
||||
: SimpleTimingPort(dev->name() + "-pciconf"), device(dev), platform(p),
|
||||
busId(busid), deviceId(devid), functionId(funcid)
|
||||
: SimpleTimingPort(dev->name() + "-pciconf", dev), device(dev),
|
||||
platform(p), busId(busid), deviceId(devid), functionId(funcid)
|
||||
{
|
||||
configAddr = platform->calcConfigAddr(busId, deviceId, functionId);
|
||||
}
|
||||
|
||||
@@ -695,7 +695,8 @@ Base::cpuIntrPost(Tick when)
|
||||
|
||||
if (intrEvent)
|
||||
intrEvent->squash();
|
||||
intrEvent = new IntrEvent(this, intrTick, true);
|
||||
intrEvent = new IntrEvent(this, true);
|
||||
schedule(intrEvent, intrTick);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1315,7 +1316,7 @@ Device::transferDone()
|
||||
|
||||
DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
|
||||
|
||||
txEvent.reschedule(curTick + ticks(1), true);
|
||||
reschedule(txEvent, curTick + ticks(1), true);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1455,7 +1456,8 @@ Base::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
Tick intrEventTick;
|
||||
UNSERIALIZE_SCALAR(intrEventTick);
|
||||
if (intrEventTick) {
|
||||
intrEvent = new IntrEvent(this, intrEventTick, true);
|
||||
intrEvent = new IntrEvent(this, true);
|
||||
schedule(intrEvent, intrEventTick);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1705,7 +1707,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
Tick transmitTick;
|
||||
UNSERIALIZE_SCALAR(transmitTick);
|
||||
if (transmitTick)
|
||||
txEvent.schedule(curTick + transmitTick);
|
||||
schedule(txEvent, curTick + transmitTick);
|
||||
|
||||
pioPort->sendStatusChange(Port::RangeChange);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ using namespace std;
|
||||
using namespace TheISA;
|
||||
|
||||
Uart8250::IntrEvent::IntrEvent(Uart8250 *u, int bit)
|
||||
: Event(&mainEventQueue), uart(u)
|
||||
: uart(u)
|
||||
{
|
||||
DPRINTF(Uart, "UART Interrupt Event Initilizing\n");
|
||||
intrBit = bit;
|
||||
@@ -93,9 +93,9 @@ Uart8250::IntrEvent::scheduleIntr()
|
||||
DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit,
|
||||
curTick + interval);
|
||||
if (!scheduled())
|
||||
schedule(curTick + interval);
|
||||
uart->schedule(this, curTick + interval);
|
||||
else
|
||||
reschedule(curTick + interval);
|
||||
uart->reschedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ Uart8250::write(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(Uart, "IER: IER_THRI cleared, descheduling TX intrrupt\n");
|
||||
if (txIntrEvent.scheduled())
|
||||
txIntrEvent.deschedule();
|
||||
deschedule(txIntrEvent);
|
||||
if (status & TX_INT)
|
||||
platform->clearConsoleInt();
|
||||
status &= ~TX_INT;
|
||||
@@ -243,7 +243,7 @@ Uart8250::write(PacketPtr pkt)
|
||||
} else {
|
||||
DPRINTF(Uart, "IER: IER_RDI cleared, descheduling RX intrrupt\n");
|
||||
if (rxIntrEvent.scheduled())
|
||||
rxIntrEvent.deschedule();
|
||||
deschedule(rxIntrEvent);
|
||||
if (status & RX_INT)
|
||||
platform->clearConsoleInt();
|
||||
status &= ~RX_INT;
|
||||
@@ -329,9 +329,9 @@ Uart8250::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
UNSERIALIZE_SCALAR(rxintrwhen);
|
||||
UNSERIALIZE_SCALAR(txintrwhen);
|
||||
if (rxintrwhen != 0)
|
||||
rxIntrEvent.schedule(rxintrwhen);
|
||||
schedule(rxIntrEvent, rxintrwhen);
|
||||
if (txintrwhen != 0)
|
||||
txIntrEvent.schedule(txintrwhen);
|
||||
schedule(txIntrEvent, txintrwhen);
|
||||
}
|
||||
|
||||
Uart8250 *
|
||||
|
||||
@@ -47,7 +47,7 @@ Bridge::BridgePort::BridgePort(const std::string &_name,
|
||||
int _delay, int _nack_delay, int _req_limit,
|
||||
int _resp_limit,
|
||||
std::vector<Range<Addr> > filter_ranges)
|
||||
: Port(_name), bridge(_bridge), otherPort(_otherPort),
|
||||
: Port(_name, _bridge), bridge(_bridge), otherPort(_otherPort),
|
||||
delay(_delay), nackDelay(_nack_delay), filterRanges(filter_ranges),
|
||||
outstandingResponses(0), queuedRequests(0), inRetry(false),
|
||||
reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
|
||||
@@ -162,7 +162,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
|
||||
// nothing on the list, add it and we're done
|
||||
if (sendQueue.empty()) {
|
||||
assert(!sendEvent.scheduled());
|
||||
sendEvent.schedule(readyTime);
|
||||
schedule(sendEvent, readyTime);
|
||||
sendQueue.push_back(buf);
|
||||
return;
|
||||
}
|
||||
@@ -184,7 +184,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
|
||||
while (i != end && !done) {
|
||||
if (readyTime < (*i)->ready) {
|
||||
if (i == begin)
|
||||
sendEvent.reschedule(readyTime);
|
||||
reschedule(sendEvent, readyTime);
|
||||
sendQueue.insert(i,buf);
|
||||
done = true;
|
||||
}
|
||||
@@ -227,7 +227,7 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
|
||||
// should already be an event scheduled for sending the head
|
||||
// packet.
|
||||
if (sendQueue.empty()) {
|
||||
sendEvent.schedule(readyTime);
|
||||
schedule(sendEvent, readyTime);
|
||||
}
|
||||
sendQueue.push_back(buf);
|
||||
}
|
||||
@@ -281,7 +281,7 @@ Bridge::BridgePort::trySend()
|
||||
if (!sendQueue.empty()) {
|
||||
buf = sendQueue.front();
|
||||
DPRINTF(BusBridge, "Scheduling next send\n");
|
||||
sendEvent.schedule(std::max(buf->ready, curTick + 1));
|
||||
schedule(sendEvent, std::max(buf->ready, curTick + 1));
|
||||
}
|
||||
} else {
|
||||
DPRINTF(BusBridge, " unsuccessful\n");
|
||||
@@ -302,7 +302,7 @@ Bridge::BridgePort::recvRetry()
|
||||
if (nextReady <= curTick)
|
||||
trySend();
|
||||
else
|
||||
sendEvent.schedule(nextReady);
|
||||
schedule(sendEvent, nextReady);
|
||||
}
|
||||
|
||||
/** Function called by the port when the bus is receiving a Atomic
|
||||
|
||||
@@ -146,11 +146,8 @@ class Bridge : public MemObject
|
||||
BridgePort *port;
|
||||
|
||||
public:
|
||||
SendEvent(BridgePort *p)
|
||||
: Event(&mainEventQueue), port(p) {}
|
||||
|
||||
SendEvent(BridgePort *p) : port(p) {}
|
||||
virtual void process() { port->trySend(); }
|
||||
|
||||
virtual const char *description() const { return "bridge send"; }
|
||||
};
|
||||
|
||||
|
||||
@@ -97,20 +97,24 @@ Bus::init()
|
||||
intIter->second->sendStatusChange(Port::RangeChange);
|
||||
}
|
||||
|
||||
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus)
|
||||
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus)
|
||||
: bus(_bus)
|
||||
{}
|
||||
|
||||
void Bus::BusFreeEvent::process()
|
||||
void
|
||||
Bus::BusFreeEvent::process()
|
||||
{
|
||||
bus->recvRetry(-1);
|
||||
}
|
||||
|
||||
const char * Bus::BusFreeEvent::description() const
|
||||
const char *
|
||||
Bus::BusFreeEvent::description() const
|
||||
{
|
||||
return "bus became available";
|
||||
}
|
||||
|
||||
Tick Bus::calcPacketTiming(PacketPtr pkt)
|
||||
Tick
|
||||
Bus::calcPacketTiming(PacketPtr pkt)
|
||||
{
|
||||
// Bring tickNextIdle up to the present tick.
|
||||
// There is some potential ambiguity where a cycle starts, which
|
||||
@@ -155,12 +159,8 @@ void Bus::occupyBus(Tick until)
|
||||
}
|
||||
|
||||
tickNextIdle = until;
|
||||
reschedule(busIdle, tickNextIdle, true);
|
||||
|
||||
if (!busIdle.scheduled()) {
|
||||
busIdle.schedule(tickNextIdle);
|
||||
} else {
|
||||
busIdle.reschedule(tickNextIdle);
|
||||
}
|
||||
DPRINTF(Bus, "The bus is now occupied from tick %d to %d\n",
|
||||
curTick, tickNextIdle);
|
||||
}
|
||||
@@ -293,7 +293,7 @@ Bus::recvRetry(int id)
|
||||
//Burn a cycle for the missed grant.
|
||||
tickNextIdle += clock;
|
||||
|
||||
busIdle.reschedule(tickNextIdle, true);
|
||||
reschedule(busIdle, tickNextIdle, true);
|
||||
}
|
||||
}
|
||||
//If we weren't able to drain before, we might be able to now.
|
||||
|
||||
2
src/mem/cache/base.cc
vendored
2
src/mem/cache/base.cc
vendored
@@ -122,7 +122,7 @@ BaseCache::CachePort::clearBlocked()
|
||||
mustSendRetry = false;
|
||||
SendRetryEvent *ev = new SendRetryEvent(this, true);
|
||||
// @TODO: need to find a better time (next bus cycle?)
|
||||
ev->schedule(curTick + 1);
|
||||
schedule(ev, curTick + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
src/mem/cache/cache_impl.hh
vendored
2
src/mem/cache/cache_impl.hh
vendored
@@ -1489,7 +1489,7 @@ Cache<TagStore>::MemSidePort::sendPacket()
|
||||
// @TODO: need to facotr in prefetch requests here somehow
|
||||
if (nextReady != MaxTick) {
|
||||
DPRINTF(CachePort, "more packets to send @ %d\n", nextReady);
|
||||
sendEvent->schedule(std::max(nextReady, curTick + 1));
|
||||
schedule(sendEvent, std::max(nextReady, curTick + 1));
|
||||
} else {
|
||||
// no more to send right now: if we're draining, we may be done
|
||||
if (drainEvent) {
|
||||
|
||||
@@ -383,7 +383,7 @@ PhysicalMemory::recvStatusChange(Port::Status status)
|
||||
|
||||
PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
|
||||
PhysicalMemory *_memory)
|
||||
: SimpleTimingPort(_name), memory(_memory)
|
||||
: SimpleTimingPort(_name, _memory), memory(_memory)
|
||||
{ }
|
||||
|
||||
void
|
||||
|
||||
@@ -138,7 +138,7 @@ SimpleTimingPort::sendDeferredPacket()
|
||||
if (success) {
|
||||
if (!transmitList.empty() && !sendEvent->scheduled()) {
|
||||
Tick time = transmitList.front().tick;
|
||||
sendEvent->schedule(time <= curTick ? curTick+1 : time);
|
||||
schedule(sendEvent, time <= curTick ? curTick+1 : time);
|
||||
}
|
||||
|
||||
if (transmitList.empty() && drainEvent) {
|
||||
|
||||
@@ -108,7 +108,8 @@ class SimpleTimingPort : public Port
|
||||
Tick deferredPacketReadyTime()
|
||||
{ return transmitList.empty() ? MaxTick : transmitList.front().tick; }
|
||||
|
||||
void schedSendEvent(Tick when)
|
||||
void
|
||||
schedSendEvent(Tick when)
|
||||
{
|
||||
if (waitingOnRetry) {
|
||||
assert(!sendEvent->scheduled());
|
||||
@@ -116,9 +117,9 @@ class SimpleTimingPort : public Port
|
||||
}
|
||||
|
||||
if (!sendEvent->scheduled()) {
|
||||
sendEvent->schedule(when);
|
||||
schedule(sendEvent, when);
|
||||
} else if (sendEvent->when() > when) {
|
||||
sendEvent->reschedule(when);
|
||||
reschedule(sendEvent, when);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +156,7 @@ class SimpleTimingPort : public Port
|
||||
|
||||
public:
|
||||
|
||||
SimpleTimingPort(std::string pname, MemObject *_owner = NULL)
|
||||
SimpleTimingPort(std::string pname, MemObject *_owner)
|
||||
: Port(pname, _owner),
|
||||
sendEvent(new SendEvent(this)),
|
||||
drainEvent(NULL),
|
||||
|
||||
@@ -326,7 +326,9 @@ def main():
|
||||
if options.trace_start:
|
||||
def enable_trace():
|
||||
internal.trace.cvar.enabled = True
|
||||
event.create(enable_trace, int(options.trace_start))
|
||||
|
||||
e = event.create(enable_trace)
|
||||
event.mainq.schedule(e, options.trace_start)
|
||||
else:
|
||||
internal.trace.cvar.enabled = True
|
||||
|
||||
|
||||
@@ -56,12 +56,9 @@ debug_break()
|
||||
// Debug event: place a breakpoint on the process function and
|
||||
// schedule the event to break at a particular cycle
|
||||
//
|
||||
class DebugBreakEvent : public Event
|
||||
struct DebugBreakEvent : public Event
|
||||
{
|
||||
public:
|
||||
|
||||
DebugBreakEvent(EventQueue *q, Tick _when);
|
||||
|
||||
DebugBreakEvent();
|
||||
void process(); // process event
|
||||
virtual const char *description() const;
|
||||
};
|
||||
@@ -69,11 +66,10 @@ class DebugBreakEvent : public Event
|
||||
//
|
||||
// constructor: schedule at specified time
|
||||
//
|
||||
DebugBreakEvent::DebugBreakEvent(EventQueue *q, Tick _when)
|
||||
: Event(q, Debug_Break_Pri)
|
||||
DebugBreakEvent::DebugBreakEvent()
|
||||
: Event(Debug_Break_Pri)
|
||||
{
|
||||
setFlags(AutoDelete);
|
||||
schedule(_when);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -99,13 +95,15 @@ DebugBreakEvent::description() const
|
||||
void
|
||||
schedBreakCycle(Tick when)
|
||||
{
|
||||
new DebugBreakEvent(&mainEventQueue, when);
|
||||
mainEventQueue.schedule(new DebugBreakEvent, when);
|
||||
warn("need to stop all queues");
|
||||
}
|
||||
|
||||
void
|
||||
eventqDump()
|
||||
{
|
||||
mainEventQueue.dump();
|
||||
warn("need to dump all queues");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "params/BaseCPU.hh"
|
||||
#include "sim/pseudo_inst.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "sim/stat_control.hh"
|
||||
#include "sim/stats.hh"
|
||||
@@ -88,7 +89,7 @@ quiesceNs(ThreadContext *tc, uint64_t ns)
|
||||
|
||||
Tick resume = curTick + Clock::Int::ns * ns;
|
||||
|
||||
quiesceEvent->reschedule(resume, true);
|
||||
mainEventQueue.reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
|
||||
tc->getCpuPtr()->name(), ns, resume);
|
||||
@@ -108,7 +109,7 @@ quiesceCycles(ThreadContext *tc, uint64_t cycles)
|
||||
|
||||
Tick resume = curTick + tc->getCpuPtr()->ticks(cycles);
|
||||
|
||||
quiesceEvent->reschedule(resume, true);
|
||||
mainEventQueue.reschedule(quiesceEvent, resume, true);
|
||||
|
||||
DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
|
||||
tc->getCpuPtr()->name(), cycles, resume);
|
||||
@@ -128,7 +129,8 @@ void
|
||||
m5exit(ThreadContext *tc, Tick delay)
|
||||
{
|
||||
Tick when = curTick + delay * Clock::Int::ns;
|
||||
schedExitSimLoop("m5_exit instruction encountered", when);
|
||||
Event *event = new SimLoopExitEvent("m5_exit instruction encountered", 0);
|
||||
mainEventQueue.schedule(event, when);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -239,7 +241,8 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
|
||||
Tick when = curTick + delay * Clock::Int::ns;
|
||||
Tick repeat = period * Clock::Int::ns;
|
||||
|
||||
schedExitSimLoop("checkpoint", when, repeat);
|
||||
Event *event = new SimLoopExitEvent("checkpoint", 0, repeat);
|
||||
mainEventQueue.schedule(event, when);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
||||
@@ -40,6 +40,13 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
SimLoopExitEvent::SimLoopExitEvent(const std::string &_cause, int c, Tick r)
|
||||
: Event(Sim_Exit_Pri), cause(_cause), code(c), repeat(r)
|
||||
{
|
||||
setFlags(IsExitEvent);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// handle termination event
|
||||
//
|
||||
@@ -49,7 +56,7 @@ SimLoopExitEvent::process()
|
||||
// if this got scheduled on a different queue (e.g. the committed
|
||||
// instruction queue) then make a corresponding event on the main
|
||||
// queue.
|
||||
if (queue() != &mainEventQueue) {
|
||||
if (!getFlags(IsMainQueue)) {
|
||||
exitSimLoop(cause, code);
|
||||
delete this;
|
||||
}
|
||||
@@ -59,7 +66,8 @@ SimLoopExitEvent::process()
|
||||
|
||||
// but if you are doing this on intervals, don't forget to make another
|
||||
if (repeat) {
|
||||
schedule(curTick + repeat);
|
||||
assert(getFlags(IsMainQueue));
|
||||
mainEventQueue.schedule(this, curTick + repeat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,43 +78,32 @@ SimLoopExitEvent::description() const
|
||||
return "simulation loop exit";
|
||||
}
|
||||
|
||||
SimLoopExitEvent *
|
||||
schedExitSimLoop(const std::string &message, Tick when, Tick repeat,
|
||||
EventQueue *q, int exit_code)
|
||||
{
|
||||
if (q == NULL)
|
||||
q = &mainEventQueue;
|
||||
|
||||
return new SimLoopExitEvent(q, when, repeat, message, exit_code);
|
||||
}
|
||||
|
||||
void
|
||||
exitSimLoop(const std::string &message, int exit_code)
|
||||
{
|
||||
schedExitSimLoop(message, curTick, 0, NULL, exit_code);
|
||||
Event *event = new SimLoopExitEvent(message, exit_code);
|
||||
mainEventQueue.schedule(event, curTick);
|
||||
}
|
||||
|
||||
CountedDrainEvent::CountedDrainEvent()
|
||||
: SimLoopExitEvent("Finished drain", 0), count(0)
|
||||
{ }
|
||||
|
||||
void
|
||||
CountedDrainEvent::process()
|
||||
{
|
||||
if (--count == 0) {
|
||||
exitSimLoop("Finished drain");
|
||||
}
|
||||
if (--count == 0)
|
||||
exitSimLoop(cause, code);
|
||||
}
|
||||
|
||||
//
|
||||
// constructor: automatically schedules at specified time
|
||||
//
|
||||
CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
|
||||
Tick _when, int &_downCounter)
|
||||
: Event(q, Sim_Exit_Pri),
|
||||
cause(_cause),
|
||||
downCounter(_downCounter)
|
||||
CountedExitEvent::CountedExitEvent(const std::string &_cause, int &counter)
|
||||
: Event(Sim_Exit_Pri), cause(_cause), downCounter(counter)
|
||||
{
|
||||
// catch stupid mistakes
|
||||
assert(downCounter > 0);
|
||||
|
||||
schedule(_when);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,9 +125,11 @@ CountedExitEvent::description() const
|
||||
return "counted exit";
|
||||
}
|
||||
|
||||
#ifdef CHECK_SWAP_CYCLES
|
||||
new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
|
||||
#endif
|
||||
CheckSwapEvent::CheckSwapEvent(int ival)
|
||||
: interval(ival)
|
||||
{
|
||||
mainEventQueue.schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
void
|
||||
CheckSwapEvent::process()
|
||||
@@ -149,7 +148,8 @@ CheckSwapEvent::process()
|
||||
exitSimLoop("Lack of swap space");
|
||||
}
|
||||
|
||||
schedule(curTick + interval);
|
||||
assert(getFlags(IsMainQueue));
|
||||
mainEventQueue.schedule(this, curTick + interval);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
||||
@@ -38,30 +38,14 @@
|
||||
//
|
||||
class SimLoopExitEvent : public Event
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
// string explaining why we're terminating
|
||||
std::string cause;
|
||||
int code;
|
||||
Tick repeat;
|
||||
|
||||
public:
|
||||
// Default constructor. Only really used for derived classes.
|
||||
SimLoopExitEvent()
|
||||
: Event(&mainEventQueue, Sim_Exit_Pri)
|
||||
{ }
|
||||
|
||||
SimLoopExitEvent(EventQueue *q,
|
||||
Tick _when, Tick _repeat, const std::string &_cause,
|
||||
int c = 0)
|
||||
: Event(q, Sim_Exit_Pri), cause(_cause),
|
||||
code(c), repeat(_repeat)
|
||||
{ setFlags(IsExitEvent); schedule(_when); }
|
||||
|
||||
// SimLoopExitEvent(EventQueue *q,
|
||||
// Tick _when, const std::string &_cause,
|
||||
// Tick _repeat = 0, int c = 0)
|
||||
// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat)
|
||||
// { setFlags(IsExitEvent); schedule(_when); }
|
||||
SimLoopExitEvent(const std::string &_cause, int c, Tick repeat = 0);
|
||||
|
||||
std::string getCause() { return cause; }
|
||||
int getCode() { return code; }
|
||||
@@ -76,10 +60,10 @@ class CountedDrainEvent : public SimLoopExitEvent
|
||||
private:
|
||||
// Count of how many objects have not yet drained
|
||||
int count;
|
||||
|
||||
public:
|
||||
CountedDrainEvent()
|
||||
: count(0)
|
||||
{ }
|
||||
CountedDrainEvent();
|
||||
|
||||
void process();
|
||||
|
||||
void setCount(int _count) { count = _count; }
|
||||
@@ -99,8 +83,7 @@ class CountedExitEvent : public Event
|
||||
int &downCounter; // decrement & terminate if zero
|
||||
|
||||
public:
|
||||
CountedExitEvent(EventQueue *q, const std::string &_cause,
|
||||
Tick _when, int &_downCounter);
|
||||
CountedExitEvent(const std::string &_cause, int &_downCounter);
|
||||
|
||||
void process(); // process event
|
||||
|
||||
@@ -116,10 +99,7 @@ class CheckSwapEvent : public Event
|
||||
int interval;
|
||||
|
||||
public:
|
||||
CheckSwapEvent(EventQueue *q, int ival)
|
||||
: Event(q), interval(ival)
|
||||
{ schedule(curTick + interval); }
|
||||
|
||||
CheckSwapEvent(int ival);
|
||||
void process(); // process event
|
||||
|
||||
virtual const char *description() const;
|
||||
|
||||
@@ -45,14 +45,6 @@ class SimLoopExitEvent;
|
||||
/// sim/main.cc.
|
||||
void registerExitCallback(Callback *);
|
||||
|
||||
/// Schedule an event to exit the simulation loop (returning to
|
||||
/// Python) at the indicated tick. The message and exit_code
|
||||
/// parameters are saved in the SimLoopExitEvent to indicate why the
|
||||
/// exit occurred.
|
||||
SimLoopExitEvent *schedExitSimLoop(const std::string &message, Tick when,
|
||||
Tick repeat = 0, EventQueue *q = NULL,
|
||||
int exit_code = 0);
|
||||
|
||||
/// Schedule an event to exit the simulation loop (returning to
|
||||
/// Python) at the end of the current cycle (curTick). The message
|
||||
/// and exit_code parameters are saved in the SimLoopExitEvent to
|
||||
|
||||
@@ -39,8 +39,14 @@ struct PyObject;
|
||||
#include <string>
|
||||
|
||||
struct EventQueue;
|
||||
|
||||
struct SimObjectParams
|
||||
{
|
||||
SimObjectParams()
|
||||
{
|
||||
extern EventQueue mainEventQueue;
|
||||
eventq = &mainEventQueue;
|
||||
}
|
||||
virtual ~SimObjectParams() {}
|
||||
|
||||
std::string name;
|
||||
|
||||
@@ -56,8 +56,9 @@ simulate(Tick num_cycles)
|
||||
else
|
||||
num_cycles = curTick + num_cycles;
|
||||
|
||||
Event *limit_event;
|
||||
limit_event = schedExitSimLoop("simulate() limit reached", num_cycles);
|
||||
Event *limit_event =
|
||||
new SimLoopExitEvent("simulate() limit reached", 0);
|
||||
mainEventQueue.schedule(limit_event, num_cycles);
|
||||
|
||||
while (1) {
|
||||
// there should always be at least one event (the SimLoopExitEvent
|
||||
@@ -82,8 +83,8 @@ simulate(Tick num_cycles)
|
||||
// if we didn't hit limit_event, delete it
|
||||
if (se_event != limit_event) {
|
||||
assert(limit_event->scheduled());
|
||||
limit_event->deschedule();
|
||||
delete limit_event;
|
||||
limit_event->squash();
|
||||
warn_once("be nice to actually delete the event here");
|
||||
}
|
||||
|
||||
return se_event;
|
||||
|
||||
@@ -154,12 +154,10 @@ class _StatEvent : public Event
|
||||
Tick repeat;
|
||||
|
||||
public:
|
||||
_StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat)
|
||||
: Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset),
|
||||
repeat(_repeat)
|
||||
_StatEvent(bool _dump, bool _reset, Tick _repeat)
|
||||
: Event(Stat_Event_Pri), dump(_dump), reset(_reset), repeat(_repeat)
|
||||
{
|
||||
setFlags(AutoDelete);
|
||||
schedule(_when);
|
||||
}
|
||||
|
||||
virtual void
|
||||
@@ -171,15 +169,18 @@ class _StatEvent : public Event
|
||||
if (reset)
|
||||
Stats::reset();
|
||||
|
||||
if (repeat)
|
||||
new _StatEvent(dump, reset, curTick + repeat, repeat);
|
||||
if (repeat) {
|
||||
Event *event = new _StatEvent(dump, reset, repeat);
|
||||
mainEventQueue.schedule(event, curTick + repeat);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
StatEvent(bool dump, bool reset, Tick when, Tick repeat)
|
||||
{
|
||||
new _StatEvent(dump, reset, when, repeat);
|
||||
Event *event = new _StatEvent(dump, reset, repeat);
|
||||
mainEventQueue.schedule(event, when);
|
||||
}
|
||||
|
||||
/* namespace Stats */ }
|
||||
|
||||
Reference in New Issue
Block a user