process.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 719 行 · 第 1/2 页
CC
719 行
/* * Copyright (c) 2001, 2002, 2003, 2004, 2005 * 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: Nathan L. Binkert * Steven K. Reinhardt * Ali G. Saidi */#include <unistd.h>#include <fcntl.h>#include <string>#include "arch/remote_gdb.hh"#include "base/intmath.hh"#include "base/loader/object_file.hh"#include "base/loader/symtab.hh"#include "base/statistics.hh"#include "config/full_system.hh"#include "cpu/thread_context.hh"#include "mem/page_table.hh"#include "mem/physical.hh"#include "mem/translating_port.hh"#include "params/Process.hh"#include "params/LiveProcess.hh"#include "sim/process.hh"#include "sim/process_impl.hh"#include "sim/stats.hh"#include "sim/syscall_emul.hh"#include "sim/system.hh"#include "arch/isa_specific.hh"#if THE_ISA == ALPHA_ISA#include "arch/alpha/linux/process.hh"#include "arch/alpha/tru64/process.hh"#elif THE_ISA == SPARC_ISA#include "arch/sparc/linux/process.hh"#include "arch/sparc/solaris/process.hh"#elif THE_ISA == MIPS_ISA#include "arch/mips/linux/process.hh"#elif THE_ISA == ARM_ISA#include "arch/arm/linux/process.hh"#else#error "THE_ISA not set"#endifusing namespace std;using namespace TheISA;//// The purpose of this code is to fake the loader & syscall mechanism// when there's no OS: thus there's no resone to use it in FULL_SYSTEM// mode when we do have an OS//#if FULL_SYSTEM#error "process.cc not compatible with FULL_SYSTEM"#endif// current number of allocated processesint num_processes = 0;Process::Process(ProcessParams * params) : SimObject(params), system(params->system), checkpointRestored(false), max_stack_size(params->max_stack_size){ string in = params->input; string out = params->output; // initialize file descriptors to default: same as simulator int stdin_fd, stdout_fd, stderr_fd; if (in == "stdin" || in == "cin") stdin_fd = STDIN_FILENO; else if (in == "None") stdin_fd = -1; else stdin_fd = Process::openInputFile(in); if (out == "stdout" || out == "cout") stdout_fd = STDOUT_FILENO; else if (out == "stderr" || out == "cerr") stdout_fd = STDERR_FILENO; else if (out == "None") stdout_fd = -1; else stdout_fd = Process::openOutputFile(out); stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; M5_pid = system->allocatePID(); // initialize first 3 fds (stdin, stdout, stderr) Process::FdMap *fdo = &fd_map[STDIN_FILENO]; fdo->fd = stdin_fd; fdo->filename = in; fdo->flags = O_RDONLY; fdo->mode = -1; fdo->fileOffset = 0; fdo = &fd_map[STDOUT_FILENO]; fdo->fd = stdout_fd; fdo->filename = out; fdo->flags = O_WRONLY | O_CREAT | O_TRUNC; fdo->mode = 0774; fdo->fileOffset = 0; fdo = &fd_map[STDERR_FILENO]; fdo->fd = stderr_fd; fdo->filename = "STDERR"; fdo->flags = O_WRONLY; fdo->mode = -1; fdo->fileOffset = 0; // mark remaining fds as free for (int i = 3; i <= MAX_FD; ++i) { Process::FdMap *fdo = &fd_map[i]; fdo->fd = -1; } mmap_start = mmap_end = 0; nxm_start = nxm_end = 0; pTable = new PageTable(this); // other parameters will be initialized when the program is loaded}voidProcess::regStats(){ using namespace Stats; num_syscalls .name(name() + ".PROG:num_syscalls") .desc("Number of system calls") ;}//// static helper functions//intProcess::openInputFile(const string &filename){ int fd = open(filename.c_str(), O_RDONLY); if (fd == -1) { perror(NULL); cerr << "unable to open \"" << filename << "\" for reading\n"; fatal("can't open input file"); } return fd;}intProcess::openOutputFile(const string &filename){ int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0774); if (fd == -1) { perror(NULL); cerr << "unable to open \"" << filename << "\" for writing\n"; fatal("can't open output file"); } return fd;}intProcess::registerThreadContext(ThreadContext *tc){ // add to list int myIndex = threadContexts.size(); threadContexts.push_back(tc); RemoteGDB *rgdb = new RemoteGDB(system, tc); GDBListener *gdbl = new GDBListener(rgdb, 7000 + myIndex); gdbl->listen(); //gdbl->accept(); remoteGDB.push_back(rgdb); // return CPU number to caller return myIndex;}voidProcess::startup(){ if (threadContexts.empty()) fatal("Process %s is not associated with any CPUs!\n", name()); // first thread context for this process... initialize & enable ThreadContext *tc = threadContexts[0]; // mark this context as active so it will start ticking. tc->activate(0); Port *mem_port; mem_port = system->physmem->getPort("functional"); initVirtMem = new TranslatingPort("process init port", this, TranslatingPort::Always); mem_port->setPeer(initVirtMem); initVirtMem->setPeer(mem_port);}voidProcess::replaceThreadContext(ThreadContext *tc, int tcIndex){ if (tcIndex >= threadContexts.size()) { panic("replaceThreadContext: bad tcIndex, %d >= %d\n", tcIndex, threadContexts.size()); } threadContexts[tcIndex] = tc;}// map simulator fd sim_fd to target fd tgt_fdvoidProcess::dup_fd(int sim_fd, int tgt_fd){ if (tgt_fd < 0 || tgt_fd > MAX_FD) panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd); Process::FdMap *fdo = &fd_map[tgt_fd]; fdo->fd = sim_fd;}// generate new target fd for sim_fdintProcess::alloc_fd(int sim_fd, string filename, int flags, int mode, bool pipe){ // in case open() returns an error, don't allocate a new fd if (sim_fd == -1) return -1; // find first free target fd for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) { Process::FdMap *fdo = &fd_map[free_fd]; if (fdo->fd == -1) { fdo->fd = sim_fd; fdo->filename = filename; fdo->mode = mode; fdo->fileOffset = 0; fdo->flags = flags; fdo->isPipe = pipe; fdo->readPipeSource = 0; return free_fd; } } panic("Process::alloc_fd: out of file descriptors!");}// free target fd (e.g., after close)voidProcess::free_fd(int tgt_fd){ Process::FdMap *fdo = &fd_map[tgt_fd]; if (fdo->fd == -1) warn("Process::free_fd: request to free unused fd %d", tgt_fd); fdo->fd = -1; fdo->filename = "NULL"; fdo->mode = 0; fdo->fileOffset = 0; fdo->flags = 0; fdo->isPipe = false; fdo->readPipeSource = 0;}// look up simulator fd for given target fdintProcess::sim_fd(int tgt_fd){ if (tgt_fd > MAX_FD) return -1; return fd_map[tgt_fd].fd;}Process::FdMap *Process::sim_fd_obj(int tgt_fd){ if (tgt_fd > MAX_FD) panic("sim_fd_obj called in fd out of range."); return &fd_map[tgt_fd];}boolProcess::checkAndAllocNextPage(Addr vaddr){ // if this is an initial write we might not have if (vaddr >= stack_min && vaddr < stack_base) { pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize); return true; } // We've accessed the next page of the stack, so extend the stack // to cover it. if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) { while (vaddr < stack_min) { stack_min -= TheISA::PageBytes; if(stack_base - stack_min > max_stack_size) fatal("Maximum stack size exceeded\n"); if(stack_base - stack_min > 8*1024*1024) fatal("Over max stack size for one thread\n"); pTable->allocate(stack_min, TheISA::PageBytes); warn("Increasing stack size by one page."); }; return true; } return false;} // find all offsets for currently open files and save themvoidProcess::fix_file_offsets() { Process::FdMap *fdo_stdin = &fd_map[STDIN_FILENO]; Process::FdMap *fdo_stdout = &fd_map[STDOUT_FILENO]; Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO]; string in = fdo_stdin->filename; string out = fdo_stdout->filename; // initialize file descriptors to default: same as simulator int stdin_fd, stdout_fd, stderr_fd; if (in == "stdin" || in == "cin") stdin_fd = STDIN_FILENO; else if (in == "None") stdin_fd = -1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?