Skip to content

Harden Foundations memory and concurrency contracts - #116

Draft
tdecroyere wants to merge 48 commits into
mainfrom
refactor/memory-pop-cleanup
Draft

Harden Foundations memory and concurrency contracts#116
tdecroyere wants to merge 48 commits into
mainfrom
refactor/memory-pop-cleanup

Conversation

@tdecroyere

@tdecroyere tdecroyere commented Sep 4, 2026

Copy link
Copy Markdown
Member

Goal

Harden the low-level Foundations runtime around explicit memory, lifetime, and concurrency contracts. This keeps the existing arena/stack design intact while fixing correctness bugs that could otherwise lead to out-of-bounds allocations, races, stale handles, corrupted free lists, or unsafe access to uncommitted memory.

MemoryArena

  • remove public SystemPopMemory and keep rollback internal to StackMemoryArena;
  • keep SystemClearMemoryArena / SystemFreeMemoryArena as explicit exclusive lifetime operations;
  • page-align the allocator header, keep it permanently committed, and make page metadata describe data pages only;
  • calculate page indexes relative to the data region and remove floating-point page calculations;
  • make system page-size initialization thread-safe without cross-translation-unit initialization-order dependence;
  • replace the shared push check-then-add race with a bounded CAS reservation loop;
  • fix StackExtraStorage capacity checks to use the actual working arena;
  • serialize shared commit/decommit bookkeeping before mutating PageInfo, committed-state bits, or page counts;
  • make platform reserve/commit/decommit accounting atomic and only update counters after successful OS operations;
  • account for still-committed pages when an arena reservation is released;
  • reject size/alignment/multiplication overflow instead of allowing wrapped reservations or array sizes;
  • propagate allocation failures through zero/array/string helpers instead of dereferencing null storage;
  • make SystemCommitMemory report success/failure and prevent committed pushes from returning a pointer when the platform commit fails;
  • preserve the existing advanced nested StackMemoryArena lifetime model and its regression coverage.

DataPool

  • replace the unsafe ABA-prone lock-free free list with a short synchronized index allocator/recycler;
  • bound concurrent index allocation so the pool cannot advance past capacity;
  • make concurrent removal of the same handle recycle the slot exactly once;
  • validate generations with atomic loads and skip the reserved invalid generation value on wrap;
  • propagate backing-memory commit failures before publishing/writing a new item;
  • document that lookups are thread-safe but returned raw pointers do not pin item lifetime against later remove/reuse.

Dictionary

  • replace the unsafe concurrent linked-list/free-list mutation scheme with deterministic synchronized dictionary operations;
  • initialize hash/value/next before publishing an entry into its bucket;
  • bound entry allocation under contention and remove timing-dependent retry loops;
  • prevent removed entries from being recycled while another dictionary operation is traversing them;
  • fix ReadOnlySpan<T> hashing so Length is converted to bytes with sizeof(T);
  • make missing SystemGetDictionaryValue return nullptr as documented while preserving the zero-value operator[] convenience;
  • document raw pointer/reference lifetime limitations after lookup.

Span and string buffers

  • keep Span / ReadOnlySpan lightweight, non-owning pointer-and-length views;
  • make const-buffer construction and slicing const-correct;
  • define character span Length as logical characters excluding the null terminator;
  • fix SystemDuplicateBuffer<char> to preserve that logical length;
  • make the shader serializer write its null terminator explicitly instead of depending on the previous incorrect string length.

Regression coverage

Adds focused tests for:

  • arena size/push overflow and exact VM accounting after free;
  • concurrent push capacity and shared-page commit;
  • StackExtraStorage ancestor allocations;
  • commit result validation;
  • DataPool capacity, duplicate concurrent remove, and thousands of concurrent remove/reuse cycles;
  • Dictionary capacity, concurrent remove/reuse cycles, missing lookup semantics, and non-char span hashing;
  • Span/string logical length and null termination.

The remaining follow-up audit items are intentionally separate from this PR's current Foundations scope: platform-specific descriptor/query free lists in the graphics backends, deeper PageInfo sparse-decommit semantics, and POSIX physical-page release policy.

@tdecroyere
tdecroyere force-pushed the refactor/memory-pop-cleanup branch from abe5a63 to 7eca504 Compare September 4, 2026 20:13
@tdecroyere
tdecroyere force-pushed the refactor/memory-pop-cleanup branch from d027210 to 3bb224b Compare September 4, 2026 20:48
@tdecroyere tdecroyere changed the title Make memory pop stack-internal Simplify memory arena page layout Sep 4, 2026
@tdecroyere tdecroyere changed the title Simplify memory arena page layout Harden Foundations memory and span contracts Sep 5, 2026
@tdecroyere tdecroyere changed the title Harden Foundations memory and span contracts Harden Foundations memory and concurrency contracts Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant