Skip to content

Commit 87f4a68

Browse files
Don't run the GC in the middle of long operations
1 parent afc5ab6 commit 87f4a68

File tree

8 files changed

+33
-19
lines changed

8 files changed

+33
-19
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_pyerrors.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ extern int _PyUnicodeError_GetParams(
207207
Py_ssize_t *slen,
208208
int as_bytes);
209209

210+
211+
int _PyErr_CheckSignalsWithoutGC(void);
212+
210213
#ifdef __cplusplus
211214
}
212215
#endif

Include/internal/pycore_uop_metadata.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/signalmodule.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,26 @@ PyErr_CheckSignals(void)
17881788
return _PyErr_CheckSignalsTstate(tstate);
17891789
}
17901790

1791+
/* Same as PyErr_CheckSignals but does not run the GC.
1792+
This can be safely used if you are certain that no allocation
1793+
is done inside the long-running C code.
1794+
*/
1795+
int
1796+
_PyErr_CheckSignalsWithoutGC(void)
1797+
{
1798+
PyThreadState *tstate = _PyThreadState_GET();
1799+
1800+
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
1801+
_PyRunRemoteDebugger(tstate);
1802+
#endif
1803+
1804+
if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
1805+
return 0;
1806+
}
1807+
1808+
return _PyErr_CheckSignalsTstate(tstate);
1809+
}
1810+
17911811

17921812
/* Declared in cpython/pyerrors.h */
17931813
int

Objects/longobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ maybe_small_long(PyLongObject *v)
113113

114114
#define SIGCHECK(PyTryBlock) \
115115
do { \
116-
if (PyErr_CheckSignals()) PyTryBlock \
116+
if (_PyErr_CheckSignalsWithoutGC()) PyTryBlock \
117117
} while(0)
118118

119119
/* Normalize (remove leading zeros from) an int object.

Python/executor_cases.c.h

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/analyzer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,9 @@ def has_error_without_pop(op: parser.CodeDef) -> bool:
635635
"_PyLong_IsNegative",
636636
"_PyLong_IsNonNegativeCompact",
637637
"_PyLong_IsZero",
638+
"_PyLong_Add",
639+
"_PyLong_Multiply",
640+
"_PyLong_Subtract",
638641
"_PyManagedDictPointer_IsValues",
639642
"_PyObject_GC_IS_SHARED",
640643
"_PyObject_GC_IS_TRACKED",

0 commit comments

Comments
 (0)