Per thread heap, GC, etc.

Markk markus.kuehni at triviso.ch
Fri May 14 13:48:12 UTC 2021


Hi,

D has this nice default per-thread static memory model, i.e. if I 
understand all this correctly, this allows for better, more 
natural thread safety, while it makes it generally unsafe to use 
this memory from other threads (without locking). I guess the 
same is implicitly true for stack memory.

Now could it equally make sense to use per-thread heaps?

I.e. all allocations would need to be per thread, and it would be 
illegal to reference memory of one thread's heap, static memory, 
or stack from another thread's memory.

Some RAII locking could pin message-passed (etc.) references 
temporarily down for them to be used legally by another thread. 
This would make the sharing of the pointer known to the original 
thread for a strictly scoped time. Perhaps the `synchronized` 
keyword could be used for these stack references (just a spur of 
the moment proposal for the purpose of this discussion). Pinning 
is coupled with message-passing (etc.), i.e. no additional 
locking required.

For permanent change of ownership i.e. storing a reference in 
static or heap memory of the other thread, the referenced memory 
would have to be copied. I.e. there are no `synchronized` 
references from inside static or heap (i.e. non-stack, 
non-scoped) memory.

I guess `synchronized` class objects could get their own, 
non-thread specific, a.k.a. shared heap (similar in a way to the 
`shared` static memory). All stack references to `synchronized` 
class objects would have to be marked with `synchronized` too (or 
this might be inferred). `synchronized` class references stored 
in other (non-stack, non-scoped) thread memory would still be 
illegal.

Given the above, the GC could be run per thread. The world would 
not have to be stopped! Which means that some threads could 
entirely run without GC while others could still benefit from 
what I personally think is the only universal and scalable 
solution to memory safety. As a middle ground, some threads might 
only use a controlled amount of allocations, therefore GC runs 
would be super-fast, perhaps still acceptable under (near) 
real-time performance constrains.

The model would force developers towards a more modularized, per 
thread (service?) oriented architecture where message passing and 
lock free programming would be king... (said from a "schoolbook" 
understanding of these matters ;-)).

Also, I guess the performance of the resulting lock free heap 
allocs/frees, of the now (by language guarantee) lock free thread 
safe memory accesses, of the now per thread, smaller and (per 
definition) lock free GC runs etc. would improve.

Being per-thread i.e. non-preemptive, this could also simplify 
the GC and allow for more compiler optimizations, I guess. There 
is no danger of register aliasing and whatnot, that I can only 
guess makes preemptively interrupting GC correctness under high 
compiler optimization hard.

Just some thoughts after reading a handful Rust and D books... 
and after having seen so many wrinkle their noses at GC ... and 
therefore, unfortunately D.

_Mark



More information about the Digitalmars-d mailing list