Skip to content

Commit 5b7b120

Browse files
eendebakptclaude
andcommitted
Check for signals every 32nd iteration and once per Karatsuba step
With the 64-row batch, Karatsuba base cases (36-70 rows) mostly never reached the check, so e.g. a 200k-digit product ran for seconds without handling a signal. A 32-row batch makes every substantial base case check, and k_mul() additionally checks once per recursion step. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 6a4fe1b commit 5b7b120

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

‎Objects/longobject.c‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ maybe_small_long(PyLongObject *v)
113113
*/
114114
#define HUGE_EXP_CUTOFF 60
115115

116-
/* Check for signals on every 64th iteration `i` of a loop. */
116+
/* Check for signals on every 32nd iteration `i` of a loop. */
117117
#define SIGCHECK(i, PyTryBlock) \
118118
do { \
119-
if ((((i) & 63) == 63) && PyErr_CheckSignals()) PyTryBlock \
119+
if ((((i) & 31) == 31) && PyErr_CheckSignals()) PyTryBlock \
120120
} while(0)
121121

122122
/* Normalize (remove leading zeros from) an int object.
@@ -4111,6 +4111,13 @@ k_mul(PyLongObject *a, PyLongObject *b)
41114111
return x_mul(a, b);
41124112
}
41134113

4114+
/* x_mul() only checks for signals every 32nd row and the base cases of
4115+
the recursion below can have fewer rows than that, so check here,
4116+
once per Karatsuba step. */
4117+
if (PyErr_CheckSignals()) {
4118+
return NULL;
4119+
}
4120+
41144121
/* If a is small compared to b, splitting on b gives a degenerate
41154122
* case with ah==0, and Karatsuba may be (even much) less efficient
41164123
* than "grade school" then. However, we can still win, by viewing

0 commit comments

Comments
 (0)