A few thoughts on std.allocator

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu May 14 11:52:50 PDT 2015


On 5/13/15 8:00 PM, Jakob Ovrum wrote:
> On Wednesday, 13 May 2015 at 17:49:38 UTC, Steven Schveighoffer wrote:
>> OK, then consider that this:
>>
>> void main()
>> {
>>    string x;
>>    x ~= "hello";
>>    x ~= " world";
>> }
>>
>> would require locking. That's unacceptable. Nobody would append with
>> strings if this all required locking for no reason. The runtime
>> currently does NOT lock for this case, it considers immutable and
>> const to be thread-local.
>
> Well, it's necessary because the design of druntime arrays is
> incompatible with D2's type system. Without locking, multi-threaded
> applications that use dynamic array operations could easily contain some
> particularly hard to track concurrency bugs.

I don't think we should go there. I would say it's very unlikely to have 
this bug occur, but you are right it could occur. I just don't think 
destroying append performance for all const and immutable array types is 
worth it to fix the bug opportunity.

>> No, I think the answer is simpler. Introduce shared(immutable), and
>> then we can distinguish between immutable data that is shared and data
>> that is not shared. It also makes implementing local heaps easier.
>> Shared really is orthogonal to mutability.
>
> Basically, shared(immutable(T)) would only be useful to allocators,
> including arrays because they may need to allocate when growing. I don't
> think it would be useful beyond that; the sharedness of immutable data
> is probably not interesting to any other kind of code.

Yes, it really only matters for cases where the immutable pointer can be 
used to obtain mutable data. But these are important cases.

The fact that most code doesn't share *at all*, makes it less of an 
issue. Perhaps we need some way to indicate that when an array is 
shared, it can no longer be appended in-place. It would be as simple as 
flipping the APPENDABLE bit. The problem is, you're not always passing 
the immutable array directly.

> It would make immutable considerably harder to use than it is today.
> shared(immutable(T)) would be implicitly convertible to
> shared(const(T)), but not const(T), which precludes the vast majority of
> mutation-agnostic D code out there today (I have never seen
> shared(const(T)) used in the wild). We would no longer be able to do
> even the simplest things, like passing a path string to another thread
> and use std.file.read on it.

Yeah, there is no attribute that takes shared/unshared. I don't know a 
good solution to that, and I understand that shared(immutable) screws up 
most usages for immutable. It's not a good answer.

The problem is that when you share an immutable pointer, it changes the 
rules for that pointer, but no type information has been altered. It's 
impossible to track.

I think the idea of making immutable not shared by default is probably 
not a good answer, but I don't know of a good one. I have a feeling 
whatever answer we choose is going to be really painful :(

-Steve


More information about the Digitalmars-d mailing list