valid uses of shared

Dmitry Olshansky dmitry.olsh at gmail.com
Fri Jun 8 00:13:04 PDT 2012


On 08.06.2012 8:03, Steven Schveighoffer wrote:
> On Thu, 07 Jun 2012 20:58:13 -0400, Artur Skawina <art.08.09 at gmail.com>
> wrote:
>
>> On 06/08/12 01:51, Steven Schveighoffer wrote:
>>>
>>> The following would be illegal:
>>>
>>> struct X
>>> {
>>> shared int x; // illegal
>>> shared(int)* y; // legal
>>>
>>> shared(X) *next; // legal
>>> }
>>
>> Note that the type of 'x' in
>>
>> shared struct S {
>> int x;
>> }
>>
>> should probably be 'shared(int)'.
>> Which lets you safely take an address of an aggregates field.
>
> That's one of the things I'm wondering about. Should it be allowed?
>
> I agree that the type should be shared(int), but the type should not
> transfer to function calls or auto, it should be sticky to the
> particular variable. Only references should be sticky typed.
>
>> And I'm not sure if marking a struct and class as shared would work
>> correctly right now, it's probably too easy to lose the 'shared'
>> qualifier.
>
> Right, I was thinking shared structs do not make sense, since I don't
> think shared members do not make sense. Either a whole struct/class is
> shared or it is not. Because you can only put classes on the heap,
> shared makes sense as an attribute for a class.
>
> But then again, it might make sense to say "this struct is only ever
> shared, so it should be required to go on the heap". I like your idea
> later about identifying shared struct types that should use
> synchronization.
>
>>> shared class C // legal, C is always a reference type
>>> {
>>> shared int x; // illegal, but useless, since C is already shared
>>> }
>>
>> Redundant, but should be accepted, just like 'static' is.
>
> That's probably fine.
>
>>> If you notice, I never allow shared values to be stored on the stack,
>>> they are always going to be stored on the heap. We can use this to
>>> our advantage -- using special allocators that are specific to shared
>>> data, we can ensure the synchronization tools necessary to protect
>>> this data gets allocated on the heap along side it. I'm not sure
>>> exactly how this could work, but I was thinking, instead of
>>> allocating a monitor based on the *type* (i.e. a class), you allocate
>>> it based on whether it's *shared* or not. Since I can never create a
>>> shared struct X on the stack, it must be in the heap, so...
>>>
>>> struct X
>>> {
>>> int y;
>>> }
>>>
>>> shared(X) *x = new shared(X);
>>>
>>> synchronized(x) // scope-locks hidden allocated monitor object
>>> {
>>> x.y = 5;
>>> }
>>>
>>> x.y = 5; // should we disallow this, or maybe even auto-lock x?
>>>
>>> Hm... another idea -- you can't extract any piece of an aggregate.
>>> That is, it would be illegal to do:
>>>
>>> shared(int)* myYptr = &x.y;
>>>
>>> because that would work around the synchronization.
>>
>> That's too restrictive. It would overload 'shared' even more. If you
>> want that kind of synchronize magic to work, just allow:
>>
>> shared synchronized(optional_locking_primitive) struct S {
>> ...
>> }
>>
>> And *now* 'x.y = 5' can do its magic, while '&x.y' can be disallowed.
>>
>>
>> shared struct S {
>> Atomic!int i;
>> }
>> shared(S)* p = ...
>> p.i += 1;
>>
>> should work, so accessing fields must remain possible.
>
> OK. You are right, synchronized may be overkill for basic types.
>
>>> auto would have to strip shared:
>>>
>>> auto myY = x.y; // typeof(myY) == int.
>>
>> Hmm, i'm not sure about this, maybe it should be disallowed; it could
>> only strip 'shared' from the head anyway.
>
> Yes, head stripping. I think it should be allowed. For instance, if you
> wanted to read a shared double, and take the cosine of it, this should
> be allowed:
>
> auto n = cos(sharedValue);

what if it's a
auto n = cos(sharedValues[k]); //type is shared(double) right?

and somebody in the other thread is halfway through writing it?

>
> If it's not, the alternatives are:
>
> auto n = cos(cast()sharedValue);
>
> or
>
> double v = sharedValue; // explicit removal of shared
> auto m = cos(v);
>
> Neither of these look necessary, I think just allowing shared value
> types to automatically convert to non-shared versions works the best.
>
>>> This is definitely not a complete proposal. But I wonder if this is
>>> the right direction?
>>
>> I think it is.
>
> good.

Indeed.

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list