Use int32_t for sequence lock · python/cpython@66ce5f5 · GitHub
Skip to content

Commit 66ce5f5

Browse files
committed
Use int32_t for sequence lock
Use atomic storage instead of exchange Use relaxed load when starting sequence lock for write Fix some formatting
1 parent 51a4b93 commit 66ce5f5

7 files changed

Lines changed: 50 additions & 24 deletions

File tree

Include/cpython/pyatomic.h

Lines changed: 3 additions & 0 deletions

Include/cpython/pyatomic_gcc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,9 @@ static inline int
495495
_Py_atomic_load_int_acquire(const int *obj)
496496
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
497497

498+
static inline uint32_t
499+
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
500+
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
498501

499502
// --- _Py_atomic_fence ------------------------------------------------------
500503

Include/cpython/pyatomic_msc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,17 @@ _Py_atomic_load_int_acquire(const int *obj)
938938
#endif
939939
}
940940

941+
static inline uint32_t
942+
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
943+
{
944+
#if defined(_M_X64) || defined(_M_IX86)
945+
return *(uint32_t volatile *)obj;
946+
#elif defined(_M_ARM64)
947+
return (int)__ldar32((uint32_t volatile *)obj);
948+
#else
949+
# error "no implementation of _Py_atomic_load_uint32_acquire"
950+
#endif
951+
}
941952

942953
// --- _Py_atomic_fence ------------------------------------------------------
943954

Include/cpython/pyatomic_std.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,13 @@ _Py_atomic_load_int_acquire(const int *obj)
870870
memory_order_acquire);
871871
}
872872

873+
static inline uint32_t
874+
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
875+
{
876+
_Py_USING_STD;
877+
return atomic_load_explicit((const _Atomic(uint32_t)*)obj,
878+
memory_order_acquire);
879+
}
873880

874881

875882
// --- _Py_atomic_fence ------------------------------------------------------

Include/internal/pycore_lock.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ PyAPI_FUNC(void) _PyRWMutex_Unlock(_PyRWMutex *rwmutex);
261261
// The writer can also detect that the undelering data has not changed and abandon the write
262262
// and restore the previous sequence.
263263
typedef struct {
264-
int sequence;
264+
uint32_t sequence;
265265
} _PySeqLock;
266266

267267
// Lock the sequence lock for the writer
@@ -275,15 +275,15 @@ PyAPI_FUNC(void) _PySeqLock_UnlockWrite(_PySeqLock *seqlock);
275275
PyAPI_FUNC(void) _PySeqLock_AbandonWrite(_PySeqLock *seqlock);
276276

277277
// Begin a read operation and return the current sequence number.
278-
PyAPI_FUNC(int) _PySeqLock_BeginRead(_PySeqLock *seqlock);
278+
PyAPI_FUNC(uint32_t) _PySeqLock_BeginRead(_PySeqLock *seqlock);
279279

280280
// End the read operation and confirm that the sequence number has not changed.
281281
// Returns 1 if the read was successful or 0 if the read should be re-tried.
282-
PyAPI_FUNC(int) _PySeqLock_EndRead(_PySeqLock *seqlock, int previous);
282+
PyAPI_FUNC(uint32_t) _PySeqLock_EndRead(_PySeqLock *seqlock, uint32_t previous);
283283

284284
// Check if the lock was held during a fork and clear the lock. Returns 1
285285
// if the lock was held and any associated datat should be cleared.
286-
PyAPI_FUNC(int) _PySeqLock_AfterFork(_PySeqLock *seqlock);
286+
PyAPI_FUNC(uint32_t) _PySeqLock_AfterFork(_PySeqLock *seqlock);
287287

288288
#ifdef __cplusplus
289289
}

Objects/typeobject.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ class object "PyObject *" "&PyBaseObject_Type"
6060
// in odd behaviors w.r.t. running with the GIL as the outer type lock could
6161
// be released and reacquired during a subclass update if there's contention
6262
// on the subclass lock.
63-
#define BEGIN_TYPE_LOCK() \
64-
{ \
65-
_PyCriticalSection _cs; \
66-
_PyCriticalSection_Begin(&_cs, &_PyRuntime.types.type_mutex); \
63+
#define BEGIN_TYPE_LOCK() \
64+
{ \
65+
_PyCriticalSection _cs; \
66+
_PyCriticalSection_Begin(&_cs, &_PyRuntime.types.type_mutex); \
6767

68-
#define END_TYPE_LOCK() \
69-
_PyCriticalSection_End(&_cs); \
68+
#define END_TYPE_LOCK() \
69+
_PyCriticalSection_End(&_cs); \
7070
}
7171

7272
#define ASSERT_TYPE_LOCK_HELD() \

Python/lock.c

Lines changed: 16 additions & 14 deletions

0 commit comments

Comments
 (0)