This section extends the single-threaded proof to multithreaded scenarios, incorporating inter-thread communication, shared immutable objects, and thread ownership rules. The proof maintains the core invariants while addressing concurrency and object transfers.
1. Definitions and Setup
Threads: Let Θ be the set of threads in the system. Each thread θ ∈ Θ maintains:
- A local set of mutable objects Mθ, disjoint from Mθ' for θ ≠ θ' (Invariant I10: Mutable Exclusivity).
- A local stack for temp pointers Tθ, scoped to θ's execution.
- Access to a global set of immutable objects F.
- Local outgoing and incoming queues for inter-thread communication.
Object Types (extended):
- Mutable Objects (M): Partitioned into {Mθ | θ ∈ Θ}. Each o ∈ Mθ is owned and accessed exclusively by θ.
- Immutable Objects (F): Shared across all threads, immutable post-creation.
Pointer Types (extended):
- Composite Pointer (Cθ): Exclusive ownership within Mθ. |Cθ| ≤ 1 per object in Mθ.
- Temp Pointer (Tθ): Stack-bound in θ, extending lifetime of objects in Mθ.
- Weak Pointer (W): Non-owning references to any M object. Cross-thread W (to Mθ' from θ ≠ θ') cannot be dereferenced (returns None on lock-and-check, Invariant I11: Weak Isolation).
- Shared Pointer (S): References to F, contributing to global reference count.
Graph Representation (extended):
- Local mutable graph per thread: Gθ = (Mθ, ECθ ∪ ETθ ∪ EWθ), where ECθ forms an acyclic tree, ETθ ⊆ Stackθ × Mθ.
- Global immutable graph: GF = (F, ES), a DAG.
- Weak edges EW may span threads but do not affect reference counts or allow cross-thread dereferencing.
Reference Counting (extended):
- For o ∈ Mθ: RCMθ(o) = |Cθ| + |Tθ| (local, non-atomic, as access is single-threaded).
- For f ∈ F: RCF(f) = Σ |Sθ| over θ ∈ Θ (global, atomic for thread-safety).
- Deallocation: o ∈ Mθ deallocated when RCMθ(o) = 0; f ∈ F when RCF(f) = 0.
- Retain/release on F: May be batched per thread (retains before releases) and applied atomically to prevent races (Invariant I12: Batch Ordering).
Inter-Thread Communication:
- Queues: Thread-safe, using shared pointers for immutable transfers and ownership transfer for mutable hierarchies.
- Mutable Transfer: Objects must be unowned (no Cθ) and unreferenced (no Tθ). Performed in two stages: a. Place in the outgoing queue (holds temporary ownership). b. Post to receiver's incoming queue after current operation ends (ensuring no residual Tθ).
- This transfers the object hierarchy from Mθ to Mθ', maintaining disjointness.
Thread Objects: Special mutable objects (sys_Thread) encapsulating thread state (Mθ, queues). Owned within other threads' mutable hierarchies. A root thread θroot is owned by the runtime. Copy/freeze/transfer operations on sys_Thread produce empty objects to prevent cycles (Invariant I13: Thread Acyclicity).
Invariants (extended from single-threaded):
- I10: Mutable Exclusivity – Mθ ∩ Mθ' = ∅ for θ ≠ θ'.
- I11: Weak Isolation – Lock-and-check on cross-thread W returns None.
- I12: Batch Ordering – Per-thread batches on RCF ensure retains precede releases; applied atomically.
- I13: Thread Acyclicity – sys_Thread ownership forms a tree rooted at θroot, with no cycles.
- All prior invariants (I1–I9) hold locally per thread for Mθ.
Goal: Prove no memory leaks in the multithreaded system, i.e., all objects are deallocated when no longer referenced, with no cycles or lost references due to concurrency or transfers.
2. Proof Structure
The proof builds on the single-threaded case, showing that multithreading introduces no leaks through local isolation, safe transfers, and global DAG management.
Statement 1: Local Mutable Objects Remain Leak-Free Per Thread
Claim: For each θ, the subgraph Gθ is leak-free as in the single-threaded proof.
Proof:
- By Invariants I1–I9 applied locally to Mθ, ECθ forms a tree, ETθ is stack-bound and acyclic.
- Access to Mθ is exclusive (I10), so no concurrent modifications.
- RCMθ is local and accurate, deallocating when =0.
- Weak pointers (local or cross) do not affect RCMθ.
- Conclusion: No leaks within each thread's mutable hierarchy (from single-threaded Statements 1, 2, 4).
Statement 2: Shared Immutable Objects Are Leak-Free
Claim: The global immutable graph GF has no cycles and deallocates correctly under concurrent access.
Proof:
- By I3, GF is a DAG (acyclic).
- RCF is global and atomic, incremented/decremented via shared pointers S.
- Batching (I12) ensures logical order: retains before releases, preventing premature deallocation.
- Traversal safety: Holding an S to a root f ensures RCF(f) ≥1; since ES forms a DAG, all descendants have RCF ≥1 from ancestors.
- Thus, traversal without additional retains is safe—no use-after-free.
- Deallocation only when RCF=0, with no cycles, ensures all unreferenced subgraphs are reclaimed.
- Conclusion: Standard ref-counted DAG guarantees no leaks (extended from Statement 3).
Statement 3: Inter-Thread Transfers Introduce No Leaks
Claim: Transferring objects (shared or mutable) between threads preserves leak-freedom and disjointness.
Proof:
- Shared Transfers: Sender retains (atomic increment RCF), enqueues S. Receiver acquires S (no increment needed, as already retained). Later release by any thread decrements RCF. No lost references; standard ref-counting applies.
- Mutable Transfers: Object o ∈ Mθ must have |Cθ|=0 and |Tθ|=0 (unowned, no stack refs).
- Stage 1: Move to the outgoing queue (queue holds effective C, RCMθ ≥1).
- Wait for operation end: Unwinds stack, releasing any residual Tθ (RCMθ=1 from queue).
- Stage 2: Post to receiver θ' incoming queue, transferring ownership (move C to θ').
- This ensures no references remain in θ (I10 preserved). o moves to Mθ', integrated into Gθ' without cycles (by local invariants).
- No intermediate loss: Queue holds reference throughout.
- Conclusion: Transfers maintain global invariants, no leaks introduced.
Statement 4: Cross-Thread Weak Pointers Introduce No Leaks
Claim: Cross-thread W pointers do not cause leaks or violate isolation.
Proof:
- By definition, W do not contribute to RC (anywhere).
- Cross-thread lock-and-check returns None (I11), preventing Tθ to Mθ' (no data races).
- Usage scenarios: a. Pass back: Enqueue W to owner thread θ'; dereference there as local W (reduces to single-threaded). b. Existence check: Atomic read (bool), no reference held. c. Async target: Task enqueued to θ', executed locally (single-threaded).
- All reduce to proven leak-free cases; no cross-thread references created.
- On deallocation in θ, cross-thread W auto-nullified (I9 extended atomically).
- Conclusion: Cross-thread set of W maintains safety without affecting leak-freedom.
Statement 5: Thread Objects Form a Leak-Free Hierarchy
Claim: sys_Thread objects are leak-free and acyclic.
Proof:
- Each sys_Thread ∈ Mθ' for some owner thread θ'.
- Root θroot owned by runtime (effective global reference).
- Ownership via C pointers in mutable hierarchies.
- Copy/freeze/transfer: Produce empty objects (no state transfer), preventing self-ownership or cycles (I13).
- Thus, sys_Thread ownership forms a tree: acyclic, rooted at θroot.
- Termination: Thread state (Mθ, queues) released locally; sys_Thread object released by owner when unreferenced.
- No cycles ensure deallocation when RC=0.
- Conclusion: Thread hierarchy integrates into mutable proofs without leaks.
3. Overall Proof of Leak Freedom
Theorem: The Argentum ownership model ensures no memory leaks in multithreaded contexts.
Proof:
- Mutable objects: Per-thread leak-free (Statement 1), with transfers preserving invariants (Statement 3).
- Immutable objects: Global DAG with atomic ref-counting, leak-free (Statement 2).
- Weak pointers: No impact on RC, cross-thread usage reduces to single-threaded (Statement 4).
- Threads: Acyclic tree, integrated without leaks (Statement 5).
- Concurrency: Mutable isolation (I10) prevents races; immutable batching (I12) ensures correct RCF.
- All operations (assignments, scopes, transfers) maintain accurate reference counts and acyclicity.
- Exceptions and terminations: Release held references (Tθ, queues), preserving integrity.
Conclusion: The model is leak-free multithreaded, with mutable isolation enabling single-thread proofs and shared immutable DAG ensuring global safety.