[llvm-branch-commits] [llvm] release/22.x: [lit] Explicitly unset timer to free thread stack (#188717) (PR #188938)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Mar 27 02:50:06 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-testing-tools

Author: llvmbot

<details>
<summary>Changes</summary>

Backport 202ef22faeb1c2a7b5846a446e8c8dfe579d7c29 b7d8831f8c432db97e5fcd5acdc470e7a82c92b2 dfefc03769f58d8982202276cd3381356da12dfe

Requested by: @<!-- -->nikic

---
Full diff: https://github.com/llvm/llvm-project/pull/188938.diff


2 Files Affected:

- (modified) llvm/utils/lit/lit/TestRunner.py (+7-3) 
- (modified) llvm/utils/lit/lit/run.py (+4-1) 


``````````diff
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index e9d73ade9827e..93f03624f9984 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -127,6 +127,8 @@ def cancel(self):
         if not self.active():
             return
         self._timer.cancel()
+        # Break reference cycle so that thread stack is freed immediately.
+        self._timer = None
 
     def active(self):
         return self.timeout > 0
@@ -136,7 +138,9 @@ def addProcess(self, proc):
             return
         needToRunKill = False
         with self._lock:
-            self._procs.append(proc)
+            # just store the pid, rather than the whole proc object.
+            # Holding the proc object keeps resources (eg pipes) open unnecessarily.
+            self._procs.append(proc.pid)
             # Avoid re-entering the lock by finding out if kill needs to be run
             # again here but call it if necessary once we have left the lock.
             # We could use a reentrant lock here instead but this code seems
@@ -176,8 +180,8 @@ def _kill(self):
         the initial call to _kill()
         """
         with self._lock:
-            for p in self._procs:
-                lit.util.killProcessAndChildren(p.pid)
+            for pid in self._procs:
+                lit.util.killProcessAndChildren(pid)
             # Empty the list and note that we've done a pass over the list
             self._procs = []  # Python2 doesn't have list.clear()
             self._doneKillPass = True
diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py
index 9c54511bfd625..fb18a60db1b39 100644
--- a/llvm/utils/lit/lit/run.py
+++ b/llvm/utils/lit/lit/run.py
@@ -142,8 +142,10 @@ def _execute(self, deadline):
 
     def _wait_for(self, async_results, deadline):
         timeout = deadline - time.time()
-        for idx, ar in enumerate(async_results):
+        idx = 0
+        while len(async_results) > 0:
             try:
+                ar = async_results.pop(0)
                 test = ar.get(timeout)
             except multiprocessing.TimeoutError:
                 raise TimeoutError()
@@ -153,6 +155,7 @@ def _wait_for(self, async_results, deadline):
                     self.failures += 1
                     if self.failures == self.max_failures:
                         raise MaxFailuresError()
+            idx += 1
 
     # Update local test object "in place" from remote test object.  This
     # ensures that the original test object which is used for printing test

``````````

</details>


https://github.com/llvm/llvm-project/pull/188938


More information about the llvm-branch-commits mailing list