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

Reply via email to