Is GC.setAttr(p, GC.BlkAttr.NO_MOVE) guaranteed to work?

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jul 1 23:17:11 PDT 2014


There is an example in GC.addRoot() documentation where the programmer 
is trying to mark a memory block as NO_MOVE:

   http://dlang.org/phobos/core_memory.html#.GC.addRoot

     auto context = new Object;
     GC.addRoot(cast(void*)context);
     GC.setAttr(cast(void*)context, GC.BlkAttr.NO_MOVE);

If I understand it correctly, as soon as addRoot() succeeds, the block 
may have already been moved perhaps due to the needs of another thread.

Will setAttr() still work if that happened? Perhaps the GC is supposed 
to track any previously used memory block reference like 'context' so 
that the call will succeed? (I doubt it.)

If the example can indeed fail, will swapping the last two statements 
work as in the following code?

     auto context = new Object;
     GC.setAttr(cast(void*)context, GC.BlkAttr.NO_MOVE);
     GC.addRoot(cast(void*)context);

How about the reverse operations: Can I still use 'ctx' to refer to 
potentially moved memory block in the following code?

     GC.removeRoot(ctx);
     GC.clrAttr(ctx, GC.BlkAttr.NO_MOVE);

It seems to me that as a general rule, one cannot trust setting NO_MOVE 
on a GC-managed block at all. If that's true, addRoot() must have an 
overload that takes attributes as well and work atomically in that 
regard, right?

Ali


More information about the Digitalmars-d-learn mailing list