On 2010-10-31 12:39:10 -0400, Andrei Alexandrescu <[email protected]> said:

On 10/31/10 5:40 AM, Michel Fortin wrote:
I'm not opposed to the idea of ruling out arbitrary-cost postblits, but
I fear it might be futile. If std::string is any indication, COW doesn't
scale well with multithreading. There is a way to make COW efficient for
thread-local objects in the GC-heap, but that would require thread-local
GC heaps, and this has been ruled out in the design of 'shared' and
'immutable'.

D's approach to concurrency is predicated by distinguishing shared data from unshared data statically (by means of the shared qualifier).

Yes, and that was a very good idea.


As such, unshared types can always use non-atomic reference count manipulation in confidence that there is no undue sharing going on.

And it works, except in a destructor when that destructor is called by the GC (because the GC can call a destructor from another thread). The discussion of 4621 shows that the compiler can't detect the races that might arise if you dereference a member in a destructor. If the compiler could be made to prevent those races, all instances of bug 4624 would be caught at compile-time and you'd have to either:

1. use a shared reference counter with atomic operations (and possibly cast your way around), or
2. restrict those structs to the stack and non-GC allocated memory.

That's the conclusion from the discussion of bug 4621. A third way would be to make the GC call a destructor in the thread that owns the memory block, but how should the GC determine which thread owns which block? Is memory always owned by the thread that allocated it? And does that mean the destructor will be postponed until that thread asks for a new memory allocation? Perhaps that's what we should do.


--
Michel Fortin
[email protected]
http://michelf.com/

Reply via email to