@@ -251,6 +251,39 @@ PyAPI_FUNC(void) _PyRWMutex_RUnlock(_PyRWMutex *rwmutex);
251251PyAPI_FUNC (void ) _PyRWMutex_Lock(_PyRWMutex *rwmutex);
252252PyAPI_FUNC (void ) _PyRWMutex_Unlock(_PyRWMutex *rwmutex);
253253
254+ // Similar to linux seqlock: https://en.wikipedia.org/wiki/Seqlock
255+ // We use a sequence number to lock the writer, an even sequence means we're unlocked, an odd
256+ // sequence means we're locked. Readers will read the sequence before attempting to read the
257+ // underlying data and then read the sequence number again after reading the data. If the
258+ // sequence has not changed the data is valid.
259+ //
260+ // Differs a little bit in that we use CAS on sequence as the lock, instead of a seperate spin lock.
261+ // The writer can also detect that the undelering data has not changed and abandon the write
262+ // and restore the previous sequence.
263+ typedef struct {
264+ uint32_t sequence;
265+ } _PySeqLock;
266+
267+ // Lock the sequence lock for the writer
268+ PyAPI_FUNC (void ) _PySeqLock_LockWrite(_PySeqLock *seqlock);
269+
270+ // Unlock the sequence lock and move to the next sequence number.
271+ PyAPI_FUNC (void ) _PySeqLock_UnlockWrite(_PySeqLock *seqlock);
272+
273+ // Abandon the current update indicating that no mutations have occured
274+ // and restore the previous sequence value.
275+ PyAPI_FUNC (void ) _PySeqLock_AbandonWrite(_PySeqLock *seqlock);
276+
277+ // Begin a read operation and return the current sequence number.
278+ PyAPI_FUNC (uint32_t ) _PySeqLock_BeginRead(_PySeqLock *seqlock);
279+
280+ // End the read operation and confirm that the sequence number has not changed.
281+ // Returns 1 if the read was successful or 0 if the read should be re-tried.
282+ PyAPI_FUNC (uint32_t ) _PySeqLock_EndRead(_PySeqLock *seqlock, uint32_t previous);
283+
284+ // Check if the lock was held during a fork and clear the lock. Returns 1
285+ // if the lock was held and any associated datat should be cleared.
286+ PyAPI_FUNC (uint32_t ) _PySeqLock_AfterFork(_PySeqLock *seqlock);
254287
255288#ifdef __cplusplus
256289}
0 commit comments