Skip to content

Commit aa0f634

Browse files
yoneymeta-codesync[bot]
authored andcommitted
Test concurrent function qualname updates
Summary: Add a free-threading regression test for concurrent __qualname__ updates and the resulting refcount race. Reviewed By: alexmalyshev Differential Revision: D115896958 fbshipit-source-id: 57275b7da5d2f6605ff30e4879c05672415bd236
1 parent 9b0fa72 commit aa0f634

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

cinderx/PythonLib/test_cinderx/test_free_threading/test_free_threading.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,34 @@ def fibonacci(n: int) -> int:
1717
return fibonacci(n - 1) + fibonacci(n - 2)
1818

1919

20+
class FunctionWatcherTest(unittest.TestCase):
21+
@unittest.skipUnless(hasattr(os, "fork"), "fork not available on Windows")
22+
@run_in_subprocess
23+
def test_concurrent_qualname_updates(self) -> None:
24+
worker_count = 10
25+
iterations = 1_000
26+
start = threading.Barrier(worker_count)
27+
28+
def target() -> None:
29+
pass
30+
31+
cinderx.jit.jit_suppress(target)
32+
self.assertFalse(cinderx.jit.is_jit_compiled(target))
33+
34+
@cinderx.jit.jit_suppress
35+
def update_qualname(worker: int) -> None:
36+
start.wait()
37+
for iteration in range(iterations):
38+
target.__qualname__ = f"target_{worker}_{iteration}"
39+
40+
# Unsynchronized updates can underflow the old qualname's refcount.
41+
with ThreadPoolExecutor(max_workers=worker_count) as executor:
42+
list(executor.map(update_qualname, range(worker_count)))
43+
44+
self.assertFalse(cinderx.jit.is_jit_compiled(target))
45+
self.assertRegex(target.__qualname__, r"^target_\d+_\d+$")
46+
47+
2048
class JITCompilationTest(unittest.TestCase):
2149
def setUp(self):
2250
self.bg_compile = cinderx.jit.get_background_compile()

0 commit comments

Comments
 (0)