Jump to page: 1 2 3
Thread overview
[dmd-concurrency] A synchronized storage class?
Jan 07, 2010
Michel Fortin
Jan 07, 2010
Michel Fortin
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
[dmd-concurrency] is shared going to be a type modifier?
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Michel Fortin
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Michel Fortin
Jan 07, 2010
Sean Kelly
Jan 07, 2010
Sean Kelly
Jan 10, 2010
Walter Bright
Jan 07, 2010
Sean Kelly
January 07, 2010
I'd like to propose "synchronized" as a storage class to help differentiate variables which are ok to use under a lock from variables intended for lock-free operations. The compiler can then enforce synchronized access to those variables:

	class A {
		synchronized int i;
		synchronized int j;
		shared int k;

		void test1() synchronized {
			++i; // ok: access to i is synchronized
			++j; // ok: access to j is synchronized
			++k; // error: k is shared, not synchronized; supports only atomic ops
			++atomic(k); // ok
		}

		void test2() shared {
			++i; // error: access to i is synchronized, not shared
			++j; // error: access to j is synchronized, not shared
			++k; // error: shared only support atomic operations
			++atomic(k); // ok
		}
	}


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/

January 07, 2010
Adding a "synchronized" qualifier (with the semantics of tail-shared) has been discussed before. Our interim conclusion was that there is enough information inside synchronized methods to dispense with that particular qualifier.

We would very much like to _not_ add new qualifiers unless absolutely necessary. Your examples don't express that necessity - if you simply remove the "synchronized" qualifier off i and j, the compiler has enough information to do what's needed.


Andrei

Michel Fortin wrote:
> I'd like to propose "synchronized" as a storage class to help differentiate variables which are ok to use under a lock from variables intended for lock-free operations. The compiler can then enforce synchronized access to those variables:
> 
> 	class A {
> 		synchronized int i;
> 		synchronized int j;
> 		shared int k;
> 
> 		void test1() synchronized {
> 			++i; // ok: access to i is synchronized
> 			++j; // ok: access to j is synchronized
> 			++k; // error: k is shared, not synchronized; supports only atomic ops
> 			++atomic(k); // ok
> 		}
> 
> 		void test2() shared {
> 			++i; // error: access to i is synchronized, not shared
> 			++j; // error: access to j is synchronized, not shared
> 			++k; // error: shared only support atomic operations
> 			++atomic(k); // ok
> 		}
> 	}
> 
> 
January 07, 2010
Le 2010-01-07 ? 8:54, Andrei Alexandrescu a ?crit :

> We would very much like to _not_ add new qualifiers unless absolutely necessary. Your examples don't express that necessity - if you simply remove the "synchronized" qualifier off i and j, the compiler has enough information to do what's needed.

Sorry, I must be getting tiresome by proposing qualifiers then. I'll refrain from proposing new qualifiers from now on.

You're right that the example doesn't show a necessity for "synchronized" qualifying i and j. But I think the essence remains: member variables explicitly written as being "shared" could stay "shared" even under synchronization, forcing you to use atomic operations. Other member variables could be accessible only from not-shared functions and from shared functions under synchronization.

This would improve thread safety because each variable would have only one way to be accessed when the object is shared, either under synchronization or with atomic operations, but not both.

The downsides are that you can't have a variable which is not shared when the object is not and become "shared but not synchronized" when the object is shared, nor can you synchronize access to shared members in a thread-local object. I don't see how to fix that (without a new storage class), so would those downsides be acceptable? I feel the first one might be too much.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



January 07, 2010
Is "synchronized" really neded here?  I was hoping those variables could remain impaneled, so synchronized functions would simply be the way to operate on normal variables in a shared object.

Sent from my iPhone

On Jan 7, 2010, at 4:39 AM, Michel Fortin <michel.fortin at michelf.com> wrote:

> I'd like to propose "synchronized" as a storage class to help differentiate variables which are ok to use under a lock from variables intended for lock-free operations. The compiler can then enforce synchronized access to those variables:
>
>    class A {
>        synchronized int i;
>        synchronized int j;
>        shared int k;
>
>        void test1() synchronized {
>            ++i; // ok: access to i is synchronized
>            ++j; // ok: access to j is synchronized
>            ++k; // error: k is shared, not synchronized; supports
> only atomic ops
>            ++atomic(k); // ok
>        }
>
>        void test2() shared {
>            ++i; // error: access to i is synchronized, not shared
>            ++j; // error: access to j is synchronized, not shared
>            ++k; // error: shared only support atomic operations
>            ++atomic(k); // ok
>        }
>    }
>
>
> -- 
> Michel Fortin
> michel.fortin at michelf.com
> http://michelf.com/
>
> _______________________________________________
> dmd-concurrency mailing list
> dmd-concurrency at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
January 07, 2010
Yeah, this is how I thought shared would work, and I like it better than the "compiler figures everything out" approach.

Sent from my iPhone

On Jan 7, 2010, at 6:48 AM, Michel Fortin <michel.fortin at michelf.com> wrote:

> Le 2010-01-07 ? 8:54, Andrei Alexandrescu a ?crit :
>
>> We would very much like to _not_ add new qualifiers unless absolutely necessary. Your examples don't express that necessity - if you simply remove the "synchronized" qualifier off i and j, the compiler has enough information to do what's needed.
>
> Sorry, I must be getting tiresome by proposing qualifiers then. I'll refrain from proposing new qualifiers from now on.
>
> You're right that the example doesn't show a necessity for "synchronized" qualifying i and j. But I think the essence remains: member variables explicitly written as being "shared" could stay "shared" even under synchronization, forcing you to use atomic operations. Other member variables could be accessible only from not- shared functions and from shared functions under synchronization.
>
> This would improve thread safety because each variable would have only one way to be accessed when the object is shared, either under synchronization or with atomic operations, but not both.
>
> The downsides are that you can't have a variable which is not shared when the object is not and become "shared but not synchronized" when the object is shared, nor can you synchronize access to shared members in a thread-local object. I don't see how to fix that (without a new storage class), so would those downsides be acceptable? I feel the first one might be too much.
>
> -- 
> Michel Fortin
> michel.fortin at michelf.com
> http://michelf.com/
>
>
>
> _______________________________________________
> dmd-concurrency mailing list
> dmd-concurrency at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
January 07, 2010
Michel Fortin wrote:
> Le 2010-01-07 ? 8:54, Andrei Alexandrescu a ?crit :
> 
>> We would very much like to _not_ add new qualifiers unless absolutely necessary. Your examples don't express that necessity - if you simply remove the "synchronized" qualifier off i and j, the compiler has enough information to do what's needed.
> 
> Sorry, I must be getting tiresome by proposing qualifiers then. I'll refrain from proposing new qualifiers from now on.

It's not tiresome at all. On the contrary, I encourage you to do so if you can demonstrate necessity.

> You're right that the example doesn't show a necessity for "synchronized" qualifying i and j. But I think the essence remains: member variables explicitly written as being "shared" could stay "shared" even under synchronization, forcing you to use atomic operations. Other member variables could be accessible only from not-shared functions and from shared functions under synchronization.
> 
> 
> This would improve thread safety because each variable would have only one way to be accessed when the object is shared, either under synchronization or with atomic operations, but not both.
> 
> The downsides are that you can't have a variable which is not shared when the object is not and become "shared but not synchronized" when the object is shared, nor can you synchronize access to shared members in a thread-local object. I don't see how to fix that (without a new storage class), so would those downsides be acceptable? I feel the first one might be too much.

What real-world scenarios would require such a member?


Andrei
January 07, 2010
Turning off shared in non-shared objects could be useful for fields in a shared_ptr.  That would be a struct though, so I'm not sure much of this applies anyway.

Sent from my iPhone

On Jan 7, 2010, at 7:00 AM, Andrei Alexandrescu <andrei at erdani.com> wrote:

> Michel Fortin wrote:
>> Le 2010-01-07 ? 8:54, Andrei Alexandrescu a ?crit :
>>> We would very much like to _not_ add new qualifiers unless absolutely necessary. Your examples don't express that necessity - if you simply remove the "synchronized" qualifier off i and j, the compiler has enough information to do what's needed.
>> Sorry, I must be getting tiresome by proposing qualifiers then. I'll refrain from proposing new qualifiers from now on.
>
> It's not tiresome at all. On the contrary, I encourage you to do so if you can demonstrate necessity.
>
>> You're right that the example doesn't show a necessity for
>> "synchronized" qualifying i and j. But I think the essence remains:
>> member variables explicitly written as being "shared" could stay
>> "shared" even under synchronization, forcing you to use atomic
>> operations. Other member variables could be accessible only from
>> not-shared functions and from shared functions under synchronization.
>> This would improve thread safety because each variable would have
>> only one way to be accessed when the object is shared, either under
>> synchronization or with atomic operations, but not both.
>> The downsides are that you can't have a variable which is not shared
>> when the object is not and become "shared but not synchronized" when
>> the object is shared, nor can you synchronize access to shared
>> members in a thread-local object. I don't see how to fix that
>> (without a new storage class), so would those downsides be
>> acceptable? I feel the first one might be too much.
>
> What real-world scenarios would require such a member?
>
>
> Andrei
> _______________________________________________
> dmd-concurrency mailing list
> dmd-concurrency at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
January 07, 2010
Forget I said that.  T would be shared, not the shared_ptr.  As long as the shared property can be determined at compile-time, then it doesn't matter.

Sent from my iPhone

On Jan 7, 2010, at 7:11 AM, Sean Kelly <sean at invisibleduck.org> wrote:

> Turning off shared in non-shared objects could be useful for fields in a shared_ptr.  That would be a struct though, so I'm not sure much of this applies anyway.
>
> Sent from my iPhone
>
> On Jan 7, 2010, at 7:00 AM, Andrei Alexandrescu <andrei at erdani.com> wrote:
>
>> Michel Fortin wrote:
>>> Le 2010-01-07 ? 8:54, Andrei Alexandrescu a ?crit :
>>>> We would very much like to _not_ add new qualifiers unless absolutely necessary. Your examples don't express that necessity - if you simply remove the "synchronized" qualifier off i and j, the compiler has enough information to do what's needed.
>>> Sorry, I must be getting tiresome by proposing qualifiers then. I'll refrain from proposing new qualifiers from now on.
>>
>> It's not tiresome at all. On the contrary, I encourage you to do so if you can demonstrate necessity.
>>
>>> You're right that the example doesn't show a necessity for
>>> "synchronized" qualifying i and j. But I think the essence remains:
>>> member variables explicitly written as being "shared" could stay
>>> "shared" even under synchronization, forcing you to use atomic
>>> operations. Other member variables could be accessible only from
>>> not-shared functions and from shared functions under
>>> synchronization.
>>> This would improve thread safety because each variable would have
>>> only one way to be accessed when the object is shared, either under
>>> synchronization or with atomic operations, but not both.
>>> The downsides are that you can't have a variable which is not shared
>>> when the object is not and become "shared but not synchronized" when
>>> the object is shared, nor can you synchronize access to shared
>>> members in a thread-local object. I don't see how to fix that
>>> (without a new storage class), so would those downsides be
>>> acceptable? I feel the first one might be too much.
>>
>> What real-world scenarios would require such a member?
>>
>>
>> Andrei
>> _______________________________________________
>> dmd-concurrency mailing list
>> dmd-concurrency at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
> _______________________________________________
> dmd-concurrency mailing list
> dmd-concurrency at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
January 07, 2010
I'm not quite understanding everything being discussed here, because I came into this discussion quite late, but is shared going to remain a type modifier?

People are mentioning shared as a storage class on member variables, but I thought shared was going to be like const, where it transitively affects all members.  I thought a shared member function is one which the 'this' pointer is marked as shared, similar to a const function.  If that's the case, aren't all unmarked variables in a class shared?  Why the need to mark them?  And how do you have a 'partially shared' class where some members are marked shared and some are not?

I'm really confused :)

-Steve




January 07, 2010
On Jan 7, 2010, at 8:36 AM, Steve Schveighoffer wrote:

> I'm not quite understanding everything being discussed here, because I came into this discussion quite late, but is shared going to remain a type modifier?
> 
> People are mentioning shared as a storage class on member variables, but I thought shared was going to be like const, where it transitively affects all members.  I thought a shared member function is one which the 'this' pointer is marked as shared, similar to a const function.  If that's the case, aren't all unmarked variables in a class shared?  Why the need to mark them?  And how do you have a 'partially shared' class where some members are marked shared and some are not?

I think the idea was exactly as you're describing.  But consider this:

class A
{
    void fnA() synchronized { x = 5; }
    void fnB() shared { x = 6; }
    int x;
}

In this case, the field x is used in both a synchronized and shared function.  Since any use of x is outside a synchronized function, all accesses to it must be made atomic, and the compiler has to be able to determine this and enforce it.  Also, I'm simply not sure that use of shared fields will be so common that we want it to be automatic like this.
« First   ‹ Prev
1 2 3