Temporally safe by default

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Fri Apr 5 10:34:24 UTC 2024


On 05/04/2024 11:24 PM, Dukc wrote:
> On Friday, 5 April 2024 at 09:59:58 UTC, Richard (Rikki) Andrew 
> Cattermole wrote:
>> See all the examples of people having to cast on/off ``shared`` to 
>> pass memory between threads.
> 
> That's what it's like if you try to share plain arrays. And that's how 
> it should be. Manipulating a shared data structure in a temporally safe 
> way is complicated, so to access `shared` data it makes sense that do 
> that you need to explicitly give up temporal safety (cast) or do it the 
> hard way (`core.atomic`).
> 
> But if you had the data structure struct, you wouldn't have to do 
> either. It would have a `shared` constructor and `shared` member 
> functions to manipulate all the data, all the ugly atomics and/or 
> casting getting done in the struct implementation. It'd let you to copy 
> part of itself to your thread local storage and inspect there at your 
> leisure. It'd let you lock part of itself for a time when you wish to do 
> an in-place update (during which the data in question would be typed as 
> thread-local and guarded against escape with DIP1000). And so on.

You are assuming the data structure is the problem.

It isn't, the problem is who knows about the data structure, its 
arguments and its return value. Across the entire program, on every 
thread, in every global, in every function call frame.

``shared`` does not offer any guarantees to references, how many there 
are, on what threads its on. None of it. Its fully up to the programmer 
to void it if they chose to do so in normal ``@safe`` code.

If you cannot prove aliasing at compile time and in doing so enable 
optimizations, it isn't good enough for temporal safety.


More information about the dip.ideas mailing list