diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-25 16:43:49 -0400 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-25 16:43:49 -0400 |
| commit | 15f231a79320cbc97cd88d8a4751515a47ce223e (patch) | |
| tree | b86b202cadc816a5da7b96372b9de4362da88116 /run | |
| parent | 2ceaa6c607ef85bde4f14017634d9d1621efca29 (diff) | |
Bug fixes from testing.
Diffstat (limited to 'run')
| -rw-r--r-- | run/experiment.py | 82 | ||||
| -rw-r--r-- | run/proc_entry.py | 11 |
2 files changed, 85 insertions, 8 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!") |
diff --git a/run/proc_entry.py b/run/proc_entry.py index 56f7c24..e222c3d 100644 --- a/run/proc_entry.py +++ b/run/proc_entry.py | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | import os | 1 | import os |
| 2 | import traceback | ||
| 2 | 3 | ||
| 3 | class ProcEntry(object): | 4 | class ProcEntry(object): |
| 4 | def __init__(self, proc, data): | 5 | def __init__(self, proc, data): |
| 5 | self.proc = proc | 6 | self.proc = proc |
| 6 | self.data = data | 7 | self.data = str(data) |
| 7 | 8 | ||
| 8 | if not os.path.exists(self.proc): | 9 | if not os.path.exists(self.proc): |
| 9 | raise ValueError("Invalid proc entry %s" % self.proc) | 10 | raise ValueError("Invalid proc entry %s" % self.proc) |
| @@ -13,4 +14,10 @@ class ProcEntry(object): | |||
| 13 | with open(self.proc, 'w') as entry: | 14 | with open(self.proc, 'w') as entry: |
| 14 | entry.write(self.data) | 15 | entry.write(self.data) |
| 15 | except: | 16 | except: |
| 16 | print("Failed to write into %s value:\n%s" % (self.proc, self.data)) | 17 | traceback.print_exc() |
| 18 | |||
| 19 | val = str(self.data) | ||
| 20 | val = val if '\n' not in val else '\n'+val | ||
| 21 | |||
| 22 | raise IOError("Failed to write into %s value: %s" % | ||
| 23 | (self.proc, val)) | ||
