More radical ideas about gc and reference counting

Jerry via Digitalmars-d digitalmars-d at puremagic.com
Sat May 17 12:38:01 PDT 2014


Rainer Schuetze <r.sagitario at gmx.de> writes:

> On 14.05.2014 12:56, "Marc Schütz" <schuetzm at gmx.net>" wrote:
>> On Tuesday, 13 May 2014 at 19:50:52 UTC, Rainer Schuetze wrote:
>>> class C { C next; }
>>>
>>> shared(C) list;
>>>
>>> C newC()
>>> {
>>>     return new C; // allocated on the local heap?
>>
>> Yes, because it doesn't say "new shared(C)".
>>
>>> }
>>>
>>> void prependToList(C c)
>>> {
>>>     synchronized(list)
>>>     {
>>>         C lst = cast(C) list;
>>>         c.next = lst;  // anything special happening here?
>>>         list = cast(shared(C)) c;  // and here?
>>
>> The casts are a problem. You're basically lying to the compiler, so this
>> cannot work. Instead, it should be something like:
>>
>>      auto newC() {
>>          return new isolated(C);
>>      }
>>
>>      void prependToList(isolated(C) c) {
>>          synchronized(list) {
>>              // transfer to shared heap
>>              // afterwards, c is no longer usable ("consumed")
>>              shared(C) tmp = c.makeShared();
>>              tmp.next = list;
>>              list = tmp;
>>          }
>>      }
>
>
> Sorry for the late reply.
>
> I currently don't know of a feasible way to replace casting away "shared" if
> you want to do more than just "tmp.next = list;", for example call "bool
> check(C c);" on tmp or list? I can't implement this with a shared object,
> because any operations on "shared" tend to not exist (ok, maybe I could for
> this very simple example, so consider C contains a container to operate
> on). Also, the object is already locked, I should not have to do it again in a
> function if it only accepts a shared C.
>
> How can I prepend something to the list that is not isolated? I guess I
> cannot, as it might create references to same object both shared and unshared.
>
> My gut feeling tells me that this ownership handling through the type system
> might work, but it is very restrictive and does not really contribute to the
> first goal of D listed on the front page: "convenience".

Reading this, I had a thought.  What if synchronized temporarily
stripped the shared qualifier from list?  At the end of the synchronized
block, shared is restored.  Then:

void prependToList(C c) {
    synchronized(list) {       // list is now C, not shared(C)
        c.next = list;         // ok
        list = c;              // ok
        check(list);           // ok, not a shared object here
    }
    // list is now shared again.  move list to shared heap if not already
}

I'm sure I'm missing something, but using shared within a synchronized
block might be saner if this worked...

Jerry



More information about the Digitalmars-d mailing list