From 4162cc0c57de22566efa6e2dab224909279f2a47 Mon Sep 17 00:00:00 2001 From: Jonathan Herman Date: Wed, 10 Apr 2013 14:35:37 -0400 Subject: run_exps will run any command whose last argument is the duration. --- README.md | 2 +- common.py | 47 +++++++++++++++++++----------------- config/config.py | 20 ++++++++-------- run/proc_entry.py | 5 ++-- run_exps.py | 71 +++++++++++++++++++++++-------------------------------- 5 files changed, 69 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 0798b61..2fa4d2c 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ Schedule files have one of the following two formats: ..., ('path/to/proc','proc_value') ], - 'spin':[ + 'task':[ ('real_time_task', 'task_arguments'), ... ('real_time_task', 'task_arguments') diff --git a/common.py b/common.py index 66df7bb..4920ec8 100644 --- a/common.py +++ b/common.py @@ -7,29 +7,34 @@ import sys from collections import defaultdict from textwrap import dedent -def get_executable(prog, hint='unknown', optional=False): - '''Search for @prog in system PATH. Print @hint if no binary is found.''' +def get_executable(prog, cwd="."): + '''Search for @prog in system PATH and @cwd.''' - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath, fname = os.path.split(prog) - if fpath: - if is_exe(prog): - return prog + cwd_path = "%s/%s" % (cwd, prog) + if is_executable(cwd_path): + return cwd_path else: for path in os.environ["PATH"].split(os.pathsep): exe_file = os.path.join(path, prog) - if is_exe(exe_file): + if is_executable(exe_file): return exe_file - if not optional: - sys.stderr.write("Cannot find executable '%s' in PATH. This is a part " - "of '%s' which should be added to PATH to run.\n" % - (prog, hint)) - sys.exit(1) - else: - return None + full_cwd = os.path.abspath(cwd) + raise IOError("Cannot find executable '%s'! (cwd='%s')" % (prog, full_cwd)) + +def get_executable_hint(prog, hint, optional=False): + '''Search for @prog in system PATH. Print @hint if no binary is found. + Die if not @optional.''' + try: + prog = get_executable(prog) + except IOError: + if not optional: + sys.stderr.write(("Cannot find executable '%s' in PATH. This is " +\ + "a part of '%s' which should be added to PATH.\n")\ + % (prog, hint)) + sys.exit(1) + + return prog def get_config_option(option): '''Search for @option in installed kernel config (if present). @@ -174,14 +179,12 @@ def ft_freq(): return freq -def uname_matches(reg): - data = subprocess.check_output(["uname", "-r"]) - return bool( re.match(reg, data) ) +def kernel(): + return subprocess.check_output(["uname", "-r"]) def is_executable(fname): '''Return whether the file passed in is executable''' - mode = os.stat(fname)[stat.ST_MODE] - return mode & stat.S_IXUSR and mode & stat.S_IRUSR + return os.path.isfile(fname) and os.access(fname, os.X_OK) def is_device(dev): if not os.path.exists(dev): diff --git a/config/config.py b/config/config.py index 3486a40..cbac6b2 100644 --- a/config/config.py +++ b/config/config.py @@ -1,18 +1,18 @@ from __future__ import print_function import itertools -from common import get_executable,ft_freq +from common import get_executable_hint,ft_freq '''Paths to binaries.''' -BINS = {'rtspin' : get_executable('rtspin', 'liblitmus'), - 'release' : get_executable('release_ts', 'liblitmus'), - 'ftcat' : get_executable('ftcat', 'feather-trace-tools'), - 'ftsplit' : get_executable('ft2csv', 'feather-trace-tools'), - 'ftsort' : get_executable('ftsort', 'feather-trace-tools'), - 'st_trace' : get_executable('st_trace', 'feather-trace-tools'), +BINS = {'rtspin' : get_executable_hint('rtspin', 'liblitmus'), + 'release' : get_executable_hint('release_ts', 'liblitmus'), + 'ftcat' : get_executable_hint('ftcat', 'feather-trace-tools'), + 'ftsplit' : get_executable_hint('ft2csv', 'feather-trace-tools'), + 'ftsort' : get_executable_hint('ftsort', 'feather-trace-tools'), + 'st_trace' : get_executable_hint('st_trace', 'feather-trace-tools'), # Option, as not everyone uses kernelshark yet - 'trace-cmd' : get_executable('trace-cmd', 'rt-kernelshark', True), + 'trace-cmd' : get_executable_hint('trace-cmd', 'rt-kernelshark', True), # Optional, as sched_trace is not a publically supported repository - 'st_show' : get_executable('st_show', 'sched_trace', True)} + 'st_show' : get_executable_hint('st_show', 'sched_trace', True)} '''Names of output files.''' FILES = {'ft_data' : 'ft.bin', @@ -38,7 +38,7 @@ PARAMS = {'sched' : 'scheduler', # Scheduler used by run_exps DEFAULTS = {'params_file' : 'params.py', 'sched_file' : 'sched.py', 'duration' : 10, - 'spin' : 'rtspin', + 'prog' : 'rtspin', 'cycles' : ft_freq() or 2000} '''Default sched_trace events (this is all of them).''' diff --git a/run/proc_entry.py b/run/proc_entry.py index 4ac2c51..56f7c24 100644 --- a/run/proc_entry.py +++ b/run/proc_entry.py @@ -5,9 +5,10 @@ class ProcEntry(object): self.proc = proc self.data = data - def write_proc(self): if not os.path.exists(self.proc): - raise Exception("Invalid proc entry %s" % self.proc) + raise ValueError("Invalid proc entry %s" % self.proc) + + def write_proc(self): try: with open(self.proc, 'w') as entry: entry.write(self.data) diff --git a/run_exps.py b/run_exps.py index 6043931..77c9631 100755 --- a/run_exps.py +++ b/run_exps.py @@ -79,13 +79,13 @@ def convert_data(data): r"(?P
/proc/[\w\-]+?/)?" r"(?P[\w\-\/]+)" r"\s*{\s*(?P.*?)\s*?}$)|" - r"(?P^" - r"(?:(?P[^\d\-\s]\w*?) )?\s*" + r"(?P^" + r"(?:(?P[^\d\-\s][\w\.]*?) )?\s*" r"(?P[\w\-_\d\. \=]+)\s*$)", re.S|re.I|re.M) procs = [] - spins = [] + tasks = [] for match in regex.finditer(data): if match.group("PROC"): @@ -94,16 +94,16 @@ def convert_data(data): proc = (loc, match.group("CONTENT")) procs.append(proc) else: - prog = match.group("TYPE") or "rtspin" + prog = match.group("PROG") or conf.DEFAULTS['prog'] spin = (prog, match.group("ARGS")) - spins.append(spin) + tasks.append(spin) - return {'proc' : procs, 'spin' : spins} + return {'proc' : procs, 'task' : tasks} def fix_paths(schedule, exp_dir, sched_file): '''Replace relative paths of command line arguments with absolute ones.''' - for (idx, (spin, args)) in enumerate(schedule['spin']): + for (idx, (task, args)) in enumerate(schedule['task']): for arg in re.split(" +", args): abspath = "%s/%s" % (exp_dir, arg) if os.path.exists(abspath): @@ -113,7 +113,7 @@ def fix_paths(schedule, exp_dir, sched_file): print("WARNING: non-existent file '%s' may be referenced:\n\t%s" % (arg, sched_file)) - schedule['spin'][idx] = (spin, args) + schedule['task'][idx] = (task, args) def load_schedule(name, fname, duration): @@ -126,48 +126,43 @@ def load_schedule(name, fname, duration): except: schedule = convert_data(data) + sched_dir = os.path.split(fname)[0] + # Make paths relative to the file's directory - fix_paths(schedule, os.path.split(fname)[0], fname) + fix_paths(schedule, sched_dir, fname) proc_entries = [] executables = [] # Create proc entries for entry_conf in schedule['proc']: - path = entry_conf[0] - data = entry_conf[1] + proc_entries += [ProcEntry(*entry_conf)] - if not os.path.exists(path): - raise IOError("Invalid proc path %s: %s" % (path, name)) + # Create executables + for task_conf in schedule['task']: + if len(task_conf) != 2: + raise Exception("Invalid task conf %s: %s" % (task_conf, name)) - proc_entries += [ProcEntry(path, data)] + (task, args) = (task_conf[0], task_conf[1]) - # Create executables - for spin_conf in schedule['spin']: - if isinstance(spin_conf, str): - # Just a string defaults to default spin - (spin, args) = (conf.DEFAULTS['spin'], spin_conf) - else: - # Otherwise its a pair, the type and the args - if len(spin_conf) != 2: - raise IOError("Invalid spin conf %s: %s" % (spin_conf, name)) - (spin, args) = (spin_conf[0], spin_conf[1]) + real_task = com.get_executable(task, sched_dir) - real_spin = com.get_executable(spin, "") - real_args = args.split() - if re.match(".*spin", real_spin): - real_args = ['-w'] + real_args + [duration] + # Last argument must always be duration + real_args = args.split() + [duration] - if not com.is_executable(real_spin): - raise OSError("Cannot run spin %s: %s" % (real_spin, name)) + # All spins take a -w flag + if re.match(".*spin$", real_task) and '-w' not in real_args: + real_args = ['-w'] + real_args - executables += [Executable(real_spin, real_args)] + executables += [Executable(real_task, real_args)] return proc_entries, executables def verify_environment(exp_params): - if exp_params.kernel and not com.uname_matches(exp_params.kernel): + '''Raise an exception if the current system doesn't match that required + by @exp_params.''' + if exp_params.kernel and not re.match(exp_params.kernel, com.kernel()): raise InvalidKernel(exp_params.kernel) if exp_params.config_options: @@ -197,15 +192,7 @@ def run_parameter(exp_dir, out_dir, params, param_name): script_params = [script_params] script_name = script_params.pop(0) - cwd_name = "%s/%s" % (exp_dir, script_name) - if os.path.isfile(cwd_name): - script = cwd_name - else: - script = com.get_executable(script_name, optional=True) - - if not script: - raise Exception("Cannot find executable %s-script: %s" % - (param_name, script_name)) + script = com.get_executable(script_name, cwd=exp_dir) out = open('%s/%s-out.txt' % (out_dir, param_name), 'w') prog = Executable(script, script_params, @@ -219,6 +206,7 @@ def run_parameter(exp_dir, out_dir, params, param_name): def get_exp_params(cmd_scheduler, cmd_duration, file_params): + '''Return ExpParam with configured values of all hardcoded params.''' kernel = copts = "" scheduler = cmd_scheduler or file_params[conf.PARAMS['sched']] @@ -267,6 +255,7 @@ def load_experiment(sched_file, cmd_scheduler, cmd_duration, else: file_params = {} + # Create input needed by Experiment exp_params = get_exp_params(cmd_scheduler, cmd_duration, file_params) procs, execs = load_schedule(exp_name, sched_file, exp_params.duration) -- cgit v1.2.2