diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-11-26 16:02:48 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-11-26 16:02:48 -0500 |
| commit | cb8db5d30ee769304c2c2b00f2a7d9bcb3c4098f (patch) | |
| tree | c5352d84285af565d5246c3eb861ffba709761f1 | |
| parent | 41c867480f1e20bd3b168258ed71450499ea6ccf (diff) | |
Removed 2-step parse for scheduling statistics.
| -rw-r--r-- | common.py | 74 | ||||
| -rw-r--r-- | config/config.example.py | 39 | ||||
| -rw-r--r-- | experiment/executable/executable.py | 10 | ||||
| -rw-r--r-- | experiment/executable/ftcat.py | 4 | ||||
| -rw-r--r-- | experiment/experiment.py | 10 | ||||
| -rw-r--r-- | experiment/litmus_util.py | 12 | ||||
| -rw-r--r-- | parse/ft.py | 47 | ||||
| -rw-r--r-- | parse/point.py | 4 | ||||
| -rw-r--r-- | parse/sched.py | 445 | ||||
| -rwxr-xr-x | parse_exps.py | 122 | ||||
| -rwxr-xr-x | run_exps.py | 4 |
11 files changed, 327 insertions, 444 deletions
| @@ -1,4 +1,78 @@ | |||
| 1 | import sys | ||
| 1 | from collections import defaultdict | 2 | from collections import defaultdict |
| 3 | from textwrap import dedent | ||
| 4 | |||
| 5 | def recordtype(typename, field_names, default=0): | ||
| 6 | ''' Mutable namedtuple. Recipe from George Sakkis of MIT.''' | ||
| 7 | field_names = tuple(map(str, field_names)) | ||
| 8 | # Create and fill-in the class template | ||
| 9 | numfields = len(field_names) | ||
| 10 | argtxt = ', '.join(field_names) | ||
| 11 | reprtxt = ', '.join('%s=%%r' % f for f in field_names) | ||
| 12 | dicttxt = ', '.join('%r: self.%s' % (f,f) for f in field_names) | ||
| 13 | tupletxt = repr(tuple('self.%s' % f for f in field_names)).replace("'",'') | ||
| 14 | inittxt = '; '.join('self.%s=%s' % (f,f) for f in field_names) | ||
| 15 | itertxt = '; '.join('yield self.%s' % f for f in field_names) | ||
| 16 | eqtxt = ' and '.join('self.%s==other.%s' % (f,f) for f in field_names) | ||
| 17 | template = dedent(''' | ||
| 18 | class %(typename)s(object): | ||
| 19 | '%(typename)s(%(argtxt)s)' | ||
| 20 | |||
| 21 | __slots__ = %(field_names)r | ||
| 22 | |||
| 23 | def __init__(self, %(argtxt)s): | ||
| 24 | %(inittxt)s | ||
| 25 | |||
| 26 | def __len__(self): | ||
| 27 | return %(numfields)d | ||
| 28 | |||
| 29 | def __iter__(self): | ||
| 30 | %(itertxt)s | ||
| 31 | |||
| 32 | def __getitem__(self, index): | ||
| 33 | return getattr(self, self.__slots__[index]) | ||
| 34 | |||
| 35 | def __setitem__(self, index, value): | ||
| 36 | return setattr(self, self.__slots__[index], value) | ||
| 37 | |||
| 38 | def todict(self): | ||
| 39 | 'Return a new dict which maps field names to their values' | ||
| 40 | return {%(dicttxt)s} | ||
| 41 | |||
| 42 | def __repr__(self): | ||
| 43 | return '%(typename)s(%(reprtxt)s)' %% %(tupletxt)s | ||
| 44 | |||
| 45 | def __eq__(self, other): | ||
| 46 | return isinstance(other, self.__class__) and %(eqtxt)s | ||
| 47 | |||
| 48 | def __ne__(self, other): | ||
| 49 | return not self==other | ||
| 50 | |||
| 51 | def __getstate__(self): | ||
| 52 | return %(tupletxt)s | ||
| 53 | |||
| 54 | def __setstate__(self, state): | ||
| 55 | %(tupletxt)s = state | ||
| 56 | ''') % locals() | ||
| 57 | # Execute the template string in a temporary namespace | ||
| 58 | namespace = {} | ||
| 59 | try: | ||
| 60 | exec template in namespace | ||
| 61 | except SyntaxError, e: | ||
| 62 | raise SyntaxError(e.message + ':\n' + template) | ||
| 63 | cls = namespace[typename] | ||
| 64 | |||
| 65 | # Setup defaults | ||
| 66 | init_defaults = tuple(default for f in field_names) | ||
| 67 | cls.__init__.im_func.func_defaults = init_defaults | ||
| 68 | |||
| 69 | # For pickling to work, the __module__ variable needs to be set to the frame | ||
| 70 | # where the named tuple is created. Bypass this step in environments where | ||
| 71 | # sys._getframe is not defined (Jython for example). | ||
| 72 | if hasattr(sys, '_getframe') and sys.platform != 'cli': | ||
| 73 | cls.__module__ = sys._getframe(1).f_globals['__name__'] | ||
| 74 | |||
| 75 | return cls | ||
| 2 | 76 | ||
| 3 | def load_params(fname): | 77 | def load_params(fname): |
| 4 | params = defaultdict(int) | 78 | params = defaultdict(int) |
diff --git a/config/config.example.py b/config/config.example.py index 50d30ba..9f24097 100644 --- a/config/config.example.py +++ b/config/config.example.py | |||
| @@ -3,56 +3,43 @@ import os | |||
| 3 | import sys | 3 | import sys |
| 4 | import itertools | 4 | import itertools |
| 5 | 5 | ||
| 6 | """ | 6 | ''' |
| 7 | These are paths to repository directories. | 7 | These are paths to repository directories. |
| 8 | 8 | ||
| 9 | """ | 9 | ''' |
| 10 | REPOS = {'liblitmus' : '/home/hermanjl/git/liblitmus', | 10 | REPOS = {'liblitmus' : '/home/hermanjl/git/liblitmus', |
| 11 | 'sched_trace' : '/home/hermanjl/git/sched_trace', | 11 | 'sched_trace' : '/home/hermanjl/git/sched_trace', |
| 12 | 'analysis' : '/home/hermanjl/git/overhead-analysis-cjk', | ||
| 13 | 'ft_tools' : '/home/hermanjl/git/feather-trace-tools', | 12 | 'ft_tools' : '/home/hermanjl/git/feather-trace-tools', |
| 14 | 'trace-cmd' : '/home/hermanjl/git/trace-cmd'} | 13 | 'trace-cmd' : '/home/hermanjl/git/trace-cmd'} |
| 15 | 14 | ||
| 16 | BINS = {'bespin' : '{}/bespin'.format(REPOS['liblitmus']), | 15 | BINS = {'rtspin' : '{}/rtspin'.format(REPOS['liblitmus']), |
| 17 | 'colorspin' : '{}/colorspin'.format(REPOS['liblitmus']), | ||
| 18 | 'rtspin' : '{}/rtspin'.format(REPOS['liblitmus']), | ||
| 19 | 'release' : '{}/release_ts'.format(REPOS['liblitmus']), | 16 | 'release' : '{}/release_ts'.format(REPOS['liblitmus']), |
| 20 | 'ftcat' : '{}/ftcat'.format(REPOS['ft_tools']), | 17 | 'ftcat' : '{}/ftcat'.format(REPOS['ft_tools']), |
| 18 | 'ftsplit' : '{}/ft2csv'.format(REPOS['ft_tools']), | ||
| 19 | 'ftsort' : '{}/ftsort'.format(REPOS['ft_tools']), | ||
| 21 | 'st_trace' : '{}/st_trace'.format(REPOS['ft_tools']), | 20 | 'st_trace' : '{}/st_trace'.format(REPOS['ft_tools']), |
| 22 | 'split' : '{}/split'.format(REPOS['analysis']), | ||
| 23 | 'sort' : '{}/sort-all'.format(REPOS['analysis']), | ||
| 24 | 'analyze' : '{}/analyze'.format(REPOS['analysis']), | ||
| 25 | 'trace-cmd' : '{}/trace-cmd'.format(REPOS['trace-cmd']), | 21 | 'trace-cmd' : '{}/trace-cmd'.format(REPOS['trace-cmd']), |
| 26 | 'st_show' : '{}/st_show'.format(REPOS['sched_trace'])} | 22 | 'st_show' : '{}/st_show'.format(REPOS['sched_trace'])} |
| 27 | 23 | ||
| 28 | DEFAULTS = {'params_file' : 'params.py', | 24 | DEFAULTS = {'params_file' : 'params.py', |
| 29 | 'sched_file' : 'sched.py', | 25 | 'sched_file' : 'sched.py', |
| 30 | 'exps_file' : 'exps.py', | 26 | 'exps_file' : 'exps.py', |
| 31 | 'duration' : '10', | 27 | 'duration' : 10, |
| 32 | 'spin' : 'rtspin'} | 28 | 'spin' : 'rtspin', |
| 29 | 'cycles' : 2000} | ||
| 33 | 30 | ||
| 34 | FILES = {'ft_data' : 'ft.bin', | 31 | FILES = {'ft_data' : 'ft.bin', |
| 35 | 'linux_data' : 'trace.dat', | 32 | 'linux_data' : 'trace.dat', |
| 36 | 'sched_data' : 'st-{}.bin', | 33 | 'sched_data' : 'st-{}.bin', |
| 37 | 'log_data' : 'trace.slog',} | 34 | 'log_data' : 'trace.slog',} |
| 38 | 35 | ||
| 39 | PARAMS = {'sched' : 'scheduler', | 36 | PARAMS = {'sched' : 'scheduler', |
| 40 | 'dur' : 'duration', | 37 | 'dur' : 'duration', |
| 41 | 'kernel' : 'uname'} | 38 | 'kernel': 'uname', |
| 39 | 'cycles' : 'cpu-frequency'} | ||
| 42 | 40 | ||
| 43 | SCHED_EVENTS = range(501, 513) | 41 | SCHED_EVENTS = range(501, 513) |
| 44 | BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS', 'SEND_RESCHED'] | 42 | BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS'] |
| 45 | BASE_EVENTS += ['CQ_ENQUEUE_READ', 'CQ_ENQUEUE_FLUSH', 'CQ_SUBMIT_WORK', | ||
| 46 | 'CQ_LOOP_WORK_CHECK', 'CQ_LOOP_PEACE_OUT', 'CQ_LOOP_BRANCH', | ||
| 47 | 'CQ_WORK_DO_WORK', 'CQ_WORK_NOTIFY', 'CQ_PHASE_WAIT'] | ||
| 48 | |||
| 49 | # Expand for mixed-crit | ||
| 50 | # TODO don't use split | ||
| 51 | CRIT_EVENTS = ['LVL{}_SCHED', 'LVL{}_RELEASE'] | ||
| 52 | CRIT_LEVELS = ['A', 'B', 'C'] | ||
| 53 | BASE_EVENTS += [s.format(l) for (l,s) in | ||
| 54 | itertools.product(CRIT_LEVELS, CRIT_EVENTS)] | ||
| 55 | |||
| 56 | ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in | 43 | ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in |
| 57 | itertools.product(BASE_EVENTS, ["START","END"])] | 44 | itertools.product(BASE_EVENTS, ["START","END"])] |
| 58 | ALL_EVENTS += ['RELEASE_LATENCY'] | 45 | ALL_EVENTS += ['RELEASE_LATENCY'] |
diff --git a/experiment/executable/executable.py b/experiment/executable/executable.py index b964699..628f711 100644 --- a/experiment/executable/executable.py +++ b/experiment/executable/executable.py | |||
| @@ -4,7 +4,7 @@ import signal | |||
| 4 | from ..litmus_util import is_executable | 4 | from ..litmus_util import is_executable |
| 5 | 5 | ||
| 6 | class Executable(object): | 6 | class Executable(object): |
| 7 | """Parent object that represents an executable for use in task-sets.""" | 7 | '''Parent object that represents an executable for use in task-sets.''' |
| 8 | 8 | ||
| 9 | def __init__(self, exec_file, extra_args=None, stdout_file = None, stderr_file = None): | 9 | def __init__(self, exec_file, extra_args=None, stdout_file = None, stderr_file = None): |
| 10 | self.exec_file = exec_file | 10 | self.exec_file = exec_file |
| @@ -47,7 +47,7 @@ class Executable(object): | |||
| 47 | return " ".join(self.__get_full_command()) | 47 | return " ".join(self.__get_full_command()) |
| 48 | 48 | ||
| 49 | def execute(self): | 49 | def execute(self): |
| 50 | """Execute the binary.""" | 50 | '''Execute the binary.''' |
| 51 | full_command = self.__get_full_command() | 51 | full_command = self.__get_full_command() |
| 52 | self.sp = subprocess.Popen(full_command, stdout=self.stdout_file, | 52 | self.sp = subprocess.Popen(full_command, stdout=self.stdout_file, |
| 53 | stderr=self.stderr_file, cwd=self.cwd) | 53 | stderr=self.stderr_file, cwd=self.cwd) |
| @@ -59,15 +59,15 @@ class Executable(object): | |||
| 59 | self.sp.send_signal(signal.SIGINT) | 59 | self.sp.send_signal(signal.SIGINT) |
| 60 | 60 | ||
| 61 | def terminate(self): | 61 | def terminate(self): |
