Skip to content

Commit afe2504

Browse files
committed
signed long long race
1 parent bce02d0 commit afe2504

File tree

6 files changed

+58
-3
lines changed

6 files changed

+58
-3
lines changed

Include/cpython/pyatomic.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ _Py_atomic_load_long_relaxed(const long *obj);
339339
static inline double
340340
_Py_atomic_load_double_relaxed(const double *obj);
341341

342+
static inline long long
343+
_Py_atomic_load_llong_relaxed(const long long *obj);
344+
342345
static inline int8_t
343346
_Py_atomic_load_int8_relaxed(const int8_t *obj);
344347

@@ -523,6 +526,9 @@ _Py_atomic_store_float_release(float *obj, float value);
523526
static inline void
524527
_Py_atomic_store_double_release(double *obj, double value);
525528

529+
static inline void
530+
_Py_atomic_store_llong_release(long long *obj, long long value);
531+
526532
static inline int
527533
_Py_atomic_load_int_acquire(const int *obj);
528534

Include/cpython/pyatomic_gcc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,10 @@ static inline unsigned long long
390390
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
391391
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
392392

393+
static inline long long
394+
_Py_atomic_load_llong_relaxed(const long long *obj)
395+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
396+
393397

394398
// --- _Py_atomic_store ------------------------------------------------------
395399

@@ -568,6 +572,10 @@ static inline void
568572
_Py_atomic_store_double_release(double *obj, double value)
569573
{ __atomic_store(obj, &value, __ATOMIC_RELEASE); }
570574

575+
static inline void
576+
_Py_atomic_store_llong_release(long long *obj, long long value)
577+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
578+
571579
static inline void
572580
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
573581
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }

Include/cpython/pyatomic_msc.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,12 @@ _Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
760760
return *(volatile unsigned long long *)obj;
761761
}
762762

763+
static inline long long
764+
_Py_atomic_load_llong_relaxed(const long long *obj)
765+
{
766+
return *(volatile long long *)obj;
767+
}
768+
763769

764770
// --- _Py_atomic_store ------------------------------------------------------
765771

@@ -1110,6 +1116,19 @@ _Py_atomic_store_double_release(double *obj, double value)
11101116
#endif
11111117
}
11121118

1119+
static inline void
1120+
_Py_atomic_store_llong_release(long long *obj, long long value)
1121+
{
1122+
#if defined(_M_X64) || defined(_M_IX86)
1123+
*(long long volatile *)obj = value;
1124+
#elif defined(_M_ARM64)
1125+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int128);
1126+
__stlr128((unsigned __int128 volatile *)obj, (unsigned __int128)value);
1127+
#else
1128+
# error "no implementation of _Py_atomic_store_llong_release"
1129+
#endif
1130+
}
1131+
11131132
static inline void
11141133
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
11151134
{

Include/cpython/pyatomic_std.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,14 @@ _Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
683683
memory_order_relaxed);
684684
}
685685

686+
static inline long long
687+
_Py_atomic_load_llong_relaxed(const long long *obj)
688+
{
689+
_Py_USING_STD;
690+
return atomic_load_explicit((const _Atomic(long long)*)obj,
691+
memory_order_relaxed);
692+
}
693+
686694

687695
// --- _Py_atomic_store ------------------------------------------------------
688696

@@ -1015,6 +1023,14 @@ _Py_atomic_store_double_release(double *obj, double value)
10151023
memory_order_release);
10161024
}
10171025

1026+
static inline void
1027+
_Py_atomic_store_llong_release(long long *obj, long long value)
1028+
{
1029+
_Py_USING_STD;
1030+
atomic_store_explicit((_Atomic(long long)*)obj, value,
1031+
memory_order_release);
1032+
}
1033+
10181034
static inline void
10191035
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
10201036
{

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ extern "C" {
101101
_Py_atomic_store_double_release(&value, new_value)
102102
#define FT_ATOMIC_LOAD_DOUBLE_RELAXED(value) \
103103
_Py_atomic_load_double_relaxed(&value)
104+
#define FT_ATOMIC_STORE_LLONG_RELEASE(value, new_value) \
105+
_Py_atomic_store_llong_release(&value, new_value)
106+
#define FT_ATOMIC_LOAD_LLONG_RELAXED(value) \
107+
_Py_atomic_load_llong_relaxed(&value)
104108

105109
#else
106110
#define FT_ATOMIC_LOAD_PTR(value) value
@@ -144,6 +148,8 @@ extern "C" {
144148
#define FT_ATOMIC_STORE_FLOAT_RELEASE(value, new_value) value = new_value
145149
#define FT_ATOMIC_LOAD_DOUBLE_RELAXED(value) value
146150
#define FT_ATOMIC_STORE_DOUBLE_RELEASE(value, new_value) value = new_value
151+
#define FT_ATOMIC_LOAD_LLONG_RELAXED(value) value
152+
#define FT_ATOMIC_STORE_LLONG_RELEASE(value, new_value) value = new_value
147153

148154
#endif
149155

Python/structmember.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l)
107107
#endif
108108
break;
109109
case Py_T_LONGLONG:
110-
v = PyLong_FromLongLong(*(long long *)addr);
110+
v = PyLong_FromLongLong(FT_ATOMIC_LOAD_LLONG_RELAXED(*(long long *)addr));
111111
break;
112112
case Py_T_ULONGLONG:
113113
v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr);
@@ -329,8 +329,8 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
329329
PyErr_SetString(PyExc_TypeError, "readonly attribute");
330330
return -1;
331331
case Py_T_LONGLONG:{
332-
long long value;
333-
*(long long*)addr = value = PyLong_AsLongLong(v);
332+
long long value = PyLong_AsLongLong(v);
333+
FT_ATOMIC_STORE_LLONG_RELEASE(*(long long*)addr, value);
334334
if ((value == -1) && PyErr_Occurred())
335335
return -1;
336336
break;

0 commit comments

Comments
 (0)