Thread-local GC (tgc) demo
Repository: dlang-supplemental/dmd feature/tgcunchecked
Design: tgc design notes
This demo explains what tgc does and how to validate it locally.
What you are looking at
-
Private heap — default for each thread.
GC.collect()on that thread collects locally without global stop-the-world. -
Shared region — opt-in heap shared by attached threads only.
_d_tgc_region_collectpauses those threads, not the whole process. -
Unrelated threads — never attached to a region are not paused when that region collects.
Try it (0.2.0)
Build DMD/druntime from feature/tgc, then:
# Smoke tests
make -C druntime/test/gc OS=windows MODEL=64 tgc tgc_regions
# Run with tgc enabled (tests pass --DRT-gcopt=gc:tgc via Makefile)
./generated/.../tgc.exe --DRT-gcopt=gc:tgc
./generated/.../tgc_regions.exe --DRT-gcopt=gc:tgc
# Benchmark harness (compare backends)
powershell -File tools/tgc-bench/run-benchmarks.ps1
API surface (C exports)
|
|
|
Create shared region; returns id |
|
Attach calling thread |
|
Allocate in region heap |
|
Region-scoped collect (attached threads only) |
Optional gcopt: tgcShared:symgc selects SymGC-backed shared regions (0.3.0 stub — native backend is default).
Test matrix
|
Private heaps, local collect, version check |
|
Cross-thread shared region survival after region collect |
|
Throughput + pause timing (manual compare across gcopt) |
Benchmark scenarios
Run the same binary with different --DRT-gcopt flags:
-
Default conservative — baseline shared heap + global STW
-
gc:tgc— private heaps + optional shared regions -
gc:sdc— SymGC (separate build with symgc linked; not combined with tgc in one process today)
Environment variables for tgc_bench:
-
TGC_BENCH_ITERS— single-thread alloc count (default 50000) -
TGC_BENCH_THREADS— worker thread count (default 4)