simple_thread.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 315 行
CC
315 行
/* * Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Steven K. Reinhardt * Nathan L. Binkert * Lisa R. Hsu * Kevin T. Lim */#include <string>#include "arch/isa_traits.hh"#include "cpu/base.hh"#include "cpu/simple_thread.hh"#include "cpu/thread_context.hh"#if FULL_SYSTEM#include "arch/kernel_stats.hh"#include "base/callback.hh"#include "base/cprintf.hh"#include "base/output.hh"#include "base/trace.hh"#include "cpu/profile.hh"#include "cpu/quiesce_event.hh"#include "sim/serialize.hh"#include "sim/sim_exit.hh"#include "arch/stacktrace.hh"#else#include "sim/process.hh"#include "sim/system.hh"#include "mem/translating_port.hh"#endifusing namespace std;// constructor#if FULL_SYSTEMSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, TheISA::ITB *_itb, TheISA::DTB *_dtb, bool use_kernel_stats) : ThreadState(_cpu, -1, _thread_num), cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb){ tc = new ProxyThreadContext<SimpleThread>(this); quiesceEvent = new EndQuiesceEvent(tc); regs.clear(); if (cpu->params->profile) { profile = new FunctionProfile(system->kernelSymtab); Callback *cb = new MakeCallback<SimpleThread, &SimpleThread::dumpFuncProfile>(this); registerExitCallback(cb); } // let's fill with a dummy node for now so we don't get a segfault // on the first cycle when there's no node available. static ProfileNode dummyNode; profileNode = &dummyNode; profilePC = 3; if (use_kernel_stats) { kernelStats = new TheISA::Kernel::Statistics(system); } else { kernelStats = NULL; }}#elseSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, TheISA::ITB *_itb, TheISA::DTB *_dtb, int _asid) : ThreadState(_cpu, -1, _thread_num, _process, _asid), cpu(_cpu), itb(_itb), dtb(_dtb){ regs.clear(); tc = new ProxyThreadContext<SimpleThread>(this);}#endifSimpleThread::SimpleThread()#if FULL_SYSTEM : ThreadState(NULL, -1, -1)#else : ThreadState(NULL, -1, -1, NULL, -1)#endif{ tc = new ProxyThreadContext<SimpleThread>(this); regs.clear();}SimpleThread::~SimpleThread(){#if FULL_SYSTEM delete physPort; delete virtPort;#endif delete tc;}voidSimpleThread::takeOverFrom(ThreadContext *oldContext){ // some things should already be set up#if FULL_SYSTEM assert(system == oldContext->getSystemPtr());#else assert(process == oldContext->getProcessPtr());#endif copyState(oldContext);#if FULL_SYSTEM EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); if (quiesce) { // Point the quiesce event's TC at this TC so that it wakes up // the proper CPU. quiesce->tc = tc; } if (quiesceEvent) { quiesceEvent->tc = tc; } TheISA::Kernel::Statistics *stats = oldContext->getKernelStats(); if (stats) { kernelStats = stats; }#endif storeCondFailures = 0; oldContext->setStatus(ThreadContext::Unallocated);}voidSimpleThread::copyTC(ThreadContext *context){ copyState(context);#if FULL_SYSTEM EndQuiesceEvent *quiesce = context->getQuiesceEvent(); if (quiesce) { quiesceEvent = quiesce; } TheISA::Kernel::Statistics *stats = context->getKernelStats(); if (stats) { kernelStats = stats; }#endif}voidSimpleThread::copyState(ThreadContext *oldContext){ // copy over functional state _status = oldContext->status(); copyArchRegs(oldContext); cpuId = oldContext->readCpuId();#if !FULL_SYSTEM funcExeInst = oldContext->readFuncExeInst();#endif inst = oldContext->getInst();}voidSimpleThread::serialize(ostream &os){ ThreadState::serialize(os); regs.serialize(os); // thread_num and cpu_id are deterministic from the config}voidSimpleThread::unserialize(Checkpoint *cp, const std::string §ion){ ThreadState::unserialize(cp, section); regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config}#if FULL_SYSTEMvoidSimpleThread::dumpFuncProfile(){ std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); profile->dump(tc, *os);}#endifvoidSimpleThread::activate(int delay){ if (status() == ThreadContext::Active) return; lastActivate = curTick;// if (status() == ThreadContext::Unallocated) {// cpu->activateWhenReady(tid);// return;// } _status = ThreadContext::Active; // status() == Suspended cpu->activateContext(tid, delay);}voidSimpleThread::suspend(){ if (status() == ThreadContext::Suspended) return; lastActivate = curTick; lastSuspend = curTick;/*#if FULL_SYSTEM // Don't change the status from active if there are pending interrupts if (cpu->check_interrupts()) { assert(status() == ThreadContext::Active); return; }#endif*/ _status = ThreadContext::Suspended; cpu->suspendContext(tid);}voidSimpleThread::deallocate(){ if (status() == ThreadContext::Unallocated) return; _status = ThreadContext::Unallocated; cpu->deallocateContext(tid);}voidSimpleThread::halt(){ if (status() == ThreadContext::Halted) return; _status = ThreadContext::Halted; cpu->haltContext(tid);}voidSimpleThread::regStats(const string &name){#if FULL_SYSTEM if (kernelStats) kernelStats->regStats(name + ".kern");#endif}voidSimpleThread::copyArchRegs(ThreadContext *src_tc){ TheISA::copyRegs(src_tc, tc);}#if FULL_SYSTEMVirtualPort*SimpleThread::getVirtPort(ThreadContext *src_tc){ if (!src_tc) return virtPort; VirtualPort *vp = new VirtualPort("tc-vport", src_tc); connectToMemFunc(vp); return vp;}voidSimpleThread::delVirtPort(VirtualPort *vp){ if (vp != virtPort) { vp->removeConn(); delete vp; }}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?