Isolated by example

Rikki Cattermole via Digitalmars-d digitalmars-d at puremagic.com
Fri May 2 00:25:31 PDT 2014


On Friday, 2 May 2014 at 06:51:49 UTC, deadalnix wrote:
> First the original post I made on this forum : 
> http://forum.dlang.org/thread/kluaojijixhwigoujeip@forum.dlang.org#post-kluaojijixhwigoujeip:40forum.dlang.org
>
> Now some sample code/explanation to get it better.
>
> Isolated in a proposal adapted from an experiment made in C# 
> for D. It introduces a new qualifier. The qualifier is 
> necessary on function signatures (inference is possible to some 
> extent, like for pure functions), object/struct fields and 
> globals. It is inferred on local variables (but can be 
> explicited if one wish).
>
> An isolated is in an 'island'. The 'island' is implicit and 
> tracked by the compiler. We have one immutable and one shared 
> island. We have one TL island per thread. And we can have an 
> infinity of isolated island.
>
> An isolated is consumed when:
>  - it is returned
>  - it is passed as argument
>  - it is assigned to another island
>
> When an isolated goes out of scope without being consumed, the 
> compiler can free the whole island:
>
> void foo() {
>   A a = new A(); // a is isolated if A's ctor allows.
>
>   // a is not consumed. The compiler can insert memory freeing.
> }
>
> As we can see, it allows the compiler to do some freeing for us 
> to reduce GC pressure. Manu why aren't you already here 
> cheering ?
>
> When an isolated is consumed, the island it is in is merged 
> into the island that consumes it. All reference to the island 
> become write only until next write.
>
> void foo() {
>   A a = new A(); // a is isolated
>   immutable b = a; // a's island is merged into immutable
>
>   // a's island has been consumed. a is not readable at this 
> point.
>   // a.foo() // Error
>   a = new A(); // OK
>   a.foo(); // OK, we have written in a.
> }
>
> So far, we saw that isolated helps to construct 
> const/immutable/shared objects and can be used by the compiler 
> to insert free.
>
> isolated also help to bridge the RC world and the GC world.
>
> struct RC(T) is(isReferenceType!T) {
>   private T mystuff;
>
>   this(isolated T stuff) {
>     mystuff = stuff;
>   }
>
>   // All code to do ref counting goes here...
> }
>
> Here, the RC struct must be constructed with an isolated. To do 
> so, the isolated have to be passed as argument: it is consumed. 
> As a result, the RC struct can be sure that it has the only 
> usable reference to stuff that is around.
>
> Now some concurrency goodies:
>
> void foo() {
>   auto tid = spawn(&spawnedFunc, thisTid);
>
>   A a = new A();
>   send(tid, a); // OK, a is an isolated.
>
>   // a can't be used here anymore as it is consumed.
>   // You can simply pass isolated around across thread safely.
> }
>
> Now that is pretty sweet. First we don't have to do the crazy 
> and unsafe dance of "cast to shared and cast back to me" and 
> this is actually safe. Go's type system do is not safe across 
> channel, that puts us ahead in one of the things go does best.
>
> std.parallelism can also benefit from this. There is also 
> several benefit when the optimizer knows about isolated 
> (different island do not alias each other).
>
> I hope the idea get across better with some sample code and 
> will be considered. As sample code shows, isolated do not need 
> to be specified explicitly often. User not annotating can get a 
> lot of benefit out of the concept right away.

I've been thinking about something similar as being an 'obvious' 
idea.
It to me seems rather a good idea.


More information about the Digitalmars-d mailing list