[llvm] [lit] Add an option to lit which ratelimits progressbar output. (PR #186479)
Nick Begg via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 4 04:12:38 PDT 2026
https://github.com/neek78 updated https://github.com/llvm/llvm-project/pull/186479
>From f61a635281640348fde22e154ab531abbc493c87 Mon Sep 17 00:00:00 2001
From: Nick Begg <nick at stunttruck.net>
Date: Fri, 13 Mar 2026 18:30:00 +0100
Subject: [PATCH 1/4] [lit] Add an option to lit which ratelimits progressbar
output.
Add a new option --min-output-interval, which ratelimits updates to
the progress bar. Only applies when using the full curses progress
bar, not the simplified one, nor does it affect the log message output.
---
llvm/utils/lit/lit/ProgressBar.py | 18 +++++++++++++++++-
llvm/utils/lit/lit/cl_arguments.py | 23 +++++++++++++++++++++++
llvm/utils/lit/lit/display.py | 4 +++-
3 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/llvm/utils/lit/lit/ProgressBar.py b/llvm/utils/lit/lit/ProgressBar.py
index 382b8f2e52540..2af916866427d 100644
--- a/llvm/utils/lit/lit/ProgressBar.py
+++ b/llvm/utils/lit/lit/ProgressBar.py
@@ -237,7 +237,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, useETA=True, minOutputInterval=None):
self.term = term
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
raise ValueError(
@@ -261,7 +261,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..fe3054fcb6065 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 0.2 seconds).",
+ default=0.2,
+ 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,21 @@ 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):
+ desc = "requires {} float, but found '{}'"
+ try:
+ f = float(arg)
+ except ValueError:
+ raise _error(desc, kind, arg)
+ if not pred(f):
+ raise _error(desc, kind, 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: ")
>From c2ae459f3d753059ecc1d02ee5ef113c4a367ace Mon Sep 17 00:00:00 2001
From: Nick Begg <nick at stunttruck.net>
Date: Thu, 19 Mar 2026 13:40:53 +0100
Subject: [PATCH 2/4] fixup! [lit] Add an option to lit which ratelimits
progressbar output.
---
llvm/utils/lit/lit/ProgressBar.py | 2 +-
llvm/utils/lit/lit/cl_arguments.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/lit/lit/ProgressBar.py b/llvm/utils/lit/lit/ProgressBar.py
index 2af916866427d..68e3e450e44b8 100644
--- a/llvm/utils/lit/lit/ProgressBar.py
+++ b/llvm/utils/lit/lit/ProgressBar.py
@@ -237,7 +237,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, minOutputInterval=None):
+ 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(
diff --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py
index fe3054fcb6065..5ed818fb93844 100644
--- a/llvm/utils/lit/lit/cl_arguments.py
+++ b/llvm/utils/lit/lit/cl_arguments.py
@@ -238,8 +238,8 @@ def parse_args():
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 0.2 seconds).",
- default=0.2,
+ 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,
)
>From 3ec996ff52ecda4dde42cfef58c844c713bce471 Mon Sep 17 00:00:00 2001
From: Nick Begg <nick at stunttruck.net>
Date: Tue, 31 Mar 2026 15:08:54 +0200
Subject: [PATCH 3/4] add --min-output-interval description to lit.rst
---
llvm/docs/CommandGuide/lit.rst | 5 +++++
1 file changed, 5 insertions(+)
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.
>From f86386afa07b44648fb018abcc4e270ad95a84cd Mon Sep 17 00:00:00 2001
From: Nick Begg <nick at stunttruck.net>
Date: Sat, 4 Apr 2026 13:12:28 +0200
Subject: [PATCH 4/4] Update llvm/utils/lit/lit/cl_arguments.py
Co-authored-by: Alexander Richardson <mail at alexrichardson.me>
---
llvm/utils/lit/lit/cl_arguments.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py
index 5ed818fb93844..a98dc04816530 100644
--- a/llvm/utils/lit/lit/cl_arguments.py
+++ b/llvm/utils/lit/lit/cl_arguments.py
@@ -568,6 +568,13 @@ def _float(arg, kind, pred):
raise _error(desc, kind, arg)
if not pred(f):
raise _error(desc, kind, arg)
+def _float(arg, kind, pred):
+ try:
+ f = float(arg)
+ if not pred(f):
+ raise ValueError()
+ except ValueError:
+ raise argparse.ArgumentTypeError(f"requires {kind} float, but found '{arg}'")
return f
More information about the llvm-commits
mailing list