gh-120496: Use CAS approach for rangeiter_next by corona10 · Pull Request #120534 · python/cpython · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Include/cpython/pyatomic.h
13 changes: 13 additions & 0 deletions Include/cpython/pyatomic_gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ static inline int64_t
_Py_atomic_add_int64(int64_t *obj, int64_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }

static inline long
_Py_atomic_add_long(long *obj, long value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }

static inline intptr_t
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
Expand Down Expand Up @@ -90,6 +94,11 @@ _Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desir
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }

static inline int
_Py_atomic_compare_exchange_long(long *obj, long *expected, long desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }

static inline int
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
Expand Down Expand Up @@ -342,6 +351,10 @@ static inline uint64_t
_Py_atomic_load_uint64_relaxed(const uint64_t *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 uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
Expand Down
38 changes: 38 additions & 0 deletions Include/cpython/pyatomic_msc.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ _Py_atomic_add_int64(int64_t *obj, int64_t value)
#endif
}

static inline long
_Py_atomic_add_long(long *obj, long value)
{
#if defined(_M_X64) || defined(_M_ARM64)
_Py_atomic_ASSERT_ARG_TYPE(long);
return (long)_InterlockedExchangeAdd((volatile long *)obj, (long)value);
#else
long old_value = _Py_atomic_load_long_relaxed(obj);
for (;;) {
long new_value = old_value + value;
if (_Py_atomic_compare_exchange_long(obj, &old_value, new_value)) {
return old_value;
}
}
#endif
}


static inline uint8_t
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
Expand Down Expand Up @@ -187,6 +204,21 @@ _Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t value
return 0;
}

static inline int
_Py_atomic_compare_exchange_long(long *obj, long *expected, long value)
{
_Py_atomic_ASSERT_ARG_TYPE(long);
long initial = (long)_InterlockedCompareExchange(
(volatile long *)obj,
(long)value,
(long)*expected);
if (initial == *expected) {
return 1;
}
*expected = initial;
return 0;
}

static inline int
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *value)
{
Expand Down Expand Up @@ -688,6 +720,12 @@ _Py_atomic_load_uint64_relaxed(const uint64_t *obj)
return *(volatile uint64_t *)obj;
}

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

static inline uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
{
Expand Down
24 changes: 24 additions & 0 deletions Include/cpython/pyatomic_std.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ _Py_atomic_add_int64(int64_t *obj, int64_t value)
return atomic_fetch_add((_Atomic(int64_t)*)obj, value);
}

static inline long
_Py_atomic_add_long(long *obj, long value)
{
_Py_USING_STD;
return atomic_fetch_add((_Atomic(long)*)obj, value);
}

static inline intptr_t
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
{
Expand Down Expand Up @@ -154,6 +161,14 @@ _Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desir
expected, desired);
}

static inline int
_Py_atomic_compare_exchange_long(long *obj, long *expected, long desired)
{
_Py_USING_STD;
return atomic_compare_exchange_strong((_Atomic(long)*)obj,
expected, desired);
}

static inline int
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
{
Expand Down Expand Up @@ -587,6 +602,15 @@ _Py_atomic_load_uint64_relaxed(const uint64_t *obj)
memory_order_relaxed);
}

static inline long
_Py_atomic_load_long_relaxed(const long *obj)
{
_Py_USING_STD;
return atomic_load_explicit((const _Atomic(long)*)obj,
memory_order_relaxed);
}


static inline uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
{
Expand Down
16 changes: 16 additions & 0 deletions Objects/rangeobject.c