Skip to content

Commit

Permalink
gh-117657: TSAN Fix races in PyMember_Get and PyMember_Set for C …
Browse files Browse the repository at this point in the history
…extensions (GH-123211)
  • Loading branch information
dpdani authored Dec 3, 2024
1 parent 84ff131 commit 979bf24
Show file tree
Hide file tree
Showing 10 changed files with 735 additions and 50 deletions.
45 changes: 45 additions & 0 deletions Include/cpython/pyatomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,27 @@ _Py_atomic_load_ptr(const void *obj);
static inline int
_Py_atomic_load_int_relaxed(const int *obj);

static inline char
_Py_atomic_load_char_relaxed(const char *obj);

static inline unsigned char
_Py_atomic_load_uchar_relaxed(const unsigned char *obj);

static inline short
_Py_atomic_load_short_relaxed(const short *obj);

static inline unsigned short
_Py_atomic_load_ushort_relaxed(const unsigned short *obj);

static inline long
_Py_atomic_load_long_relaxed(const long *obj);

static inline double
_Py_atomic_load_double_relaxed(const double *obj);

static inline long long
_Py_atomic_load_llong_relaxed(const long long *obj);

static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t *obj);

Expand Down Expand Up @@ -458,6 +479,30 @@ static inline void
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
unsigned long long value);

static inline void
_Py_atomic_store_char_relaxed(char *obj, char value);

static inline void
_Py_atomic_store_uchar_relaxed(unsigned char *obj, unsigned char value);

static inline void
_Py_atomic_store_short_relaxed(short *obj, short value);

static inline void
_Py_atomic_store_ushort_relaxed(unsigned short *obj, unsigned short value);

static inline void
_Py_atomic_store_long_relaxed(long *obj, long value);

static inline void
_Py_atomic_store_float_relaxed(float *obj, float value);

static inline void
_Py_atomic_store_double_relaxed(double *obj, double value);

static inline void
_Py_atomic_store_llong_relaxed(long long *obj, long long value);


// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------

Expand Down
64 changes: 64 additions & 0 deletions Include/cpython/pyatomic_gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,34 @@ static inline int
_Py_atomic_load_int_relaxed(const int *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline char
_Py_atomic_load_char_relaxed(const char *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline unsigned char
_Py_atomic_load_uchar_relaxed(const unsigned char *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline short
_Py_atomic_load_short_relaxed(const short *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline unsigned short
_Py_atomic_load_ushort_relaxed(const unsigned short *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline long
_Py_atomic_load_long_relaxed(const long *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline float
_Py_atomic_load_float_relaxed(const float *obj)
{ float ret; __atomic_load(obj, &ret, __ATOMIC_RELAXED); return ret; }

static inline double
_Py_atomic_load_double_relaxed(const double *obj)
{ double ret; __atomic_load(obj, &ret, __ATOMIC_RELAXED); return ret; }

static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
Expand Down Expand Up @@ -362,6 +390,10 @@ static inline unsigned long long
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }

static inline long long
_Py_atomic_load_llong_relaxed(const long long *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }


// --- _Py_atomic_store ------------------------------------------------------

Expand Down Expand Up @@ -485,6 +517,38 @@ _Py_atomic_store_ullong_relaxed(unsigned long long *obj,
unsigned long long value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_char_relaxed(char *obj, char value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }

static inline void
_Py_atomic_store_uchar_relaxed(unsigned char *obj, unsigned char value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_short_relaxed(short *obj, short value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_ushort_relaxed(unsigned short *obj, unsigned short value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_long_relaxed(long *obj, long value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_float_relaxed(float *obj, float value)
{ __atomic_store(obj, &value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_double_relaxed(double *obj, double value)
{ __atomic_store(obj, &value, __ATOMIC_RELAXED); }

static inline void
_Py_atomic_store_llong_relaxed(long long *obj, long long value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }


// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------

Expand Down
102 changes: 102 additions & 0 deletions Include/cpython/pyatomic_msc.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,48 @@ _Py_atomic_load_int_relaxed(const int *obj)
return *(volatile int *)obj;
}

static inline char
_Py_atomic_load_char_relaxed(const char *obj)
{
return *(volatile char *)obj;
}

static inline unsigned char
_Py_atomic_load_uchar_relaxed(const unsigned char *obj)
{
return *(volatile unsigned char *)obj;
}

static inline short
_Py_atomic_load_short_relaxed(const short *obj)
{
return *(volatile short *)obj;
}

static inline unsigned short
_Py_atomic_load_ushort_relaxed(const unsigned short *obj)
{
return *(volatile unsigned short *)obj;
}

static inline long
_Py_atomic_load_long_relaxed(const long *obj)
{
return *(volatile long *)obj;
}

static inline float
_Py_atomic_load_float_relaxed(const float *obj)
{
return *(volatile float *)obj;
}

static inline double
_Py_atomic_load_double_relaxed(const double *obj)
{
return *(volatile double *)obj;
}

static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t *obj)
{
Expand Down Expand Up @@ -718,6 +760,12 @@ _Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
return *(volatile unsigned long long *)obj;
}

static inline long long
_Py_atomic_load_llong_relaxed(const long long *obj)
{
return *(volatile long long *)obj;
}


// --- _Py_atomic_store ------------------------------------------------------

Expand Down Expand Up @@ -899,6 +947,60 @@ _Py_atomic_store_ullong_relaxed(unsigned long long *obj,
*(volatile unsigned long long *)obj = value;
}

static inline void
_Py_atomic_store_char_relaxed(char *obj, char value)
{
*(volatile char *)obj = value;
}

static inline void
_Py_atomic_store_uchar_relaxed(unsigned char *obj, unsigned char value)
{
*(volatile unsigned char *)obj = value;
}

static inline void
_Py_atomic_store_short_relaxed(short *obj, short value)
{
*(volatile short *)obj = value;
}

static inline void
_Py_atomic_store_ushort_relaxed(unsigned short *obj, unsigned short value)
{
*(volatile unsigned short *)obj = value;
}

static inline void
_Py_atomic_store_uint_release(unsigned int *obj, unsigned int value)
{
*(volatile unsigned int *)obj = value;
}

static inline void
_Py_atomic_store_long_relaxed(long *obj, long value)
{
*(volatile long *)obj = value;
}

static inline void
_Py_atomic_store_float_relaxed(float *obj, float value)
{
*(volatile float *)obj = value;
}

static inline void
_Py_atomic_store_double_relaxed(double *obj, double value)
{
*(volatile double *)obj = value;
}

static inline void
_Py_atomic_store_llong_relaxed(long long *obj, long long value)
{
*(volatile long long *)obj = value;
}


// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------

Expand Down
Loading

0 comments on commit 979bf24

Please sign in to comment.