diff options
Diffstat (limited to 'run/experiment.py')
-rw-r--r-- | run/experiment.py | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/run/experiment.py b/run/experiment.py index b0e46b6..4667cb1 100644 --- a/run/experiment.py +++ b/run/experiment.py | |||
@@ -1,8 +1,13 @@ | |||
1 | import config.config as conf | ||
1 | import os | 2 | import os |
2 | import time | 3 | import re |
3 | import run.litmus_util as lu | 4 | import run.litmus_util as lu |
4 | import shutil as sh | 5 | import shutil as sh |
6 | import sys | ||
7 | import time | ||
8 | |||
5 | from operator import methodcaller | 9 | from operator import methodcaller |
10 | from run.proc_entry import ProcEntry | ||
6 | 11 | ||
7 | class ExperimentException(Exception): | 12 | class ExperimentException(Exception): |
8 | '''Used to indicate when there are problems with an experiment.''' | 13 | '''Used to indicate when there are problems with an experiment.''' |
@@ -17,6 +22,10 @@ class ExperimentDone(ExperimentException): | |||
17 | class SystemCorrupted(Exception): | 22 | class SystemCorrupted(Exception): |
18 | pass | 23 | pass |
19 | 24 | ||
25 | PROC_ADD_PAGES = '/proc/sys/litmus/color/add_pages' | ||
26 | PROC_NR_PAGES = '/proc/sys/litmus/color/nr_pages' | ||
27 | REG_NR_PAGES = re.compile(r'\s*\d+\s*:\s*(\d+)', re.M) | ||
28 | |||
20 | class Experiment(object): | 29 | class Experiment(object): |
21 | '''Execute one task-set and save the results. Experiments have unique IDs.''' | 30 | '''Execute one task-set and save the results. Experiments have unique IDs.''' |
22 | INTERRUPTED_DIR = ".interrupted" | 31 | INTERRUPTED_DIR = ".interrupted" |
@@ -100,7 +109,7 @@ class Experiment(object): | |||
100 | for e in self.executables: | 109 | for e in self.executables: |
101 | status = e.poll() | 110 | status = e.poll() |
102 | if status != None and status: | 111 | if status != None and status: |
103 | err_msg = "Task %s failed with status: %s" % (e.wait(), status) | 112 | err_msg = "Task %s failed with status: %s" % (e, status) |
104 | msgs += [err_msg] | 113 | msgs += [err_msg] |
105 | 114 | ||
106 | if msgs: | 115 | if msgs: |
@@ -108,7 +117,7 @@ class Experiment(object): | |||
108 | # up the terminal | 117 | # up the terminal |
109 | if len(msgs) > 3: | 118 | if len(msgs) > 3: |
110 | num_errs = len(msgs) - 3 | 119 | num_errs = len(msgs) - 3 |
111 | msgs = msgs[0:4] + ["...%d more task errors..." % num_errs] | 120 | msgs = msgs[0:3] + ["...%d more task errors..." % num_errs] |
112 | 121 | ||
113 | out_name = self.__strip_path(self.exec_out.name) | 122 | out_name = self.__strip_path(self.exec_out.name) |
114 | err_name = self.__strip_path(self.exec_err.name) | 123 | err_name = self.__strip_path(self.exec_err.name) |
@@ -138,7 +147,7 @@ class Experiment(object): | |||
138 | now_ready = lu.waiting_tasks() | 147 | now_ready = lu.waiting_tasks() |
139 | if now_ready != num_ready: | 148 | if now_ready != num_ready: |
140 | wait_start = time.time() | 149 | wait_start = time.time() |
141 | num_ready = lu.now_ready | 150 | num_ready = now_ready |
142 | 151 | ||
143 | def __run_tasks(self): | 152 | def __run_tasks(self): |
144 | self.log("Starting %d tasks" % len(self.executables)) | 153 | self.log("Starting %d tasks" % len(self.executables)) |
@@ -197,11 +206,67 @@ class Experiment(object): | |||
197 | if msgs: | 206 | if msgs: |
198 | raise SystemCorrupted("\n".join(msgs)) | 207 | raise SystemCorrupted("\n".join(msgs)) |
199 | 208 | ||
209 | def __get_nr_pages(self): | ||
210 | with open(PROC_NR_PAGES, 'r') as f: | ||
211 | data = f.read() | ||
212 | |||
213 | pages = map(int, REG_NR_PAGES.findall(data)) | ||
214 | return pages | ||
215 | |||
216 | def __create_colored_pages(self): | ||
217 | if self.scheduler != 'COLOR' and self.scheduler != 'MC': | ||
218 | return | ||
219 | |||
220 | self.log("Creating colored pages...") | ||
221 | |||
222 | # On system startup, it takes some time for these entries to appear | ||
223 | start = time.time() | ||
224 | while not os.path.exists(PROC_ADD_PAGES) or\ | ||
225 | not os.path.exists(PROC_NR_PAGES): | ||
226 | |||
227 | if time.time() - start > 30.0: | ||
228 | raise Exception("Cannot find %s or %s!" % | ||
229 | (PROC_ADD_PAGES, PROC_NR_PAGES)) | ||
230 | time.sleep(1) | ||
231 | |||
232 | start_pages = self.__get_nr_pages() | ||
233 | num_started = sum(start_pages) | ||
234 | num_created = 0 | ||
235 | num_needed = len(start_pages) * conf.PAGES_PER_COLOR | ||
236 | |||
237 | ProcEntry(PROC_ADD_PAGES, 1).write_proc() | ||
238 | |||
239 | # Spin until pages are done adding | ||
240 | start = time.time() | ||
241 | while True: | ||
242 | if time.time() - start > 30.0: | ||
243 | raise Exception("Too much time spent creating pages!") | ||
244 | |||
245 | pages = sum(self.__get_nr_pages()) | ||
246 | |||
247 | if pages == num_needed: | ||
248 | break | ||
249 | else: | ||
250 | if pages > num_created: | ||
251 | num_created = pages | ||
252 | start = time.time() | ||
253 | sys.stderr.write('\rPages needed: {0: 4}'.format(num_needed - pages)) | ||
254 | |||
255 | # Unknown why this has to be done again.... | ||
256 | ProcEntry(PROC_ADD_PAGES, 1).write_proc() | ||
257 | time.sleep(1) | ||
258 | |||
259 | if num_created: | ||
260 | sys.stderr.write('\n') | ||
261 | self.log("Created %d colored pages." % (num_needed - num_started)) | ||
262 | |||
200 | def __setup(self): | 263 | def __setup(self): |
201 | self.__make_dirs() | 264 | self.__make_dirs() |
202 | self.__assign_executable_cwds() | 265 | self.__assign_executable_cwds() |
203 | self.__setup_tracers() | 266 | self.__setup_tracers() |
204 | 267 | ||
268 | self.__create_colored_pages() | ||
269 | |||
205 | self.log("Writing %d proc entries" % len(self.proc_entries)) | 270 | self.log("Writing %d proc entries" % len(self.proc_entries)) |
206 | map(methodcaller('write_proc'), self.proc_entries) | 271 | map(methodcaller('write_proc'), self.proc_entries) |
207 | 272 | ||
@@ -229,6 +294,8 @@ class Experiment(object): | |||
229 | self.log("Stopping regular tracers") | 294 | self.log("Stopping regular tracers") |
230 | map(methodcaller('stop_tracing'), self.regular_tracers) | 295 | map(methodcaller('stop_tracing'), self.regular_tracers) |
231 | 296 | ||
297 | os.system('sync') | ||
298 | |||
232 | def log(self, msg): | 299 | def log(self, msg): |
233 | print("[Exp %s]: %s" % (self.name, msg)) | 300 | print("[Exp %s]: %s" % (self.name, msg)) |
234 | 301 | ||
@@ -253,8 +320,11 @@ class Experiment(object): | |||
253 | self.__teardown() | 320 | self.__teardown() |
254 | finally: | 321 | finally: |
255 | self.log("Switching back to Linux scheduler") | 322 | self.log("Switching back to Linux scheduler") |
256 | self.__to_linux() | 323 | try: |
257 | 324 | self.__to_linux() | |
325 | except Exception as e: | ||
326 | print(e) | ||
327 | |||
258 | if succ: | 328 | if succ: |
259 | self.__save_results() | 329 | self.__save_results() |
260 | self.log("Experiment done!") | 330 | self.log("Experiment done!") |