diff options
| -rw-r--r-- | common.py | 3 | ||||
| -rw-r--r-- | config/config.py | 21 | ||||
| -rw-r--r-- | gen/__init__.py | 7 | ||||
| -rw-r--r-- | gen/edf_generators.py | 33 | ||||
| -rw-r--r-- | gen/generator.py | 9 | ||||
| -rw-r--r-- | parse/ft.py | 29 | ||||
| -rwxr-xr-x | parse_exps.py | 1 | ||||
| -rw-r--r-- | run/tracer.py | 9 | ||||
| -rwxr-xr-x | run_exps.py | 7 |
9 files changed, 88 insertions, 31 deletions
| @@ -161,10 +161,9 @@ def num_cpus(): | |||
| 161 | 161 | ||
| 162 | def ft_freq(): | 162 | def ft_freq(): |
| 163 | umachine = subprocess.check_output(["uname", "-m"]) | 163 | umachine = subprocess.check_output(["uname", "-m"]) |
| 164 | |||
| 165 | if re.match("armv7", umachine): | 164 | if re.match("armv7", umachine): |
| 166 | # Arm V7s use a millisecond timer | 165 | # Arm V7s use a millisecond timer |
| 167 | freq = 1000.0 | 166 | freq = 800.0 |
| 168 | elif re.match("x86", umachine): | 167 | elif re.match("x86", umachine): |
| 169 | # X86 timer is equal to processor clock | 168 | # X86 timer is equal to processor clock |
| 170 | reg = re.compile(r'^cpu MHz\s*:\s*(?P<FREQ>\d+)', re.M) | 169 | reg = re.compile(r'^cpu MHz\s*:\s*(?P<FREQ>\d+)', re.M) |
diff --git a/config/config.py b/config/config.py index cfdfb05..599371c 100644 --- a/config/config.py +++ b/config/config.py | |||
| @@ -4,6 +4,7 @@ from common import get_executable_hint,ft_freq | |||
| 4 | 4 | ||
| 5 | '''Paths to binaries.''' | 5 | '''Paths to binaries.''' |
| 6 | BINS = {'rtspin' : get_executable_hint('rtspin', 'liblitmus'), | 6 | BINS = {'rtspin' : get_executable_hint('rtspin', 'liblitmus'), |
| 7 | 'mc2spin' : get_executable_hint('mc2spin', 'liblitmus'), | ||
| 7 | 'release' : get_executable_hint('release_ts', 'liblitmus'), | 8 | 'release' : get_executable_hint('release_ts', 'liblitmus'), |
| 8 | 'ftcat' : get_executable_hint('ftcat', 'feather-trace-tools'), | 9 | 'ftcat' : get_executable_hint('ftcat', 'feather-trace-tools'), |
| 9 | 'ftsplit' : get_executable_hint('ft2csv', 'feather-trace-tools'), | 10 | 'ftsplit' : get_executable_hint('ft2csv', 'feather-trace-tools'), |
| @@ -18,7 +19,8 @@ BINS = {'rtspin' : get_executable_hint('rtspin', 'liblitmus'), | |||
| 18 | FILES = {'params_file' : 'params.py', | 19 | FILES = {'params_file' : 'params.py', |
| 19 | 'sched_file' : 'sched.py', | 20 | 'sched_file' : 'sched.py', |
| 20 | 'ft_data' : 'ft.bin', | 21 | 'ft_data' : 'ft.bin', |
| 21 | 'ft_matches' : r'(ft.*\.bin$)|(.*\.ft)', | 22 | 'ft_msg_data' : 'ftmsg.bin', |
| 23 | 'ft_matches' : r'(ft.*\.bin$)|(ftmsg.*\.bin$)|(.*\.ft)', | ||
| 22 | 'linux_data' : 'trace.dat', | 24 | 'linux_data' : 'trace.dat', |
| 23 | 'sched_data' : 'st-{}.bin', | 25 | 'sched_data' : 'st-{}.bin', |
| 24 | 'log_data' : 'trace.slog'} | 26 | 'log_data' : 'trace.slog'} |
| @@ -38,24 +40,35 @@ PARAMS = {'sched' : 'scheduler', # Scheduler used by run_exps | |||
| 38 | 40 | ||
| 39 | '''Default values for program options.''' | 41 | '''Default values for program options.''' |
| 40 | DEFAULTS = {'duration' : 10, | 42 | DEFAULTS = {'duration' : 10, |
| 41 | 'prog' : 'rtspin', | 43 | #'prog' : 'rtspin', |
| 44 | 'prog' : 'mc2spin', | ||
| 42 | 'out-gen' : 'exps', | 45 | 'out-gen' : 'exps', |
| 43 | 'out-run' : 'run-data', | 46 | 'out-run' : 'run-data', |
| 44 | 'out-parse' : 'parse-data', | 47 | 'out-parse' : 'parse-data', |
| 45 | 'out-plot' : 'plot-data', | 48 | 'out-plot' : 'plot-data', |
| 46 | 'cycles' : ft_freq() or 2000} | 49 | 'cycles' : ft_freq()} #ft_freq()} # or 2000} |
| 47 | 50 | ||
| 48 | 51 | ||
| 49 | '''Default sched_trace events (this is all of them).''' | 52 | '''Default sched_trace events (this is all of them).''' |
| 50 | SCHED_EVENTS = range(501, 513) | 53 | SCHED_EVENTS = range(501, 513) |
| 51 | 54 | ||
| 52 | '''Overhead events.''' | 55 | '''Overhead events.''' |
| 53 | OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS', 'LOCK', 'UNLOCK'] | 56 | #OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'RELEASE_C', 'SCHED2', 'TICK', 'CXS', 'LOCK', 'UNLOCK', 'ISR', 'SCHED_A', 'SCHED_C'] |
| 57 | OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'RELEASE_C', 'SCHED2', 'TICK', 'CXS', 'ISR', 'SCHED_A', 'SCHED_C'] | ||
| 54 | OVH_ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in | 58 | OVH_ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in |
| 55 | itertools.product(OVH_BASE_EVENTS, ["START","END"])] | 59 | itertools.product(OVH_BASE_EVENTS, ["START","END"])] |
| 56 | OVH_ALL_EVENTS += ['RELEASE_LATENCY'] | 60 | OVH_ALL_EVENTS += ['RELEASE_LATENCY'] |
| 61 | OVH_ALL_EVENTS += ['RELEASE_LATENCY_A'] | ||
| 62 | OVH_ALL_EVENTS += ['RELEASE_LATENCY_B'] | ||
| 63 | OVH_ALL_EVENTS += ['RELEASE_LATENCY_C'] | ||
| 57 | # This event doesn't have a START and END | 64 | # This event doesn't have a START and END |
| 58 | OVH_BASE_EVENTS += ['RELEASE_LATENCY'] | 65 | OVH_BASE_EVENTS += ['RELEASE_LATENCY'] |
| 66 | OVH_BASE_EVENTS += ['RELEASE_LATENCY_A'] | ||
| 67 | OVH_BASE_EVENTS += ['RELEASE_LATENCY_B'] | ||
| 68 | OVH_BASE_EVENTS += ['RELEASE_LATENCY_C'] | ||
| 69 | |||
| 70 | OVH_MSG_EVENTS = ['SEND_RESCHED_START' , 'SEND_RESCHED_END'] | ||
| 71 | OVH_BASE_EVENTS += ['SEND_RESCHED'] | ||
| 59 | 72 | ||
| 60 | # If a task is missing more than this many records, its measurements | 73 | # If a task is missing more than this many records, its measurements |
| 61 | # are not included in sched_trace summaries | 74 | # are not included in sched_trace summaries |
diff --git a/gen/__init__.py b/gen/__init__.py index 8c60b46..07bbc91 100644 --- a/gen/__init__.py +++ b/gen/__init__.py | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | import generator as gen | 1 | import generator as gen |
| 2 | import edf_generators as edf | 2 | import edf_generators as edf |
| 3 | 3 | ||
| 4 | gen.register_generator("G-EDF", edf.GedfGenerator) | 4 | #gen.register_generator("G-EDF", edf.GedfGenerator) |
| 5 | gen.register_generator("P-EDF", edf.PedfGenerator) | 5 | #gen.register_generator("P-EDF", edf.PedfGenerator) |
| 6 | gen.register_generator("C-EDF", edf.CedfGenerator) | 6 | gen.register_generator("MC2", edf.Mc2Generator) |
| 7 | #gen.register_generator("C-EDF", edf.CedfGenerator) | ||
diff --git a/gen/edf_generators.py b/gen/edf_generators.py index 8e4b8df..c769e46 100644 --- a/gen/edf_generators.py +++ b/gen/edf_generators.py | |||
| @@ -6,6 +6,7 @@ TP_TBASE = """#for $t in $task_set | |||
| 6 | #end for""" | 6 | #end for""" |
| 7 | TP_GLOB_TASK = TP_TBASE.format("") | 7 | TP_GLOB_TASK = TP_TBASE.format("") |
| 8 | TP_PART_TASK = TP_TBASE.format("-p $t.cpu") | 8 | TP_PART_TASK = TP_TBASE.format("-p $t.cpu") |
| 9 | TP_MC_TASK = TP_TBASE.format("-p $t.cpu -m $t.crit -i $t.id") | ||
| 9 | 10 | ||
| 10 | class EdfGenerator(gen.Generator): | 11 | class EdfGenerator(gen.Generator): |
| 11 | '''Creates sporadic task sets with the most common Litmus options.''' | 12 | '''Creates sporadic task sets with the most common Litmus options.''' |
| @@ -16,7 +17,7 @@ class EdfGenerator(gen.Generator): | |||
| 16 | 17 | ||
| 17 | def __make_options(self): | 18 | def __make_options(self): |
| 18 | '''Return generic EDF options.''' | 19 | '''Return generic EDF options.''' |
| 19 | return [gen.Generator._dist_option('utils', 'uni-medium', | 20 | return [gen.Generator._dist_option('utils', 'uni-very-light', |
| 20 | gen.NAMED_UTILIZATIONS, | 21 | gen.NAMED_UTILIZATIONS, |
| 21 | 'Task utilization distributions.'), | 22 | 'Task utilization distributions.'), |
| 22 | gen.Generator._dist_option('periods', 'harmonic', | 23 | gen.Generator._dist_option('periods', 'harmonic', |
| @@ -87,3 +88,33 @@ class GedfGenerator(EdfGenerator): | |||
| 87 | def __init__(self, params={}): | 88 | def __init__(self, params={}): |
| 88 | super(GedfGenerator, self).__init__("GSN-EDF", [TP_GLOB_TASK], | 89 | super(GedfGenerator, self).__init__("GSN-EDF", [TP_GLOB_TASK], |
| 89 | [], params) | 90 | [], params) |
| 91 | |||
| 92 | class Mc2Generator(EdfGenerator): | ||
| 93 | def __init__(self, params={}): | ||
| 94 | super(Mc2Generator, self).__init__("MC2", [TP_MC_TASK], | ||
| 95 | [], params) | ||
| 96 | |||
| 97 | def _customize(self, taskset, exp_params): | ||
| 98 | cpus = exp_params['cpus'] | ||
| 99 | start = 0 | ||
| 100 | |||
| 101 | # Partition using worst-fit for most even distribution | ||
| 102 | utils = [0]*cpus | ||
| 103 | tasks = [0]*cpus | ||
| 104 | index = [1]*cpus | ||
| 105 | taskset = sorted(taskset, key=lambda task: task.period) | ||
| 106 | for t in taskset: | ||
| 107 | t.cpu = utils.index(min(utils)) | ||
| 108 | t.id = index[t.cpu] | ||
| 109 | if utils[t.cpu] < 0.05: | ||
| 110 | t.crit = 0 | ||
| 111 | elif utils[t.cpu] < 0.10: | ||
| 112 | t.crit = 1 | ||
| 113 | else: | ||
| 114 | t.crit = 2 | ||
| 115 | utils[t.cpu] += t.utilization() | ||
| 116 | tasks[t.cpu] += 1 | ||
| 117 | index[t.cpu] += 1 | ||
| 118 | |||
| 119 | # Increment by one so release master has no tasks | ||
| 120 | t.cpu += start | ||
diff --git a/gen/generator.py b/gen/generator.py index 0999e84..909c730 100644 --- a/gen/generator.py +++ b/gen/generator.py | |||
| @@ -75,13 +75,14 @@ class Generator(object): | |||
| 75 | release_master = list(set([False, bool(rm_config)])) | 75 | release_master = list(set([False, bool(rm_config)])) |
| 76 | 76 | ||
| 77 | 77 | ||
| 78 | return [GenOption('tasks', int, range(cpus, 5*cpus, cpus), | 78 | return [GenOption('tasks', int, range(cpus, 10*cpus, cpus), |
| 79 | 'Number of tasks per experiment.'), | 79 | 'Number of tasks per experiment.'), |
| 80 | GenOption('cpus', int, [cpus], | 80 | GenOption('cpus', int, [cpus], |
| 81 | 'Number of processors on target system.'), | 81 | 'Number of processors on target system.'), |
| 82 | GenOption('release_master', [True,False], release_master, | 82 | GenOption('release_master', [True,False], release_master, |
| 83 | 'Redirect release interrupts to a single CPU.'), | 83 | 'Redirect release interrupts to a single CPU.'), |
| 84 | GenOption('duration', float, [30], 'Experiment duration.')] | 84 | #GenOption('post', str, ['refill.sh'], 'Post script.'), |
| 85 | GenOption('duration', float, [10], 'Experiment duration.')] | ||
| 85 | 86 | ||
| 86 | @staticmethod | 87 | @staticmethod |
| 87 | def _dist_option(name, default, distribution, help): | 88 | def _dist_option(name, default, distribution, help): |
| @@ -113,9 +114,9 @@ class Generator(object): | |||
| 113 | print(("Only created task set of size %d < %d for params %s. " + | 114 | print(("Only created task set of size %d < %d for params %s. " + |
| 114 | "Switching to light utilization.") % | 115 | "Switching to light utilization.") % |
| 115 | (len(ts), params['tasks'], params)) | 116 | (len(ts), params['tasks'], params)) |
| 116 | print("Switching to light util. This usually means the " + | 117 | print("Switching to very-light util. This usually means the " + |
| 117 | "utilization distribution is too agressive.") | 118 | "utilization distribution is too agressive.") |
| 118 | return self._create_taskset(params, periods, NAMED_UTILIZATIONS['uni-light'], | 119 | return self._create_taskset(params, periods, NAMED_UTILIZATIONS['uni-very-light'], |
| 119 | max_util) | 120 | max_util) |
| 120 | return ts | 121 | return ts |
| 121 | 122 | ||
diff --git a/parse/ft.py b/parse/ft.py index 1f05323..6e7278e 100644 --- a/parse/ft.py +++ b/parse/ft.py | |||
| @@ -68,18 +68,21 @@ def extract_ft_data(result, data_dir, work_dir, cycles): | |||
| 68 | 68 | ||
| 69 | if not len(bins): | 69 | if not len(bins): |
