Skip to content

Commit 3dfaab8

Browse files
committed
unsigned long long race
1 parent afe2504 commit 3dfaab8

File tree

6 files changed

+40
-3
lines changed

6 files changed

+40
-3
lines changed

Include/cpython/pyatomic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,10 @@ _Py_atomic_store_double_release(double *obj, double value);
529529
static inline void
530530
_Py_atomic_store_llong_release(long long *obj, long long value);
531531

532+
static inline void
533+
_Py_atomic_store_ullong_release(unsigned long long *obj,
534+
unsigned long long value);
535+
532536
static inline int
533537
_Py_atomic_load_int_acquire(const int *obj);
534538

Include/cpython/pyatomic_gcc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,11 @@ static inline void
576576
_Py_atomic_store_llong_release(long long *obj, long long value)
577577
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
578578

579+
static inline void
580+
_Py_atomic_store_ullong_release(unsigned long long *obj,
581+
unsigned long long value)
582+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
583+
579584
static inline void
580585
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
581586
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }

Include/cpython/pyatomic_msc.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,19 @@ _Py_atomic_store_llong_release(long long *obj, long long value)
11291129
#endif
11301130
}
11311131

1132+
static inline void
1133+
_Py_atomic_store_ullong_release(unsigned long long *obj, unsigned long long value)
1134+
{
1135+
#if defined(_M_X64) || defined(_M_IX86)
1136+
*(unsigned long long volatile *)obj = value;
1137+
#elif defined(_M_ARM64)
1138+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int128);
1139+
__stlr128((unsigned __int128 volatile *)obj, (unsigned __int128)value);
1140+
#else
1141+
# error "no implementation of _Py_atomic_store_ullong_release"
1142+
#endif
1143+
}
1144+
11321145
static inline void
11331146
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
11341147
{

Include/cpython/pyatomic_std.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,15 @@ _Py_atomic_store_llong_release(long long *obj, long long value)
10311031
memory_order_release);
10321032
}
10331033

1034+
static inline void
1035+
_Py_atomic_store_ullong_release(unsigned long long *obj,
1036+
unsigned long long value)
1037+
{
1038+
_Py_USING_STD;
1039+
atomic_store_explicit((_Atomic(unsigned long long)*)obj, value,
1040+
memory_order_release);
1041+
}
1042+
10341043
static inline void
10351044
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
10361045
{

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ extern "C" {
105105
_Py_atomic_store_llong_release(&value, new_value)
106106
#define FT_ATOMIC_LOAD_LLONG_RELAXED(value) \
107107
_Py_atomic_load_llong_relaxed(&value)
108+
#define FT_ATOMIC_STORE_ULLONG_RELEASE(value, new_value) \
109+
_Py_atomic_store_ullong_release(&value, new_value)
110+
#define FT_ATOMIC_LOAD_ULLONG_RELAXED(value) \
111+
_Py_atomic_load_ullong_relaxed(&value)
108112

109113
#else
110114
#define FT_ATOMIC_LOAD_PTR(value) value
@@ -150,6 +154,8 @@ extern "C" {
150154
#define FT_ATOMIC_STORE_DOUBLE_RELEASE(value, new_value) value = new_value
151155
#define FT_ATOMIC_LOAD_LLONG_RELAXED(value) value
152156
#define FT_ATOMIC_STORE_LLONG_RELEASE(value, new_value) value = new_value
157+
#define FT_ATOMIC_LOAD_ULLONG_RELAXED(value) value
158+
#define FT_ATOMIC_STORE_ULLONG_RELEASE(value, new_value) value = new_value
153159

154160
#endif
155161

Python/structmember.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l)
110110
v = PyLong_FromLongLong(FT_ATOMIC_LOAD_LLONG_RELAXED(*(long long *)addr));
111111
break;
112112
case Py_T_ULONGLONG:
113-
v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr);
113+
v = PyLong_FromUnsignedLongLong(FT_ATOMIC_LOAD_ULLONG_RELAXED(*(unsigned long long *)addr));
114114
break;
115115
case _Py_T_NONE:
116116
// doesn't require free-threading code path
@@ -346,7 +346,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
346346
if (long_val == -1 && PyErr_Occurred()) {
347347
return -1;
348348
}
349-
*(unsigned long long *)addr = (unsigned long long)(long long)long_val;
349+
FT_ATOMIC_STORE_ULLONG_RELEASE(*(unsigned long long *)addr, (unsigned long long)(long long)long_val);
350350
WARN("Writing negative value into unsigned field");
351351
}
352352
else {
@@ -355,7 +355,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
355355
if (ulonglong_val == (unsigned long long)-1 && PyErr_Occurred()) {
356356
return -1;
357357
}
358-
*(unsigned long long*)addr = ulonglong_val;
358+
FT_ATOMIC_STORE_ULLONG_RELEASE(*(unsigned long long *)addr, ulonglong_val);
359359
}
360360
break;
361361
}

0 commit comments

Comments
 (0)