aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2017-04-03 23:35:59 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2017-04-03 23:35:59 -0400
commitfb72dd09cfc16d0260363d38df1225b6663bc084 (patch)
treedb1472467249286171d3e35c4b7a77c165571892
parente15736509ab36e33bc71a0fe1120f2974e389725 (diff)
-rw-r--r--common.py3
-rw-r--r--config/config.py21
-rw-r--r--gen/__init__.py7
-rw-r--r--gen/edf_generators.py33
-rw-r--r--gen/generator.py9
-rw-r--r--parse/ft.py29
-rwxr-xr-xparse_exps.py1
-rw-r--r--run/tracer.py9
-rwxr-xr-xrun_exps.py7
9 files changed, 88 insertions, 31 deletions
diff --git a/common.py b/common.py
index 9ea2915..2326ec3 100644
--- a/common.py
+++ b/common.py
@@ -161,10 +161,9 @@ def num_cpus():
161 161
162def ft_freq(): 162def 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.'''
6BINS = {'rtspin' : get_executable_hint('rtspin', 'liblitmus'), 6BINS = {'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'),
18FILES = {'params_file' : 'params.py', 19FILES = {'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.'''
40DEFAULTS = {'duration' : 10, 42DEFAULTS = {'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).'''
50SCHED_EVENTS = range(501, 513) 53SCHED_EVENTS = range(501, 513)
51 54
52'''Overhead events.''' 55'''Overhead events.'''
53OVH_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']
57OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'RELEASE_C', 'SCHED2', 'TICK', 'CXS', 'ISR', 'SCHED_A', 'SCHED_C']
54OVH_ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in 58OVH_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"])]
56OVH_ALL_EVENTS += ['RELEASE_LATENCY'] 60OVH_ALL_EVENTS += ['RELEASE_LATENCY']
61OVH_ALL_EVENTS += ['RELEASE_LATENCY_A']
62OVH_ALL_EVENTS += ['RELEASE_LATENCY_B']
63OVH_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
58OVH_BASE_EVENTS += ['RELEASE_LATENCY'] 65OVH_BASE_EVENTS += ['RELEASE_LATENCY']
66OVH_BASE_EVENTS += ['RELEASE_LATENCY_A']
67OVH_BASE_EVENTS += ['RELEASE_LATENCY_B']
68OVH_BASE_EVENTS += ['RELEASE_LATENCY_C']
69
70OVH_MSG_EVENTS = ['SEND_RESCHED_START' , 'SEND_RESCHED_END']
71OVH_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 @@
1import generator as gen 1import generator as gen
2import edf_generators as edf 2import edf_generators as edf
3 3
4gen.register_generator("G-EDF", edf.GedfGenerator) 4#gen.register_generator("G-EDF", edf.GedfGenerator)
5gen.register_generator("P-EDF", edf.PedfGenerator) 5#gen.register_generator("P-EDF", edf.PedfGenerator)
6gen.register_generator("C-EDF", edf.CedfGenerator) 6gen.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"""
7TP_GLOB_TASK = TP_TBASE.format("") 7TP_GLOB_TASK = TP_TBASE.format("")
8TP_PART_TASK = TP_TBASE.format("-p $t.cpu") 8TP_PART_TASK = TP_TBASE.format("-p $t.cpu")
9TP_MC_TASK = TP_TBASE.format("-p $t.cpu -m $t.crit -i $t.id")
9 10
10class EdfGenerator(gen.Generator): 11class 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
92class 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):
70 return False 70 return False
71 71
72 bin_file = "{}/{}".format(data_dir, bins[0]) 72 for bin in bins:
73 if not os.path.getsize(bin_file): 73 #bin_file = "{}/{}".format(data_dir, bins[0])
74 return False 74 bin_file = "{}/{}".format(data_dir, bin)
75 75 if not os.path.getsize(bin_file):
76 with open("%s/%s" % (work_dir, FT_ERR_NAME), 'w') as err_file: 76 return False
77 sorted_bin = sort_ft(bin_file, err_file, work_dir) 77 #sys.stderr.write(bin_file)
78 78 #sys.stderr.write("\n")
79 for event in conf.OVH_BASE_EVENTS: 79 with open("%s/%s" % (work_dir, FT_ERR_NAME), 'w') as err_file:
80 parse_overhead(result, sorted_bin, event, cycles, 80 sorted_bin = sort_ft(bin_file, err_file, work_dir)
81 work_dir, err_file) 81
82 82 for event in conf.OVH_BASE_EVENTS:
83 os.remove(sorted_bin) 83 parse_overhead(result, sorted_bin, event, cycles,
84 work_dir, err_file)
85
86 os.remove(sorted_bin)
84 87
85 return True 88 return True
diff --git a/parse_exps.py b/parse_exps.py
index ee7b29f..e11b4ad 100755
--- a/parse_exps.py
+++ b/parse_exps.py
@@ -75,6 +75,7 @@ def parse_exp(exp_force):
75 75
76 # Write overheads into result 76 # Write overheads into result
77 cycles = exp.params[PARAMS['cycles']] 77 cycles = exp.params[PARAMS['cycles']]
78 sys.stderr.write("CPU cycles = %s\n" % cycles)
78 ft.extract_ft_data(result, exp.path, exp.work_dir, cycles) 79 ft.extract_ft_data(result, exp.path, exp.work_dir, cycles)
79 80
80 # Write scheduling statistics into result 81 # Write scheduling statistics into result
diff --git a/run/tracer.py b/run/tracer.py
index 5e92a74..5099dff 100644
--- a/run/tracer.py
+++ b/run/tracer.py
@@ -93,7 +93,8 @@ class SchedTracer(Tracer):
93 return is_device("%s%d" % (SchedTracer.DEVICE_STR, 0)) 93 return is_device("%s%d" % (SchedTracer.DEVICE_STR, 0))
94 94
95class OverheadTracer(Tracer): 95class OverheadTracer(Tracer):
96 DEVICE_STR = '/dev/litmus/ft_trace0' 96 DEVICE_STR = '/dev/litmus/ft_cpu_trace0'
97 MSG_DEVICE_STR = '/dev/litmus/ft_msg_trace0'
97 98
98 def __init__(self, output_dir): 99 def __init__(self, output_dir):
99 super(OverheadTracer, self).__init__("Overhead Trace", output_dir, True) 100 super(OverheadTracer, self).__init__("Overhead Trace", output_dir, True)
@@ -103,7 +104,13 @@ class OverheadTracer(Tracer):
103 ftc = FTcat(conf.BINS['ftcat'], stdout_f, stderr_f, 104 ftc = FTcat(conf.BINS['ftcat'], stdout_f, stderr_f,
104 OverheadTracer.DEVICE_STR, conf.OVH_ALL_EVENTS) 105 OverheadTracer.DEVICE_STR, conf.OVH_ALL_EVENTS)
105 106
107 stdout_f2 = open('{0}/{1}'.format(self.output_dir, conf.FILES['ft_msg_data']), 'w')
108 stderr_f2 = open('{0}/{1}.stderr.txt'.format(self.output_dir, conf.FILES['ft_msg_data']), 'w')
109 ftc2 = FTcat(conf.BINS['ftcat'], stdout_f2, stderr_f2,
110 OverheadTracer.MSG_DEVICE_STR, conf.OVH_MSG_EVENTS)
111
106 self.bins.append(ftc) 112 self.bins.append(ftc)
113 self.bins.append(ftc2)
107 114
108 @staticmethod 115 @staticmethod
109 def enabled(): 116 def enabled():
diff --git a/run_exps.py b/run_exps.py
index 21666a9..6b61c86 100755
--- a/run_exps.py
+++ b/run_exps.py
@@ -216,7 +216,7 @@ def run_script(script_params, exp, exp_dir, out_dir):
216 if type(script_params) != type([]): 216 if type(script_params) != type([]):
217 script_params = [script_params] 217 script_params = [script_params]
218 218
219 exp.log("Running %s" % script_params.join(" ")) 219 exp.log("Running %s" % script_params)
220 220
221 script_name = script_params.pop(0) 221 script_name = script_params.pop(0)
222 script = com.get_executable(script_name, cwd=exp_dir) 222 script = com.get_executable(script_name, cwd=exp_dir)
@@ -443,8 +443,9 @@ def run_exps(exps, opts):
443 exps_remaining = enumerate(exps) 443 exps_remaining = enumerate(exps)
444 # But run experiments which have failed the most last 444 # But run experiments which have failed the most last
445 exps_remaining = sorted(exps_remaining, key=lambda x: get_tries(x[1])) 445 exps_remaining = sorted(exps_remaining, key=lambda x: get_tries(x[1]))
446 finished = 0
446 447
447 while exps_remaining: 448 while exps_remaining and finished < 3:
448 i, exp = exps_remaining.pop(0) 449 i, exp = exps_remaining.pop(0)
449 450
450 verb = "Loading" if exp.state == ExpState.None else "Re-running failed" 451 verb = "Loading" if exp.state == ExpState.None else "Re-running failed"
@@ -456,7 +457,7 @@ def run_exps(exps, opts):
456 raise Exception("Hit maximum retries of %d" % MAX_RETRY) 457 raise Exception("Hit maximum retries of %d" % MAX_RETRY)
457 458
458 run_experiment(exp, start_message, opts.ignore, jabber) 459 run_experiment(exp, start_message, opts.ignore, jabber)
459 460 finished += 1
460 set_tries(exp, 0) 461 set_tries(exp, 0)
461 exp.state = ExpState.Succeeded 462 exp.state = ExpState.Succeeded
462 except KeyboardInterrupt: 463 except KeyboardInterrupt: