Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/utils/lit/lit/worker.py
# The functions in this module are meant to run on a separate worker process. | |||||
# Exception: in single process mode _execute_test is called directly. | |||||
import time | |||||
import traceback | |||||
import lit.Test | |||||
import lit.util | |||||
_lit_config = None | |||||
_parallelism_semaphores = None | |||||
def initializer(lit_config, parallelism_semaphores): | |||||
"""Copy expensive repeated data into worker processes""" | |||||
global _lit_config | |||||
global _parallelism_semaphores | |||||
_lit_config = lit_config | |||||
_parallelism_semaphores = parallelism_semaphores | |||||
def run_one_test(test_index, test): | |||||
"""Run one test in a multiprocessing.Pool | |||||
Side effects in this function and functions it calls are not visible in the | |||||
main lit process. | |||||
Arguments and results of this function are pickled, so they should be cheap | |||||
to copy. For efficiency, we copy all data needed to execute all tests into | |||||
each worker and store it in the worker_* global variables. This reduces the | |||||
cost of each task. | |||||
Returns an index and a Result, which the parent process uses to update | |||||
the display. | |||||
""" | |||||
try: | |||||
_execute_test_in_parallelism_group(test, _lit_config, | |||||
_parallelism_semaphores) | |||||
return (test_index, test) | |||||
except KeyboardInterrupt: | |||||
# If a worker process gets an interrupt, abort it immediately. | |||||
lit.util.abort_now() | |||||
except: | |||||
traceback.print_exc() | |||||
def _execute_test_in_parallelism_group(test, lit_config, parallelism_semaphores): | |||||
"""Execute one test inside the appropriate parallelism group""" | |||||
pg = test.config.parallelism_group | |||||
if callable(pg): | |||||
pg = pg(test) | |||||
if pg: | |||||
semaphore = parallelism_semaphores[pg] | |||||
try: | |||||
semaphore.acquire() | |||||
_execute_test(test, lit_config) | |||||
finally: | |||||
semaphore.release() | |||||
else: | |||||
_execute_test(test, lit_config) | |||||
def _execute_test(test, lit_config): | |||||
"""Execute one test""" | |||||
try: | |||||
start_time = time.time() | |||||
result = test.config.test_format.execute(test, lit_config) | |||||
# Support deprecated result from execute() which returned the result | |||||
# code and additional output as a tuple. | |||||
if isinstance(result, tuple): | |||||
code, output = result | |||||
result = lit.Test.Result(code, output) | |||||
elif not isinstance(result, lit.Test.Result): | |||||
raise ValueError("unexpected result from test execution") | |||||
result.elapsed = time.time() - start_time | |||||
except KeyboardInterrupt: | |||||
raise | |||||
except: | |||||
if lit_config.debug: | |||||
raise | |||||
output = 'Exception during script execution:\n' | |||||
output += traceback.format_exc() | |||||
output += '\n' | |||||
result = lit.Test.Result(lit.Test.UNRESOLVED, output) | |||||
test.setResult(result) |