aboutsummaryrefslogtreecommitdiffstats
path: root/run
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2012-11-26 17:06:27 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2012-11-26 17:06:27 -0500
commitb43b83beead92ff7cf28a5fe5a2710537268aae1 (patch)
treed9c29b14cd18a9df520f36d7e85eb460c30fa7a9 /run
parentcb8db5d30ee769304c2c2b00f2a7d9bcb3c4098f (diff)
Read locations of binary files from path instead of config.py.
Diffstat (limited to 'run')
-rw-r--r--run/__init__.py0
-rw-r--r--run/executable/__init__.py0
-rw-r--r--run/executable/executable.py77
-rw-r--r--run/executable/ftcat.py33
-rw-r--r--run/experiment.py209
-rw-r--r--run/litmus_util.py79
-rw-r--r--run/proc_entry.py12
-rw-r--r--run/tracer.py112
8 files changed, 522 insertions, 0 deletions
diff --git a/run/__init__.py b/run/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/run/__init__.py
diff --git a/run/executable/__init__.py b/run/executable/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/run/executable/__init__.py
diff --git a/run/executable/executable.py b/run/executable/executable.py
new file mode 100644
index 0000000..628f711
--- /dev/null
+++ b/run/executable/executable.py
@@ -0,0 +1,77 @@
1import sys
2import subprocess
3import signal
4from ..litmus_util import is_executable
5
6class Executable(object):
7 '''Parent object that represents an executable for use in task-sets.'''
8
9 def __init__(self, exec_file, extra_args=None, stdout_file = None, stderr_file = None):
10 self.exec_file = exec_file
11 self.cwd = None
12 self.stdout_file = stdout_file
13 self.stderr_file = stderr_file
14 self.sp = None
15
16 if extra_args is None:
17 self.extra_args = None
18 else:
19 self.extra_args = list(extra_args) # make a duplicate
20
21 if not is_executable(self.exec_file):
22 raise Exception("Not executable ? : %s" % self.exec_file)
23
24 def __del__(self):
25 # Try and clean up
26 if self.stdout_file is not None:
27 self.stdout_file.close()
28 if self.stderr_file is not None:
29 self.stderr_file.close()
30
31 if self.sp is not None:
32 try:
33 self.sp.terminate()
34 except OSError as e:
35 if e.errno == 3:
36 pass # no such process (already killed), okay
37 else:
38 raise e
39
40 def __get_full_command(self):
41 full_command = [self.exec_file]
42 if self.extra_args is not None:
43 full_command += self.extra_args
44 return full_command
45
46 def __str__(self):
47 return " ".join(self.__get_full_command())
48
49 def execute(self):
50 '''Execute the binary.'''
51 full_command = self.__get_full_command()
52 self.sp = subprocess.Popen(full_command, stdout=self.stdout_file,
53 stderr=self.stderr_file, cwd=self.cwd)
54
55 def kill(self):
56 self.sp.kill()
57
58 def interrupt(self):
59 self.sp.send_signal(signal.SIGINT)
60
61 def terminate(self):
62 '''Send the terminate signal to the binary.'''
63 self.sp.terminate()
64
65 def wait(self):
66 '''Wait until the executable is finished, checking return code.
67
68 If the exit status is non-zero, raise an exception.
69
70 '''
71
72 self.sp.wait()
73 if self.sp.returncode != 0:
74 print >>sys.stderr, "Non-zero return: %s %s" % (self.exec_file, " ".join(self.extra_args))
75 return 0
76 else:
77 return 1
diff --git a/run/executable/ftcat.py b/run/executable/ftcat.py
new file mode 100644
index 0000000..5da8fa7
--- /dev/null
+++ b/run/executable/ftcat.py
@@ -0,0 +1,33 @@
1import os
2import stat
3
4from executable import Executable
5
6class FTcat(Executable):
7 '''Used to wrap the ftcat binary in the Experiment object.'''
8
9 def __init__(self, ft_cat_bin, stdout_file, stderr_file, dev, events, cpu=None):
10 '''Extends the Executable initializer method with ftcat attributes.'''
11
12 # hack to run FTCat at higher priority
13 chrt_bin = '/usr/bin/chrt'
14
15 super(FTcat, self).__init__(chrt_bin)
16 self.stdout_file = stdout_file
17 self.stderr_file = stderr_file
18
19 mode = os.stat(dev)[stat.ST_MODE]
20 if not mode & stat.S_IFCHR:
21 raise Exception("%s is not a character device" % dev)
22
23 if events is None:
24 raise Exception('No events!')
25
26 # hack to run FTCat at higher priority
27 self.extra_args = ['-f', '40']
28 if cpu is not None:
29 # and bind it to a CPU
30 self.extra_args.extend(['/usr/bin/taskset', '-c', str(cpu)])
31 events_str_arr = map(str, events)
32 self.extra_args.extend([ft_cat_bin, dev] + events_str_arr)
33
diff --git a/run/experiment.py b/run/experiment.py
new file mode 100644
index 0000000..4bd47c6
--- /dev/null
+++ b/run/experiment.py
@@ -0,0 +1,209 @@
1import os
2import time
3import litmus_util
4from operator import methodcaller
5from tracer import SchedTracer, LogTracer, PerfTracer, LinuxTracer, OverheadTracer
6
7class ExperimentException(Exception):
8 '''Used to indicate when there are problems with an experiment.'''
9 def __init__(self, name):
10 self.name = name
11
12
13class ExperimentDone(ExperimentException):
14 '''Raised when an experiment looks like it's been run already.'''
15 def __str__(self):
16 return "Experiment finished already: %d" % self.name
17
18
19class ExperimentInterrupted(ExperimentException):
20 '''Raised when an experiment appears to be interrupted (partial results).'''
21 def __str__(self):
22 return "Experiment was interrupted in progress: %d" % self.name
23
24
25class ExperimentFailed(ExperimentException):
26 def __str__(self):
27 return "Experiment failed during execution: %d" % self.name
28
29
30class Experiment(object):
31 '''Execute one task-set and save the results. Experiments have unique IDs.'''
32 INTERRUPTED_DIR = ".interrupted"
33
34 def __init__(self, name, scheduler, working_dir, finished_dir, proc_entries, executables):
35 '''Run an experiment, optionally wrapped in tracing.'''
36
37 self.name = name
38 self.scheduler = scheduler
39 self.working_dir = working_dir
40 self.finished_dir = finished_dir
41 self.proc_entries = proc_entries
42 self.executables = executables
43 self.exec_out = None
44 self.exec_err = None
45
46 self.__make_dirs()
47 self.__assign_executable_cwds()
48
49 self.tracers = []
50 if SchedTracer.enabled():
51 self.log("Enabling sched_trace")
52 self.tracers.append( SchedTracer(working_dir) )
53 if LinuxTracer.enabled():
54 self.log("Enabling trace-cmd / ftrace / kernelshark")
55 self.tracers.append( LinuxTracer(working_dir) )
56 if LogTracer.enabled():
57 self.log("Enabling logging")
58 self.tracers.append( LogTracer(working_dir) )
59 if PerfTracer.enabled():
60 self.log("Tracking CPU performance counters")
61 self.tracers.append( PerfTracer(working_dir) )
62
63 # Overhead trace must be handled seperately, see __run_tasks
64 if OverheadTracer.enabled():
65 self.log("Enabling overhead tracing")
66 self.overhead_trace = OverheadTracer(working_dir)
67 else:
68 self.overhead_trace = None
69
70 def __make_dirs(self):
71 interrupted = None
72
73 if os.path.exists(self.finished_dir):
74 raise ExperimentDone(self.name)
75
76 if os.path.exists(self.working_dir):
77 self.log("Found interrupted experiment, saving in %s" %
78 Experiment.INTERRUPTED_DIR)
79 interrupted = "%s/%s" % (os.path.split(self.working_dir)[0],
80 Experiment.INTERRUPTED_DIR)
81 os.rename(self.working_dir, interrupted)
82
83 os.mkdir(self.working_dir)
84
85 if interrupted:
86 os.rename(interrupted, "%s/%s" % (self.working_dir,
87 os.path.split(interrupted)[1]))
88