diff options
43 files changed, 840 insertions, 1584 deletions
diff --git a/SConstruct b/SConstruct index fb6bc609e..0cf15b1f9 100644 --- a/SConstruct +++ b/SConstruct @@ -287,7 +287,6 @@ sticky_opts.AddOptions( BoolOption('USE_SSE2', 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', False), - BoolOption('STATS_BINNING', 'Bin statistics by CPU mode', have_mysql), BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql), BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), ('CC', 'C compiler', os.environ.get('CC', env['CC'])), @@ -304,8 +303,7 @@ nonsticky_opts.AddOptions( # These options get exported to #defines in config/*.hh (see m5/SConscript). env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \ - 'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \ - 'STATS_BINNING'] + 'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP'] # Define a handy 'no-op' action def no_action(target, source, env): diff --git a/configs/test/test.py b/configs/test/test.py index 8bdea16ac..8c5b06e6a 100644 --- a/configs/test/test.py +++ b/configs/test/test.py @@ -11,7 +11,6 @@ from m5.objects import * parser = optparse.OptionParser(option_list=m5.standardOptions) parser.add_option("-c", "--cmd", default="hello") -parser.add_option("-a", "--arch", choices=["Alpha", "Mips"], default="Alpha") parser.add_option("-t", "--timing", action="store_true") (options, args) = parser.parse_args() @@ -23,10 +22,7 @@ if args: # build configuration this_dir = os.path.dirname(__file__) -print "arch =", options.arch -process_class = eval(options.arch + "LiveProcess") - -process = process_class() +process = LiveProcess() process.executable = os.path.join(this_dir, options.cmd) process.cmd = options.cmd diff --git a/src/SConscript b/src/SConscript index b166720a1..a1c18711c 100644 --- a/src/SConscript +++ b/src/SConscript @@ -219,7 +219,6 @@ full_system_sources = Split(''' dev/uart.cc dev/uart8250.cc - kern/kernel_binning.cc kern/kernel_stats.cc kern/system_events.cc kern/linux/events.cc diff --git a/src/arch/SConscript b/src/arch/SConscript index c90694a68..ff460dafd 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -28,7 +28,7 @@ # # Authors: Steve Reinhardt -import os.path +import os.path, sys # Import build environment variable from SConstruct. Import('env') @@ -134,7 +134,8 @@ def isa_desc_emitter(target, source, env): return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source) # Pieces are in place, so create the builder. -isa_desc_builder = Builder(action='python2.4 $SOURCES $TARGET.dir $CPU_MODELS', +python = sys.executable # use same Python binary used to run scons +isa_desc_builder = Builder(action=python + ' $SOURCES $TARGET.dir $CPU_MODELS', emitter = isa_desc_emitter) env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index 91f8b5af1..7cf68e0db 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -109,10 +109,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) Param<uint64_t> system_type; Param<uint64_t> system_rev; - Param<bool> bin; - VectorParam<string> binned_fns; - Param<bool> bin_int; - END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) @@ -127,10 +123,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), - INIT_PARAM_DFLT(bin, "is this system to be binned", false), - INIT_PARAM(binned_fns, "functions to be broken down and binned"), - INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10) END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) @@ -148,9 +141,6 @@ CREATE_SIM_OBJECT(FreebsdAlphaSystem) p->readfile = readfile; p->system_type = system_type; p->system_rev = system_rev; - p->bin = bin; - p->binned_fns = binned_fns; - p->bin_int = bin_int; return new FreebsdAlphaSystem(p); } diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index 3e061bba8..bb35f046d 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -137,24 +137,6 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p) } else { printThreadEvent = NULL; } - - if (params()->bin_int) { - intStartEvent = addPalFuncEvent<InterruptStartEvent>("sys_int_21"); - if (!intStartEvent) - panic("could not find symbol: sys_int_21\n"); - - intEndEvent = addPalFuncEvent<InterruptEndEvent>("rti_to_kern"); - if (!intEndEvent) - panic("could not find symbol: rti_to_kern\n"); - - intEndEvent2 = addPalFuncEvent<InterruptEndEvent>("rti_to_user"); - if (!intEndEvent2) - panic("could not find symbol: rti_to_user\n"); - - intEndEvent3 = addKernelFuncEvent<InterruptEndEvent>("do_softirq"); - if (!intEndEvent3) - panic("could not find symbol: do_softirq\n"); - } } LinuxAlphaSystem::~LinuxAlphaSystem() @@ -224,10 +206,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) Param<uint64_t> system_type; Param<uint64_t> system_rev; - Param<bool> bin; - VectorParam<string> binned_fns; - Param<bool> bin_int; - END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) @@ -242,10 +220,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), - INIT_PARAM_DFLT(bin, "is this system to be binned", false), - INIT_PARAM(binned_fns, "functions to be broken down and binned"), - INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10) END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) @@ -263,9 +238,6 @@ CREATE_SIM_OBJECT(LinuxAlphaSystem) p->readfile = readfile; p->system_type = system_type; p->system_rev = system_rev; - p->bin = bin; - p->binned_fns = binned_fns; - p->bin_int = bin_int; return new LinuxAlphaSystem(p); } diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index c03586ac5..6921ba820 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -45,7 +45,7 @@ using namespace AlphaISA; using namespace Linux; /** - * This class contains linux specific system code (Loading, Events, Binning). + * This class contains linux specific system code (Loading, Events). * It points to objects that are the system binaries to load and patches them * appropriately to work in simulator. */ @@ -124,18 +124,6 @@ class LinuxAlphaSystem : public AlphaSystem */ PrintThreadInfo *printThreadEvent; - /** - * Event to bin Interrupts seperately from kernel code - */ - InterruptStartEvent *intStartEvent; - - /** - * Event to bin Interrupts seperately from kernel code - */ - InterruptEndEvent *intEndEvent; - InterruptEndEvent *intEndEvent2; - InterruptEndEvent *intEndEvent3; - /** Grab the PCBB of the idle process when it starts */ IdleStartEvent *idleStartEvent; diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 4c0c68761..970292cd8 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -31,55 +31,15 @@ #include "arch/alpha/constants.hh" #include "arch/alpha/process.hh" -#include "arch/alpha/linux/process.hh" -#include "arch/alpha/tru64/process.hh" #include "base/loader/object_file.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" -#include "sim/builder.hh" #include "sim/system.hh" using namespace AlphaISA; using namespace std; -AlphaLiveProcess * -AlphaLiveProcess::create(const std::string &nm, System *system, int stdin_fd, - int stdout_fd, int stderr_fd, std::string executable, - std::vector<std::string> &argv, std::vector<std::string> &envp) -{ - AlphaLiveProcess *process = NULL; - - ObjectFile *objFile = createObjectFile(executable); - if (objFile == NULL) { - fatal("Can't load object file %s", executable); - } - - - if (objFile->getArch() != ObjectFile::Alpha) - fatal("Object file does not match architecture."); - switch (objFile->getOpSys()) { - case ObjectFile::Tru64: - process = new AlphaTru64Process(nm, objFile, system, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - - case ObjectFile::Linux: - process = new AlphaLinuxProcess(nm, objFile, system, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - - default: - fatal("Unknown/unsupported operating system."); - } - - if (process == NULL) - fatal("Unknown error creating process object."); - return process; -} - AlphaLiveProcess::AlphaLiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp) @@ -111,60 +71,3 @@ AlphaLiveProcess::startup() } - - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess) - - VectorParam<string> cmd; - Param<string> executable; - Param<string> input; - Param<string> output; - VectorParam<string> env; - SimObjectParam<System *> system; - -END_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess) - - -BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess) - - INIT_PARAM(cmd, "command line (executable plus arguments)"), - INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), - INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), - INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), - INIT_PARAM(env, "environment settings"), - INIT_PARAM(system, "system") - -END_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess) - - -CREATE_SIM_OBJECT(AlphaLiveProcess) -{ - string in = input; - string out = 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 - stdin_fd = Process::openInputFile(input); - - if (out == "stdout" || out == "cout") - stdout_fd = STDOUT_FILENO; - else if (out == "stderr" || out == "cerr") - stdout_fd = STDERR_FILENO; - else - stdout_fd = Process::openOutputFile(out); - - stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; - - return AlphaLiveProcess::create(getInstanceName(), system, - stdin_fd, stdout_fd, stderr_fd, - (string)executable == "" ? cmd[0] : executable, - cmd, env); -} - - -REGISTER_SIM_OBJECT("AlphaLiveProcess", AlphaLiveProcess) - diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 7fa913cad..5d5c9a52e 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -49,18 +49,6 @@ class AlphaLiveProcess : public LiveProcess std::vector<std::string> &envp); void startup(); - - public: - // this function is used to create the LiveProcess object, since - // we can't tell which subclass of LiveProcess to use until we - // open and look at the object file. - static AlphaLiveProcess *create(const std::string &nm, - System *_system, - int stdin_fd, int stdout_fd, int stderr_fd, - std::string executable, - std::vector<std::string> &argv, - std::vector<std::string> &envp); - }; diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index a68e440b0..3aaba7d58 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -232,10 +232,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) Param<uint64_t> system_type; Param<uint64_t> system_rev; - Param<bool> bin; - VectorParam<std::string> binned_fns; - Param<bool> bin_int; - END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) @@ -250,10 +246,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), - INIT_PARAM_DFLT(bin, "is this system to be binned", false), - INIT_PARAM(binned_fns, "functions to be broken down and binned"), - INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10) END_INIT_SIM_OBJECT_PARAMS(AlphaSystem) @@ -271,9 +264,6 @@ CREATE_SIM_OBJECT(AlphaSystem) p->readfile = readfile; p->system_type = system_type; p->system_rev = system_rev; - p->bin = bin; - p->binned_fns = binned_fns; - p->bin_int = bin_int; return new AlphaSystem(p); } diff --git a/src/arch/alpha/tru64/system.cc b/src/arch/alpha/tru64/system.cc index 8d9a53273..6c0edc1ee 100644 --- a/src/arch/alpha/tru64/system.cc +++ b/src/arch/alpha/tru64/system.cc @@ -107,9 +107,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) Param<uint64_t> system_type; Param<uint64_t> system_rev; - Param<bool> bin; - VectorParam<string> binned_fns; - END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) @@ -124,9 +121,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1), - INIT_PARAM_DFLT(bin, "is this system to be binned", false), - INIT_PARAM(binned_fns, "functions to be broken down and binned") + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1) END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) @@ -144,9 +139,6 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem) p->readfile = readfile; p->system_type = system_type; p->system_rev = system_rev; - p->bin = bin; - p->binned_fns = binned_fns; - p->bin_int = false; return new Tru64AlphaSystem(p); } diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 6f2c88f69..7762c2fa0 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -32,49 +32,14 @@ #include "arch/mips/isa_traits.hh" #include "arch/mips/process.hh" -#include "arch/mips/linux/process.hh" #include "base/loader/object_file.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" -#include "sim/builder.hh" #include "sim/system.hh" using namespace std; using namespace MipsISA; - -MipsLiveProcess * -MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd, - int stdout_fd, int stderr_fd, std::string executable, - std::vector<std::string> &argv, std::vector<std::string> &envp) -{ - MipsLiveProcess *process = NULL; - - ObjectFile *objFile = createObjectFile(executable); - if (objFile == NULL) { - fatal("Can't load object file %s", executable); - } - - - if (objFile->getArch() != ObjectFile::Mips) - fatal("Object file does not match MIPS architecture."); - - switch (objFile->getOpSys()) { - case ObjectFile::Linux: - process = new MipsLinuxProcess(nm, objFile, system, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - - default: - fatal("Unknown/unsupported operating system."); - } - - if (process == NULL) - fatal("Unknown error creating process object."); - return process; -} - MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, std::vector<std::string> &argv, std::vector<std::string> &envp) @@ -101,63 +66,3 @@ MipsLiveProcess::startup() { argsInit(MachineBytes, VMPageSize); } - - - - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess) - - VectorParam<string> cmd; - Param<string> executable; - Param<string> input; - Param<string> output; - VectorParam<string> env; - SimObjectParam<System *> system; - -END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess) - - -BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess) - - INIT_PARAM(cmd, "command line (executable plus arguments)"), - INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), - INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), - INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), - INIT_PARAM(env, "environment settings"), - INIT_PARAM(system, "system") - -END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess) - - -CREATE_SIM_OBJECT(MipsLiveProcess) -{ - string in = input; - string out = 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 - stdin_fd = Process::openInputFile(input); - - if (out == "stdout" || out == "cout") - stdout_fd = STDOUT_FILENO; - else if (out == "stderr" || out == "cerr") - stdout_fd = STDERR_FILENO; - else - stdout_fd = Process::openOutputFile(out); - - stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; - - return MipsLiveProcess::create(getInstanceName(), system, - stdin_fd, stdout_fd, stderr_fd, - (string)executable == "" ? cmd[0] : executable, - cmd, env); -} - - -REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess) - - diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index dae891125..b0ef20399 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -50,18 +50,6 @@ class MipsLiveProcess : public LiveProcess std::vector<std::string> &envp); void startup(); - - public: - // this function is used to create the LiveProcess object, since - // we can't tell which subclass of LiveProcess to use until we - // open and look at the object file. - static MipsLiveProcess *create(const std::string &nm, - System *_system, - int stdin_fd, int stdout_fd, int stderr_fd, - std::string executable, - std::vector<std::string> &argv, - std::vector<std::string> &envp); - }; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 762de243a..40afb3722 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -48,7 +48,7 @@ output header {{ output decoder {{ #include "base/cprintf.hh" #include "base/loader/symtab.hh" -#include "cpu/exec_context.hh" // for Jump::branchTarget() +#include "cpu/thread_context.hh" // for Jump::branchTarget() #include <math.h> #if defined(linux) diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 633c202ca..75f01e038 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -31,56 +31,16 @@ #include "arch/sparc/isa_traits.hh" #include "arch/sparc/process.hh" -#include "arch/sparc/linux/process.hh" -#include "arch/sparc/solaris/process.hh" #include "base/loader/object_file.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" #include "mem/page_table.hh" #include "mem/translating_port.hh" -#include "sim/builder.hh" #include "sim/system.hh" using namespace std; using namespace SparcISA; -SparcLiveProcess * -SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd, - int stdout_fd, int stderr_fd, std::string executable, - std::vector<std::string> &argv, std::vector<std::string> &envp) -{ - SparcLiveProcess *process = NULL; - - ObjectFile *objFile = createObjectFile(executable); - if (objFile == NULL) { - fatal("Can't load object file %s", executable); - } - - - if (objFile->getArch() != ObjectFile::SPARC) - fatal("Object file with arch %x does not match architecture %x.", - objFile->getArch(), ObjectFile::SPARC); - switch (objFile->getOpSys()) { - case ObjectFile::Linux: - process = new SparcLinuxProcess(nm, objFile, system, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - - - case ObjectFile::Solaris: - process = new SparcSolarisProcess(nm, objFile, system, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - default: - fatal("Unknown/unsupported operating system."); - } - - if (process == NULL) - fatal("Unknown error creating process object."); - return process; -} SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile, System *_system, int stdin_fd, int stdout_fd, int stderr_fd, @@ -322,61 +282,3 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) // num_processes++; } - - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess) - - VectorParam<string> cmd; - Param<string> executable; - Param<string> input; - Param<string> output; - VectorParam<string> env; - SimObjectParam<System *> system; - -END_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess) - - -BEGIN_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess) - - INIT_PARAM(cmd, "command line (executable plus arguments)"), - INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), - INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), - INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), - INIT_PARAM(env, "environment settings"), - INIT_PARAM(system, "system") - -END_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess) - - -CREATE_SIM_OBJECT(SparcLiveProcess) -{ - string in = input; - string out = 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 - stdin_fd = Process::openInputFile(input); - - if (out == "stdout" || out == "cout") - stdout_fd = STDOUT_FILENO; - else if (out == "stderr" || out == "cerr") - stdout_fd = STDERR_FILENO; - else - stdout_fd = Process::openOutputFile(out); - - stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; - - return SparcLiveProcess::create(getInstanceName(), system, - stdin_fd, stdout_fd, stderr_fd, - (string)executable == "" ? cmd[0] : executable, - cmd, env); -} - - -REGISTER_SIM_OBJECT("SparcLiveProcess", SparcLiveProcess) - - diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index db5e64352..7ba8d7109 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -65,15 +65,6 @@ class SparcLiveProcess : public LiveProcess void startup(); public: - // this function is used to create the LiveProcess object, since - // we can't tell which subclass of LiveProcess to use until we - // open and look at the object file. - static SparcLiveProcess *create(const std::string &nm, - System *_system, - int stdin_fd, int stdout_fd, int stderr_fd, - std::string executable, - std::vector<std::string> &argv, - std::vector<std::string> &envp); void argsInit(int intSize, int pageSize); diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 760edc41e..cbeb3c7b9 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -244,17 +244,22 @@ namespace SparcISA //In each of these cases, we have to copy the value into a temporary //variable. This is because we may otherwise try to access an //unaligned portion of memory. + + uint32_t result32; + uint64_t result64; switch(width) { case SingleWidth: - uint32_t result32 = gtoh((uint32_t)val); + result32 = gtoh((uint32_t)val); memcpy(regSpace + 4 * floatReg, &result32, width); + break; case DoubleWidth: - uint64_t result64 = gtoh((uint64_t)val); + result64 = gtoh((uint64_t)val); memcpy(regSpace + 4 * floatReg, &result64, width); + break; case QuadWidth: - uint64_t result128 = gtoh((uint64_t)val); - memcpy(regSpace + 4 * floatReg, &result128, width); + panic("Quad width FP not implemented."); + break; default: panic("Attempted to read a %d bit floating point register!", width); } @@ -266,17 +271,21 @@ namespace SparcISA //In each of these cases, we have to copy the value into a temporary //variable. This is because we may otherwise try to access an //unaligned portion of memory. + uint32_t result32; + uint64_t result64; switch(width) { case SingleWidth: - uint32_t result32 = gtoh((uint32_t)val); + result32 = gtoh((uint32_t)val); memcpy(regSpace + 4 * floatReg, &result32, width); + break; case DoubleWidth: - uint64_t result64 = gtoh((uint64_t)val); + result64 = gtoh((uint64_t)val); memcpy(regSpace + 4 * floatReg, &result64, width); + break; case QuadWidth: - uint64_t result128 = gtoh((uint64_t)val); - memcpy(regSpace + 4 * floatReg, &result128, width); + panic("Quad width FP not implemented."); + break; default: panic("Attempted to read a %d bit floating point register!", width); } diff --git a/src/base/statistics.cc b/src/base/statistics.cc index 03c6b5196..2acef83c5 100644 --- a/src/base/statistics.cc +++ b/src/base/statistics.cc @@ -43,7 +43,6 @@ #include "base/time.hh" #include "base/trace.hh" #include "base/stats/statdb.hh" -#include "config/stats_binning.hh" using namespace std; @@ -174,12 +173,6 @@ FormulaBase::size() const return root->size(); } -bool -FormulaBase::binned() const -{ - return root && root->binned(); -} - void FormulaBase::reset() { @@ -238,33 +231,6 @@ Formula::operator+=(Temp r) return *this; } -MainBin::MainBin(const string &name) - : _name(name), mem(NULL), memsize(-1) -{ - Database::regBin(this, name); -} - -MainBin::~MainBin() -{ - if (mem) - delete [] mem; -} - -char * -MainBin::memory(off_t off) -{ - if (memsize == -1) - memsize = ceilPow2((size_t) offset()); - - if (!mem) { - mem = new char[memsize]; - memset(mem, 0, memsize); - } - - assert(offset() <= size()); - return mem + off; -} - void check() { @@ -287,13 +253,6 @@ check() Database::stats().sort(StatData::less); -#if STATS_BINNING - if (MainBin::curBin() == NULL) { - static MainBin mainBin("main bin"); - mainBin.activate(); - } -#endif - if (i == end) return; @@ -313,39 +272,14 @@ CallbackQueue resetQueue; void reset() { - // reset non-binned stats Database::stat_list_t::iterator i = Database::stats().begin(); Database::stat_list_t::iterator end = Database::stats().end(); while (i != end) { StatData *data = *i; - if (!data->binned()) - data->reset(); + data->reset(); ++i; } - // save the bin so we can go back to where we were - MainBin *orig = MainBin::curBin(); - - // reset binned stats - Database::bin_list_t::iterator bi = Database::bins().begin(); - Database::bin_list_t::iterator be = Database::bins().end(); - while (bi != be) { - MainBin *bin = *bi; - bin->activate(); - - i = Database::stats().begin(); - while (i != end) { - StatData *data = *i; - if (data->binned()) - data->reset(); - ++i; - } - ++bi; - } - - // restore bin - MainBin::curBin() = orig; - resetQueue.process(); } diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 84a323071..59f219c07 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -60,11 +60,9 @@ #include "base/intmath.hh" #include "base/refcnt.hh" #include "base/str.hh" -#include "base/stats/bin.hh" #include "base/stats/flags.hh" #include "base/stats/visit.hh" #include "base/stats/types.hh" -#include "config/stats_binning.hh" #include "sim/host.hh" class Callback; @@ -103,11 +101,6 @@ struct StatData virtual ~StatData(); /** - * @return true if the stat is binned. - */ - virtual bool binned() const = 0; - - /** * Reset the corresponding stat to the default state. */ virtual void reset() = 0; @@ -160,7 +153,6 @@ class ScalarStatData : public ScalarData public: ScalarStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return s.binned(); } virtual bool check() const { return s.check(); } virtual Counter value() const { return s.value(); } virtual Result result() const { return s.result(); } @@ -203,7 +195,6 @@ class VectorStatData : public VectorData public: VectorStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return s.binned(); } virtual bool check() const { return s.check(); } virtual bool zero() const { return s.zero(); } virtual void reset() { s.reset(); } @@ -261,7 +252,6 @@ class DistStatData : public DistData public: DistStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return s.binned(); } virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } virtual bool zero() const { return s.zero(); } @@ -300,12 +290,10 @@ class VectorDistStatData : public VectorDistData { protected: Stat &s; - typedef typename Stat::bin_t bin_t; public: VectorDistStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return bin_t::binned; } virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } virtual size_t size() const { return s.size(); } @@ -342,12 +330,10 @@ class Vector2dStatData : public Vector2dData { protected: Stat &s; - typedef typename Stat::bin_t bin_t; public: Vector2dStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return bin_t::binned; } virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } virtual bool zero() const { return s.zero(); } @@ -359,7 +345,6 @@ class Vector2dStatData : public Vector2dData } }; - class DataAccess { protected: @@ -615,22 +600,16 @@ struct StatStor * changes. This allows the quick calculation of a per cycle count of the item * being watched. This is good for keeping track of residencies in structures * among other things. - * @todo add lateny to the stat and fix binning. */ struct AvgStor { public: /** The paramaters for this storage type */ - struct Params - { - /** - * The current count. We stash this here because the current - * value is not a binned value. - */ - Counter current; - }; + struct Params { }; private: + /** The current count. */ + Counter current; /** The total count for all cycles. */ mutable Result total; /** The cycle that current last changed. */ @@ -640,7 +619,7 @@ struct AvgStor /** * Build and initializes this stat storage. */ - AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); } + AvgStor(Params &p) : current(0), total(0), last(0) { } /** * Set the current count to the one provided, update the total and last @@ -649,9 +628,9 @@ struct AvgStor * @param p The parameters for this storage. */ void set(Counter val, Params &p) { - total += p.current * (curTick - last); + total += current * (curTick - last); last = curTick; - p.current = val; + current = val; } /** @@ -659,21 +638,21 @@ struct AvgStor * @param val The amount to increment. * @param p The parameters for this storage. */ - void inc(Counter val, Params &p) { set(p.current + val, p); } + void inc(Counter val, Params &p) { set(current + val, p); } /** * Deccrement the current count by the provided value, calls set. * @param val The amount to decrement. * @param p The parameters for this storage. */ - void dec(Counter val, Params &p) { set(p.current - val, p); } + void dec(Counter val, Params &p) { set(current - val, p); } /** * Return the current count. * @param p The parameters for this storage. * @return The current count. */ - Counter value(const Params &p) const { return p.current; } + Counter value(const Params &p) const { return current; } /** * Return the current average. @@ -682,9 +661,9 @@ struct AvgStor */ Result result(const Params &p) const { - total += p.current * (curTick - last); + total += current * (curTick - last); last = curTick; - return (Result)(total + p.current) / (Result)(curTick + 1); + return (Result)(total + current) / (Result)(curTick + 1); } /** @@ -704,39 +683,53 @@ struct AvgStor /** * Implementation of a scalar stat. The type of stat is determined by the - * Storage template. The storage for this stat is held within the Bin class. - * This allows for breaking down statistics across multiple bins easily. + * Storage template. */ -template <class Storage, class Bin> +template <class Stor> class ScalarBase : public DataAccess { public: + typedef Stor Storage; + /** Define the params of the storage class. */ - typedef typename Storage::Params params_t; - /** Define the bin type. */ - typedef typename Bin::template Bin<Storage> bin_t; + typedef typename Storage::Params Params; protected: - /** The bin of this stat. */ - bin_t bin; + /** The storage of this stat. */ + char storage[sizeof(Storage)]; + /** The parameters for this stat. */ - params_t params; + Params params; protected: /** - * Retrieve the storage from the bin. - * @return The storage object for this stat. + * Retrieve the storage. + * @param index The vector index to access. + * @return The storage object at the given index. */ - Storage *data() { return bin.data(params); } + Storage * + data() + { + return reinterpret_cast<Storage *>(storage); + } + /** - * Retrieve a const pointer to the storage from the bin. - * @return A const pointer to the storage object for this stat. + * Retrieve a const pointer to the storage. + * for the given index. + * @param index The vector index to access. + * @return A const pointer to the storage object at the given index. */ - const Storage *data() const + const Storage * + data() const { - bin_t *_bin = const_cast<bin_t *>(&bin); - params_t *_params = const_cast<params_t *>(¶ms); - return _bin->data(*_params); + return reinterpret_cast<const Storage *>(storage); + } + + void + doInit() + { + new (storage) Storage(params); + setInit(); } public: @@ -751,9 +744,7 @@ class ScalarBase : public DataAccess * Create and initialize this stat, register it with the database. */ ScalarBase() - { - bin.init(params); - } + { } public: // Common operators for stats @@ -802,18 +793,13 @@ class ScalarBase : public DataAccess * @return 1. */ size_t size() const { return 1; } - /** - * Return true if stat is binned. - *@return True is stat is binned. - */ - bool binned() const { return bin_t::binned; } - bool check() const { return bin.initialized(); } + bool check() const { return true; } /** * Reset stat value to default */ - void reset() { bin.reset(); } + void reset() { data()->reset(); } Counter value() { return data()->value(params); } @@ -829,7 +815,6 @@ class ProxyData : public ScalarData { public: virtual void visit(Visit &visitor) { visitor.visit(*this); } - virtual bool binned() const { return false; } virtual std::string str() const { return to_string(value()); } virtual size_t size() const { return 1; } virtual bool zero() const { return value() == 0; } @@ -891,7 +876,6 @@ class ValueBase : public DataAccess Result total() const { return proxy->total(); }; size_t size() const { return proxy->size(); } - bool binned() const { return proxy->binned(); } std::string str() const { return proxy->str(); } bool zero() const { return proxy->zero(); } bool check() const { return proxy != NULL; } @@ -903,195 +887,62 @@ class ValueBase : public DataAccess // Vector Statistics // ////////////////////////////////////////////////////////////////////// -template <class Storage, class Bin> -class ScalarProxy; - -/** - * Implementation of a vector of stats. The type of stat is determined by the - * Storage class. @sa ScalarBase - */ -template <class Storage, class Bin> -class VectorBase : public DataAccess -{ - public: - /** Define the params of the storage class. */ - typedef typename Storage::Params params_t; - /** Define the bin type. */ - typedef typename Bin::template VectorBin<Storage> bin_t; - - protected: - /** The bin of this stat. */ - bin_t bin; - /** The parameters for this stat. */ - params_t params; - - protected: - /** - * Retrieve the storage from the bin for the given index. - * @param index The vector index to access. - * @return The storage object at the given index. - */ - Storage *data(int index) { return bin.data(index, params); } - /** - * Retrieve a const pointer to the storage from the bin - * for the given index. - * @param index The vector index to access. - * @return A const pointer to the storage object at the given index. - */ - const Storage *data(int index) const - { - bin_t *_bin = const_cast<bin_t *>(&bin); - params_t *_params = const_cast<params_t *>(¶ms); - return _bin->data(index, *_params); - } - - public: - void value(VCounter &vec) const - { - vec.resize(size()); - for (int i = 0; i < size(); ++i) - vec[i] = data(i)->value(params); - } - - /** - * Copy the values to a local vector and return a reference to it. - * @return A reference to a vector of the stat values. - */ - void result(VResult &vec) const - { - vec.resize(size()); - for (int i = 0; i < size(); ++i) - vec[i] = data(i)->result(params); - } - - /** - * @return True is stat is binned. - */ - bool binned() const { return bin_t::binned; } - - /** - * Return a total of all entries in this vector. - * @return The total of all vector entries. - */ - Result total() const { - Result total = 0.0; - for (int i = 0; i < size(); ++i) - total += data(i)->result(params); - return total; - } - - /** - * @return the number of elements in this vector. - */ - size_t size() const { return bin.size(); } - - bool zero() const - { - for (int i = 0; i < size(); ++i) - if (data(i)->zero()) - return true; - return false; - } - - bool check() const { return bin.initialized(); } - void reset() { bin.reset(); } - - public: - VectorBase() {} - - /** Friend this class with the associated scalar proxy. */ - friend class ScalarProxy<Storage, Bin>; - - /** - * Return a reference (ScalarProxy) to the stat at the given index. - * @param index The vector index to access. - * @return A reference of the stat. - */ - ScalarProxy<Storage, Bin> operator[](int index); - - void update(StatData *data) {} -}; - -const StatData * getStatData(const void *stat); /** * A proxy class to access the stat at a given index in a VectorBase stat. * Behaves like a ScalarBase. */ -template <class Storage, class Bin> +template <class Stat> class ScalarProxy { - public: - /** Define the params of the storage class. */ - typedef typename Storage::Params params_t; - /** Define the bin type. */ - typedef typename Bin::template VectorBin<Storage> bin_t; - private: - /** Pointer to the bin in the parent VectorBase. */ - bin_t *bin; - /** Pointer to the params in the parent VectorBase. */ - params_t *params; + /** Pointer to the parent Vector. */ + Stat *stat; + /** The index to access in the parent VectorBase. */ int index; - /** Keep a pointer to the original stat so was can get data */ - void *stat; - - protected: - /** - * Retrieve the storage from the bin. - * @return The storage from the bin for this stat. - */ - Storage *data() { return bin->data(index, *params); } - /** - * Retrieve a const pointer to the storage from the bin. - * @return A const pointer to the storage for this stat. - */ - const Storage *data() const - { - bin_t *_bin = const_cast<bin_t *>(bin); - params_t *_params = const_cast<params_t *>(params); - return _bin->data(index, *_params); - } public: /** * Return the current value of this stat as its base type. * @return The current value. */ - Counter value() const { return data()->value(*params); } + Counter value() const { return stat->data(index)->value(stat->params); } /** * Return the current value of this statas a result type. * @return The current value. */ - Result result() const { return data()->result(*params); } + Result result() const { return stat->data(index)->result(stat->params); } public: /** * Create and initialize this proxy, do not register it with the database. - * @param b The bin to use. * @param p The params to use. * @param i The index to access. */ - ScalarProxy(bin_t &b, params_t &p, int i, void *s) - : bin(&b), params(&p), index(i), stat(s) {} + ScalarProxy(Stat *s, int i) + : stat(s), index(i) + { + assert(stat); + } + /** * Create a copy of the provided ScalarProxy. * @param sp The proxy to copy. */ ScalarProxy(const ScalarProxy &sp) - : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {} + : stat(sp.stat), index(sp.index) + {} + /** * Set this proxy equal to the provided one. * @param sp The proxy to copy. * @return A reference to this proxy. */ const ScalarProxy &operator=(const ScalarProxy &sp) { - bin = sp.bin; - params = sp.params; - index = sp.index; stat = sp.stat; + index = sp.index; return *this; } @@ -1101,12 +952,12 @@ class ScalarProxy * Increment the stat by 1. This calls the associated storage object inc * function. */ - void operator++() { data()->inc(1, *params); } + void operator++() { stat->data(index)->inc(1, stat->params); } /** * Decrement the stat by 1. This calls the associated storage object dec * function. */ - void operator--() { data()->dec(1, *params); } + void operator--() { stat->data(index)->dec(1, stat->params); } /** Increment the stat by 1. */ void operator++(int) { ++*this; } @@ -1119,7 +970,7 @@ class ScalarProxy * @param v The new value. */ template <typename U> - void operator=(const U &v) { data()->set(v, *params); } + void operator=(const U &v) { stat->data(index)->set(v, stat->params); } /** * Increment the stat by the given value. This calls the associated @@ -1127,7 +978,7 @@ class ScalarProxy * @param v The value to add. */ template <typename U> - void operator+=(const U &v) { data()->inc(v, *params); } + void operator+=(const U &v) { stat->data(index)->inc(v, stat->params); } /** * Decrement the stat by the given value. This calls the associated @@ -1135,7 +986,7 @@ class ScalarProxy * @param v The value to substract. */ template <typename U> - void operator-=(const U &v) { data()->dec(v, *params); } + void operator-=(const U &v) { stat->data(index)->dec(v, stat->params); } /** * Return the number of elements, always 1 for a scalar. @@ -1144,192 +995,356 @@ class ScalarProxy size_t size() const { return 1; } /** - * Return true if stat is binned. - *@return false since Proxies aren't printed/binned - */ - bool binned() const { return false; } - - /** * This stat has no state. Nothing to reset */ void reset() { } public: - const StatData *statData() const { return getStatData(stat); } - std::string str() const + std::string + str() const { - return csprintf("%s[%d]", this->statData()->name, index); + return csprintf("%s[%d]", stat->str(), index); } }; -template <class Storage, class Bin> -inline ScalarProxy<Storage, Bin> -VectorBase<Storage, Bin>::operator[](int index) +/** + * Implementation of a vector of stats. The type of stat is determined by the + * Storage class. @sa ScalarBase + */ +template <class Stor> +class VectorBase : public DataAccess { - assert (index >= 0 && index < size()); - return ScalarProxy<Storage, Bin>(bin, params, index, this); -} + public: + typedef Stor Storage; + + /** Define the params of the storage class. */ + typedef typename Storage::Params Params; -template <class Storage, class Bin> -class VectorProxy; + /** Proxy type */ + typedef ScalarProxy<VectorBase<Storage> > Proxy; -template <class Storage, class Bin> -class Vector2dBase : public DataAccess -{ - public: - typedef typename Storage::Params params_t; - typedef typename Bin::template VectorBin<Storage> bin_t; + friend class ScalarProxy<VectorBase<Storage> >; protected: - size_t x; - size_t y; - bin_t bin; - params_t params; + /** The storage of this stat. */ + Storage *storage; + size_t _size; + + /** The parameters for this stat. */ + Params params; protected: - Storage *data(int index) { return bin.data(index, params); } - const Storage *data(int index) const + /** + * Retrieve the storage. + * @param index The vector index to access. + * @return The storage object at the given index. + */ + Storage *data(int index) { return &storage[index]; } + + /** + * Retrieve a const pointer to the storage. + * @param index The vector index to access. + * @return A const pointer to the storage object at the given index. + */ + const Storage *data(int index) const { return &storage[index]; } + + void + doInit(int s) { - bin_t *_bin = const_cast<bin_t *>(&bin); - params_t *_params = const_cast<params_t *>(¶ms); - return _bin->data(index, *_params); + assert(s > 0 && "size must be positive!"); + assert(!storage && "already initialized"); + _size = s; + + char *ptr = new char[_size * sizeof(Storage)]; + storage = reinterpret_cast<Storage *>(ptr); + + for (int i = 0; i < _size; ++i) + new (&storage[i]) Storage(params); + + setInit(); } public: - Vector2dBase() {} + void value(VCounter &vec) const + { + vec.resize(size()); + for (int i = 0; i < size(); ++i) + vec[i] = data(i)->value(params); + } - void update(Vector2dData *data) + /** + * Copy the values to a local vector and return a reference to it. + * @return A reference to a vector of the stat values. + */ + void result(VResult &vec) const { - int size = this->size(); - data->cvec.resize(size); - for (int i = 0; i < size; ++i) - data->cvec[i] = this->data(i)->value(params); + vec.resize(size()); + for (int i = 0; i < size(); ++i) + vec[i] = data(i)->result(params); } - std::string ysubname(int i) const { return (*this->y_subnames)[i]; } + /** + * Return a total of all entries in this vector. + * @return The total of all vector entries. + */ + Result total() const { + Result total = 0.0; + for (int i = 0; i < size(); ++i) + total += data(i)->result(params); + return total; + } + + /** + * @return the number of elements in this vector. + */ + size_t size() const { return _size; } - friend class VectorProxy<Storage, Bin>; - VectorProxy<Storage, Bin> operator[](int index); + bool + zero() const + { + for (int i = 0; i < size(); ++i) + if (data(i)->zero()) + return false; + return true; + } - size_t size() const { return bin.size(); } - bool zero() const { return data(0)->value(params) == 0.0; } + bool + check() const + { + return storage != NULL; + } + + void + reset() + { + for (int i = 0; i < size(); ++i) + data(i)->reset(); + } + + public: + VectorBase() + : storage(NULL) + {} + + ~VectorBase() + { + if (!storage) + return; + + for (int i = 0; i < _size; ++i) + data(i)->~Storage(); + delete [] reinterpret_cast<char *>(storage); + } /** - * Reset stat value to default + * Return a reference (ScalarProxy) to the stat at the given index. + * @param index The vector index to access. + * @return A reference of the stat. */ - void reset() { bin.reset(); } + Proxy + operator[](int index) + { + assert (index >= 0 && index < size()); + return Proxy(this, index); + } - bool check() { return bin.initialized(); } + void update(StatData *data) {} }; -template <class Storage, class Bin> +template <class Stat> class VectorProxy { - public: - typedef typename Storage::Params params_t; - typedef typename Bin::template VectorBin<Storage> bin_t; - private: - bin_t *bin; - params_t *params; + Stat *stat; int offset; int len; - void *stat; private: - mutable VResult *vec; + mutable VResult vec; - Storage *data(int index) { + typename Stat::Storage * + data(int index) + { assert(index < len); - return bin->data(offset + index, *params); + return stat->data(offset + index); } - const Storage *data(int index) const { - bin_t *_bin = const_cast<bin_t *>(bin); - params_t *_params = const_cast<params_t *>(params); - return _bin->data(offset + index, *_params); + const typename Stat::Storage * + data(int index) const + { + assert(index < len); + return const_cast<Stat *>(stat)->data(offset + index); } public: - const VResult &result() const { - if (vec) - vec->resize(size()); - else - vec = new VResult(size()); + const VResult & + result() const + { + vec.resize(size()); for (int i = 0; i < size(); ++i) - (*vec)[i] = data(i)->result(*params); + vec[i] = data(i)->result(stat->params); - return *vec; + return vec; } - Result total() const { - Result total = 0.0; + Result + total() const + { + Result total = 0; for (int i = 0; i < size(); ++i) - total += data(i)->result(*params); + total += data(i)->result(stat->params); return total; } public: - VectorProxy(bin_t &b, params_t &p, int o, int l, void *s) - : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL) + VectorProxy(Stat *s, int o, int l) + : stat(s), offset(o), len(l) { } VectorProxy(const VectorProxy &sp) - : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len), - stat(sp.stat), vec(NULL) - { - } - - ~VectorProxy() + : stat(sp.stat), offset(sp.offset), len(sp.len) { - if (vec) - delete vec; } - const VectorProxy &operator=(const VectorProxy &sp) + const VectorProxy & + operator=(const VectorProxy &sp) { - bin = sp.bin; - params = sp.params; + stat = sp.stat; offset = sp.offset; len = sp.len; - stat = sp.stat; - if (vec) - delete vec; - vec = NULL; return *this; } - ScalarProxy<Storage, Bin> operator[](int index) + ScalarProxy<Stat> operator[](int index) { assert (index >= 0 && index < size()); - return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat); + return ScalarProxy<Stat>(stat, offset + index); } size_t size() const { return len; } /** - * Return true if stat is binned. - *@return false since Proxies aren't printed/binned - */ - bool binned() const { return false; } - - /** * This stat has no state. Nothing to reset. */ void reset() { } }; -template <class Storage, class Bin> -inline VectorProxy<Storage, Bin> -Vector2dBase<Storage, Bin>::operator[](int index) +template <class Stor> +class Vector2dBase : public DataAccess { - int offset = index * y; - assert (index >= 0 && offset < size()); - return VectorProxy<Storage, Bin>(bin, params, offset, y, this); -} + public: + typedef Stor Storage; + typedef typename Storage::Params Params; + typedef VectorProxy<Vector2dBase<Storage> > Proxy; + friend class ScalarProxy<Vector2dBase<Storage> >; + friend class VectorProxy<Vector2dBase<Storage> >; + + protected: + size_t x; + size_t y; + size_t _size; + Storage *storage; + Params params; + + protected: + Storage *data(int index) { return &storage[index]; } + const Storage *data(int index) const { return &storage[index]; } + + void + doInit(int _x, int _y) + { + assert(_x > 0 && _y > 0 && "sizes must be positive!"); + assert(!storage && "already initialized"); + + Vector2dData *statdata = dynamic_cast<Vector2dData *>(find()); + + x = _x; + y = _y; + statdata->x = _x; + statdata->y = _y; + _size = x * y; + + char *ptr = new char[_size * sizeof(Storage)]; + storage = reinterpret_cast<Storage *>(ptr); + + for (int i = 0; i < _size; ++i) + new (&storage[i]) Storage(params); + + setInit(); + } + + public: + Vector2dBase() + : storage(NULL) + {} + + ~Vector2dBase() + { + if (!storage) + return; + + for (int i = 0; i < _size; ++i) + data(i)->~Storage(); + delete [] reinterpret_cast<char *>(storage); + } + + void + update(Vector2dData *newdata) + { + int size = this->size(); + newdata->cvec.resize(size); + for (int i = 0; i < size; ++i) + newdata->cvec[i] = data(i)->value(params); + } + + std::string ysubname(int i) const { return (*this->y_subnames)[i]; } + + Proxy + operator[](int index) + { + int offset = index * y; + assert (index >= 0 && offset + index < size()); + return Proxy(this, offset, y); + } + + + size_t + size() const + { + return _size; + } + + bool + zero() const + { + return data(0)->zero(); +#if 0 + for (int i = 0; i < size(); ++i) + if (!data(i)->zero()) + return false; + return true; +#endif + } + + /** + * Reset stat value to default + */ + void + reset() + { + for (int i = 0; i < size(); ++i) + data(i)->reset(); + } + + bool + check() + { + return storage != NULL; + } +}; ////////////////////////////////////////////////////////////////////// // @@ -1376,14 +1391,8 @@ struct DistStor VCounter cvec; public: - /** - * Construct this storage with the supplied params. - * @param params The parameters. - */ DistStor(const Params ¶ms) - : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()), - overflow(Counter()), sum(Counter()), squares(Counter()), - samples(Counter()), cvec(params.size) + : cvec(params.size) { reset(); } @@ -1618,36 +1627,46 @@ struct AvgFancy * Implementation of a distribution stat. The type of distribution is * determined by the Storage template. @sa ScalarBase */ -template <class Storage, class Bin> +template <class Stor> class DistBase : public DataAccess { public: + typedef Stor Storage; /** Define the params of the storage class. */ - typedef typename Storage::Params params_t; - /** Define the bin type. */ - typedef typename Bin::template Bin<Storage> bin_t; + typedef typename Storage::Params Params; protected: - /** The bin of this stat. */ - bin_t bin; + /** The storage for this stat. */ + char storage[sizeof(Storage)]; + /** The parameters for this stat. */ - params_t params; + Params params; protected: /** - * Retrieve the storage from the bin. + * Retrieve the storage. * @return The storage object for this stat. */ - Storage *data() { return bin.data(params); } + Storage *data() + { + return reinterpret_cast<Storage *>(storage); + } + /** - * Retrieve a const pointer to the storage from the bin. + * Retrieve a const pointer to the storage. * @return A const pointer to the storage object for this stat. */ - const Storage *data() const + const Storage * + data() const { - bin_t *_bin = const_cast<bin_t *>(&bin); - params_t *_params = const_cast<params_t *>(¶ms); - return _bin->data(*_params); + return reinterpret_cast<const Storage *>(storage); + } + + void + doInit() + { + new (storage) Storage(params); + setInit(); } public: @@ -1678,65 +1697,122 @@ class DistBase : public DataAccess base->data.fancy = Storage::fancy; data()->update(&(base->data), params); } - /** - * @return True is stat is binned. - */ - bool binned() const { return bin_t::binned; } + /** * Reset stat value to default */ - void reset() + void + reset() { - bin.reset(); + data()->reset(); } - bool check() { return bin.initialized(); } + bool + check() + { + return true; + } }; -template <class Storage, class Bin> +template <class Stat> class DistProxy; -template <class Storage, class Bin> +template <class Stor> class VectorDistBase : public DataAccess { public: - typedef typename Storage::Params params_t; - typedef typename Bin::template VectorBin<Storage> bin_t; + typedef Stor Storage; + typedef typename Storage::Params Params; + typedef DistProxy<VectorDistBase<Storage> > Proxy; + friend class DistProxy<VectorDistBase<Storage> >; protected: - bin_t bin; - params_t params; + Storage *storage; + size_t _size; + Params params; protected: - Storage *data(int index) { return bin.data(index, params); } - const Storage *data(int index) const + Storage * + data(int index) + { + return &storage[index]; + } + + const Storage * + data(int index) const { - bin_t *_bin = const_cast<bin_t *>(&bin); - params_t *_params = const_cast<params_t *>(¶ms); - return _bin->data(index, *_params); + return &storage[index]; + } + + void + doInit(int s) + { + assert(s > 0 && "size must be positive!"); + assert(!storage && "already initialized"); + _size = s; + + char *ptr = new char[_size * sizeof(Storage)]; + storage = reinterpret_cast<Storage *>(ptr); + + for (int i = 0; i < _size; ++i) + new (&storage[i]) Storage(params); + + setInit(); } public: - VectorDistBase() {} + VectorDistBase() + : storage(NULL) + {} - friend class DistProxy<Storage, Bin>; - DistProxy<Storage, Bin> operator[](int index); - const DistProxy<Storage, Bin> operator[](int index) const; + ~VectorDistBase() + { + if (!storage) + return ; + + for (int i = 0; i < _size; ++i) + data(i)->~Storage(); + delete [] reinterpret_cast<char *>(storage); + } + + Proxy operator[](int index); + + size_t + size() const + { + return _size; + } + + bool + zero() const + { + return false; +#if 0 + for (int i = 0; i < size(); ++i) + if (!data(i)->zero(params)) + return false; + return true; +#endif + } - size_t size() const { return bin.size(); } - bool zero() const { return false; } - /** - * Return true if stat is binned. - *@return True is stat is binned. - */ - bool binned() const { return bin_t::binned; } /** * Reset stat value to default */ - void reset() { bin.reset(); } + void + reset() + { + for (int i = 0; i < size(); ++i) + data(i)->reset(); + } + + bool + check() + { + return storage != NULL; + } - bool check() { return bin.initialized(); } - void update(VectorDistData *base) + void + update(VectorDistData *base) { int size = this->size(); base->data.resize(size); @@ -1747,75 +1823,75 @@ class VectorDistBase : public DataAccess } }; -template <class Storage, class Bin> +template <class Stat> class DistProxy { - public: - typedef typename Storage::Params params_t; - typedef typename Bin::template Bin<Storage> bin_t; - typedef VectorDistBase<Storage, Bin> base_t; - private: - union { - base_t *stat; - const base_t *cstat; - }; + Stat *stat; int index; protected: - Storage *data() { return stat->data(index); } - const Storage *data() const { return cstat->data(index); } + typename Stat::Storage *data() { return stat->data(index); } + const typename Stat::Storage *data() const { return stat->data(index); } public: - DistProxy(const VectorDistBase<Storage, Bin> &s, int i) - : cstat(&s), index(i) {} + DistProxy(Stat *s, int i) + : stat(s), index(i) + {} + DistProxy(const DistProxy &sp) - : cstat(sp.cstat), index(sp.index) {} - const DistProxy &operator=(const DistProxy &sp) { - cstat = sp.cstat; index = sp.index; return *this; + : stat(sp.stat), index(sp.index) + {} + + const DistProxy &operator=(const DistProxy &sp) + { + stat = sp.stat; + index = sp.index; + return *this; } public: template <typename U> - void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); } + void + sample(const U &v, int n = 1) + { + data()->sample(v, n, stat->params); + } + + size_t + size() const + { + return 1; + } + + bool + zero() const + { + return data()->zero(stat->params); + } - size_t size() const { return 1; } - bool zero() const { return data()->zero(cstat->params); } - /** - * Return true if stat is binned. - *@return false since Proxies are not binned/printed. - */ - bool binned() const { return false; } /** * Proxy has no state. Nothing to reset. */ void reset() { } }; -template <class Storage, class Bin> -inline DistProxy<Storage, Bin> -VectorDistBase<Storage, Bin>::operator[](int index) +template <class Storage> +inline typename VectorDistBase<Storage>::Proxy +VectorDistBase<Storage>::operator[](int index) { assert (index >= 0 && index < size()); - return DistProxy<Storage, Bin>(*this, index); -} - -template <class Storage, class Bin> -inline const DistProxy<Storage, Bin> -VectorDistBase<Storage, Bin>::operator[](int index) const -{ - assert (index >= 0 && index < size()); - return DistProxy<Storage, Bin>(*this, index); + return typename VectorDistBase<Storage>::Proxy(this, index); } #if 0 -template <class Storage, class Bin> +template <class Storage> Result -VectorDistBase<Storage, Bin>::total(int index) const +VectorDistBase<Storage>::total(int index) const { int total = 0; - for (int i=0; i < x_size(); ++i) { - total += data(i)->result(*params); + for (int i = 0; i < x_size(); ++i) { + total += data(i)->result(stat->params); } } #endif @@ -1848,11 +1924,6 @@ class Node : public RefCounted * @return The total of the result vector. */ virtual Result total() const = 0; - /** - * Return true if stat is binned. - *@return True is stat is binned. - */ - virtual bool binned() const = 0; /** * @@ -1879,11 +1950,6 @@ class ScalarStatNode : public Node virtual Result total() const { return data->result(); }; virtual size_t size() const { return 1; } - /** - * Return true if stat is binned. - *@return True is stat is binned. - */ - virtual bool binned() const { return data->binned(); } /** * @@ -1891,34 +1957,45 @@ class ScalarStatNode : public Node virtual std::string str() const { return data->name; } }; -template <class Storage, class Bin> +template <class Stat> class ScalarProxyNode : public Node { private: - const ScalarProxy<Storage, Bin> proxy; + const ScalarProxy<Stat> proxy; mutable VResult vresult; public: - ScalarProxyNode(const ScalarProxy<Storage, Bin> &p) - : proxy(p), vresult(1) { } - virtual const VResult &result() const + ScalarProxyNode(const ScalarProxy<Stat> &p) + : proxy(p), vresult(1) + { } + + virtual const VResult & + result() const { vresult[0] = proxy.result(); return vresult; } - virtual Result total() const { return proxy.result(); }; - virtual size_t size() const { return 1; } - /** - * Return true if stat is binned. - *@return True is stat is binned. - */ - virtual bool binned() const { return proxy.binned(); } + virtual Result + total() const + { + return proxy.result(); + } + + virtual size_t + size() const + { + return 1; + } /** * */ - virtual std::string str() const { return proxy.str(); } + virtual std::string + str() const + { + return proxy.str(); + } }; class VectorStatNode : public Node @@ -1932,11 +2009,6 @@ class VectorStatNode : public Node virtual Result total() const { return data->total(); }; virtual size_t size() const { return data->size(); } - /** - * Return true if stat is binned. - *@return True is stat is binned. - */ - virtual bool binned() const { return data->binned(); } virtual std::string str() const { return data->name; } }; @@ -1952,13 +2024,6 @@ class ConstNode : public Node const VResult &result() const { return vresult; } virtual Result total() const { return vresult[0]; }; virtual size_t size() const { return 1; } - - /** - * Return true if stat is binned. - *@return False since constants aren't binned. - */ - virtual bool binned() const { return false; } - virtual std::string str() const { return to_string(vresult[0]); } }; @@ -2032,11 +2097,6 @@ class UnaryNode : public Node } virtual size_t size() const { return l->size(); } - /** - * Return true if child of node is binned. - *@return True if child of node is binned. - */ - virtual bool binned() const { return l->binned(); } virtual std::string str() const { @@ -2103,11 +2163,6 @@ class BinaryNode : public Node return ls; } } - /** - * Return true if any children of node are binned - *@return True if either child of node is binned. - */ - virtual bool binned() const { return (l->binned() || r->binned()); } virtual std::string str() const { @@ -2156,11 +2211,6 @@ class SumNode : public Node } virtual size_t size() const { return 1; } - /** - * Return true if child of node is binned. - *@return True if child of node is binned. - */ - virtual bool binned() const { return l->binned(); } virtual std::string str() const { @@ -2176,40 +2226,24 @@ class SumNode : public Node ////////////////////////////////////////////////////////////////////// /** * @defgroup VisibleStats "Statistic Types" - * These are the statistics that are used in the simulator. By default these - * store counters and don't use binning, but are templatized to accept any type - * and any Bin class. + * These are the statistics that are used in the simulator. * @{ */ /** - * This is an easy way to assign all your stats to be binned or not - * binned. If the typedef is NoBin, nothing is binned. If it is - * MainBin, then all stats are binned under that Bin. - */ -#if STATS_BINNING -typedef MainBin DefaultBin; -#else -typedef NoBin DefaultBin; -#endif - -/** * This is a simple scalar statistic, like a counter. * @sa Stat, ScalarBase, StatStor */ -template <class Bin = DefaultBin> -class Scalar - : public Wrap<Scalar<Bin>, - ScalarBase<StatStor, Bin>, - ScalarStatData> +template<int N = 0> +class Scalar : public Wrap<Scalar<N>, ScalarBase<StatStor>, ScalarStatData> { public: /** The base implementation. */ - typedef ScalarBase<StatStor, Bin> Base; + typedef ScalarBase<StatStor> Base; Scalar() { - this->setInit(); + this->doInit(); } /** @@ -2221,10 +2255,7 @@ class Scalar void operator=(const U &v) { Base::operator=(v); } }; -class Value - : public Wrap<Value, - ValueBase, - ScalarStatData> +class Value : public Wrap<Value, ValueBase, ScalarStatData> { public: /** The base implementation. */ @@ -2249,19 +2280,16 @@ class Value * A stat that calculates the per cycle average of a value. * @sa Stat, ScalarBase, AvgStor */ -template <class Bin = DefaultBin> -class Average - : public Wrap<Average<Bin>, - ScalarBase<AvgStor, Bin>, - ScalarStatData> +template<int N = 0> +class Average : public Wrap<Average<N>, ScalarBase<AvgStor>, ScalarStatData> { public: /** The base implementation. */ - typedef ScalarBase<AvgStor, Bin> Base; + typedef ScalarBase<AvgStor> Base; Average() { - this->setInit(); + this->doInit(); } /** @@ -2277,15 +2305,12 @@ class Average * A vector of scalar stats. * @sa Stat, VectorBase, StatStor */ -template <class Bin = DefaultBin> -class Vector - : public WrapVec<Vector<Bin>, - VectorBase<StatStor, Bin>, - VectorStatData> +template<int N = 0> +class Vector : public WrapVec<Vector<N>, VectorBase<StatStor>, VectorStatData> { public: /** The base implementation. */ - typedef ScalarBase<StatStor, Bin> Base; + typedef ScalarBase<StatStor> Base; /** * Set this vector to have the given size. @@ -2293,9 +2318,7 @@ class Vector * @return A reference to this stat. */ Vector &init(size_t size) { - this->bin.init(size, this->params); - this->setInit(); - + this->doInit(size); return *this; } }; @@ -2304,11 +2327,9 @@ class Vector * A vector of Average stats. * @sa Stat, VectorBase, AvgStor */ -template <class Bin = DefaultBin> +template<int N = 0> class AverageVector - : public WrapVec<AverageVector<Bin>, - VectorBase<AvgStor, Bin>, - VectorStatData> + : public WrapVec<AverageVector<N>, VectorBase<AvgStor>, VectorStatData> { public: /** @@ -2317,9 +2338,7 @@ class AverageVector * @return A reference to this stat. */ AverageVector &init(size_t size) { - this->bin.init(size, this->params); - this->setInit(); - + this->doInit(size); return *this; } }; @@ -2328,19 +2347,13 @@ class AverageVector * A 2-Dimensional vecto of scalar stats. * @sa Stat, Vector2dBase, StatStor */ -template <class Bin = DefaultBin> +template<int N = 0> class Vector2d - : public WrapVec2d<Vector2d<Bin>, - Vector2dBase<StatStor, Bin>, - Vector2dStatData> + : public WrapVec2d<Vector2d<N>, Vector2dBase<StatStor>, Vector2dStatData> { public: - Vector2d &init(size_t _x, size_t _y) { - this->statData()->x = this->x = _x; - this->statData()->y = this->y = _y; - this->bin.init(this->x * this->y, this->params); - this->setInit(); - + Vector2d &init(size_t x, size_t y) { + this->doInit(x, y); return *this; } }; @@ -2349,17 +2362,15 @@ class Vector2d * A simple distribution stat. * @sa Stat, DistBase, DistStor */ -template <class Bin = DefaultBin> +template<int N = 0> class Distribution - : public Wrap<Distribution<Bin>, - DistBase<DistStor, Bin>, - DistStatData> + : public Wrap<Distribution<N>, DistBase<DistStor>, DistStatData> { public: /** Base implementation. */ - typedef DistBase<DistStor, Bin> Base; + typedef DistBase<DistStor> Base; /** The Parameter type. */ - typedef typename DistStor::Params Params; + typedef DistStor::Params Params; public: /** @@ -2374,9 +2385,7 @@ class Distribution this->params.max = max; this->params.bucket_size = bkt; this->params.size = (int)rint((max - min) / bkt + 1.0); - this->bin.init(this->params); - this->setInit(); - + this->doInit(); return *this; } }; @@ -2385,25 +2394,22 @@ class Distribution * Calculates the mean and variance of all the samples. * @sa Stat, DistBase, FancyStor */ -template <class Bin = DefaultBin> +template<int N = 0> class StandardDeviation - : public Wrap<StandardDeviation<Bin>, - DistBase<FancyStor, Bin>, - DistStatData> + : public Wrap<StandardDeviation<N>, DistBase<FancyStor>, DistStatData> { public: /** The base implementation */ - typedef DistBase<DistStor, Bin> Base; + typedef DistBase<DistStor> Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef DistStor::Params Params; public: /** * Construct and initialize this distribution. */ StandardDeviation() { - this->bin.init(this->params); - this->setInit(); + this->doInit(); } }; @@ -2411,17 +2417,15 @@ class StandardDeviation * Calculates the per cycle mean and variance of the samples. * @sa Stat, DistBase, AvgFancy */ -template <class Bin = DefaultBin> +template<int N = 0> class AverageDeviation - : public Wrap<AverageDeviation<Bin>, - DistBase<AvgFancy, Bin>, - DistStatData> + : public Wrap<AverageDeviation<N>, DistBase<AvgFancy>, DistStatData> { public: /** The base implementation */ - typedef DistBase<DistStor, Bin> Base; + typedef DistBase<DistStor> Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef DistStor::Params Params; public: /** @@ -2429,8 +2433,7 @@ class AverageDeviation */ AverageDeviation() { - this->bin.init(this->params); - this->setInit(); + this->doInit(); } }; @@ -2438,17 +2441,17 @@ class AverageDeviation * A vector of distributions. * @sa Stat, VectorDistBase, DistStor */ -template <class Bin = DefaultBin> +template<int N = 0> class VectorDistribution - : public WrapVec<VectorDistribution<Bin>, - VectorDistBase<DistStor, Bin>, + : public WrapVec<VectorDistribution<N>, + VectorDistBase<DistStor>, VectorDistStatData> { public: /** The base implementation */ - typedef VectorDistBase<DistStor, Bin> Base; + typedef VectorDistBase<DistStor> Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef DistStor::Params Params; public: /** @@ -2464,9 +2467,7 @@ class VectorDistribution this->params.max = max; this->params.bucket_size = bkt; this->params.size = (int)rint((max - min) / bkt + 1.0); - this->bin.init(size, this->params); - this->setInit(); - + this->doInit(size); return *this; } }; @@ -2475,17 +2476,17 @@ class VectorDistribution * This is a vector of StandardDeviation stats. * @sa Stat, VectorDistBase, FancyStor */ -template <class Bin = DefaultBin> +template<int N = 0> class VectorStandardDeviation - : public WrapVec<VectorStandardDeviation<Bin>, - VectorDistBase<FancyStor, Bin>, + : public WrapVec<VectorStandardDeviation<N>, + VectorDistBase<FancyStor>, VectorDistStatData> { public: /** The base implementation */ - typedef VectorDistBase<FancyStor, Bin> Base; + typedef VectorDistBase<FancyStor> Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef DistStor::Params Params; public: /** @@ -2494,9 +2495,7 @@ class VectorStandardDeviation * @return A reference to this distribution. */ VectorStandardDeviation &init(int size) { - this->bin.init(size, this->params); - this->setInit(); - + this->doInit(size); return *this; } }; @@ -2505,17 +2504,17 @@ class VectorStandardDeviation * This is a vector of AverageDeviation stats. * @sa Stat, VectorDistBase, AvgFancy */ -template <class Bin = DefaultBin> +template<int N = 0> class VectorAverageDeviation - : public WrapVec<VectorAverageDeviation<Bin>, - VectorDistBase<AvgFancy, Bin>, + : public WrapVec<VectorAverageDeviation<N>, + VectorDistBase<AvgFancy>, VectorDistStatData> { public: /** The base implementation */ - typedef VectorDistBase<AvgFancy, Bin> Base; + typedef VectorDistBase<AvgFancy> Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef DistStor::Params Params; public: /** @@ -2524,9 +2523,7 @@ class VectorAverageDeviation * @return A reference to this distribution. */ VectorAverageDeviation &init(int size) { - this->bin.init(size, this->params); - this->setInit(); - + this->doInit(size); return *this; } }; @@ -2570,13 +2567,6 @@ class FormulaBase : public DataAccess */ size_t size() const; - /** - * Return true if Formula is binned. i.e. any of its children - * nodes are binned - * @return True if Formula is binned. - */ - bool binned() const; - bool check() const { return true; } /** @@ -2615,7 +2605,6 @@ class FormulaStatData : public FormulaData public: FormulaStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return s.binned(); } virtual bool zero() const { return s.zero(); } virtual void reset() { s.reset(); } @@ -2682,7 +2671,6 @@ class FormulaNode : public Node virtual size_t size() const { return formula.size(); } virtual const VResult &result() const { formula.result(vec); return vec; } virtual Result total() const { return formula.total(); } - virtual bool binned() const { return formula.binned(); } virtual std::string str() const { return formula.str(); } }; @@ -2716,8 +2704,8 @@ class Temp * Create a new ScalarStatNode. * @param s The ScalarStat to place in a node. */ - template <class Bin> - Temp(const Scalar<Bin> &s) + template <int N> + Temp(const Scalar<N> &s) : node(new ScalarStatNode(s.statData())) { } /** @@ -2731,16 +2719,16 @@ class Temp * Create a new ScalarStatNode. * @param s The ScalarStat to place in a node. */ - template <class Bin> - Temp(const Average<Bin> &s) + template <int N> + Temp(const Average<N> &s) : node(new ScalarStatNode(s.statData())) { } /** * Create a new VectorStatNode. * @param s The VectorStat to place in a node. */ - template <class Bin> - Temp(const Vector<Bin> &s) + template <int N> + Temp(const Vector<N> &s) : node(new VectorStatNode(s.statData())) { } /** @@ -2753,9 +2741,9 @@ class Temp * Create a new ScalarProxyNode. * @param p The ScalarProxy to place in a node. */ - template <class Storage, class Bin> - Temp(const ScalarProxy<Storage, Bin> &p) - : node(new ScalarProxyNode<Storage, Bin>(p)) { } + template <class Stat> + Temp(const ScalarProxy<Stat> &p) + : node(new ScalarProxyNode<Stat>(p)) { } /** * Create a ConstNode diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc index fa4bcd5ee..0fb31f4ce 100644 --- a/src/base/stats/mysql.cc +++ b/src/base/stats/mysql.cc @@ -158,14 +158,6 @@ MySqlRun::cleanup() if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); - mysql.query("DELETE bins " - "FROM bins " - "LEFT JOIN data ON bn_id=dt_bin " - "WHERE dt_bin IS NULL"); - - if (mysql.commit()) - panic("could not commit transaction\n%s\n", mysql.error); - mysql.query("DELETE events" "FROM events" "LEFT JOIN runs ON ev_run=rn_id" @@ -309,52 +301,6 @@ SetupStat::setup() return statid; } -unsigned -SetupBin(const string &bin) -{ - static map<string, int> binmap; - - using namespace MySQL; - map<string,int>::const_iterator i = binmap.find(bin); - if (i != binmap.end()) - return (*i).second; - - Connection &mysql = MySqlDB.conn(); - assert(mysql.connected()); - - uint16_t bin_id; - - stringstream select; - stringstream insert; - ccprintf(select, "SELECT bn_id FROM bins WHERE bn_name=\"%s\"", bin); - - mysql.query(select); - MySQL::Result result = mysql.store_result(); - if (result) { - assert(result.num_fields() == 1); - MySQL::Row row = result.fetch_row(); - if (row) { - to_number(row[0], bin_id); - goto exit; - } - } - - ccprintf(insert, "INSERT INTO bins(bn_name) values(\"%s\")", bin); - - mysql.query(insert); - if (mysql.error) - panic("could not get a bin\n%s\n", mysql.error); - - bin_id = mysql.insert_id(); - if (mysql.commit()) - panic("could not commit transaction\n%s\n", mysql.error); - - binmap.insert(make_pair(bin, bin_id)); - - exit: - return bin_id; -} - InsertData::InsertData() { query = new char[maxsize + 1]; @@ -384,7 +330,7 @@ InsertData::flush() size = 0; first = true; strcpy(query, "INSERT INTO " - "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) " + "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_data) " "values"); size = strlen(query); } @@ -402,9 +348,9 @@ InsertData::insert() first = false; - size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")", + size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")", stat, x, y, MySqlDB.run(), (unsigned long long)tick, - bin, data); + data); } struct InsertSubData @@ -656,29 +602,6 @@ MySql::configure(const FormulaData &data) InsertFormula(find(data.id), data.str()); } -void -MySql::output(MainBin *bin) -{ - MySQL::Connection &mysql = MySqlDB.conn(); - - if (bin) { - bin->activate(); - newdata.bin = SetupBin(bin->name()); - } else { - newdata.bin = 0; - } - - Database::stat_list_t::const_iterator i, end = Database::stats().end(); - for (i = Database::stats().begin(); i != end; ++i) { - StatData *stat = *i; - if (bin && stat->binned() || !bin && !stat->binned()) { - stat->visit(*this); - if (mysql.commit()) - panic("could not commit transaction\n%s\n", mysql.error); - } - } -} - bool MySql::valid() const { @@ -697,11 +620,14 @@ MySql::output() // store sample # newdata.tick = curTick; - output(NULL); - if (!bins().empty()) { - bin_list_t::iterator i, end = bins().end(); - for (i = bins().begin(); i != end; ++i) - output(*i); + MySQL::Connection &mysql = MySqlDB.conn(); + + Database::stat_list_t::const_iterator i, end = Database::stats().end(); + for (i = Database::stats().begin(); i != end; ++i) { + StatData *stat = *i; + stat->visit(*this); + if (mysql.commit()) + panic("could not commit transaction\n%s\n", mysql.error); } newdata.flush(); diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh index 1d88fbcd9..50f7d9e97 100644 --- a/src/base/stats/mysql.hh +++ b/src/base/stats/mysql.hh @@ -39,7 +39,6 @@ namespace MySQL { class Connection; } namespace Stats { -class MainBin; class DistDataData; class MySqlRun; bool MySqlConnected(); @@ -82,7 +81,6 @@ class InsertData uint64_t tick; double data; uint16_t stat; - uint16_t bin; int16_t x; int16_t y; @@ -133,7 +131,6 @@ class MySql : public Output protected: // Output helper - void output(MainBin *bin); void output(const DistDataData &data); void output(const ScalarData &data); void output(const VectorData &data); diff --git a/src/base/stats/statdb.cc b/src/base/stats/statdb.cc index 682f62dc1..f9136807a 100644 --- a/src/base/stats/statdb.cc +++ b/src/base/stats/statdb.cc @@ -31,7 +31,6 @@ #include "base/misc.hh" #include "base/trace.hh" #include "base/statistics.hh" -#include "base/stats/bin.hh" #include "base/stats/statdb.hh" using namespace std; @@ -51,17 +50,6 @@ find(void *stat) } void -regBin(MainBin *bin, const std::string &_name) -{ - bin_list_t::iterator i, end = bins().end(); - for (i = bins().begin(); i != end; ++i) - if ((*i)->name() == _name) - panic("re-registering bin %s", _name); - bins().push_back(bin); - DPRINTF(Stats, "registering %s\n", _name); -} - -void regStat(void *stat, StatData *data) { if (map().find(stat) != map().end()) diff --git a/src/base/stats/statdb.hh b/src/base/stats/statdb.hh index 8c56e031e..a5b9be7eb 100644 --- a/src/base/stats/statdb.hh +++ b/src/base/stats/statdb.hh @@ -40,31 +40,25 @@ class Python; namespace Stats { -class MainBin; class StatData; namespace Database { typedef std::map<void *, StatData *> stat_map_t; typedef std::list<StatData *> stat_list_t; -typedef std::list<MainBin *> bin_list_t; // We wrap the database in a struct to make sure it is built in time. struct TheDatabase { stat_map_t map; stat_list_t stats; - bin_list_t bins; - }; TheDatabase &db(); inline stat_map_t &map() { return db().map; } inline stat_list_t &stats() { return db().stats; } -inline bin_list_t &bins() { return db().bins; } StatData *find(void *stat); -void regBin(MainBin *bin, const std::string &name); void regStat(void *stat, StatData *data); void regPrint(void *stat); diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc index 8d2144665..c4448efc9 100644 --- a/src/base/stats/text.cc +++ b/src/base/stats/text.cc @@ -129,23 +129,9 @@ Text::output() using namespace Database; ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n"); - if (bins().empty() || bins().size() == 1) { - stat_list_t::const_iterator i, end = stats().end(); - for (i = stats().begin(); i != end; ++i) - (*i)->visit(*this); - } else { - ccprintf(*stream, "PRINTING BINNED STATS\n"); - bin_list_t::iterator i, end = bins().end(); - for (i = bins().begin(); i != end; ++i) { - MainBin *bin = *i; - bin->activate(); - ccprintf(*stream,"---%s Bin------------\n", bin->name()); - stat_list_t::const_iterator i, end = stats().end(); - for (i = stats().begin(); i != end; ++i) - (*i)->visit(*this); - ccprintf(*stream, "---------------------------------\n"); - } - } + stat_list_t::const_iterator i, end = stats().end(); + for (i = stats().begin(); i != end; ++i) + (*i)->visit(*this); ccprintf(*stream, "\n---------- End Simulation Statistics ----------\n"); stream->flush(); } diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh index de27abe1b..b3faf5ad5 100644 --- a/src/base/stats/text.hh +++ b/src/base/stats/text.hh @@ -46,7 +46,6 @@ class Text : public Output protected: bool noOutput(const StatData &data); - void binout(); public: bool compat; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index b854dfab2..b4258fce6 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -415,11 +415,6 @@ void BaseSimpleCPU::postExecute() { #if FULL_SYSTEM - if (system->kernelBinning->fnbin) { - assert(thread->getKernelStats()); - system->kernelBinning->execute(tc, inst); - } - if (thread->profile) { bool usermode = (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index e3bb7d9c3..48c8fa28d 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -245,6 +245,7 @@ class ThreadContext virtual void setSyscallReturn(SyscallReturn return_value) = 0; + virtual void syscall(int64_t callnum) = 0; // Same with st cond failures. virtual Counter readFuncExeInst() = 0; @@ -431,6 +432,7 @@ class ProxyThreadContext : public ThreadContext void setSyscallReturn(SyscallReturn return_value) { actualTC->setSyscallReturn(return_value); } + void syscall(int64_t callnum) { actualTC->syscall(callnum); } Counter readFuncExeInst() { return actualTC->readFuncExeInst(); } #endif diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc index 2ba120b6f..f7868b50f 100644 --- a/src/kern/kernel_stats.cc +++ b/src/kern/kernel_stats.cc @@ -45,13 +45,12 @@ using namespace Stats; namespace Kernel { -const char *modestr[] = { "kernel", "user", "idle", "interrupt" }; +const char *modestr[] = { "kernel", "user", "idle" }; Statistics::Statistics(System *system) : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), iplLast(0), iplLastTick(0) { - bin_int = system->params()->bin_int; } void @@ -186,7 +185,7 @@ Statistics::regStats(const string &_name) void Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) { - assert(themode == kernel || themode == interrupt); + assert(themode == kernel); idleProcess = idlepcbb; themode = idle; changeMode(themode, tc); @@ -206,8 +205,6 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) _modeGood[newmode]++; _modeTicks[themode] += curTick - lastModeTick; - tc->getSystemPtr()->kernelBinning->changeMode(newmode); - lastModeTick = curTick; themode = newmode; } @@ -233,13 +230,9 @@ Statistics::mode(cpu_mode newmode, ThreadContext *tc) { Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); - if ((newmode == kernel || newmode == interrupt) && - pcbb == idleProcess) + if (newmode == kernel && pcbb == idleProcess) newmode = idle; - if (bin_int == false && newmode == interrupt) - newmode = kernel; - changeMode(newmode, tc); } @@ -268,11 +261,6 @@ Statistics::callpal(int code, ThreadContext *tc) _syscall[cvtnum]++; } } break; - - case PAL::swpctx: - if (tc->getSystemPtr()->kernelBinning) - tc->getSystemPtr()->kernelBinning->palSwapContext(tc); - break; } } diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh index 781b6f6da..c691ad8cf 100644 --- a/src/kern/kernel_stats.hh +++ b/src/kern/kernel_stats.hh @@ -47,95 +47,17 @@ class System; namespace Kernel { -enum cpu_mode { kernel, user, idle, interrupt, cpu_mode_num }; +enum cpu_mode { kernel, user, idle, cpu_mode_num }; extern const char *modestr[]; -class Binning -{ - private: - std::string myname; - System *system; - - private: - // lisa's binning stuff - struct fnCall - { - Stats::MainBin *myBin; - std::string name; - }; - - struct SWContext - { - Counter calls; - std::stack<fnCall *> callStack; - }; - - std::map<const std::string, Stats::MainBin *> fnBins; - std::map<const Addr, SWContext *> swCtxMap; - - std::multimap<const std::string, std::string> callerMap; - void populateMap(std::string caller, std::string callee); - - std::vector<FnEvent *> fnEvents; - - Stats::Scalar<> fnCalls; - - Stats::MainBin *getBin(const std::string &name); - bool findCaller(std::string, std::string) const; - - SWContext *findContext(Addr pcb); - bool addContext(Addr pcb, SWContext *ctx) - { - return (swCtxMap.insert(std::make_pair(pcb, ctx))).second; - } - - void remContext(Addr pcb) - { - swCtxMap.erase(pcb); - } - - void dumpState() const; - - SWContext *swctx; - std::vector<std::string> binned_fns; - - private: - Stats::MainBin *modeBin[cpu_mode_num]; - - public: - const bool bin; - const bool fnbin; - - cpu_mode themode; - void palSwapContext(ThreadContext *tc); - void execute(ThreadContext *tc, StaticInstPtr inst); - void call(ThreadContext *tc, Stats::MainBin *myBin); - void changeMode(cpu_mode mode); - - public: - Binning(System *sys); - virtual ~Binning(); - - const std::string name() const { return myname; } - void regStats(const std::string &name); - - public: - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - class Statistics : public Serializable { private: - friend class Binning; - - private: std::string myname; Addr idleProcess; cpu_mode themode; Tick lastModeTick; - bool bin_int; void changeMode(cpu_mode newmode, ThreadContext *tc); diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc index fe3805ce2..177ce96d1 100644 --- a/src/kern/system_events.cc +++ b/src/kern/system_events.cc @@ -55,22 +55,6 @@ SkipFuncEvent::process(ThreadContext *tc) */ } - -FnEvent::FnEvent(PCEventQueue *q, const std::string &desc, Addr addr, - Stats::MainBin *bin) - : PCEvent(q, desc, addr), _name(desc), mybin(bin) -{ -} - -void -FnEvent::process(ThreadContext *tc) -{ - if (tc->misspeculating()) - return; - - tc->getSystemPtr()->kernelBinning->call(tc, mybin); -} - void IdleStartEvent::process(ThreadContext *tc) { @@ -79,19 +63,3 @@ IdleStartEvent::process(ThreadContext *tc) tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc); remove(); } - -void -InterruptStartEvent::process(ThreadContext *tc) -{ - if (tc->getKernelStats()) - tc->getKernelStats()->mode(Kernel::interrupt, tc); -} - -void -InterruptEndEvent::process(ThreadContext *tc) -{ - // We go back to kernel, if we are user, inside the rti - // pal code we will get switched to user because of the ICM write - if (tc->getKernelStats()) - tc->getKernelStats()->mode(Kernel::kernel, tc); -} diff --git a/src/kern/system_events.hh b/src/kern/system_events.hh index 05c878577..ccd6bd9a4 100644 --- a/src/kern/system_events.hh +++ b/src/kern/system_events.hh @@ -45,19 +45,6 @@ class SkipFuncEvent : public PCEvent virtual void process(ThreadContext *tc); }; -class FnEvent : public PCEvent -{ - public: - FnEvent(PCEventQueue *q, const std::string &desc, Addr addr, - Stats::MainBin *bin); - virtual void process(ThreadContext *tc); - std::string myname() const { return _name; } - - private: - std::string _name; - Stats::MainBin *mybin; -}; - class IdleStartEvent : public PCEvent { public: @@ -67,23 +54,4 @@ class IdleStartEvent : public PCEvent virtual void process(ThreadContext *tc); }; -class InterruptStartEvent : public PCEvent -{ - public: - InterruptStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) - : PCEvent(q, desc, addr) - {} - virtual void process(ThreadContext *tc); -}; - -class InterruptEndEvent : public PCEvent -{ - public: - InterruptEndEvent(PCEventQueue *q, const std::string &desc, Addr addr) - : PCEvent(q, desc, addr) - {} - virtual void process(ThreadContext *tc); -}; - - #endif // __SYSTEM_EVENTS_HH__ diff --git a/src/python/m5/config.py b/src/python/m5/config.py index 3eb99972f..97e13c900 100644 --- a/src/python/m5/config.py +++ b/src/python/m5/config.py @@ -143,8 +143,8 @@ def isSimObjectClass(value): # happens if value is not a class at all return False -def isSimObjSequence(value): - if not isinstance(value, (list, tuple)): +def isSimObjectSequence(value): + if not isinstance(value, (list, tuple)) or len(value) == 0: return False for val in value: @@ -153,8 +153,8 @@ def isSimObjSequence(value): return True -def isSimObjClassSequence(value): - if not isinstance(value, (list, tuple)): +def isSimObjectClassSequence(value): + if not isinstance(value, (list, tuple)) or len(value) == 0: return False for val in value: @@ -163,9 +163,31 @@ def isSimObjClassSequence(value): return True +def isSimObjectOrSequence(value): + return isSimObject(value) or isSimObjectSequence(value) + +def isSimObjectClassOrSequence(value): + return isSimObjectClass(value) or isSimObjectClassSequence(value) + def isNullPointer(value): return isinstance(value, NullSimObject) +# Apply method to object. +# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) +def applyMethod(obj, meth, *args, **kwargs): + return getattr(obj, meth)(*args, **kwargs) + +# If the first argument is an (non-sequence) object, apply the named +# method with the given arguments. If the first argument is a +# sequence, apply the method to each element of the sequence (a la +# 'map'). +def applyOrMap(objOrSeq, meth, *args, **kwargs): + if not isinstance(objOrSeq, (list, tuple)): + return applyMethod(objOrSeq, meth, *args, **kwargs) + else: + return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] + + # The metaclass for ConfigNode (and thus for everything that derives # from ConfigNode, including SimObject). This class controls how new # classes that derive from ConfigNode are instantiated, and provides @@ -255,21 +277,15 @@ class MetaSimObject(type): # Existing classes should not have any instance values, so # these can only occur at the lowest level dict (the # parameters just being set in this class definition). - if isSimObject(val): - assert(val == cls._values.local[key]) - cls._values[key] = val.makeClass(memo) - elif isSimObjSequence(val) and len(val): + if isSimObjectOrSequence(val): assert(val == cls._values.local[key]) - cls._values[key] = [ v.makeClass(memo) for v in val ] + cls._values[key] = applyOrMap(val, 'makeClass', memo) # SimObject classes need to be subclassed so that # parameters that get set at this level only affect this # level and derivatives. - elif isSimObjectClass(val): - assert(not cls._values.local.has_key(key)) - cls._values[key] = val.makeSubclass({}, memo) - elif isSimObjClassSequence(val) and len(val): + elif isSimObjectClassOrSequence(val): assert(not cls._values.local.has_key(key)) - cls._values[key] = [ v.makeSubclass({}, memo) for v in val ] + cls._values[key] = applyOrMap(val, 'makeSubclass', {}, memo) def _set_keyword(cls, keyword, val, kwtype): @@ -301,8 +317,7 @@ class MetaSimObject(type): param = cls._params.get(attr, None) if param: # It's ok: set attribute by delegating to 'object' class. - if (isSimObject(value) or isSimObjSequence(value)) \ - and cls._instantiated: + if isSimObjectOrSequence(value) and cls._instantiated: raise AttributeError, \ "Cannot set SimObject parameter '%s' after\n" \ " class %s has been instantiated or subclassed" \ @@ -315,7 +330,7 @@ class MetaSimObject(type): e.args = (msg, ) raise # I would love to get rid of this - elif isSimObject(value) or isSimObjSequence(value): + elif isSimObjectOrSequence(value): cls._values[attr] = value else: raise AttributeError, \ @@ -407,7 +422,7 @@ class SimObject(object): for key,val in self.__class__._values.iteritems(): if isSimObjectClass(val): setattr(self, key, val(_memo)) - elif isSimObjClassSequence(val) and len(val): + elif isSimObjectClassSequence(val) and len(val): setattr(self, key, [ v(_memo) for v in val ]) # apply attribute assignments from keyword args, if any for key,val in kwargs.iteritems(): @@ -454,7 +469,7 @@ class SimObject(object): e.args = (msg, ) raise # I would love to get rid of this - elif isSimObject(value) or isSimObjSequence(value): + elif isSimObjectOrSequence(value): pass else: raise AttributeError, "Class %s has no parameter %s" \ @@ -465,7 +480,7 @@ class SimObject(object): if isSimObject(value): value.set_path(self, attr) - elif isSimObjSequence(value): + elif isSimObjectSequence(value): value = SimObjVector(value) [v.set_path(self, "%s%d" % (attr, i)) for i,v in enumerate(value)] @@ -888,7 +903,7 @@ class VectorParamDesc(ParamDesc): if isinstance(value, (list, tuple)): # list: coerce each element into new list tmp_list = [ ParamDesc.convert(self, v) for v in value ] - if isSimObjSequence(tmp_list): + if isSimObjectSequence(tmp_list): return SimObjVector(tmp_list) else: return VectorParamValue(tmp_list) diff --git a/src/python/m5/objects/System.py b/src/python/m5/objects/System.py index a8063a274..9a1e1d690 100644 --- a/src/python/m5/objects/System.py +++ b/src/python/m5/objects/System.py @@ -8,8 +8,6 @@ class System(SimObject): boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, "boot processor frequency") init_param = Param.UInt64(0, "numerical value to pass into simulator") - bin = Param.Bool(False, "is this system binned") - binned_fns = VectorParam.String([], "functions broken down and binned") boot_osflags = Param.String("a", "boot flags to pass to the kernel") kernel = Param.String("file that contains the kernel code") readfile = Param.String("", "file to read startup script from") diff --git a/src/sim/process.cc b/src/sim/process.cc index 1533a376d..5080c3ac1 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -50,6 +50,20 @@ #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" +#else +#error "THE_ISA not set" +#endif + + using namespace std; using namespace TheISA; @@ -362,4 +376,132 @@ LiveProcess::syscall(int64_t callnum, ThreadContext *tc) desc->doSyscall(callnum, this, tc); } -DEFINE_SIM_OBJECT_CLASS_NAME("LiveProcess", LiveProcess); +LiveProcess * +LiveProcess::create(const std::string &nm, System *system, int stdin_fd, + int stdout_fd, int stderr_fd, std::string executable, + std::vector<std::string> &argv, + std::vector<std::string> &envp) +{ + LiveProcess *process = NULL; + + ObjectFile *objFile = createObjectFile(executable); + if (objFile == NULL) { + fatal("Can't load object file %s", executable); + } + +#if THE_ISA == ALPHA_ISA + if (objFile->getArch() != ObjectFile::Alpha) + fatal("Object file architecture does not match compiled ISA (Alpha)."); + switch (objFile->getOpSys()) { + case ObjectFile::Tru64: + process = new AlphaTru64Process(nm, objFile, system, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + case ObjectFile::Linux: + process = new AlphaLinuxProcess(nm, objFile, system, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + default: + fatal("Unknown/unsupported operating system."); + } +#elif THE_ISA == SPARC_ISA + if (objFile->getArch() != ObjectFile::SPARC) + fatal("Object file architecture does not match compiled ISA (SPARC)."); + switch (objFile->getOpSys()) { + case ObjectFile::Linux: + process = new SparcLinuxProcess(nm, objFile, system, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + + case ObjectFile::Solaris: + process = new SparcSolarisProcess(nm, objFile, system, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + default: + fatal("Unknown/unsupported operating system."); + } +#elif THE_ISA == MIPS_ISA + if (objFile->getArch() != ObjectFile::Mips) + fatal("Object file architecture does not match compiled ISA (MIPS)."); + switch (objFile->getOpSys()) { + case ObjectFile::Linux: + process = new MipsLinuxProcess(nm, objFile, system, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + default: + fatal("Unknown/unsupported operating system."); + } +#else +#error "THE_ISA not set" +#endif + + + if (process == NULL) + fatal("Unknown error creating process object."); + return process; +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) + + VectorParam<string> cmd; + Param<string> executable; + Param<string> input; + Param<string> output; + VectorParam<string> env; + SimObjectParam<System *> system; + +END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) + + +BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess) + + INIT_PARAM(cmd, "command line (executable plus arguments)"), + INIT_PARAM(executable, "executable (overrides cmd[0] if set)"), + INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"), + INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"), + INIT_PARAM(env, "environment settings"), + INIT_PARAM(system, "system") + +END_INIT_SIM_OBJECT_PARAMS(LiveProcess) + + +CREATE_SIM_OBJECT(LiveProcess) +{ + string in = input; + string out = 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 + stdin_fd = Process::openInputFile(input); + + if (out == "stdout" || out == "cout") + stdout_fd = STDOUT_FILENO; + else if (out == "stderr" || out == "cerr") + stdout_fd = STDERR_FILENO; + else + stdout_fd = Process::openOutputFile(out); + + stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; + + return LiveProcess::create(getInstanceName(), system, + stdin_fd, stdout_fd, stderr_fd, + (string)executable == "" ? cmd[0] : executable, + cmd, env); +} + + +REGISTER_SIM_OBJECT("LiveProcess", LiveProcess) diff --git a/src/sim/process.hh b/src/sim/process.hh index edbc1e492..763deb100 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -186,6 +186,16 @@ class LiveProcess : public Process virtual void syscall(int64_t callnum, ThreadContext *tc); virtual SyscallDesc* getDesc(int callnum) = 0; + + // this function is used to create the LiveProcess object, since + // we can't tell which subclass of LiveProcess to use until we + // open and look at the object file. + static LiveProcess *create(const std::string &nm, + System *_system, + int stdin_fd, int stdout_fd, int stderr_fd, + std::string executable, + std::vector<std::string> &argv, + std::vector<std::string> &envp); }; diff --git a/src/sim/system.cc b/src/sim/system.cc index 7953607d5..b3c7870fd 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -132,8 +132,6 @@ System::~System() #if FULL_SYSTEM delete kernelSymtab; delete kernel; - - delete kernelBinning; #else panic("System::fixFuncEventAddr needs to be rewritten " "to work with syscall emulation"); @@ -220,19 +218,9 @@ System::new_page() #endif void -System::regStats() -{ -#if FULL_SYSTEM - kernelBinning->regStats(name() + ".kern"); -#endif // FULL_SYSTEM -} - -void System::serialize(ostream &os) { #if FULL_SYSTEM - kernelBinning->serialize(os); - kernelSymtab->serialize("kernel_symtab", os); #endif // FULL_SYSTEM } @@ -242,8 +230,6 @@ void System::unserialize(Checkpoint *cp, const string §ion) { #if FULL_SYSTEM - kernelBinning->unserialize(cp, section); - kernelSymtab->unserialize("kernel_symtab", cp, section); #endif // FULL_SYSTEM } diff --git a/src/sim/system.hh b/src/sim/system.hh index 3a9fdc3d2..059dc92dc 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -56,7 +56,6 @@ class PhysicalMemory; class Platform; class GDBListener; class RemoteGDB; -namespace Kernel { class Binning; } #endif class System : public SimObject @@ -100,8 +99,6 @@ class System : public SimObject /** Entry point in the kernel to start at */ Addr kernelEntry; - Kernel::Binning *kernelBinning; - #else int page_ptr; @@ -161,9 +158,6 @@ class System : public SimObject Tick boot_cpu_frequency; std::string boot_osflags; uint64_t init_param; - bool bin; - std::vector<std::string> binned_fns; - bool bin_int; std::string kernel_path; std::string readfile; @@ -211,7 +205,6 @@ class System : public SimObject int registerThreadContext(ThreadContext *tc, int tcIndex); void replaceThreadContext(ThreadContext *tc, int tcIndex); - void regStats(); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/src/unittest/stattest.cc b/src/unittest/stattest.cc index 496d1f672..4e504fde9 100644 --- a/src/unittest/stattest.cc +++ b/src/unittest/stattest.cc @@ -50,10 +50,10 @@ Tick ticksPerSecond = ULL(2000000000); Scalar<> s1; Scalar<> s2; Average<> s3; -Scalar<MainBin> s4; -Vector<MainBin> s5; -Distribution<MainBin> s6; -Vector<MainBin> s7; +Scalar<> s4; +Vector<> s5; +Distribution<> s6; +Vector<> s7; AverageVector<> s8; StandardDeviation<> s9; AverageDeviation<> s10; @@ -72,9 +72,6 @@ Value f5; Formula f6; Formula f7; -MainBin bin1("bin1"); -MainBin bin2("bin2"); - ostream *outputStream = &cout; double @@ -303,8 +300,6 @@ main(int argc, char *argv[]) check(); reset(); - bin1.activate(); - s16[1][0] = 1; s16[0][1] = 3; s16[0][0] = 2; @@ -495,7 +490,6 @@ main(int argc, char *argv[]) s6.sample(8); s6.sample(9); - bin2.activate(); s6.sample(10); s6.sample(10); s6.sample(10); diff --git a/util/stats/db.py b/util/stats/db.py index 9ef51afe0..e1198d438 100644 --- a/util/stats/db.py +++ b/util/stats/db.py @@ -137,10 +137,6 @@ class Database(object): self.allRunIds = {} self.allRunNames = {} - self.allBins = [] - self.allBinIds = {} - self.allBinNames = {} - self.allFormulas = {} self.stattop = {} @@ -149,7 +145,6 @@ class Database(object): self.mode = 'sum'; self.runs = None - self.bins = None self.ticks = None self.method = 'sum' self._method = type(self).sum @@ -220,11 +215,6 @@ class Database(object): self.allRunIds[run.run] = run self.allRunNames[run.name] = run - self.query('select * from bins') - for id,name in self.cursor.fetchall(): - self.allBinIds[int(id)] = name - self.allBinNames[name] = int(id) - self.query('select sd_stat,sd_x,sd_y,sd_name,sd_descr from subdata') for result in self.cursor.fetchall(): subdata = SubData(result) @@ -247,18 +237,6 @@ class Database(object): self.allStatIds[stat.stat] = stat self.allStatNames[stat.name] = stat - # Name: listbins - # Desc: Prints all bins matching regex argument, if no argument - # is given all bins are returned - def listBins(self, regex='.*'): - print '%-50s %-10s' % ('bin name', 'id') - print '-' * 61 - names = self.allBinNames.keys() - names.sort() - for name in names: - id = self.allBinNames[name] - print '%-50s %-10d' % (name, id) - # Name: listruns # Desc: Prints all runs matching a given user, if no argument # is given all runs are returned @@ -362,39 +340,10 @@ class Database(object): ret.append(stat) return ret - def getBin(self, bins): - if type(bins) is not list: - bins = [ bins ] - - ret = [] - for bin in bins: - if type(bin) is int: - ret.append(bin) - elif type(bin) is str: - ret.append(self.allBinNames[bin]) - else: - for name,id in self.allBinNames.items(): - if bin.match(name): - ret.append(id) - - return ret - - def getNotBin(self, bin): - map = {} - for bin in getBin(bin): - map[bin] = 1 - - ret = [] - for bin in self.allBinIds.keys(): - if not map.has_key(bin): - ret.append(bin) - - return ret - ######################################### # get the data # - def inner(self, op, stat, bins, ticks, group=False): + def query(self, op, stat, ticks, group=False): sql = 'select ' sql += 'dt_stat as stat, ' sql += 'dt_run as run, ' @@ -416,10 +365,6 @@ class Database(object): val = ' or '.join([ 'dt_run=%d' % r for r in self.runs ]) sql += ' and (%s)' % val - if bins != None and len(bins): - val = ' or '.join([ 'dt_bin=%d' % b for b in bins ]) - sql += ' and (%s)' % val - if ticks != None and len(ticks): val = ' or '.join([ 'dt_tick=%d' % s for s in ticks ]) sql += ' and (%s)' % val @@ -429,35 +374,21 @@ class Database(object): sql += ',dt_tick' return sql - def outer(self, op_out, op_in, stat, bins, ticks): - sql = self.inner(op_in, stat, bins, ticks, True) - sql = 'select stat,run,x,y,%s(data) from (%s) as tb ' % (op_out, sql) - sql += 'group by stat,run,x,y' - return sql - # Name: sum - # Desc: given a run, a stat and an array of samples and bins, - # sum all the bins and then get the standard deviation of the - # samples for non-binned runs. This will just return the average - # of samples, however a bin array still must be passed - def sum(self, stat, bins, ticks): - return self.inner('sum', stat, bins, ticks) + # Desc: given a run, a stat and an array of samples, total the samples + def sum(self, *args, **kwargs): + return self.query('sum', *args, **kwargs) # Name: avg - # Desc: given a run, a stat and an array of samples and bins, - # sum all the bins and then average the samples for non-binned - # runs this will just return the average of samples, however - # a bin array still must be passed - def avg(self, stat, bins, ticks): - return self.outer('avg', 'sum', stat, bins, ticks) + # Desc: given a run, a stat and an array of samples, average the samples + def avg(self, stat, ticks): + return self.query('avg', *args, **kwargs) # Name: stdev - # Desc: given a run, a stat and an array of samples and bins, - # sum all the bins and then get the standard deviation of the - # samples for non-binned runs. This will just return the average - # of samples, however a bin array still must be passed - def stdev(self, stat, bins, ticks): - return self.outer('stddev', 'sum', stat, bins, ticks) + # Desc: given a run, a stat and an array of samples, get the standard + # deviation + def stdev(self, stat, ticks): + return self.query('stddev', *args, **kwargs) def __setattr__(self, attr, value): super(Database, self).__setattr__(attr, value) @@ -473,12 +404,10 @@ class Database(object): else: raise AttributeError, "can only set get to: sum | avg | stdev" - def data(self, stat, bins=None, ticks=None): - if bins is None: - bins = self.bins + def data(self, stat, ticks=None): if ticks is None: ticks = self.ticks - sql = self._method(self, stat, bins, ticks) + sql = self._method(self, stat, ticks) self.query(sql) runs = {} diff --git a/util/stats/dbinit.py b/util/stats/dbinit.py index 8f7608bba..036941675 100644 --- a/util/stats/dbinit.py +++ b/util/stats/dbinit.py @@ -100,28 +100,6 @@ class MyDB(object): ) TYPE=InnoDB''') # - # We keep the bin names separate so that the data table doesn't get - # huge since bin names are frequently repeated. - # - # COLUMNS: - # 'id' is the unique bin identifer. - # 'name' is the string name for the bin. - # - # INDEXES: - # 'bin' is indexed to get the name of a bin when data is retrieved - # via the data table. - # 'name' is indexed to get the bin id for a named bin when you want - # to search the data table based on a specific bin. - # - self.query(''' - CREATE TABLE bins( - bn_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, - bn_name VARCHAR(255) NOT NULL, - PRIMARY KEY(bn_id), - UNIQUE (bn_name) - ) TYPE=InnoDB''') - - # # The stat table gives us all of the data for a particular stat. # # COLUMNS: @@ -222,14 +200,12 @@ class MyDB(object): # 'run' is the run that the data was generated from. Details up in # the run table # 'tick' is a timestamp generated by the simulator. - # 'bin' is the name of the bin that the data was generated in, if - # any. # 'data' is the actual stat value. # # INDEXES: # 'stat' is indexed so that a user can find all of the data for a # particular stat. It is not unique, because that specific stat - # can be found in many runs, bins, and samples, in addition to + # can be found in many runs and samples, in addition to # having entries for the mulidimensional cases. # 'run' is indexed to allow a user to remove all of the data for a # particular execution run. It can also be used to allow the @@ -242,11 +218,10 @@ class MyDB(object): dt_y SMALLINT NOT NULL, dt_run SMALLINT UNSIGNED NOT NULL, dt_tick BIGINT UNSIGNED NOT NULL, - dt_bin SMALLINT UNSIGNED NOT NULL, dt_data DOUBLE NOT NULL, INDEX (dt_stat), INDEX (dt_run), - UNIQUE (dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin) + UNIQUE (dt_stat,dt_x,dt_y,dt_run,dt_tick) ) TYPE=InnoDB;''') # @@ -398,12 +373,6 @@ class MyDB(object): WHERE dt_stat IS NULL''') self.query(''' - DELETE bins - FROM bins - LEFT JOIN data ON bn_id=dt_bin - WHERE dt_bin IS NULL''') - - self.query(''' DELETE events FROM events LEFT JOIN runs ON ev_run=rn_id diff --git a/util/stats/info.py b/util/stats/info.py index 4954b0519..193159b4c 100644 --- a/util/stats/info.py +++ b/util/stats/info.py @@ -176,7 +176,7 @@ def WrapValue(value): class Statistic(object): def __getattr__(self, attr): if attr in ('data', 'x', 'y'): - result = self.source.data(self, self.bins, self.ticks) + result = self.source.data(self, self.ticks) self.data = result.data self.x = result.x self.y = result.y @@ -185,7 +185,7 @@ class Statistic(object): def __setattr__(self, attr, value): if attr == 'stat': raise AttributeError, '%s is read only' % stat - if attr in ('source', 'bins', 'ticks'): + if attr in ('source', 'ticks'): if getattr(self, attr) != value: if hasattr(self, 'data'): delattr(self, 'data') @@ -761,7 +761,6 @@ def NewStat(source, data): stat = Formula() stat.__dict__['source'] = source - stat.__dict__['bins'] = None stat.__dict__['ticks'] = None stat.__dict__.update(data.__dict__) diff --git a/util/stats/output.py b/util/stats/output.py index abfb8d901..03c100edc 100644 --- a/util/stats/output.py +++ b/util/stats/output.py @@ -29,24 +29,16 @@ from chart import ChartOptions class StatOutput(ChartOptions): - def __init__(self, jobfile, info, stat=None, binstats=None): + def __init__(self, jobfile, info, stat=None): super(StatOutput, self).__init__() self.jobfile = jobfile self.stat = stat - self.binstats = None self.invert = False self.info = info - def printdata(self, name, bin = None, printmode = 'G'): + def display(self, name, printmode = 'G'): import info - if bin: - print '%s %s stats' % (name, bin) - - if self.binstats: - for stat in self.binstats: - stat.bins = bin - if printmode == 'G': valformat = '%g' elif printmode != 'F' and value > 1e6: @@ -70,16 +62,6 @@ class StatOutput(ChartOptions): valstring = ', '.join([ valformat % val for val in value ]) print '%-50s %s' % (job.name + ':', valstring) - def display(self, name, binned = False, printmode = 'G'): - if binned and self.binstats: - self.printdata(name, 'kernel', printmode) - self.printdata(name, 'idle', printmode) - self.printdata(name, 'user', printmode) - self.printdata(name, 'interrupt', printmode) - - print '%s total stats' % name - self.printdata(name, printmode=printmode) - def graph(self, name, graphdir, proxy=None): from os.path import expanduser, isdir, join as joinpath from barchart import BarChart diff --git a/util/stats/stats.py b/util/stats/stats.py index fa0dad513..2aa0d4e0b 100755 --- a/util/stats/stats.py +++ b/util/stats/stats.py @@ -39,7 +39,6 @@ Usage: %s [-E] [-F] [ -G <get> ] [-d <db> ] [-g <graphdir> ] [-h <host>] [-p] commands extra parameters description ----------- ------------------ --------------------------------------- - bins [regex] List bins (only matching regex) formula <formula> Evaluated formula specified formulas [regex] List formulas (only matching regex) runs none List all runs in database @@ -142,16 +141,6 @@ def commands(options, command, args): return - if command == 'bins': - if len(args) == 0: - source.listBins() - elif len(args) == 1: - source.listBins(args[0]) - else: - raise CommandException - - return - if command == 'formulas': if len(args) == 0: source.listFormulas() @@ -281,7 +270,7 @@ def commands(options, command, args): if options.graph: output.graph(stat.name, options.graphdir) else: - output.display(stat.name, options.binned, options.printmode) + output.display(stat.name, options.printmode) return @@ -301,22 +290,10 @@ def commands(options, command, args): if options.graph: output.graph(command, options.graphdir, proxy) else: - output.display(command, options.binned, options.printmode) - - if command == 'usertime': - import copy - user = copy.copy(system.run0.numCycles) - user.bins = 'user' - - output.stat = user / system.run0.numCycles - output.ylabel = 'User Fraction' - - display() - return + output.display(command, options.printmode) if command == 'ticks': output.stat = system.run0.numCycles - output.binstats = [ system.run0.numCycles ] display() return @@ -403,7 +380,6 @@ def commands(options, command, args): if command == 'mpkb': output.stat = misses / (bytes / 1024) - output.binstats = [ misses ] output.ylabel = 'Misses / KB' display() return @@ -411,7 +387,6 @@ def commands(options, command, args): if command == 'ipkb': interrupts = system.run0.kern.faults[4] output.stat = interrupts / kbytes - output.binstats = [ interrupts ] output.ylabel = 'Interrupts / KB' display() return @@ -448,7 +423,6 @@ if __name__ == '__main__': options.runs = None options.system = 'client' options.method = None - options.binned = False options.graph = False options.ticks = False options.printmode = 'G' @@ -456,10 +430,8 @@ if __name__ == '__main__': options.jobfile = None options.all = False - opts, args = getopts(sys.argv[1:], '-BEFJad:g:h:j:m:pr:s:u:T:') + opts, args = getopts(sys.argv[1:], '-EFJad:g:h:j:m:pr:s:u:T:') for o,a in opts: - if o == '-B': - options.binned = True if o == '-E': options.printmode = 'E' if o == '-F': |