summaryrefslogtreecommitdiffstats
path: root/iwyu_tool.py
diff options
context:
space:
mode:
Diffstat (limited to 'iwyu_tool.py')
-rwxr-xr-xiwyu_tool.py37
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__':