diff --git a/quaddtype/numpy_quaddtype/src/quaddtype_main.c b/quaddtype/numpy_quaddtype/src/quaddtype_main.c index e91016b0..6d68c5af 100644 --- a/quaddtype/numpy_quaddtype/src/quaddtype_main.c +++ b/quaddtype/numpy_quaddtype/src/quaddtype_main.c @@ -31,16 +31,25 @@ py_is_longdouble_128(PyObject *self, PyObject *args) } #ifdef SLEEF_QUAD_C -// Native __float128 support static const Sleef_quad SMALLEST_SUBNORMAL_VALUE = SLEEF_QUAD_DENORM_MIN; #else -// Use static union for thread-safe initialization +// Use the exact same struct layout as the original buggy code static const union { struct { +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + uint64_t h, l; +#else uint64_t l, h; +#endif } parts; Sleef_quad value; -} smallest_subnormal_const = {.parts = {.l = 0x0000000000000001ULL, .h = 0x0000000000000000ULL}}; +} smallest_subnormal_const = {.parts = { +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + .h = 0x0000000000000000ULL, .l = 0x0000000000000001ULL +#else + .l = 0x0000000000000001ULL, .h = 0x0000000000000000ULL +#endif + }}; #define SMALLEST_SUBNORMAL_VALUE (smallest_subnormal_const.value) #endif diff --git a/quaddtype/numpy_quaddtype/src/scalar.c b/quaddtype/numpy_quaddtype/src/scalar.c index 6c2e4b51..07b18bf0 100644 --- a/quaddtype/numpy_quaddtype/src/scalar.c +++ b/quaddtype/numpy_quaddtype/src/scalar.c @@ -15,10 +15,22 @@ #include "scalar_ops.h" #include "dragon4.h" +#ifdef Py_GIL_DISABLED +static PyMutex scalar_mutex = {0}; +#endif + QuadPrecisionObject * QuadPrecision_raw_new(QuadBackendType backend) { - QuadPrecisionObject *new = PyObject_New(QuadPrecisionObject, &QuadPrecision_Type); + QuadPrecisionObject *new; +#ifdef Py_GIL_DISABLED + PyMutex_Lock(&scalar_mutex); +#endif + new = PyObject_New(QuadPrecisionObject, &QuadPrecision_Type); +#ifdef Py_GIL_DISABLED + PyMutex_Unlock(&scalar_mutex); +#endif + if (!new) return NULL; new->backend = backend; @@ -184,6 +196,9 @@ QuadPrecision_str(QuadPrecisionObject *self) static PyObject * QuadPrecision_repr(QuadPrecisionObject *self) { +#ifdef Py_GIL_DISABLED + PyMutex_Lock(&scalar_mutex); +#endif PyObject *str = QuadPrecision_str(self); if (str == NULL) { return NULL; @@ -191,12 +206,18 @@ QuadPrecision_repr(QuadPrecisionObject *self) const char *backend_str = (self->backend == BACKEND_SLEEF) ? "sleef" : "longdouble"; PyObject *res = PyUnicode_FromFormat("QuadPrecision('%S', backend='%s')", str, backend_str); Py_DECREF(str); +#ifdef Py_GIL_DISABLED + PyMutex_Unlock(&scalar_mutex); +#endif return res; } static PyObject * QuadPrecision_repr_dragon4(QuadPrecisionObject *self) { +#ifdef Py_GIL_DISABLED + PyMutex_Lock(&scalar_mutex); +#endif Dragon4_Options opt = {.scientific = 1, .digit_mode = DigitMode_Unique, .cutoff_mode = CutoffMode_TotalLength, @@ -226,6 +247,9 @@ QuadPrecision_repr_dragon4(QuadPrecisionObject *self) const char *backend_str = (self->backend == BACKEND_SLEEF) ? "sleef" : "longdouble"; PyObject *res = PyUnicode_FromFormat("QuadPrecision('%S', backend='%s')", str, backend_str); Py_DECREF(str); +#ifdef Py_GIL_DISABLED + PyMutex_Unlock(&scalar_mutex); +#endif return res; }