From d7dfe51faed84ba2b06c32a302597c0226ea239c Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 5 Aug 2004 02:03:47 -0700 Subject: [PATCH] Integrate Python configuration script parsing into m5 itself. SConscript: Add pyconfig/{pyconfig,code}.cc Add list of object description (.od) files. Include pyconfig/SConscript. base/inifile.cc: Get rid of CPP_PIPE... it never really worked anyway. base/inifile.hh: Make load(ifstream&) method public so pyconfig code can call it. sim/main.cc: Handle Python config scripts (end in '.py' instead of '.ini'). sim/pyconfig/m5configbase.py: Add license. Fix minor __setattr__ problem (2.3 related?) --HG-- rename : util/config/m5configbase.py => sim/pyconfig/m5configbase.py extra : convert_revision : 5e004922f950bfdefced333285584b80ad7ffb83 --- SConscript | 86 ++++++++++++++++++- base/inifile.cc | 42 ++------- base/inifile.hh | 12 +-- sim/main.cc | 37 ++++++-- sim/pyconfig/SConscript | 50 +++++++++++ {util/config => sim/pyconfig}/m5configbase.py | 30 ++++++- 6 files changed, 203 insertions(+), 54 deletions(-) create mode 100644 sim/pyconfig/SConscript rename {util/config => sim/pyconfig}/m5configbase.py (94%) diff --git a/SConscript b/SConscript index cd41c3143..f6875a630 100644 --- a/SConscript +++ b/SConscript @@ -193,8 +193,42 @@ base_sources = Split(''' sim/sw_context.cc sim/trace_context.cc sim/universe.cc + sim/pyconfig/pyconfig.cc + sim/pyconfig/code.cc ''') +base_obj_desc_files = Split(''' + cpu/full_cpu/iq/segmented/SegmentedIQ.od + cpu/full_cpu/iq/seznec/SeznecIQ.od + cpu/full_cpu/iq/standard/StandardIQ.od + cpu/full_cpu/iq/BaseIQ.od + cpu/full_cpu/BranchPred.od + cpu/full_cpu/FUDesc.od + cpu/full_cpu/FullCPU.od + cpu/full_cpu/FuncUnitPool.od + cpu/full_cpu/OpDesc.od + cpu/full_cpu/PipeTrace.od + cpu/sampling_cpu/SamplingCPU.od + cpu/simple_cpu/SimpleCPU.od + cpu/BaseCPU.od + cpu/IntrControl.od + mem/bus/Bus.od + mem/bus/BusBridge.od + mem/cache/coherence/CoherenceProtocol.od + mem/cache/tags/repl/GenRepl.od + mem/cache/tags/repl/Repl.od + mem/cache/BaseCache.od + mem/functional_mem/FunctionalMemory.od + mem/functional_mem/MainMemory.od + mem/functional_mem/MemoryController.od + mem/functional_mem/PhysicalMemory.od + mem/timing_mem/BaseMemory.od + mem/BaseHier.od + mem/BaseMem.od + mem/HierParams.od + ''') + + # MySql sources mysql_sources = Split(''' base/mysql.cc @@ -273,6 +307,44 @@ full_system_sources = Split(''' sim/system.cc ''') +full_system_obj_desc_files = Split(''' + arch/alpha/AlphaDTB.od + arch/alpha/AlphaITB.od + arch/alpha/AlphaTLB.od + dev/AlphaConsole.od + dev/ConsoleListener.od + dev/CowDiskImage.od + dev/DiskImage.od + dev/DmaDevice.od + dev/DmaEngine.od + dev/EtherBus.od + dev/EtherDev.od + dev/EtherDevInt.od + dev/EtherDump.od + dev/EtherInt.od + dev/EtherLink.od + dev/EtherTap.od + dev/PioDevice.od + dev/RawDiskImage.od + dev/ScsiController.od + dev/ScsiDevice.od + dev/ScsiDisk.od + dev/SimConsole.od + dev/SimpleDisk.od + dev/TlaserClock.od + dev/TlaserIpi.od + dev/TlaserMBox.od + dev/TlaserMC146818.od + dev/TlaserNode.od + dev/TlaserPciDev.od + dev/TlaserPcia.od + dev/TlaserSerial.od + dev/TlaserUart.od + dev/Turbolaser.od + kern/tru64/Tru64System.od + sim/System.od + ''') + # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' arch/alpha/alpha_common_syscall_emul.cc @@ -287,13 +359,23 @@ syscall_emulation_sources = Split(''' sim/syscall_emul.cc ''') +syscall_emulation_obj_desc_files = Split(''' + cpu/memtest/MemTest.od + eio/EioProcess.od + sim/LiveProcess.od + sim/Process.od + ''') + # Set up complete list of sources based on configuration. sources = base_sources +obj_desc_files = base_obj_desc_files if env['FULL_SYSTEM']: sources += full_system_sources + obj_desc_files += full_system_obj_desc_files else: sources += syscall_emulation_sources + obj_desc_files += syscall_emulation_obj_desc_files if env['USE_MYSQL']: sources += mysql_sources @@ -338,7 +420,9 @@ env.Command('targetarch', None, link_targetarch) # libelf build is described in its own SConscript file. -SConscript('libelf/SConscript', exports = 'env', +SConscript('libelf/SConscript', exports = 'env', duplicate=0) + +SConscript('sim/pyconfig/SConscript', exports = ['env', 'obj_desc_files'], duplicate=0) diff --git a/base/inifile.cc b/base/inifile.cc index 10836baea..94b17966a 100644 --- a/base/inifile.cc +++ b/base/inifile.cc @@ -27,8 +27,6 @@ */ #define USE_CPP -// #define CPP_PIPE - #ifdef USE_CPP #include @@ -43,9 +41,6 @@ #include #include -#if __GNUC__ >= 3 -#include -#endif #include #include @@ -74,8 +69,6 @@ IniFile::~IniFile() bool IniFile::loadCPP(const string &file, vector &cppArgs) { - int fd[2]; - // Open the file just to verify that we can. Otherwise if the // file doesn't exist or has bad permissions the user will get // confusing errors from cpp/g++. @@ -99,18 +92,13 @@ IniFile::loadCPP(const string &file, vector &cppArgs) delete [] cfile; -#ifdef CPP_PIPE - if (pipe(fd) == -1) - return false; -#else char tempfile[] = "/tmp/configXXXXXX"; - fd[0] = fd[1] = mkstemp(tempfile); -#endif + int tmp_fd = mkstemp(tempfile); int pid = fork(); if (pid == -1) - return 1; + return false; if (pid == 0) { char filename[FILENAME_MAX]; @@ -141,7 +129,7 @@ IniFile::loadCPP(const string &file, vector &cppArgs) args[nextArg++] = NULL; close(STDOUT_FILENO); - if (dup2(fd[1], STDOUT_FILENO) == -1) + if (dup2(tmp_fd, STDOUT_FILENO) == -1) exit(1); execvp("g++", args); @@ -158,33 +146,13 @@ IniFile::loadCPP(const string &file, vector &cppArgs) if (!WIFEXITED(retval) || WEXITSTATUS(retval) != 0) return false; -#ifdef CPP_PIPE - close(fd[1]); -#else - lseek(fd[0], 0, SEEK_SET); -#endif + close(tmp_fd); bool status = false; -#if __GNUC__ >= 3 - using namespace __gnu_cxx; - stdio_filebuf fbuf(fd[0], ios_base::in, true, - static_cast::int_type>(BUFSIZ)); - - if (fbuf.is_open()) { - istream f(&fbuf); - status = load(f); - } - -#else - ifstream f(fd[0]); - if (f.is_open()) - status = load(f); -#endif + status = load(tempfile); -#ifndef CPP_PIPE unlink(tempfile); -#endif return status; } diff --git a/base/inifile.hh b/base/inifile.hh index 01e4e6c17..58a657db4 100644 --- a/base/inifile.hh +++ b/base/inifile.hh @@ -151,12 +151,6 @@ class IniFile /// @retval Pointer to section object, or NULL if not found. Section *findSection(const std::string §ionName) const; - /// Load parameter settings from given istream. This is a helper - /// function for load(string) and loadCPP(), which open a file - /// and then pass it here. - /// @retval True if successful, false if errors were encountered. - bool load(std::istream &f); - public: /// Constructor. IniFile(); @@ -164,6 +158,12 @@ class IniFile /// Destructor. ~IniFile(); + /// Load parameter settings from given istream. This is a helper + /// function for load(string) and loadCPP(), which open a file + /// and then pass it here. + /// @retval True if successful, false if errors were encountered. + bool load(std::istream &f); + /// Load the specified file, passing it through the C preprocessor. /// Parameter settings found in the file will be merged with any /// already defined in this object. diff --git a/sim/main.cc b/sim/main.cc index 54c74fd1a..2a0427303 100644 --- a/sim/main.cc +++ b/sim/main.cc @@ -56,6 +56,7 @@ #include "sim/stat_control.hh" #include "sim/stats.hh" #include "sim/universe.hh" +#include "sim/pyconfig/pyconfig.hh" using namespace std; @@ -340,15 +341,35 @@ main(int argc, char **argv) else { // no '-', treat as config file name - // If we haven't loaded default.ini yet, and we want to, - // now is the time. Can't do it sooner because we need to - // look for '-n', can't do it later since we want - // default.ini loaded first (so that any other settings - // override it). - handleDefaultIni(loadDefaultIni, cppArgs); + // make STL string out of file name + string filename(arg_str); - if (!simConfigDB.loadCPP(arg_str, cppArgs)) { - cprintf("Error processing file %s\n", arg_str); + int ext_loc = filename.rfind("."); + + string ext = + (ext_loc != string::npos) ? filename.substr(ext_loc) : ""; + + if (ext == ".ini") { + // If we haven't loaded default.ini yet, and we want to, + // now is the time. Can't do it sooner because we need to + // look for '-n', can't do it later since we want + // default.ini loaded first (so that any other settings + // override it). + handleDefaultIni(loadDefaultIni, cppArgs); + + if (!simConfigDB.loadCPP(filename, cppArgs)) { + cprintf("Error processing file %s\n", filename); + exit(1); + } + } else if (ext == ".py") { + if (!loadPythonConfig(filename, &simConfigDB)) { + cprintf("Error processing file %s\n", filename); + exit(1); + } + } + else { + cprintf("Config file name '%s' must end in '.py' or '.ini'.\n", + filename); exit(1); } } diff --git a/sim/pyconfig/SConscript b/sim/pyconfig/SConscript new file mode 100644 index 000000000..7661e7603 --- /dev/null +++ b/sim/pyconfig/SConscript @@ -0,0 +1,50 @@ +# -*- mode:python -*- + +# Copyright (c) 2004 The Regents of The University of Michigan +# All rights reserved. +# +# 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. + +import os + +Import('env', 'obj_desc_files') + +my_obj_desc_files = map(lambda x: '../../' + x, obj_desc_files) + +env.Command('m5odescs.py', my_obj_desc_files, + '$TARGET.srcdir/load_odescs.py $_CPPDEFFLAGS $SOURCES $TARGET') + +# Python modules to encapsulate +string_module_bases = Split('m5config m5configbase m5odescs') +string_modules = map(lambda x: x + '_as_string.py', string_module_bases) + +for m in string_module_bases: + env.Command(m + '_as_string.py', m + '.py', + '$TARGET.srcdir/make_string_module.py $SOURCE $TARGET') + +embedded_py_files = Split('string_importer.py') + string_modules + +env.Command('code.cc', embedded_py_files, + '$TARGET.srcdir/make_c_file.py pyconfig_code $SOURCES $TARGET') + diff --git a/util/config/m5configbase.py b/sim/pyconfig/m5configbase.py similarity index 94% rename from util/config/m5configbase.py rename to sim/pyconfig/m5configbase.py index 2daf5d94d..66660994e 100644 --- a/util/config/m5configbase.py +++ b/sim/pyconfig/m5configbase.py @@ -1,3 +1,29 @@ +# Copyright (c) 2004 The Regents of The University of Michigan +# All rights reserved. +# +# 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. + from __future__ import generators import os @@ -186,7 +212,7 @@ class MetaConfigNode(type): def __setattr__(cls, attr_name, value): # normal processing for private attributes if attr_name.startswith('_'): - object.__setattr__(cls, attr_name, value) + type.__setattr__(cls, attr_name, value) return # no '_': must be SimObject param param = cls.lookup_param(attr_name) @@ -196,7 +222,7 @@ class MetaConfigNode(type): # It's ok: set attribute by delegating to 'object' class. # Note the use of param.make_value() to verify/canonicalize # the assigned value - object.__setattr__(cls, attr_name, param.make_value(value)) + type.__setattr__(cls, attr_name, param.make_value(value)) # generator that iterates across all parameters for this class and # all classes it inherits from -- 2.30.2