Whatever is calling fetch should be checking if the state is Drained
or Draining and not do it.
Ali
On Aug 13, 2009, at 3:59 PM, Rick Strong wrote:
> Hi all
>
> In TimingSimpleCPU copied below, I have encountered a case where
> _status==IcacheWaitResponse as the core is currently waiting for a
> response from the instruction cache and I see the response from the
> icache about to be satisfied (1000 ticks later). At this point, I have
> resumed from a checkpoint in atomic mode, switch to timingMode for
> 100
> ticks and am now switching the core to O3. It appears that some event
> is supposed to make sure the _status of the core is in running or idle
> before this function is called. Upon further debugging, I notice that
> the drain() function is being called in timing.cc for each of 4 cores
> (in a 4 core system) and then core 0 is initially able to change state
> to drained. However, CPU 1 and 3 are waiting on a nICacheReply. While
> waiting, I see core0's fetch() (in timing.cc) get called which
> creates
> a new event that prevents switch out. It appears that there is a race
> condition between drain being called and switchOut that sometimes
> leads
> to problems (with more problems happening as I go to 64 cores). Should
> there be code in TimingSimpleCPU::fetch() (marked in a comment below)
> that prevents this corner case from happening? Is there some other
> means
> that prevents fetch from being called after the core has been drained?
>
> Thanks in advance,
> -Richard Strong
>
> void
> TimingSimpleCPU::switchOut()
> {
> assert(_status == Running || _status == Idle);
> _status = SwitchedOut;
> numCycles += tickToCycles(curTick - previousTick);
>
> // If we've been scheduled to resume but are then told to switch
> out,
> // we'll need to cancel it.
> if (fetchEvent.scheduled())
> deschedule(fetchEvent);
> }
>
> void
> TimingSimpleCPU::fetch()
> {
> DPRINTF(SimpleCPU, "Fetch\n");
> /* PLACE TO ADD CHECK FOR STATE DRAINED */
> if (!curStaticInst || !curStaticInst->isDelayedCommit())
> checkForInterrupts();
>
> checkPcEventQueue();
>
> bool fromRom = isRomMicroPC(thread->readMicroPC());
>
> if (!fromRom && !curMacroStaticInst) {
> Request *ifetch_req = new Request();
> ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
> setupFetchRequest(ifetch_req);
> thread->itb->translateTiming(ifetch_req, tc, &fetchTranslation,
> BaseTLB::Execute);
> } else {
> _status = IcacheWaitResponse;
> completeIfetch(NULL);
>
> numCycles += tickToCycles(curTick - previousTick);
> previousTick = curTick;
> }
> }
> _______________________________________________
> m5-users mailing list
> [email protected]
> http://m5sim.org/cgi-bin/mailman/listinfo/m5-users
>
_______________________________________________
m5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/m5-users