diff options
Diffstat (limited to 'iwyu_tool.py')
-rwxr-xr-x | iwyu_tool.py | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/iwyu_tool.py b/iwyu_tool.py index a0768d6..eaf0abc 100755 --- a/iwyu_tool.py +++ b/iwyu_tool.py @@ -242,6 +242,10 @@ class Process(object): """ return self.proc.poll() + @property + def returncode(self): + return self.proc.returncode + def get_output(self): """ Return stdout+stderr output of the process. @@ -352,12 +356,16 @@ def slice_compilation_db(compilation_db, selection): return new_db -def execute(invocations, verbose, formatter, jobs): +def execute(invocations, verbose, formatter, jobs, max_load_average=0): """ Launch processes described by invocations. """ + exit_code = 0 if jobs == 1: for invocation in invocations: - print(formatter(invocation.start(verbose).get_output())) - return + proc = invocation.start(verbose) + print(formatter(proc.get_output())) + if proc.returncode != 2: + exit_code = 1 + return exit_code pending = [] while invocations or pending: @@ -366,18 +374,33 @@ def execute(invocations, verbose, formatter, jobs): for proc in complete: pending.remove(proc) print(formatter(proc.get_output())) + if proc.returncode != 2: + exit_code = 1 # Schedule new processes if there's room. capacity = jobs - len(pending) + + if max_load_average > 0: + one_min_load_average, _, _ = os.getloadavg() + load_capacity = max_load_average - one_min_load_average + if load_capacity < 0: + load_capacity = 0 + if load_capacity < capacity: + capacity = int(load_capacity) + if not capacity and not pending: + # Ensure there is at least one job running. + capacity = 1 + pending.extend(i.start(verbose) for i in invocations[:capacity]) invocations = invocations[capacity:] # Yield CPU. time.sleep(0.0001) + return exit_code def main(compilation_db_path, source_files, verbose, formatter, jobs, - extra_args): + max_load_average, extra_args): """ Entry point. """ if not IWYU_EXECUTABLE: @@ -407,7 +430,7 @@ def main(compilation_db_path, source_files, verbose, formatter, jobs, Invocation.from_compile_command(e, extra_args) for e in compilation_db ] - return execute(invocations, verbose, formatter, jobs) + return execute(invocations, verbose, formatter, jobs, max_load_average) def _bootstrap(sys_argv): @@ -448,6 +471,8 @@ def _bootstrap(sys_argv): help='Output format (default: %s)' % DEFAULT_FORMAT) parser.add_argument('-j', '--jobs', type=int, default=1, help='Number of concurrent subprocesses') + parser.add_argument('-l', '--load', type=float, default=0, + help='Do not start new jobs if the 1min load average is greater than the provided value') parser.add_argument('-p', metavar='<build-path>', required=True, help='Compilation database path', dest='dbpath') parser.add_argument('source', nargs='*', @@ -466,7 +491,7 @@ def _bootstrap(sys_argv): args = parser.parse_args(argv) return main(args.dbpath, args.source, args.verbose, - FORMATTERS[args.output_format], args.jobs, extra_args) + FORMATTERS[args.output_format], args.jobs, args.load, extra_args) if __name__ == '__main__': |