Skip to content

Commit

Permalink
Clean-up pyatomic_msc.h and add Py_BUILD_ASSERT
Browse files Browse the repository at this point in the history
  • Loading branch information
colesbury committed Aug 23, 2023
1 parent c5aec0d commit 21b6e2d
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions Include/cpython/pyatomic_msc.h
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
// This is the implementation of Python atomic operations for MSVC if the
// compiler does not support C11 or C++11 atomics.
//
// MSVC intrinsics are defined on char, short, long, __int64, and pointer
// types. Note that long and int are both 32-bits even on 64-bit Windows.

#ifndef Py_ATOMIC_MSC_H
# error "this header file must not be included directly"
#endif

#include <intrin.h>


static inline int
_Py_atomic_add_int(int *address, int value)
{
Py_BUILD_ASSERT(sizeof(int) == sizeof(long));
return (int)_InterlockedExchangeAdd((volatile long*)address, (long)value);
}

static inline int8_t
_Py_atomic_add_int8(int8_t *address, int8_t value)
{
Py_BUILD_ASSERT(sizeof(int8_t) == sizeof(char));
return (int8_t)_InterlockedExchangeAdd8((volatile char*)address, (char)value);
}

static inline int16_t
_Py_atomic_add_int16(int16_t *address, int16_t value)
{
Py_BUILD_ASSERT(sizeof(int16_t) == sizeof(short));
return (int16_t)_InterlockedExchangeAdd16((volatile short*)address, (short)value);
}

static inline int32_t
_Py_atomic_add_int32(int32_t *address, int32_t value)
{
Py_BUILD_ASSERT(sizeof(int32_t) == sizeof(long));
return (int32_t)_InterlockedExchangeAdd((volatile long*)address, (long)value);
}

Expand All @@ -39,9 +45,9 @@ _Py_atomic_add_int64(int64_t *address, int64_t value)
return (int64_t)_InterlockedExchangeAdd64((volatile __int64*)address, (__int64)value);
#else
for (;;) {
__int64 old_value = *(volatile __int64*)address;
__int64 new_value = old_value + (__int64)value;
if (old_value == _InterlockedCompareExchange64((volatile __int64*)address, new_value, old_value)) {
int64_t old_value = *(volatile int64_t*)address;
int64_t new_value = old_value + value;
if (_Py_atomic_compare_exchange_int64(address, old_value, new_value)) {
return old_value;
}
}
Expand Down Expand Up @@ -228,9 +234,15 @@ _Py_atomic_exchange_int64(int64_t *address, int64_t value)
return (int64_t)_InterlockedExchange64((volatile __int64*)address, (__int64)value);
#else
for (;;) {
__int64 old_value = *(volatile __int64*)address;
__int64 new_value = (__int64)value;
if (old_value == _InterlockedCompareExchange64((volatile __int64*)address, new_value, old_value)) {
int64_t old_value = *(volatile int64_t*)address;
if (old_value == _Py_atomic_compare_exchange_int64(address, old_value, value)) {
return old_value;
}
}

for (;;) {
int64_t old_value = *(volatile int64_t*)address;
if (old_value == _Py_atomic_compare_exchange_int64(address, old_value, value)) {
return old_value;
}
}
Expand Down Expand Up @@ -322,7 +334,7 @@ _Py_atomic_and_uint64(uint64_t *address, uint64_t value)
for (;;) {
uint64_t old_value = *(volatile uint64_t*)address;
uint64_t new_value = old_value & value;
if ((__int64)old_value == _InterlockedCompareExchange64((volatile __int64*)address, (__int64)new_value, (__int64)old_value)) {
if (_Py_atomic_compare_exchange_uint64(address, old_value, new_value)) {
return old_value;
}
}
Expand Down Expand Up @@ -366,7 +378,7 @@ _Py_atomic_or_uint64(uint64_t *address, uint64_t value)
for (;;) {
uint64_t old_value = *(volatile uint64_t *)address;
uint64_t new_value = old_value | value;
if (old_value == _InterlockedCompareExchange64((volatile __int64*)address, (__int64)new_value, (__int64)old_value)) {
if (_Py_atomic_compare_exchange_uint64(address, old_value, new_value)) {
return old_value;
}
}
Expand Down

0 comments on commit 21b6e2d

Please sign in to comment.