Re: JMM- synchronization access in a concrete example.

2018-09-26 Thread Tom Lee
Oops: "use x and y somehow" should read "use y and z somehow" in the
example I gave. Hopefully that's not too confusing.

On Tue, Sep 25, 2018 at 11:09 PM Tom Lee  wrote:

> How to interpret a citation given by Cezary?: "If x and y are actions of
>> the same thread and x comes before y in program order, then hb(x, y)."
>
>
> This is a great question! Hopefully I'm not too far off-base but I think
> it comes down to effects/"visibility" and this statement hints at the kinds
> of optimization that might be legal. Assume a single thread of execution
> where reordering is in play. *Instructions* implementing the actions can
> be reordered in such a way that we perform all the work required to execute
> *actions* x and y, but until the effects of those operations "leak"
> you're still not strictly violating the hb(x, y) rule.
>
> For example, sticking to the "single thread of execution" example and
> local variables:
>
> a: x =1
> b: y = 2
> c: z = x + y * 3
> d: y = z
> e...: (use x and y somehow)
>
> We could reorder the underlying instructions such that we compute z
> directly & simply omit the assignment to x and y such that what actually
> gets executed by the CPU looks more like:
>
> a: (optimized away)
> b: (optimized away)
> c: z = 3 * 2 + 1
> d: y = z
> e: (use x and y somehow)
>
> Does it matter that we've eliminated the assignments and reordered some of
> the arithmetic? Probably not: we've changed the underlying instructions but
> as far as the *effects *are concerned we ultimately "see" hb(a,b) ->
> hb(b,c) -> hb(c,d) -> hb(d,e...) and a correct execution of our program! Of
> course, this is easier to reason about when the instructions/actions
> involved are simple. Replace simple arithmetic with method calls, volatile
> reads & writes, allocation, threads, etc. and it obviously gets a whole lot
> messier.
>
> (No doubt somebody out there can formalize what I'm trying to get across
> here, I'm sort of running on intuition. :))
>
> On Tue, Sep 25, 2018 at 10:34 PM John Hening  wrote:
>
>> Tom,
>>
>> Actually you right. I get it!
>>
>> Gil,
>> thanks for your note. You obviously right. If I use multithreaded
>> executor I got a lot races in a result.
>> So, does it mean that my both version of example are correct?
>>
>> How to interpret a citation given by Cezary?: "If x and y are actions of
>> the same thread and x comes before y in program order, then hb(x, y)."
>> For my eye the key is in interpreting of program order. So, if we have
>> two statements [X, Y] and order of execution does not matter because both
>> are intrathread-consistent it means that [Y,X] are in program order and
>> HB(Y,X) by a rule I cite above.
>>
>> So, If we had no Executor's (and no other) guarantee it could be
>> reordered.
>>
>>
>> W dniu środa, 26 września 2018 04:49:21 UTC+2 użytkownik Gil Tene napisał:
>>>
>>> As Tom noted, The Executor's submission happens-before promise prevents
>>> a reordering of (1) and (2) above.
>>>
>>> Note that, as written, the reason you you don't have data races between
>>> (2) and (2) is that executor is known to be a single threaded executor (and
>>> will only run one task at a time). Without that quality, you would have
>>> plenty of (2) vs. (2) races. It is not that "doers contain different
>>> objects": your code submits executions of functions using the same x member
>>> of xs to all doers, and it is only the guaranteed serialization in your
>>> chosen executor implementation that prevents x,f()s from racing on the same
>>> x...
>>>
>>> On Tuesday, September 25, 2018 at 8:52:14 AM UTC-7, John Hening wrote:

 public class Test {
 ArrayList xs;
 ArrayList doers;
 Executor executor = Executors.newSingleThreadExecutor();

 static class Doer {
   public void does(X x){
x.f();
 // (2)
   }
 }

 void test() {
 for(X x : xs){
 x.f();
  // (1)

 for(Doer d : doers) {
 executor.execute(() -> d.does(x));
 }
 }
 }
 }




 For my eye, if X.f is not synchronized it is incorrect because of two
 facts (and only that two facts):

 1. Obviously, there is data race between (1) and (2). There are no more
 data races here. (doers contains different objects)
 2. There is no guarantee that (1) will be executed before (2). Yes?

 If X.f would be synchronized that code will be correct because:
 1. There is no data race.
 2. There is guarantee that (1) will be executed before (2) because (1)
 is a synchronization action and Executor.execute is also a synchronization
 access (not specifically execute itself)

 Yes?

>>> --
>> You received this message because you are subscribed to the Google Groups
>> "mechanical-sympathy" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to 

Re: JMM- synchronization access in a concrete example.

2018-09-26 Thread Tom Lee
>
> How to interpret a citation given by Cezary?: "If x and y are actions of
> the same thread and x comes before y in program order, then hb(x, y)."


This is a great question! Hopefully I'm not too far off-base but I think it
comes down to effects/"visibility" and this statement hints at the kinds of
optimization that might be legal. Assume a single thread of execution where
reordering is in play. *Instructions* implementing the actions can be
reordered in such a way that we perform all the work required to execute
*actions* x and y, but until the effects of those operations "leak" you're
still not strictly violating the hb(x, y) rule.

For example, sticking to the "single thread of execution" example and local
variables:

a: x =1
b: y = 2
c: z = x + y * 3
d: y = z
e...: (use x and y somehow)

We could reorder the underlying instructions such that we compute z
directly & simply omit the assignment to x and y such that what actually
gets executed by the CPU looks more like:

a: (optimized away)
b: (optimized away)
c: z = 3 * 2 + 1
d: y = z
e: (use x and y somehow)

Does it matter that we've eliminated the assignments and reordered some of
the arithmetic? Probably not: we've changed the underlying instructions but
as far as the *effects *are concerned we ultimately "see" hb(a,b) ->
hb(b,c) -> hb(c,d) -> hb(d,e...) and a correct execution of our program! Of
course, this is easier to reason about when the instructions/actions
involved are simple. Replace simple arithmetic with method calls, volatile
reads & writes, allocation, threads, etc. and it obviously gets a whole lot
messier.

(No doubt somebody out there can formalize what I'm trying to get across
here, I'm sort of running on intuition. :))

On Tue, Sep 25, 2018 at 10:34 PM John Hening  wrote:

> Tom,
>
> Actually you right. I get it!
>
> Gil,
> thanks for your note. You obviously right. If I use multithreaded executor
> I got a lot races in a result.
> So, does it mean that my both version of example are correct?
>
> How to interpret a citation given by Cezary?: "If x and y are actions of
> the same thread and x comes before y in program order, then hb(x, y)."
> For my eye the key is in interpreting of program order. So, if we have two
> statements [X, Y] and order of execution does not matter because both are
> intrathread-consistent it means that [Y,X] are in program order and HB(Y,X)
> by a rule I cite above.
>
> So, If we had no Executor's (and no other) guarantee it could be
> reordered.
>
>
> W dniu środa, 26 września 2018 04:49:21 UTC+2 użytkownik Gil Tene napisał:
>>
>> As Tom noted, The Executor's submission happens-before promise prevents a
>> reordering of (1) and (2) above.
>>
>> Note that, as written, the reason you you don't have data races between
>> (2) and (2) is that executor is known to be a single threaded executor (and
>> will only run one task at a time). Without that quality, you would have
>> plenty of (2) vs. (2) races. It is not that "doers contain different
>> objects": your code submits executions of functions using the same x member
>> of xs to all doers, and it is only the guaranteed serialization in your
>> chosen executor implementation that prevents x,f()s from racing on the same
>> x...
>>
>> On Tuesday, September 25, 2018 at 8:52:14 AM UTC-7, John Hening wrote:
>>>
>>> public class Test {
>>> ArrayList xs;
>>> ArrayList doers;
>>> Executor executor = Executors.newSingleThreadExecutor();
>>>
>>> static class Doer {
>>>   public void does(X x){
>>>x.f();
>>>   // (2)
>>>   }
>>> }
>>>
>>> void test() {
>>> for(X x : xs){
>>> x.f();  //
>>> (1)
>>>
>>> for(Doer d : doers) {
>>> executor.execute(() -> d.does(x));
>>> }
>>> }
>>> }
>>> }
>>>
>>>
>>>
>>>
>>> For my eye, if X.f is not synchronized it is incorrect because of two
>>> facts (and only that two facts):
>>>
>>> 1. Obviously, there is data race between (1) and (2). There are no more
>>> data races here. (doers contains different objects)
>>> 2. There is no guarantee that (1) will be executed before (2). Yes?
>>>
>>> If X.f would be synchronized that code will be correct because:
>>> 1. There is no data race.
>>> 2. There is guarantee that (1) will be executed before (2) because (1)
>>> is a synchronization action and Executor.execute is also a synchronization
>>> access (not specifically execute itself)
>>>
>>> Yes?
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-sympathy+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>


-- 
*Tom Lee */ http://tomlee.co / @tglee 

-- 
You received this message because you are subscribed to the Google Groups 

Re: JMM- synchronization access in a concrete example.

2018-09-25 Thread John Hening
Tom, 

Actually you right. I get it! 

Gil, 
thanks for your note. You obviously right. If I use multithreaded executor 
I got a lot races in a result. 
So, does it mean that my both version of example are correct? 

How to interpret a citation given by Cezary?: "If x and y are actions of 
the same thread and x comes before y in program order, then hb(x, y)."
For my eye the key is in interpreting of program order. So, if we have two 
statements [X, Y] and order of execution does not matter because both are 
intrathread-consistent it means that [Y,X] are in program order and HB(Y,X) 
by a rule I cite above. 

So, If we had no Executor's (and no other) guarantee it could be reordered. 


W dniu środa, 26 września 2018 04:49:21 UTC+2 użytkownik Gil Tene napisał:
>
> As Tom noted, The Executor's submission happens-before promise prevents a 
> reordering of (1) and (2) above.
>
> Note that, as written, the reason you you don't have data races between 
> (2) and (2) is that executor is known to be a single threaded executor (and 
> will only run one task at a time). Without that quality, you would have 
> plenty of (2) vs. (2) races. It is not that "doers contain different 
> objects": your code submits executions of functions using the same x member 
> of xs to all doers, and it is only the guaranteed serialization in your 
> chosen executor implementation that prevents x,f()s from racing on the same 
> x...
>
> On Tuesday, September 25, 2018 at 8:52:14 AM UTC-7, John Hening wrote:
>>
>> public class Test {
>> ArrayList xs;  
>> ArrayList doers;
>> Executor executor = Executors.newSingleThreadExecutor();
>>
>> static class Doer {
>>   public void does(X x){
>>x.f();   
>>   // (2)
>>   }
>> } 
>>
>> void test() {
>> for(X x : xs){
>> x.f();  // 
>> (1)
>> 
>> for(Doer d : doers) {
>> executor.execute(() -> d.does(x));
>> }
>> }
>> }
>> }
>>
>>
>>
>>
>> For my eye, if X.f is not synchronized it is incorrect because of two 
>> facts (and only that two facts): 
>>
>> 1. Obviously, there is data race between (1) and (2). There are no more 
>> data races here. (doers contains different objects)
>> 2. There is no guarantee that (1) will be executed before (2). Yes?
>>
>> If X.f would be synchronized that code will be correct because:
>> 1. There is no data race.
>> 2. There is guarantee that (1) will be executed before (2) because (1) is 
>> a synchronization action and Executor.execute is also a synchronization 
>> access (not specifically execute itself)
>>
>> Yes?
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: JMM- synchronization access in a concrete example.

2018-09-25 Thread Gil Tene
As Tom noted, The Executor's submission happens-before promise prevents a 
reordering of (1) and (2) above.

Note that, as written, the reason you you don't have data races between (2) 
and (2) is that executor is known to be a single threaded executor (and 
will only run one task at a time). Without that quality, you would have 
plenty of (2) vs. (2) races. It is not that "doers contain different 
objects": your code submits executions of functions using the same x member 
of xs to all doers, and it is only the guaranteed serialization in your 
chosen executor implementation that prevents x,f()s from racing on the same 
x...

On Tuesday, September 25, 2018 at 8:52:14 AM UTC-7, John Hening wrote:
>
> public class Test {
> ArrayList xs;  
> ArrayList doers;
> Executor executor = Executors.newSingleThreadExecutor();
>
> static class Doer {
>   public void does(X x){
>x.f(); // 
> (2)
>   }
> } 
>
> void test() {
> for(X x : xs){
> x.f();  // 
> (1)
> 
> for(Doer d : doers) {
> executor.execute(() -> d.does(x));
> }
> }
> }
> }
>
>
>
>
> For my eye, if X.f is not synchronized it is incorrect because of two 
> facts (and only that two facts): 
>
> 1. Obviously, there is data race between (1) and (2). There are no more 
> data races here. (doers contains different objects)
> 2. There is no guarantee that (1) will be executed before (2). Yes?
>
> If X.f would be synchronized that code will be correct because:
> 1. There is no data race.
> 2. There is guarantee that (1) will be executed before (2) because (1) is 
> a synchronization action and Executor.execute is also a synchronization 
> access (not specifically execute itself)
>
> Yes?
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: JMM- synchronization access in a concrete example.

2018-09-25 Thread 'Cezary Biernacki' via mechanical-sympathy
My guess because "If x and y are actions of the same thread and x comes
before y in program order, then hb(x, y)."
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5

On Tue, Sep 25, 2018 at 8:44 PM John Hening  wrote:

> (1) should happen before "executor.execute()" (because they are on the
>> same thread),
>>
>
> It does not matter that they are executed on the same thread. I do not see
> cause here to HB relation was set up.
>
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-sympathy+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>


-- 
Cezary Biernacki
Director of Software Development
crosswordcybersecurity.com @crosswordcyber

Crossword Cybersecurity Plc is a public limited company registered in
England and Wales. Registered number: 08927013. Registered office: 6th
Floor, 60 Gracechurch Street, London, EC3V 0HR.

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: JMM- synchronization access in a concrete example.

2018-09-25 Thread John Hening

>
> (1) should happen before "executor.execute()" (because they are on the 
> same thread), 
>

It does not matter that they are executed on the same thread. I do not see 
cause here to HB relation was set up.

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: JMM- synchronization access in a concrete example.

2018-09-25 Thread 'Cezary Biernacki' via mechanical-sympathy
Hi,
I assume you are worried that (1) can be moved by the compiler below
"executor.execute()"  or on processors with weak memory models changes from
(1) might not be fully visible to other threads  when (2) is executed. I
believe it is not going to happen, as (1) should happen before
"executor.execute()" (because they are on the same thread), which in turn
should happen before retrieving a task for execution (because they are
synchronised via task queue), which again happens before (2) (because on
the same thread with the retrieving operation).

Best regards,
Cezary


On Tue, Sep 25, 2018 at 5:52 PM John Hening  wrote:

> public class Test {
> ArrayList xs;
> ArrayList doers;
> Executor executor = Executors.newSingleThreadExecutor();
>
> static class Doer {
>   public void does(X x){
>x.f(); //
> (2)
>   }
> }
>
> void test() {
> for(X x : xs){
> x.f();  //
> (1)
>
> for(Doer d : doers) {
> executor.execute(() -> d.does(x));
> }
> }
> }
> }
>
>
>
>
> For my eye, if X.f is not synchronized it is incorrect because of two
> facts (and only that two facts):
>
> 1. Obviously, there is data race between (1) and (2). There are no more
> data races here. (doers contains different objects)
> 2. There is no guarantee that (1) will be executed before (2). Yes?
>
> If X.f would be synchronized that code will be correct because:
> 1. There is no data race.
> 2. There is guarantee that (1) will be executed before (2) because (1) is
> a synchronization action and Executor.execute is also a synchronization
> access (not specifically execute itself)
>
> Yes?
>
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-sympathy+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>


-- 
Cezary Biernacki
Director of Software Development
crosswordcybersecurity.com @crosswordcyber

Crossword Cybersecurity Plc is a public limited company registered in
England and Wales. Registered number: 08927013. Registered office: 6th
Floor, 60 Gracechurch Street, London, EC3V 0HR.

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.