Skip to content

Commit 72b2023

Browse files
committed
lock init on py < 3.13
1 parent 9f95d21 commit 72b2023

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

quaddtype/numpy_quaddtype/src/scalar.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@
2222
// src: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
2323
#define SLEEF_QUAD_DECIMAL_DIG 36
2424

25+
#if PY_VERSION_HEX < 0x30d00b3
26+
static PyThread_type_lock sleef_lock;
27+
#define LOCK_SLEEF PyThread_acquire_lock(sleef_lock, WAIT_LOCK)
28+
#define UNLOCK_SLEEF PyThread_release_lock(sleef_lock)
29+
#else
30+
static PyMutex sleef_lock = {0};
31+
#define LOCK_SLEEF PyMutex_Lock(&sleef_lock)
32+
#define UNLOCK_SLEEF PyMutex_Unlock(&sleef_lock)
33+
#endif
34+
35+
36+
2537

2638
QuadPrecisionObject *
2739
QuadPrecision_raw_new(QuadBackendType backend)
@@ -422,13 +434,16 @@ QuadPrecision_is_integer(QuadPrecisionObject *self, PyObject *Py_UNUSED(ignored)
422434
}
423435
}
424436

425-
// this is thread-unsafe
426437
PyObject* quad_to_pylong(Sleef_quad value)
427438
{
428439
char buffer[128];
440+
441+
// Sleef_snprintf call is thread-unsafe
442+
// LOCK_SLEEF;
429443
// Format as integer (%.0Qf gives integer with no decimal places)
430444
// Q modifier means pass Sleef_quad by value
431445
int written = Sleef_snprintf(buffer, sizeof(buffer), "%.0Qf", value);
446+
// UNLOCK_SLEEF;
432447
if (written < 0 || written >= sizeof(buffer)) {
433448
PyErr_SetString(PyExc_RuntimeError, "Failed to convert quad to string");
434449
return NULL;
@@ -503,7 +518,6 @@ QuadPrecision_as_integer_ratio(QuadPrecisionObject *self, PyObject *Py_UNUSED(ig
503518
exponent--;
504519
}
505520

506-
507521
// numerator and denominators can't fit in int
508522
// convert items to PyLongObject from string instead
509523

@@ -587,6 +601,13 @@ PyTypeObject QuadPrecision_Type = {
587601
int
588602
init_quadprecision_scalar(void)
589603
{
604+
#if PY_VERSION_HEX < 0x30d00b3
605+
sleef_lock = PyThread_allocate_lock();
606+
if (sleef_lock == NULL) {
607+
PyErr_NoMemory();
608+
return -1;
609+
}
610+
#endif
590611
QuadPrecision_Type.tp_base = &PyFloatingArrType_Type;
591612
return PyType_Ready(&QuadPrecision_Type);
592613
}

quaddtype/tests/test_multithreading.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121

2222
def test_as_integer_ratio_reconstruction():
2323
"""Multi-threaded test that as_integer_ratio() can reconstruct the original value."""
24-
values = ["3.14", "0.1", "1.414213562373095", "2.718281828459045",
25-
"-1.23456789", "1000.001", "0.0001", "1e20", "1.23e15", "1e-30", pi]
2624

2725
def test(barrier):
2826
barrier.wait() # All threads start simultaneously
27+
values = ["3.14", "0.1", "1.414213562373095", "2.718281828459045",
28+
"-1.23456789", "1000.001", "0.0001", "1e20", "1.23e15", "1e-30", pi]
2929
for val in values:
3030
quad_val = QuadPrecision(val)
3131
num, denom = quad_val.as_integer_ratio()

0 commit comments

Comments
 (0)