diff options
author | Brandon Potter <brandon.potter@amd.com> | 2015-07-24 12:25:22 -0700 |
---|---|---|
committer | Brandon Potter <brandon.potter@amd.com> | 2015-07-24 12:25:22 -0700 |
commit | b90711ea53f51d85890dd6e1bed0ca852adb8074 (patch) | |
tree | eded5a2ba8f4b283271f1ee4c7deb508f3b42cac /src/sim | |
parent | ef08046af413e2dc19cf7e8e1a3a329cc3c05bec (diff) | |
download | gem5-b90711ea53f51d85890dd6e1bed0ca852adb8074.tar.xz |
base: refactor process class (specifically FdMap and friends)
This patch extends the previous patch's alterations around fd_map. It cleans
up some of the uglier code in the process file and replaces it with a more
concise C++11 version. As part of the changes, the FdMap class is pulled out
of the Process class and receives its own file.
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/SConscript | 1 | ||||
-rw-r--r-- | src/sim/fd_entry.cc | 91 | ||||
-rw-r--r-- | src/sim/fd_entry.hh | 92 | ||||
-rw-r--r-- | src/sim/process.cc | 392 | ||||
-rw-r--r-- | src/sim/process.hh | 40 | ||||
-rw-r--r-- | src/sim/serialize.hh | 2 | ||||
-rw-r--r-- | src/sim/syscall_emul.cc | 6 | ||||
-rw-r--r-- | src/sim/syscall_emul.hh | 22 |
8 files changed, 359 insertions, 287 deletions
diff --git a/src/sim/SConscript b/src/sim/SConscript index 400d595e3..0b3a35915 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -72,6 +72,7 @@ if env['TARGET_ISA'] != 'null': SimObject('Process.py') Source('faults.cc') Source('process.cc') + Source('fd_entry.cc') Source('pseudo_inst.cc') Source('syscall_emul.cc') diff --git a/src/sim/fd_entry.cc b/src/sim/fd_entry.cc new file mode 100644 index 000000000..72975a7a6 --- /dev/null +++ b/src/sim/fd_entry.cc @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Advanced Micro Devices, Inc. + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + */ + +#include "base/misc.hh" +#include "fd_entry.hh" + +using namespace std; + +void +FDEntry::serialize(CheckpointOut &cp) const +{ + SERIALIZE_SCALAR(fd); + if (fd != -1) { + SERIALIZE_SCALAR(mode); + SERIALIZE_SCALAR(flags); + SERIALIZE_SCALAR(isPipe); + SERIALIZE_SCALAR(readPipeSource); + SERIALIZE_SCALAR(fileOffset); + SERIALIZE_SCALAR(filename); + } + if (driver) + warn("EmulatedDriver objects do not currently support checkpoints"); +} + +void +FDEntry::unserialize(CheckpointIn &cp) +{ + UNSERIALIZE_SCALAR(fd); + if (fd != -1) { + UNSERIALIZE_SCALAR(mode); + UNSERIALIZE_SCALAR(flags); + UNSERIALIZE_SCALAR(isPipe); + UNSERIALIZE_SCALAR(readPipeSource); + UNSERIALIZE_SCALAR(fileOffset); + UNSERIALIZE_SCALAR(filename); + } + driver = NULL; +} + +bool +FDEntry::isFree() +{ + return (fd == -1 && driver == NULL); +} + +void +FDEntry::set(int sim_fd, const string name, int flags, int mode, bool pipe) +{ + fd = sim_fd; + filename = name; + this->flags = flags; + this->mode = mode; + isPipe = pipe; + fileOffset = 0; + readPipeSource = 0; + driver = NULL; +} + +void +FDEntry::reset() +{ + set(-1, "", 0, 0, false); +} diff --git a/src/sim/fd_entry.hh b/src/sim/fd_entry.hh new file mode 100644 index 000000000..e0fd0b0a2 --- /dev/null +++ b/src/sim/fd_entry.hh @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015 Advanced Micro Devices, Inc. + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + */ + +#ifndef __FD_ENTRY_HH__ +#define __FD_ENTRY_HH__ + +#include <ostream> +#include <string> + +#include "sim/emul_driver.hh" + +/** + * FDEntry is used to manage a single file descriptor mapping and metadata + * for processes. + * Note that the fields are all declared publicly since system calls have a + * habit of only needing to access a single field at a time and accessor + * methods seem like overkill. + */ +class FDEntry : public Serializable +{ + public: + /** + * Constructor contains default values + * The file descriptor is free. + */ + FDEntry() + : fd(-1), mode(0), flags(0), isPipe(false), readPipeSource(0), + fileOffset(0), filename(""), driver(NULL) + { } + + void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; + void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; + + /** + * Check if the target file descriptor is in use. + * @return value denoting if target file descriptor already used + */ + bool isFree(); + + /** + * Fill in members for this file descriptor entry. + * @param sim_fd host file descriptor + * @param name filename string + * @param flags current flags of the file descriptor + * @param mode current mode of the file descriptor + * @param pipe denotes whether the file descriptor belongs to a pipe + */ + void set(int sim_fd, const std::string name, int flags, int mode, + bool pipe); + + /** Reset members to their default values. */ + void reset(); + + int fd; + int mode; + int flags; + bool isPipe; + int readPipeSource; + uint64_t fileOffset; + std::string filename; + EmulatedDriver *driver; +}; + +#endif // __FD_ENTRY_HH__ diff --git a/src/sim/process.cc b/src/sim/process.cc index 8aca849a6..f27b70853 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -47,6 +47,7 @@ #include <unistd.h> #include <cstdio> +#include <map> #include <string> #include "base/loader/object_file.hh" @@ -103,6 +104,27 @@ AuxVector<IntType>::AuxVector(IntType type, IntType val) template struct AuxVector<uint32_t>; template struct AuxVector<uint64_t>; +static int +openFile(const string& filename, int flags, mode_t mode) +{ + int sim_fd = open(filename.c_str(), flags, mode); + if (sim_fd != -1) + return sim_fd; + fatal("Unable to open %s with mode %O", filename, mode); +} + +static int +openInputFile(const string &filename) +{ + return openFile(filename, O_RDONLY, 0); +} + +static int +openOutputFile(const string &filename) +{ + return openFile(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664); +} + Process::Process(ProcessParams * params) : SimObject(params), system(params->system), brk_point(0), stack_base(0), stack_size(0), stack_min(0), @@ -116,70 +138,48 @@ Process::Process(ProcessParams * params) static_cast<PageTableBase *>(new FuncPageTable(name(), M5_pid)) ), initVirtMem(system->getSystemPort(), this, SETranslatingPortProxy::Always), - fd_map(new FdMap[NUM_FDS]) + fd_array(make_shared<array<FDEntry, NUM_FDS>>()), + imap {{"", -1}, + {"cin", STDIN_FILENO}, + {"stdin", STDIN_FILENO}}, + oemap{{"", -1}, + {"cout", STDOUT_FILENO}, + {"stdout", STDOUT_FILENO}, + {"cerr", STDERR_FILENO}, + {"stderr", STDERR_FILENO}} { - string in = params->input; - string out = params->output; - string err = params->errout; - - // 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; + int sim_fd; + std::map<string,int>::iterator it; + + // Search through the input options and set fd if match is found; + // otherwise, open an input file and seek to location. + FDEntry *fde_stdin = get_fd_entry(STDIN_FILENO); + if ((it = imap.find(params->input)) != imap.end()) + sim_fd = it->second; 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; + sim_fd = openInputFile(params->input); + fde_stdin->set(sim_fd, params->input, O_RDONLY, -1, false); + + // Search through the output/error options and set fd if match is found; + // otherwise, open an output file and seek to location. + FDEntry *fde_stdout = get_fd_entry(STDOUT_FILENO); + if ((it = oemap.find(params->output)) != oemap.end()) + sim_fd = it->second; else - stdout_fd = Process::openOutputFile(out); - - if (err == "stdout" || err == "cout") - stderr_fd = STDOUT_FILENO; - else if (err == "stderr" || err == "cerr") - stderr_fd = STDERR_FILENO; - else if (err == "None") - stderr_fd = -1; - else if (err == out) - stderr_fd = stdout_fd; + sim_fd = openOutputFile(params->output); + fde_stdout->set(sim_fd, params->output, O_WRONLY | O_CREAT | O_TRUNC, + 0664, false); + + FDEntry *fde_stderr = get_fd_entry(STDERR_FILENO); + if (params->output == params->errout) + // Reuse the same file descriptor if these match. + sim_fd = fde_stdout->fd; + else if ((it = oemap.find(params->errout)) != oemap.end()) + sim_fd = it->second; else - stderr_fd = Process::openOutputFile(err); - - // 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 = err; - fdo->flags = O_WRONLY; - fdo->mode = -1; - fdo->fileOffset = 0; - - - // mark remaining fds as free - for (int i = 3; i < NUM_FDS; ++i) { - fdo = &fd_map[i]; - fdo->fd = -1; - } + sim_fd = openOutputFile(params->errout); + fde_stderr->set(sim_fd, params->errout, O_WRONLY | O_CREAT | O_TRUNC, + 0664, false); mmap_start = mmap_end = 0; nxm_start = nxm_end = 0; @@ -198,37 +198,10 @@ Process::regStats() ; } -// -// static helper functions -// - -int -Process::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; -} - - -int -Process::openOutputFile(const string &filename) +void +Process::inheritFdArray(Process *p) { - int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664); - - if (fd == -1) { - perror(NULL); - cerr << "unable to open \"" << filename << "\" for writing\n"; - fatal("can't open output file"); - } - - return fd; + fd_array = p->fd_array; } ThreadContext * @@ -268,64 +241,48 @@ int Process::alloc_fd(int sim_fd, const 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 < NUM_FDS; ++free_fd) { - Process::FdMap *fdo = &fd_map[free_fd]; - if (fdo->fd == -1 && fdo->driver == NULL) { - fdo->fd = sim_fd; - fdo->filename = filename; - fdo->mode = mode; - fdo->fileOffset = 0; - fdo->flags = flags; - fdo->isPipe = pipe; - fdo->readPipeSource = 0; + for (int free_fd = 0; free_fd < fd_array->size(); free_fd++) { + FDEntry *fde = get_fd_entry(free_fd); + if (fde->isFree()) { + fde->set(sim_fd, filename, flags, mode, pipe); return free_fd; } } - panic("Process::alloc_fd: out of file descriptors!"); + fatal("Out of target file descriptors"); } void -Process::free_fdmap_entry(int tgt_fd) +Process::reset_fd_entry(int tgt_fd) { - Process::FdMap *fdo = &fd_map[tgt_fd]; - assert(fd_map[tgt_fd].fd > -1); - - fdo->fd = -1; - fdo->filename = "NULL"; - fdo->mode = 0; - fdo->fileOffset = 0; - fdo->flags = 0; - fdo->isPipe = false; - fdo->readPipeSource = 0; - fdo->driver = NULL; + FDEntry *fde = get_fd_entry(tgt_fd); + assert(fde->fd > -1); + + fde->reset(); } int Process::sim_fd(int tgt_fd) { - FdMap *obj = sim_fd_obj(tgt_fd); - return obj ? obj->fd : -1; + FDEntry *entry = get_fd_entry(tgt_fd); + return entry ? entry->fd : -1; } -Process::FdMap * -Process::sim_fd_obj(int tgt_fd) +FDEntry * +Process::get_fd_entry(int tgt_fd) { - if (tgt_fd < 0 || tgt_fd >= NUM_FDS) - return NULL; - return &fd_map[tgt_fd]; + assert(0 <= tgt_fd && tgt_fd < fd_array->size()); + return &(*fd_array)[tgt_fd]; } int Process::tgt_fd(int sim_fd) { - for (int index = 0; index < NUM_FDS; ++index) - if (fd_map[index].fd == sim_fd) + for (int index = 0; index < fd_array->size(); index++) + if ((*fd_array)[index].fd == sim_fd) return index; return -1; } @@ -363,98 +320,70 @@ Process::fixupStackFault(Addr vaddr) return false; } -// find all offsets for currently open files and save them void Process::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; - string err = fdo_stderr->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 == "NULL") - stdin_fd = -1; - else { - // open standard in and seek to the right location - stdin_fd = Process::openInputFile(in); - if (lseek(stdin_fd, fdo_stdin->fileOffset, SEEK_SET) < 0) - panic("Unable to seek to correct location in file: %s", in); + auto seek = [] (FDEntry *fde) + { + if (lseek(fde->fd, fde->fileOffset, SEEK_SET) < 0) + fatal("Unable to see to location in %s", fde->filename); + }; + + std::map<string,int>::iterator it; + + // Search through the input options and set fd if match is found; + // otherwise, open an input file and seek to location. + FDEntry *fde_stdin = get_fd_entry(STDIN_FILENO); + if ((it = imap.find(fde_stdin->filename)) != imap.end()) { + fde_stdin->fd = it->second; + } else { + fde_stdin->fd = openInputFile(fde_stdin->filename); + seek(fde_stdin); } - if (out == "stdout" || out == "cout") - stdout_fd = STDOUT_FILENO; - else if (out == "stderr" || out == "cerr") - stdout_fd = STDERR_FILENO; - else if (out == "NULL") - stdout_fd = -1; - else { - stdout_fd = Process::openOutputFile(out); - if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0) - panic("Unable to seek to correct location in file: %s", out); + // Search through the output/error options and set fd if match is found; + // otherwise, open an output file and seek to location. + FDEntry *fde_stdout = get_fd_entry(STDOUT_FILENO); + if ((it = oemap.find(fde_stdout->filename)) != oemap.end()) { + fde_stdout->fd = it->second; + } else { + fde_stdout->fd = openOutputFile(fde_stdout->filename); + seek(fde_stdout); } - if (err == "stdout" || err == "cout") - stderr_fd = STDOUT_FILENO; - else if (err == "stderr" || err == "cerr") - stderr_fd = STDERR_FILENO; - else if (err == "NULL") - stderr_fd = -1; - else if (err == out) - stderr_fd = stdout_fd; - else { - stderr_fd = Process::openOutputFile(err); - if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0) - panic("Unable to seek to correct location in file: %s", err); + FDEntry *fde_stderr = get_fd_entry(STDERR_FILENO); + if (fde_stdout->filename == fde_stderr->filename) { + // Reuse the same file descriptor if these match. + fde_stderr->fd = fde_stdout->fd; + } else if ((it = oemap.find(fde_stderr->filename)) != oemap.end()) { + fde_stderr->fd = it->second; + } else { + fde_stderr->fd = openOutputFile(fde_stderr->filename); + seek(fde_stderr); } - fdo_stdin->fd = stdin_fd; - fdo_stdout->fd = stdout_fd; - fdo_stderr->fd = stderr_fd; - - - for (int free_fd = 3; free_fd < NUM_FDS; ++free_fd) { - Process::FdMap *fdo = &fd_map[free_fd]; - if (fdo->fd != -1) { - if (fdo->isPipe){ - if (fdo->filename == "PIPE-WRITE") - continue; - else { - assert (fdo->filename == "PIPE-READ"); - //create a new pipe - int fds[2]; - int pipe_retval = pipe(fds); - - if (pipe_retval < 0) { - // error - panic("Unable to create new pipe."); - } - fdo->fd = fds[0]; //set read pipe - Process::FdMap *fdo_write = &fd_map[fdo->readPipeSource]; - if (fdo_write->filename != "PIPE-WRITE") - panic ("Couldn't find write end of the pipe"); - - fdo_write->fd = fds[1];//set write pipe - } - } else { - //Open file - int fd = open(fdo->filename.c_str(), fdo->flags, fdo->mode); - - if (fd == -1) - panic("Unable to open file: %s", fdo->filename); - fdo->fd = fd; - - //Seek to correct location before checkpoint - if (lseek(fd, fdo->fileOffset, SEEK_SET) < 0) - panic("Unable to seek to correct location in file: %s", - fdo->filename); - } + for (int tgt_fd = 3; tgt_fd < fd_array->size(); tgt_fd++) { + FDEntry *fde = get_fd_entry(tgt_fd); + if (fde->fd == -1) + continue; + + if (fde->isPipe) { + if (fde->filename == "PIPE-WRITE") + continue; + assert(fde->filename == "PIPE-READ"); + + int fds[2]; + if (pipe(fds) < 0) + fatal("Unable to create new pipe"); + + fde->fd = fds[0]; + + FDEntry *fde_write = get_fd_entry(fde->readPipeSource); + assert(fde_write->filename == "PIPE-WRITE"); + fde_write->fd = fds[1]; + } else { + fde->fd = openFile(fde->filename.c_str(), fde->flags, fde->mode); + seek(fde); } } } @@ -462,44 +391,18 @@ Process::fix_file_offsets() void Process::find_file_offsets() { - for (int free_fd = 0; free_fd < NUM_FDS; ++free_fd) { - Process::FdMap *fdo = &fd_map[free_fd]; - if (fdo->fd != -1) { - fdo->fileOffset = lseek(fdo->fd, 0, SEEK_CUR); - } else { - fdo->filename = "NULL"; - fdo->fileOffset = 0; - } + for (auto& fde : *fd_array) { + if (fde.fd != -1) + fde.fileOffset = lseek(fde.fd, 0, SEEK_CUR); } } void Process::setReadPipeSource(int read_pipe_fd, int source_fd) { - Process::FdMap *fdo = &fd_map[read_pipe_fd]; - fdo->readPipeSource = source_fd; -} - -void -Process::FdMap::serialize(CheckpointOut &cp) const -{ - SERIALIZE_SCALAR(fd); - SERIALIZE_SCALAR(isPipe); - SERIALIZE_SCALAR(filename); - SERIALIZE_SCALAR(flags); - SERIALIZE_SCALAR(readPipeSource); - SERIALIZE_SCALAR(fileOffset); -} - -void -Process::FdMap::unserialize(CheckpointIn &cp) -{ - UNSERIALIZE_SCALAR(fd); - UNSERIALIZE_SCALAR(isPipe); - UNSERIALIZE_SCALAR(filename); - UNSERIALIZE_SCALAR(flags); - UNSERIALIZE_SCALAR(readPipeSource); - UNSERIALIZE_SCALAR(fileOffset); + FDEntry *fde = get_fd_entry(read_pipe_fd); + assert(source_fd >= -1); + fde->readPipeSource = source_fd; } void @@ -515,8 +418,8 @@ Process::serialize(CheckpointOut &cp) const SERIALIZE_SCALAR(nxm_start); SERIALIZE_SCALAR(nxm_end); pTable->serialize(cp); - for (int x = 0; x < NUM_FDS; x++) { - fd_map[x].serializeSection(cp, csprintf("FdMap%d", x)); + for (int x = 0; x < fd_array->size(); x++) { + (*fd_array)[x].serializeSection(cp, csprintf("FDEntry%d", x)); } SERIALIZE_SCALAR(M5_pid); @@ -535,14 +438,15 @@ Process::unserialize(CheckpointIn &cp) UNSERIALIZE_SCALAR(nxm_start); UNSERIALIZE_SCALAR(nxm_end); pTable->unserialize(cp); - for (int x = 0; x < NUM_FDS; x++) { - fd_map[x].unserializeSection(cp, csprintf("FdMap%d", x)); + for (int x = 0; x < fd_array->size(); x++) { + FDEntry *fde = get_fd_entry(x); + fde->unserializeSection(cp, csprintf("FDEntry%d", x)); } fix_file_offsets(); UNSERIALIZE_OPT_SCALAR(M5_pid); // The above returns a bool so that you could do something if you don't // find the param in the checkpoint if you wanted to, like set a default - // but in this case we'll just stick with the instantianted value if not + // but in this case we'll just stick with the instantiated value if not // found. } diff --git a/src/sim/process.hh b/src/sim/process.hh index fe41a35e4..2de83565c 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -33,6 +33,7 @@ #ifndef __PROCESS_HH__ #define __PROCESS_HH__ +#include <array> #include <string> #include <vector> @@ -41,6 +42,7 @@ #include "base/types.hh" #include "config/the_isa.hh" #include "mem/se_translating_port_proxy.hh" +#include "sim/fd_entry.hh" #include "sim/sim_object.hh" #include "sim/syscallreturn.hh" @@ -135,27 +137,6 @@ class Process : public SimObject PageTableBase* pTable; - class FdMap : public Serializable - { - public: - int fd; - std::string filename; - int mode; - int flags; - bool isPipe; - int readPipeSource; - uint64_t fileOffset; - EmulatedDriver *driver; - - FdMap() - : fd(-1), filename("NULL"), mode(0), flags(0), - isPipe(false), readPipeSource(0), fileOffset(0), driver(NULL) - { } - - void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; - void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; - }; - protected: /// Memory proxy for initialization (image loading) SETranslatingPortProxy initVirtMem; @@ -164,12 +145,15 @@ class Process : public SimObject static const int NUM_FDS = 1024; // File descriptor remapping support. - FdMap *fd_map; + std::shared_ptr<std::array<FDEntry, NUM_FDS>> fd_array; + + // Standard file descriptor options for initialization and checkpoints. + std::map<std::string, int> imap; + std::map<std::string, int> oemap; public: - // static helper functions to generate file descriptors for constructor - static int openInputFile(const std::string &filename); - static int openOutputFile(const std::string &filename); + // inherit file descriptor map from another process (necessary for clone) + void inheritFdArray(Process *p); // override of virtual SimObject method: register statistics virtual void regStats(); @@ -192,13 +176,13 @@ class Process : public SimObject bool pipe); // disassociate target fd with simulator fd and cleanup subsidiary fields - void free_fdmap_entry(int tgt_fd); + void reset_fd_entry(int tgt_fd); // look up simulator fd for given target fd int sim_fd(int tgt_fd); - // look up simulator fd_map object for a given target fd - FdMap *sim_fd_obj(int tgt_fd); + // look up fd entry for a given target fd + FDEntry *get_fd_entry(int tgt_fd); // look up target fd for given host fd // Assumes a 1:1 mapping between target file descriptor and host file diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index ea2bd2928..a0be62db5 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -76,7 +76,7 @@ typedef std::ostream CheckpointOut; * SimObject shouldn't cause the version number to increase, only changes to * existing objects such as serializing/unserializing more state, changing sizes * of serialized arrays, etc. */ -static const uint64_t gem5CheckpointVersion = 0x000000000000000e; +static const uint64_t gem5CheckpointVersion = 0x000000000000000f; template <class T> void paramOut(CheckpointOut &cp, const std::string &name, const T ¶m); diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 00506125e..4f1cd2a75 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -216,7 +216,7 @@ closeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) if (sim_fd > 2) status = close(sim_fd); if (status >= 0) - p->free_fdmap_entry(target_fd); + p->reset_fd_entry(target_fd); return status; } @@ -597,11 +597,11 @@ dupFunc(SyscallDesc *desc, int num, LiveProcess *process, ThreadContext *tc) if (sim_fd < 0) return -EBADF; - Process::FdMap *fdo = process->sim_fd_obj(tgt_fd); + FDEntry *fde = process->get_fd_entry(tgt_fd); int result = dup(sim_fd); return (result == -1) ? -errno : - process->alloc_fd(result, fdo->filename, fdo->flags, fdo->mode, false); + process->alloc_fd(result, fde->filename, fde->flags, fde->mode, false); } diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 07b910727..b942cb601 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -553,20 +553,20 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { int index = 0; - int fd = process->getSyscallArg(tc, index); + int tgt_fd = process->getSyscallArg(tc, index); unsigned req = process->getSyscallArg(tc, index); - DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); + DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", tgt_fd, req); - Process::FdMap *fdObj = process->sim_fd_obj(fd); + FDEntry *fde = process->get_fd_entry(tgt_fd); - if (fdObj == NULL) { + if (fde == NULL) { // doesn't map to any simulator fd: not a valid target fd return -EBADF; } - if (fdObj->driver != NULL) { - return fdObj->driver->ioctl(process, tc, req); + if (fde->driver != NULL) { + return fde->driver->ioctl(process, tc, req); } if (OS::isTtyReq(req)) { @@ -574,7 +574,7 @@ ioctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } warn("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ \n", - fd, req, tc->pcState()); + tgt_fd, req, tc->pcState()); return -ENOTTY; } @@ -1235,18 +1235,18 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) warn("mmap length argument %#x is unreasonably large.\n", length); if (!(flags & OS::TGT_MAP_ANONYMOUS)) { - Process::FdMap *fd_map = p->sim_fd_obj(tgt_fd); - if (!fd_map || fd_map->fd < 0) { + FDEntry *fde = p->get_fd_entry(tgt_fd); + if (!fde || fde->fd < 0) { warn("mmap failing: target fd %d is not valid\n", tgt_fd); return -EBADF; } - if (fd_map->filename != "/dev/zero") { + if (fde->filename != "/dev/zero") { // This is very likely broken, but leave a warning here // (rather than panic) in case /dev/zero is known by // another name on some platform warn("allowing mmap of file %s; mmap not supported on files" - " other than /dev/zero\n", fd_map->filename); + " other than /dev/zero\n", fde->filename); } } |