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 &section){    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 + -
显示快捷键?