On 10/31/10 5:40 AM, Michel Fortin wrote:
On 2010-10-30 23:56:24 -0400, Andrei Alexandrescu
<[email protected]> said:
On 10/30/2010 09:40 PM, Michel Fortin wrote:
But like File and many similar ref-counted structs, it has this race
condition (bug 4624) when stored inside the GC heap. Currently, most of
Phobos's ref-counted structs are race-free only when they reside on the
stack or if your program has only one thread (because the GC doesn't
spawn threads if I'm correct).
It's a little sad that the language doesn't prevent races in destructors
(bug 4621).
I hope we're able to solve these implementation issues that can be
seen as independent from the decision at hand.
Whether they're independent or not depends on the assumptions behind
your question. Since everywhere you propose ruling out arbitrary-cost
copy construction you also suggest COW with a reference counter, my
understanding is that you assume COW is usable and efficient.
Now, perhaps this isn't bothering you, but keep in mind that std::string
in C++ was originally specified in a way that allows COW, and this
ability was removed in C++0x because it isn't efficient in a
multithreaded environment. What makes you think it'll work differently
for D?
Fixing the bugs above will either 1) affect the performance of the
ref-counted things (need to use atomic ops on the counter) or 2)
restrict usage of RefCounted and others to non-GC memory for
multithreaded programs (as the current design does, even though the
compiler doesn't warn you). This is a drawback you should consider
before asking everyone to use copy on write with reference counting. I
haven't seen you acknowledge it yet.
Walter and I discussed the matter again today and we're on the brink
of deciding that cheap copy construction is to be assumed. This
simplifies the language and the library a great deal, and makes it
perfectly good for 95% of the cases. For a minority of types, code
would need to go through extra hoops (e.g. COW, refcounting) to be
compliant.
I take note that disabling postblit and forcing the use of a separate
copy function would also be compliant. :-)
I'm looking for more feedback from the larger D community. This is a
very important decision that marks one of the largest departures from
the C++ style. Taking the wrong turn here could alienate many
programmers coming from C++.
As far as I understand, nothing would prevent me from writing a value
type with arbitrary-cost copy construction if I wanted to. And someone
could have good reasons to do this (porting a C++ app for instance).
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). As
such, unshared types can always use non-atomic reference count
manipulation in confidence that there is no undue sharing going on.
Andrei