Skip to content

Commit 8521bbe

Browse files
committed
Declare free-threaded safety for _scalene_unwind module
The _scalene_unwind native extension (native_unwind.cpp) was the only one of Scalene's three C extension modules that did not call PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED) in its init. On free-threaded builds (3.13t/3.14t) importing a module that has not declared free-threaded safety makes CPython silently re-enable the GIL and emit a RuntimeWarning. Because Scalene always imports _scalene_unwind, the GIL was restored on every free-threaded run -- so Scalene never actually ran free-threaded, adding startup overhead and serializing threads. pywhere.cpp and get_line_atomic.cpp already make this call; this brings _scalene_unwind in line with them. Verified on Linux (3.13t and 3.14t): after the fix sys._is_gil_enabled() stays False after importing scalene, the RuntimeWarning is gone, the memory attribution suite passes, and the free-threaded parity test shows the contention ratio drop below 1.0 (real parallel scaling) instead of being masked by a re-enabled GIL.
1 parent 00d07bf commit 8521bbe

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

src/source/native_unwind.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,13 @@ PyModuleDef moduledef = {
806806
extern "C" PyObject* PyInit__scalene_unwind(void) {
807807
PyObject* m = PyModule_Create(&moduledef);
808808
if (!m) return nullptr;
809+
#ifdef Py_GIL_DISABLED
810+
// Declare free-threaded safety so importing this module does not silently
811+
// re-enable the GIL on free-threaded (3.13t/3.14t) builds. Without this,
812+
// CPython restores the GIL with a RuntimeWarning, so Scalene never actually
813+
// runs free-threaded -- matches pywhere.cpp and get_line_atomic.cpp.
814+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
815+
#endif
809816
PyModule_AddIntConstant(m, "available", SCALENE_UNWIND_AVAILABLE);
810817
// Expose the per-call cap so callers (and tests) read the single
811818
// source of truth instead of hard-coding the value.

0 commit comments

Comments
 (0)