[llvm] c1d6f76 - [lit] Add an option to lit which ratelimits progressbar output. (#186479)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 10:53:30 PDT 2026


Author: Nick Begg
Date: 2026-04-14T10:53:25-07:00
New Revision: c1d6f7609e16d16864063c6d98feed1a9cdc3270

URL: https://github.com/llvm/llvm-project/commit/c1d6f7609e16d16864063c6d98feed1a9cdc3270
DIFF: https://github.com/llvm/llvm-project/commit/c1d6f7609e16d16864063c6d98feed1a9cdc3270.diff

LOG: [lit] Add an option to lit which ratelimits progressbar output. (#186479)

Add a new option --min-output-interval, which ratelimits updates to the
progress bar.

When running Lit with the full curses progressbar, it updates both the
bar, and the status text below on every test completion. Running
check-llvm on my laptop runs about 44k tests and takes about 260 seconds
for a release build. Or about 171 tests/second on average.

Moreover, when ssh'd to another host, this generates quite a bit of
traffic. Using tcpdump, I measured the traffic for a run of check-llvm
and -clang. With all updates, its about 8.7 megabytes. With a rate limit
of 5 update/sec, this came down to 175 kilobytes. This can be
significant on slow/metered connections.

This patch adds an option to limit lit's output to once per a given
interval. This only affects the progressbar and status message below,
not any log messages above. It also does not affect anything when not
running with the full progressbar (eg outputting to a logfile).

---------

Co-authored-by: Nick Begg <neek78 at users.noreply.github.com>
Co-authored-by: Alexander Richardson <mail at alexrichardson.me>

Added: 
    

Modified: 
    llvm/docs/CommandGuide/lit.rst
    llvm/utils/lit/lit/ProgressBar.py
    llvm/utils/lit/lit/cl_arguments.py
    llvm/utils/lit/lit/display.py

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/lit.rst b/llvm/docs/CommandGuide/lit.rst
index bbeafd2b9234c..2e14f53d110cb 100644
--- a/llvm/docs/CommandGuide/lit.rst
+++ b/llvm/docs/CommandGuide/lit.rst
@@ -120,6 +120,11 @@ OUTPUT OPTIONS
 
  Do not use curses based progress bar.
 
+.. option:: --min-output-interval INTERVAL
+
+ Only output updates to the progress bar and status line at most once per
+ INTERVAL seconds. Has no effect if the curses based progress bar is not used.
+
 .. option:: --show-excluded
 
  Show excluded tests.

diff  --git a/llvm/utils/lit/lit/ProgressBar.py b/llvm/utils/lit/lit/ProgressBar.py
index dadbe6522ed19..4374269525d68 100644
--- a/llvm/utils/lit/lit/ProgressBar.py
+++ b/llvm/utils/lit/lit/ProgressBar.py
@@ -297,7 +297,7 @@ class ProgressBar:
     BAR = "%s${%s}[${BOLD}%s%s${NORMAL}${%s}]${NORMAL}%s"
     HEADER = "${BOLD}${CYAN}%s${NORMAL}\n\n"
 
-    def __init__(self, term, header, useETA=True):
+    def __init__(self, term, header, minOutputInterval, useETA=True):
         self.term = term
         if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
             raise ValueError(
@@ -321,7 +321,23 @@ def __init__(self, term, header, useETA=True):
             self.startTime = time.time()
         # self.update(0, '')
 
+        self.lastUpdateTime = 0
+        self.minOutputInterval = minOutputInterval
+        # the checks preceeding us should prevent getting here if output is redirected
+        # - we don't want to rate limit (ie drop) output to a file
+        assert sys.stdout.isatty()
+
     def update(self, percent, message):
+        # ratelimit updates
+        if self.minOutputInterval is not None:
+            now = time.time()
+            if now - self.lastUpdateTime < self.minOutputInterval:
+                # ... too soon. Technically, this means we could 'starve'
+                # the output if the next update takes too long to come, but that
+                # doesn't seem to be an issue in practice
+                return
+            self.lastUpdateTime = now
+
         if self.cleared:
             sys.stdout.write(self.header)
             self.cleared = 0

diff  --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py
index 2fe2ed60aca70..bebde4b762b0e 100644
--- a/llvm/utils/lit/lit/cl_arguments.py
+++ b/llvm/utils/lit/lit/cl_arguments.py
@@ -235,6 +235,14 @@ def parse_args():
         help="Do not use curses based progress bar (default)",
         action="store_false",
     )
+    format_group.add_argument(
+        "--min-output-interval",
+        dest="minOutputInterval",
+        help="Limit updates to progressbar to at most once per INTERVAL, in seconds. Set to 0 to disable ratelimit (default - no ratelimit).",
+        default=0.0,
+        metavar="INTERVAL",
+        type=_non_negative_float,
+    )
 
     # Note: this does not generate flags for user-defined result codes.
     success_codes = [c for c in lit.Test.ResultCode.all_codes() if not c.isFailure]
@@ -548,6 +556,24 @@ def _int(arg, kind, pred):
     return i
 
 
+def _non_negative_float(arg):
+    return _float(arg, "non-negative", lambda f: f >= 0.0)
+
+
+def _float(arg, kind, pred):
+    try:
+        f = float(arg)
+        if not pred(f):
+            raise argparse.ArgumentTypeError(
+                f"requires {kind} float, but found '{arg}'"
+            )
+    except ValueError:
+        raise argparse.ArgumentTypeError(
+            f"conversion error - requires {kind} float, but found '{arg}'"
+        )
+    return f
+
+
 def _case_insensitive_regex(arg):
     import re
 

diff  --git a/llvm/utils/lit/lit/display.py b/llvm/utils/lit/lit/display.py
index c6057fde39d59..278a82b555564 100644
--- a/llvm/utils/lit/lit/display.py
+++ b/llvm/utils/lit/lit/display.py
@@ -19,7 +19,9 @@ def create_display(opts, tests, total_tests, workers):
 
         try:
             tc = lit.ProgressBar.TerminalController()
-            progress_bar = lit.ProgressBar.ProgressBar(tc, header)
+            progress_bar = lit.ProgressBar.ProgressBar(
+                tc, header, minOutputInterval=opts.minOutputInterval
+            )
             header = None
         except ValueError:
             progress_bar = lit.ProgressBar.SimpleProgressBar("Testing: ")


        


More information about the llvm-commits mailing list