What I've found during the refactoring process is that fixing one data race bug 
will expose another.

The latest test failure on multiple architectures has previously never failed 
during testing (its the only test failure on ubuntu x64 and arm jdk7), here a 
boolean field is written to while synchronized by an event listening thread, 
the field value is then read unsynchronized by the test thread, twice in short 
succession, the first read should have caused the test to pass, but this read 
experiences a data race.  The second read of the field sees the updated value 
and causes a test failure.  Without the race condition the test thread wouldn't 
arrive at this point.

I don't know the internal workings of the jvm, but it seems like the more 
correct code is, the more agressively the jvm optimises.

So now I've fixed so many other issues, these race conditions are starting to 
fail every time, rather than occassionally.

Regards,

Peter.
----- Original message -----
> On 12/17/2013 7:42 AM, Gregg Wonderly wrote:
> ...
> > As I’ve discussed here before, one of the most destructive
> > activities
> that has happened in the JDK, has been the “enforcement” of “volatile”
> vs “non-volatile” correctness in the activities of the JIT. The standing
> example, is this:
> >
> > class foo implements Runnable {
> >     bool done;
> >
> >     public void run() {
> >         while(!done) {
> >             doAllTheWork();
> >         }
> >     }
> >     public void stop() {
> >         done = true;
> >     }
> > }
> >
> > In JDK 1.4 and before, this class would function correctly on single
> processor machines (which most developers used), and would hardly ever
> exhibit a “bug” on multi-core and multi-processor machines. In JDK 5 and
> later, the JIT rewrites this class to look like
>
> >
> > class foo implements Runnable {
> >     bool done;
> >
> >     public void run() {
> >         if(!done) {
> >             while( true ) {
> >                 doAllTheWork();
> >             }
> >         }
> >     }
> >     public void stop() {
> >         done = true;
> >     }
> > }
> ...
> > It’s amazingly frustrating and has made Java a very complex language
> > to use, because the focus is first on “all out performance” and not
> > on “developer success”.
>
> I disagree with this summary.
>
> The effect of the JIT change, in addition to improving performance for
> correct code, is to make missing volatile declarations much more
> visible. It is likely to make the difference between a bug that happens
> in a day of simple regression testing and one that happens much less
> frequently, and only on some multiprocessor hardware configurations.
>
> Counting on uniprocessor-only is rapidly becoming unrealistic. Ideas for
> using chip space, or additional chips on a board, to add performance are
> running out of steam. Most hardware performance gains will have to come
> from more processors. Even if a developer does some of their work on a
> uniprocessor, they should expect their code to be used on
> multiprocessors.
>
> I've debugged a problem that happened about once a week if a particular
> workload was run on at least 50 processors, and it is one of the most
> technically difficult and frustrating tasks I've ever done - and I had
> access to resources that most software developers do not have.
>
> Converting a "hardly-ever" failure to one that is likely to show up
> often enough to be easy to detect and debug, even on a uniprocessor, is
> highly positive for developer success. It enables changing "hardly-ever"
> to "never".
>
> Patricia
>

Reply via email to