valid uses of shared

Steven Schveighoffer schveiguy at yahoo.com
Mon Jun 11 05:07:31 PDT 2012


On Mon, 11 Jun 2012 07:51:37 -0400, Artur Skawina <art.08.09 at gmail.com>  
wrote:

> On 06/11/12 12:26, Steven Schveighoffer wrote:
>> On Sat, 09 Jun 2012 08:31:01 -0400, Mike Wey <mike-wey at example.com>  
>> wrote:
>>
>>> On 06/09/2012 04:01 AM, mta`chrono wrote:
>>>> Would this be legal?
>>>>
>>>> class A
>>>> {
>>>>       private static shared int counter; // shared across all  
>>>> instances
>>>>
>>>>       this()
>>>>       {
>>>>            auto i = ++counter;
>>>>            pragma(msg, typeof(i)); // prints int
>>>>       }
>>>> }
>>>>
>>>
>>> Would it also be legal if the variable wasn't static?
>>
>> No.
>
> Why? What if this class would like to launch a few threads to do some  
> work,
> export the address of the counter and have them report back by updating  
> it?
>
> Unlike the shared-on-stack case, this wouldn't even be unsafe (the memory
> won't be freed until all threads stop using it.) The alternative is to  
> have
> to split the class into two, more heap allocations etc.

The interesting thing here is, then you have both shared and unshared data  
in the same heap block.  Because a class is heap-allocated by default, you  
are right, you have a much smaller chance of sharing stack data.

However, allocating another heap block to do sharing, in my opinion, is  
worth the extra cost.  This way, you have clearly separated what is shared  
and what isn't.

You can always cast to get around the limitations.

auto sharedCounter = cast(shared int *)&counter;

dispatchThreadsToUpdateCounter(sharedCounter);

waitForThreadsToExit();

>> I think a better way to mark progress is to make it an atomic integer  
>> type (like Artur has developed).
>
> Yes. The problem with that however is that I never managed to make this
> do the right thing:
>
>    Atomic!int a; // somewhere in a shared struct/class.
>    ...
>    int x = s.a;  // OK, access via getter.
>    auto y = s.a; // Oops, we just copied the whole struct.
>    void f(T)(T arg);
>    f(s.a);       // Ditto.
>
> Which may happen to work for properly aligned small structs because
> accessing those are atomic anyway, but is wrong.

You can disable copying with @disable this(this);

-Steve


More information about the Digitalmars-d mailing list