Skip to content

Glossary

Terms used in concurrent C programming and free-threaded CPython. Synonyms and related API names are grouped together; links point to explanations in the primer. General computing vocabulary and routine C API names are omitted. Internal CPython mechanisms described here are not general public extension APIs.

A

ABA problem

A value changes from A to B and back to A, hiding the intervening changes from value-only comparison. Address reuse and counter wraparound can cause ABA. See ABA and generation counters.

Acquire ordering

Ordering that constrains accesses after an acquire operation. An acquire that reads from a release or its release sequence can synchronize with that release, ordering the releasing thread's earlier accesses before the acquiring thread's later accesses. An acquire load uses memory_order_acquire; successful mutex acquisition also supplies acquire ordering. See acquire and synchronizes-with.

Acquire-release ordering

Ordering for an atomic read-modify-write operation that combines acquire and release effects. In C, it is selected with memory_order_acq_rel. See acquire-release.

Address reuse

Allocating a new object at an address previously occupied by another object. The address does not preserve the old object's identity or lifetime. See ABA and allocator reuse.

Allocator page retention

CPython's use of QSBR to delay reuse of selected empty mimalloc pages for another size class or thread. Blocks can still be reused within the same size class and heap; retention preserves a required layout, not object identity. See allocator reuse.

As-if rule

The compiler's freedom to transform a C program while preserving the observable behavior required by the language. Source operations need not become identical machine operations. See compiler transformations.

Attached thread state

A PyThreadState attached to its executing native thread, permitting Python execution and most C API calls. Attachment requires the GIL when enabled; with it disabled, attachment does not imply exclusive execution. See thread-state contracts.

Atomic coherence

C memory-model constraints on how operations observe one atomic object's modification order. These constraints do not create a global order for all memory. See modification order and versioned snapshot proof.

Atomic exchange

An atomic read-modify-write operation that replaces a value and returns the old value. See exchange.

Atomic fence

An ordering operation that does not itself load or store the communicated value. Synchronization through fences still requires suitable atomic accesses. A C fence need not correspond to a separate CPU fence instruction. See fences.

Atomic load

An indivisible read of an atomic object's value. It does not guarantee the latest stored value or that the observed value remains current. See loads and stores.

Atomic object

An object accessed using atomic operations. C11 atomic types, such as atomic_int and atomic_uint, provide atomic semantics even for ordinary-looking expressions; CPython's atomic helpers instead operate on ordinary C fields that must consistently follow their access protocol. See atomic access requirements.

Atomic operation / atomicity

An operation that is indivisible under the applicable memory-model rules. Atomicity does not itself order accesses to other objects, combine several operations into one transaction, guarantee lock-free progress, or protect lifetime. See atomicity versus ordering.

Atomic pointer

A pointer whose value is accessed atomically. Atomic pointer access does not protect the pointed-to object's contents or lifetime. See pointer versus target.

Atomic read-modify-write (RMW)

One indivisible operation that reads a value and writes an updated value. Exchange, successful compare-exchange, and fetch-add / fetch-subtract are examples. A separate atomic load and store are not one RMW. See read-modify-write.

Atomic store

An indivisible write to an atomic object. The write participates in that object's modification order. See loads and stores.

B

Backoff

Delaying retries to reduce contention. Exponential backoff increases the delay after repeated failures; bounded spinning limits active retries before changing strategy. Neither establishes a progress guarantee by itself. See CAS contention.

Batching

Combining updates to reduce shared lock acquisitions or shared atomic writes. It can reduce contention while delaying visibility or reclamation. See sharding and batching and QSBR sequence batching.

Biased reference counting

An internal free-threaded CPython mechanism that accounts separately for references handled by an object's owning thread and other threads. The owner can often update its local count without atomic read-modify-write operations. See concurrency-aware reference counting.

Blocking

Waiting for a resource or event instead of continuing execution. A blocking operation may depend on another thread making progress; CPython mutex waits can also detach the thread state and suspend active critical sections. See mutex waiting and progress guarantees.

Borrowed reference / borrowed pointer

A reference or pointer that does not itself keep its target alive. A Python borrowed reference gives the caller no owned reference to release. Safe use requires a race-free lookup and separate lifetime protection throughout use. See borrowed references.

C

C abstract machine

The execution model defined by the C standard. Correct concurrent C code must satisfy this model, not merely behave as expected on one processor. See the compiler and the abstract machine.

C memory model

The C language rules governing memory accesses, atomicity, ordering between threads, and data races. Compilers and hardware implementations must implement these guarantees for valid programs. See the C memory model.

C11 atomics

The atomic types, operations, and memory-order constants provided through <stdatomic.h>, used in the primer's C11/C17 examples. CPython interpreter code uses its internal atomic helper layer instead. See atomic APIs.

Cache coherence

Hardware coordination that keeps cached copies of memory consistent across cores. It does not replace C synchronization or impose one order on accesses to different memory locations. See cache coherence.

Cache line

The unit of memory transferred and tracked by processor caches for coherence. Independent fields on the same line can interfere when threads write them. See cache-line granularity.

Cache-line bouncing

Repeated movement of writable cache-line ownership between cores. The resulting cache-coherence traffic can limit scaling even for relaxed atomic operations. See contended writes.

Caller-held lock / locked-helper convention

A function contract requiring the caller to hold the lock protecting its state. The helper does not acquire that lock again. The contract must also account for calls that could suspend a CPython critical section. See locking ownership and nonrecursive PyMutex.

CAS loop

A retry loop that reads a value, computes an update, and attempts compare-exchange. It must handle interference, retry cleanup, and possibly spurious failure. See CAS updates.

Check-then-act race

A race condition in which another operation changes state between checking a condition and acting on it. Individually synchronized accesses do not protect the combined operation. See race conditions.

Compare-exchange / compare-and-swap (CAS)

An atomic conditional update that stores a desired value only if the current value equals an expected value. C's compare-exchange interface updates the expected value on failure. Weak compare-exchange may fail spuriously; strong compare-exchange does not. See compare-exchange.

Compound operation / logical operation

Related checks and updates that implement one logical action. Synchronization must cover the complete action when interference between its steps would be incorrect. See shared-state invariants and compound container operations.

Concurrency

Execution in which operations overlap, even if threads do not execute at the same instant. Parallelism means execution at the same time. See shared mutable memory.

Condition variable

A synchronization primitive for waiting until protected state changes. Waiting atomically releases the associated mutex and reacquires it before returning. The waiter must recheck its predicate in a loop because wakeups do not guarantee that the condition holds. See condition variables.

Conflicting accesses

Accesses to the same C memory location where at least one access is a write. Across threads, conflicting accesses need atomic access or happens-before ordering to avoid a data race. See data races and memory locations.

Consume ordering

The dependency-based atomic ordering specified by memory_order_consume in C11/C17. It is excluded from the primer's simplified happens-before explanation; the publication examples use acquire ordering instead. See the primer's ordering model.

Contention

Competition between threads for a lock or shared resource, including a writable cache line. It can cause waiting, retries, and serialization. See contended writes and mutex paths.

Continuous lock ownership

Holding a lock without releasing it throughout an operation. Direct mutex locking provides this until explicit unlock; CPython critical sections may release their locks during suspension. See direct mutex versus critical section.

CPython critical section

A suspendable locking scope managed by CPython over one or two object locks or explicit mutexes. It protects state while its locks are held, but detachment can release them temporarily. These APIs lock in a free-threaded build, even with the GIL re-enabled, and are no-ops in the default build. See critical-section semantics and build contract.

Critical section

Conventionally, a region of code protected by exclusive locking from entry to exit. A CPython critical section differs because it can be suspended. See CPython's distinction and mutex protection.

Critical-section stack

Per-thread bookkeeping in PyThreadState tracking active and suspended CPython critical sections. It allows the runtime to release and resume their locks; lexical nesting does not guarantee all enclosing locks remain held. See the per-thread stack.

Cyclic garbage collection

Collection of unreachable objects whose references form cycles. Free-threaded CPython uses stop-the-world coordination for parts of this work; reference counting and QSBR serve different purposes. See reference counting and GC and GC does not prove a pause.

D

Data race

Conflicting accesses by different threads, with at least one non-atomic access, that are not ordered by happens-before. A C data race causes undefined behavior, not merely an unexpected or stale value. It differs from a logical race condition. See data race versus race condition and C undefined behavior.

Deadlock

A situation in which execution cannot proceed because required resources or progress cannot become available, often due to a cycle of waits. Reacquiring a nonrecursive mutex in its owning thread can also deadlock. See lock ordering and stop-the-world lock hazards.

Deferred reference counting

An internal CPython mechanism that accounts for selected references later rather than updating reference counts on every interpreter-stack operation. It is not the same as queuing a delayed decref for QSBR. See reference-counting mechanisms.

Delayed decref

A queued release of an existing strong reference after covered readers are safe. It does not acquire a new reference. Processing the release can run deallocation code and must occur in an appropriate execution context. See delayed frees and decrefs.

Delayed-work list

CPython's internal queue of retired allocations and owned references awaiting QSBR goals. Processing eligible work is separate from reporting a quiescent state. See retirement sequence and delayed-work processing.

Detached thread state / detachment

A detached PyThreadState does not permit Python execution or most C API calls. Detachment releases the GIL if held, suspends active CPython critical sections, and marks the thread's QSBR entry offline. The native thread can still run and access independently synchronized C state. See thread-state contracts, critical-section detachment, and QSBR transitions.

Direct field access

Reading or writing a C structure field without the synchronization and lifetime handling supplied by an API function. Some accessor macros also do this and may be unsafe during concurrent mutation. See API synchronization bypass.

Direct mutex locking

Explicit acquisition and release, such as PyMutex_Lock() and PyMutex_Unlock(), without CPython critical-section management. A directly held lock is not released by critical-section suspension. See choosing direct locking.

Double-width CAS

Compare-exchange that atomically compares and updates a double-width value, such as a pointer and generation counter together. Platform support and lock-free behavior vary; CPython's atomic helper family does not provide this operation. See ABA defenses.

E–F

Epoch-based reclamation

A lifetime protocol in which readers announce participation in generations called epochs. Retired objects wait until every reader that could still use them has left its region or advanced sufficiently. See epoch-based reclamation.

Eval-breaker

CPython's mechanism for handling pending runtime events at evaluation-loop checks. Its handler also processes delayed work, but quiescent-state reporting does not require a pending event. See quiescent reports and delayed processing.

Event

A notification primitive that commonly retains a Boolean state until explicitly cleared. Unlike a condition-variable notification, it can record a notification before a waiter arrives. Ordering guarantees depend on the implementation. See events.

Fairness

A guarantee about competing threads' opportunities to proceed, such as bounded waiting or arrival-order service. Mutual exclusion and lock-free progress do not by themselves guarantee fairness. See fairness and starvation.

False sharing

Performance interference between threads accessing distinct data on one cache line when at least one writes. The data need not be logically shared or have a data race. Padding can separate fields onto different lines at a memory cost. See cache-line granularity.

Fast path / parked path

A mutex's short uncontended acquisition path versus a contended path that may spin and put the thread to sleep. PyMutex detaches an attached thread state when parking, not on an uncontended fast-path acquisition. See PyMutex implementation paths.

Finalizer / destructor

Code run during object cleanup, potentially acquiring locks, invoking Python, or reentering related code. Reaching a grace period does not by itself provide a safe context to execute this code. See reclamation versus destruction and callbacks during a pause.

Free-threaded build

A CPython build configured with Py_GIL_DISABLED that supports execution without the GIL. The GIL can still be enabled at runtime; this does not change compiled object layouts, critical-section behavior, or build-selected atomic wrappers. See build versus runtime GIL.

G–H

GC state

CPython's bookkeeping for cyclic garbage collection, which can change even for an immutable Python object. The gc.collecting flag means collection is in progress, not that threads are stopped; world_stopped describes a completed pause in a particular scope. See mutable object bookkeeping and GC versus pause state.

Generation counter / version counter

A change marker used to distinguish occurrences of a value or validate a snapshot. The counter and described state must follow one update protocol; wraparound must not make an old observation appear current. See ABA counters, versioned reads, and invariants before suspension.

GIL (global interpreter lock)

The lock that serializes attached Python execution when enabled. It protects only accesses following its rules, not arbitrary detached or native-thread accesses. Multiple attached threads can execute with it disabled. See traditional GIL behavior and replacing GIL assumptions.

GIL-enabled build / default build

CPython's conventional build without Py_GIL_DISABLED, in which attachment requires the interpreter's GIL. It differs from a free-threaded build whose GIL has merely been re-enabled at runtime. See build distinctions and critical-section build contract.

Global exclusion

Preventing competing accesses across a defined interpreter or runtime scope. A stop-the-world pause excludes affected accesses requiring attachment, not all native-thread accesses in the process. See pause exclusion scope.

Goal sequence

The QSBR progress marker assigned to a retired allocation or reference. CPython can reclaim it once the minimum relevant reader sequence reaches the goal. See QSBR sequence tracking.

Grace period

The interval after removal until every covered reader that could have observed the old object has passed a point where it can no longer use it. Its completion rule depends on the reclamation protocol, not elapsed time alone. See grace periods.

Happens-before

The C memory-model relation used to order conflicting accesses. In this primer's model, which excludes dependency-based consume ordering, it is the transitive combination of sequenced-before and synchronizes-with. It is not wall-clock order. See happens-before.

Hardware atomicity

Indivisibility of a hardware access, such as an aligned load or store supported by a processor. It does not make an ordinary C access atomic in the language model. See hardware versus C atomicity.

Hardware memory model

An architecture's rules for ordering and observing memory accesses. Compilers must select instructions implementing C's guarantees on that architecture; hardware ordering cannot legalize a C data race. See compiler and hardware layers and architecture differences.

Hash cache

Lazily filled runtime storage of an object's computed hash. It illustrates how an immutable Python value can still have mutable C bookkeeping requiring atomic access or other synchronization. See shared mutable memory.

Hazard pointer

A shared slot where a reader publishes the particular object it intends to access. Publication, validation, and reclaimer scanning must follow a protocol that prevents freeing the object during protected use. See hazard pointers.

Helping protocol

A protocol allowing other threads to complete an operation described by shared metadata. Ownership, ordering, and failed-attempt cleanup must be explicit. See multi-field commit mechanisms.

I–L

Immortal object

A Python object whose lifetime does not depend on ordinary reference-count updates. Immortality avoids those updates; it does not make mutable contents safe to access concurrently. See reference-counting mechanisms.

Immutable state / immutable snapshot

State that does not change after safe publication. An immutable snapshot or immutable descriptor can represent related fields together, but readers still need ordering and lifetime protection. A Python value's immutability does not imply that every byte of its C representation is immutable. See snapshots and multi-field state.

Interpreter finalization

Shutdown of an interpreter and its runtime state. Attachment and delayed reclamation have special finalization behavior; a thread must not assume it can reattach normally once shutdown begins. See attachment lifecycle and finalization reclamation.

Interpreter-wide pause

A stop-the-world pause coordinating thread states belonging to one interpreter, not every native thread in the process. See pause scopes.

Invariant

A condition or relationship that shared state must satisfy whenever competing operations can observe it. Synchronization must protect the complete update, and CPython critical sections must restore invariants before possible suspension. See protecting invariants and suspension boundaries.

Linearizability

The guarantee that each completed operation appears to take effect at one instant between its call and return. The resulting order respects the real-time order of non-overlapping operations. See linearization.

Linearization point

The conceptual instant when a concurrent operation takes effect. A successful CAS is often that point; identifying it does not alone prove ordering or lifetime safety. See linearization points.

Lock-free

A system-wide progress guarantee: some operation completes after finitely many steps while threads continue taking steps under the algorithm's assumptions. An individual operation may starve. Avoiding an explicit mutex is not sufficient, and atomic implementations can themselves use internal locks; C's atomic_is_lock_free() checks the latter property for an atomic object. See progress guarantees.

Lock order

A consistent rule for acquiring multiple locks to avoid circular waits. Every competing path, including callbacks, must follow compatible rules. See multiple mutexes and PyMutex lock order.

Logical removal / retirement

Making an object or allocation unreachable to new operations while existing readers may still use it. A retired allocation or retired-list entry awaits safe physical reclamation. See removal versus reclamation and CPython retirement.

M–O

Memory location

In C, a scalar object or a maximal sequence of adjacent non-zero-width bit-fields. Adjacent bit-fields can therefore share one location; a zero-width bit-field separates such sequences. Data-race rules apply to memory locations, not arbitrary source-level field names. See memory locations.

Memory ordering / memory order

Constraints on how memory accesses are ordered and observed. An atomic operation's memory order determines its guarantees for other accesses; atomicity and ordering are separate properties. See atomicity and ordering and memory-order choices.

Memory retention

Keeping retired objects or storage allocated because reclamation is not yet safe. A stalled reader can increase retention without preventing logical updates. See stalled readers and CPython QSBR retention.

Modification order

The total order of all modifications to one atomic object. It does not by itself order changes to different objects or provide a multi-field snapshot. See modification order.

Module state / per-interpreter state

Extension data associated with one module or interpreter. Separating state by interpreter does not make it private to a thread; threads attached to that interpreter can still access it concurrently. See shared extension state.

Mutual exclusion

Preventing competing operations from accessing protected state at the same time. A lock supplies this only to operations following the same locking protocol. See mutex guarantees.

Mutex

A mutual-exclusion lock held by one thread at a time. Unlock and a subsequent acquisition of the same mutex also provide ordering for protected accesses. All conflicting accesses must follow the protection rule. See mutex synchronization.

Mutex-backed critical section

A CPython critical section operating on explicit PyMutex pointers rather than Python object locks. Py_BEGIN_CRITICAL_SECTION_MUTEX and Py_BEGIN_CRITICAL_SECTION2_MUTEX retain suspension semantics and are no-ops in the default build, unlike direct PyMutex locking. See explicit-mutex variants.

Nonrecursive mutex / recursive mutex

A nonrecursive mutex does not permit repeated acquisition by its owning thread; the consequence depends on the interface. A recursive mutex permits repeated acquisition with matching releases. PyMutex is nonrecursive, and CPython critical-section recursive entry is not continuous recursive-mutex ownership. See locking ownership, PyMutex recursion, and critical-section recursive entry.

ob_mutex / per-object lock

The internal mutex associated with a free-threaded Python object. Ordinary extension code must acquire ob_mutex through critical sections, not direct mutex locking. It protects cooperating object operations, not every reachable object or every lock-free access path. See ob_mutex protocol and cooperating accesses.

Object lifetime / lifetime protection

The period during which an object exists and can be validly accessed, and the protocol keeping it valid throughout use. A safe pointer load or a lock protecting that load does not automatically keep the target alive after unlocking. See pointer and lifetime and lifetime after unlock.

Obstruction-free

A progress guarantee that an operation completes if it eventually runs without interference from other threads. See progress guarantees.

Optimistic read / tentative read

A read that collects a tentative result, validates it against concurrent changes, and retries if needed. Every tentative access must already be legal and lifetime-safe; later validation cannot repair a C data race or use-after-free. See optimistic operations and precise snapshot protocol.

Optimistic reference acquisition

Obtaining a strong reference from a shared pointer without first locking its container, then validating the pointer. CPython's internal _Py_TryIncrefCompare, _Py_XGetRef, and _Py_TryXGetRef require specialized writer, reference-count, and allocator protocols, including maybe-weakref state. They are not permission to increment an arbitrary stale pointer. See allocator and reference-acquisition protocol.

Ordinary memory access

A non-atomic read or write. Conflicting accesses across threads require happens-before ordering even when the hardware instruction is indivisible. See ordinary C data races.

Owned reference / strong reference

A Python reference that keeps an object alive and whose holder must eventually release or transfer it. It protects lifetime, not mutable contents. A safely acquired strong reference can allow use after a protecting lock is released. See reference ownership and lookup and lifetime after unlock.

Ownership rule

A contract defining who controls state or references and how ownership can be transferred. Single-thread ownership removes synchronization only while other threads cannot access that state. See private-state ownership and reference cleanup in optimistic code.

P

Parking-lot mechanism

CPython's internal mechanism for putting mutex waiters to sleep and waking them. Waiters are associated with the mutex's address, which must remain stable. An unlock can hand ownership directly to a waiter rather than let new arrivals acquire first. See fast and parked paths and stable address.

Pause latency

The cost of a stop-the-world pause, including waiting for affected threads to reach safe points, not just the work performed while stopped. See pause performance.

Per-thread state / thread-local state

State assigned separately to each thread, often using thread-local storage. It needs no synchronization only while no other thread accesses it; publishing a pointer can make it shared. See per-thread state.

Physical reclamation

Destroying an object, reusing its storage, or returning storage to the allocator once covered readers can no longer use it. Destruction can have execution-context requirements beyond lifetime safety. See removal and reclamation and destruction concerns.

Pointer lifetime

Restrictions on a saved pointer imposed by its target's lifetime. In strict C, the pointer becomes indeterminate when that lifetime ends; comparing or publishing it afterward also requires care, not just dereferencing it. See hazard-pointer C lifetime constraints.

Predicate

A condition computed from protected state that determines whether a waiter may proceed. Condition-variable waiters recheck it in a loop while holding the mutex. See condition-variable predicates.

Progress guarantee

A statement about which concurrent operations must complete under specified execution assumptions. The guarantee applies to the whole operation, including allocation, reclamation, and called functions, not just its CAS loop. See progress categories and complete algorithm proof.

Publication / safe publication

Making initialized state available to other threads with ordering that makes initialization visible. Release/acquire publication establishes this through a release and an acquire that observes it or its release sequence. Publication does not protect later mutation or extend lifetime. See publication example and reuse constraints.

Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS

Public macros delimiting a detached region, commonly around blocking native work. The region must not use APIs requiring attachment, even in a free-threaded build. Detachment can suspend critical sections and end QSBR pointer protection. See attachment rules and QSBR pointer scope.

Py_BEGIN_CRITICAL_SECTION / Py_END_CRITICAL_SECTION

Public macros delimiting a one-object CPython critical section. They create a lexical C block and must be paired without an early exit skipping the end. The low-level PyCriticalSection_Begin / PyCriticalSection_End functions provide corresponding paired entry and exit. See macro scope and cleanup.

Py_GIL_DISABLED

The compile-time macro identifying a free-threaded CPython build. It does not report whether the GIL is currently enabled at runtime. See build versus runtime configuration.

Py_mod_gil / Py_MOD_GIL_NOT_USED

The module-initialization slot and value by which a multi-phase extension declares support for execution without the GIL. Single-phase extensions can use PyUnstable_Module_SetGIL. The declaration does not itself synchronize extension state. See extension support declarations.

Py_atomic* helpers

CPython's internal portable atomic-operation family, operating on ordinary C fields. Unsuffixed operations are sequentially consistent; available suffixes select other orders. All competing accesses must follow the atomic protocol. See CPython atomic API.

_PyEval_StopTheWorld / _PyEval_StopTheWorldAll

Internal operations pausing thread states for one interpreter or all interpreters. The corresponding _PyEval_StartTheWorld / _PyEval_StartTheWorldAll restart must match the stop's scope on every exit path. These operations are no-ops in the default build. See pause scope.

_PyMem_FreeDelayed / _PyMem_ProcessDelayed

Internal helpers retiring raw storage and processing delayed work. Normal free-threaded processing waits for QSBR goals; it can also release queued strong references and thereby invoke arbitrary deallocation code. See delayed reclamation helpers.

_PyObject_XDecRefDelayed / _PyObject_XSetRefDelayed

Internal helpers delaying release of an existing reference, or replacing a pointer and delaying release of its old reference. The replacement helper takes ownership of the new reference and publishes it, but does not serialize competing writers. See delayed reference release.

PyMutex

CPython's public lightweight nonrecursive mutex type. It must be zero-initialized and must not be copied or moved after initialization. Direct locking works in both build configurations independently of the GIL. See PyMutex and stable address.

PyMutex_IsLocked

A diagnostic query reporting whether a mutex appears locked at one instant. It does not acquire ownership, identify the owner, or promise memory ordering. See diagnostic-only query.

PyMutex_Lock / PyMutex_Unlock

Public direct acquisition and release functions with acquire and release ordering. A parked acquisition temporarily detaches an attached thread state and reattaches before returning. A directly acquired lock must be released exactly once. See ordering, waiting, and unlock discipline.

PyThreadState

CPython's execution-state record for a thread in one interpreter. It tracks Python execution context and, in a free-threaded build, the critical-section stack and participation in runtime coordination. See attachment states and APIs.

Q–R

QSBR (quiescent-state-based reclamation)

A reclamation scheme in which participating threads report that they retain no protected pointers from earlier work. Retired storage or references can be reclaimed once all relevant threads have progressed sufficiently. CPython's implementation is internal, supplies lifetime protection only for covered readers, and does not itself provide publication ordering. See general QSBR, CPython QSBR, and ordering limitations.

Quiescent state / quiescent point

A point where a participating thread promises it no longer retains protected pointers from earlier work. Those pointers must not be used afterward without new lifetime protection. Being paused at an arbitrary instruction is insufficient. See the quiescent-state contract.

Race condition

A logical bug whose outcome depends on the interleaving of concurrent operations. It can occur even when every access is atomic or individually locked and no C data race exists. See race-condition distinction.

Raw storage / backing array

An allocation managed separately from Python object reference counting, such as a list's item-pointer array. Keeping the containing object alive does not keep its replaced internal storage alive. See QSBR and internal storage.

RCU (read-copy-update)

A family of techniques with defined read-side regions, replacement publication, and reclamation after a grace period covering old readers. Blocking and ordering rules vary by implementation. See RCU.

rd_seq / wr_seq

CPython's internal QSBR progress values: wr_seq is the interpreter's current write sequence; rd_seq tracks the minimum reported sequence of attached threads. Valid write sequences are odd, and a per-thread sequence of zero marks it offline. See sequence tracking.

Read-mostly data

Data read much more frequently than it is updated. Immutable snapshots and reclamation protocols can avoid shared metadata writes on every read. See read-mostly snapshots and QSBR use cases.

Read-side region

A defined interval in which a reader may obtain and use protected pointers. The protocol specifies entry, exit, ordering, blocking restrictions, and whether pointers may escape that region. See reader scopes.

Reacquisition

Acquiring a lock again after release or critical-section suspension. It orders access with intervening lock holders but does not restore the earlier state. See reacquisition and stale facts.

Reentrancy / recursive entry

Entering related code before an earlier invocation finishes, often through a callback or finalizer. Reentrancy can invalidate assumptions even with the GIL. Recursive CPython critical-section entry avoids self-deadlock but can release outer locks; it is not ordinary recursive-mutex ownership. See callback risks and recursive critical-section entry.

Reference acquisition

Obtaining an owned reference that keeps a Python object alive. The object must remain valid during acquisition; incrementing its count after an unprotected pointer load can be too late. See reference-acquisition race and safe borrowed-reference alternatives.

Reference counting

Tracking references to manage object lifetime. Free-threaded CPython uses concurrency-aware internal mechanisms while preserving public reference-ownership contracts. QSBR and cyclic GC complement rather than replace reference counting. See CPython reference counting.

Relaxed ordering

Atomic ordering that provides atomicity and the object's modification-order guarantees without independently synchronizing other accesses. C uses memory_order_relaxed. Suitable fences or release sequences can let relaxed operations participate in synchronization. See relaxed ordering.

Release ordering

Ordering that can publish accesses preceding a release to accesses following a matching acquire. A release store uses memory_order_release; mutex unlock also supplies release ordering. It does not publish future writes. See release.

Release sequence

A sequence in one atomic object's modification order headed by a release operation. An immediately following relaxed RMW can extend it; an acquire reading a value from the sequence can synchronize with its head. The exact sequence definition depends on the C standard version. See release sequences.

Runtime-wide pause

A stop-the-world pause coordinating Python thread states across all interpreters. It has broader cost than an interpreter-wide pause and does not by itself stop independent native-thread accesses. See pause scopes.

S

Safe memory reclamation

A protocol preventing storage from being freed or dangerously reused while covered readers can still use it. Lifetime safety is separate from pointer atomicity, publication ordering, and data-race freedom. See safe memory reclamation and separate correctness proofs.

Safe point / evaluation-loop checkpoint

A runtime execution point where a thread can respond to coordination requests, such as a stop-the-world pause. Selected CPython evaluation-loop checks also report QSBR quiescent states, which have a separate pointer-use contract. See pause safe points and QSBR reports.

Sequenced-before

C's ordering relation between operations within one thread. It constrains the abstract execution, not necessarily emitted instruction order, and alone does not synchronize different threads. See sequenced-before.

Sequential consistency

Atomic ordering supplying acquire or release effects as appropriate and one total order of sequentially consistent operations shared by threads. C uses memory_order_seq_cst. This does not put every program operation in that order or combine separate atomic operations into a transaction. See sequential consistency.

Serialization

Forcing competing work to proceed in an order rather than simultaneously. Both mutexes and updates to a single atomic object can serialize progress. See atomic and lock serialization.

Sharding

Splitting shared state into separately updated parts to reduce contention. Combining parts costs work and may mix values from different moments; concurrent access to any one shard still requires an access rule. See sharding.

Shared state / shared mutable memory

Memory accessible to multiple threads, potentially including related fields forming one logical state. If threads can modify it, synchronization must cover all conflicting accesses and preserve its invariants. See identifying shared state.

Signal / broadcast

Condition-variable notifications waking one or more eligible waiters, or all waiters respectively, according to the interface. A notification tells a waiter to recheck state; it does not transfer ownership of an item or prove the predicate. See condition-variable notifications.

Snapshot

A view of related values representing one consistent state. Separate atomic loads do not automatically form an atomic snapshot, and QSBR does not provide one. See multi-field commit and versioned snapshots.

Spin lock

A lock whose waiting threads repeatedly poll instead of sleeping. Spinning can waste processor time when the owner cannot run or holds the lock too long. See spin locks.

Spurious failure

Failure of weak compare-exchange even when the current and expected values compare equal. Retry loops must handle it without assuming another thread made progress. See weak and strong CAS.

Spurious wakeup

Return from a wait without a notification establishing the desired condition. A condition-variable waiter must recheck its predicate under the mutex. See condition-variable waits.

Stalled reader

A reader delayed while it may retain a protected pointer. Safe reclamation keeps the required storage rather than freeing it merely because a timeout elapsed. See stalled-reader retention.

Starvation

An individual thread or operation repeatedly failing to proceed while others continue progressing. Mutual exclusion and lock-free algorithms can both allow it. See fairness and lock-free guarantees.

Stop-the-world / stopped region

CPython runtime coordination suspending affected attached thread states and preventing detached states from reattaching until restart. The stopped region runs between completed stop and matching restart. It must not depend on suspended threads making progress or run arbitrary Python code. A pause is not a general replacement for safe reclamation after execution resumes. See stop-the-world, lock hazards, and ordering versus lifetime.

Store-load ordering

A protocol's requirement that a later load not take effect before an earlier store. Hazard-pointer publication and validation need this on reader and reclaimer paths; acquire and release alone do not automatically supply it. See hazard-pointer ordering.

Subinterpreter

An interpreter in a process distinct from the main interpreter. Thread attachment must select the correct interpreter, and per-interpreter state can still be shared by its threads. See foreign-thread attachment and extension state.

Suspended thread state

A thread state paused by runtime coordination. Unlike an ordinarily detached thread, it cannot attach and resume Python execution until the pause controller permits it. See distinct thread states.

Suspension (critical section)

Temporarily marking a CPython critical section inactive and releasing its locks. Other threads can change the state before resumption, so old observations may need revalidation. See suspension and reacquisition.

Synchronization

Coordination that controls concurrent access or establishes ordering between threads. A synchronization protocol must cover every competing access path; source statement order alone is insufficient. See synchronization and protocol review.

Synchronizes-with

A relation established by suitable synchronization operations, such as mutex unlock and subsequent acquisition or a release and an acquire observing its value or release sequence. It connects threads and contributes to happens-before. See synchronizes-with.

T–W

Thread registration

Enrolling a thread in a reclamation protocol before it accesses protected data. Exit and detachment must update metadata without dropping protection while the thread can still use old pointers. See reclamation lifecycle and CPython QSBR registration.

Torn access

An access observing part of a write rather than one complete value. Atomic access prevents tearing of its own object, not inconsistent snapshots across multiple objects. See atomic loads and stores.

Two-object critical section

Py_BEGIN_CRITICAL_SECTION2 / Py_END_CRITICAL_SECTION2 protect two object locks together while active. The section can still suspend both locks. Nested single-object sections do not reliably provide simultaneous ownership. See two-object locking.

Type-stable storage

Backing storage whose relevant layout remains suitable for explicitly permitted speculative accesses even during allocation reuse. It does not preserve object identity or make arbitrary stale-pointer accesses valid in portable C. See type-stable reuse and CPython allocator guarantees.

Undefined behavior

An execution for which C imposes no requirements. A data race need not crash or produce a predictable failure, and optimizers can assume valid programs avoid it. See undefined behavior.

Use-after-free

Access to storage after its allocation has been freed. Atomic pointer access and validation after dereferencing do not make it safe. See pointer target lifetime.

Validation / revalidation

Checking that tentative observations still satisfy the protocol, or checking them again after possible interference such as lock suspension. Validation cannot retroactively make invalid memory accesses legal. See optimistic validation and revalidation after reacquisition.

volatile

A C qualifier governing volatile-object accesses, not a synchronization mechanism. In ISO C it does not make accesses atomic, establish happens-before, or safely publish other data. Compiler-specific modes such as MSVC's /volatile:ms are not portable ISO C synchronization. See volatile.

Wait-free / bounded wait-free

A progress guarantee that each operation completes in finitely many of its own steps regardless of other threads. Bounded wait-free adds a fixed bound on those steps. This is stronger than system-wide lock-free progress. See progress guarantees.

Wraparound

A bounded counter cycling back to a previously used value. Generation, version, and epoch protocols must not confuse that value with an earlier occurrence. See ABA and counter wraparound and epoch comparisons.


Return to the contents and topic index or primer introduction.

Markdown source