public inbox for java-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Boehm, Hans" <hans.boehm@hp.com>
To: Andrew Haley <aph@redhat.com>,
	Java Patch List <java-patches@gcc.gnu.org>
Subject: RE: Remove data race in libgcj interpreter
Date: Fri, 05 Sep 2008 09:39:00 -0000	[thread overview]
Message-ID: <238A96A773B3934685A7269CC8A8D0423152AF178E@GVW0436EXB.americas.hpqcorp.net> (raw)
In-Reply-To: <48C0042C.5080804@redhat.com>

>
> +
> /*************************************************************
> **********
> +   Locking in the direct-threaded case is quite subtle.  See PR
> +   libgcj/8995 for more details.
> +
> +   We must ensure that no-one ever reads an inconsistent {insn,value}
> +   pair.  Rather than trying to lock everything we detect when some
> +   other thread has modified the insn we are trying to
> modify and back
> +   out.
> +
> +   When we read a pair before rewriting it we do this:
> +
> +     i1 = insn
> +     v = value
> +     lock
> +       i2 = insn
> +     unlock
> +     if (i2 != i1) try again
This is probably statistically likely to generate correct code on some machines, but it doesn't look correct to me.  I think you're counting on the three loads to be performed in the order written.  But the compiler gets to reshuffle the first two.  And there is generally no prohibition against moving loads INTO a critical section, so they can in fact also be arbitrarily reordered with the i2 assignment as well.  (On IA64 and SPARC, the hardware might conceivably do that, depending on the lock implementation.  There is a long story about when this is Posix compatible, but it doesn't really matter here.)

There is also another important issue:  Posix and the upcoming C++ standard (among others) give undefined behavior to any program involving a data race.  Clearly this program involves data races on the initial insn and value reads.  The problem is that there are several good reasons for the Posix and C++ positions:

1) Compilers, including I believe gcc, implicitly assume that there are no asynchronous changes on non-volatile variables.  If you invalidate this assumption, weird things may happen.  These weird things don't always correspond to reading a different value.  For example, the compiler may reread a register copy of the value from the shared variable when it has to spill the register, making it appear that a local variable (which is a copy of the shared variable) suddenly changes without an assignment to it.  It's not hard to come up with cases in which this would provoke a crash.  Empirically, this sort of thing doesn't happen much, but we were told at some point that gcc may behave this way.

2) I would guess that gcc supports some platforms on which things like pointer loads are not always atomic.

3) In the not-too-distant future, we'd really like to have reliable data-race detectors.  This is much easier if code doesn't contain intentional data races.

4) None of us has managed to come up with an entirely satisfactory definition of what programs with data races mean.  The JSR133 definition is reasonably close, but still has some issues that have come up recently.  And it would probably have more serious performance implications on something like C++.

I haven't thought though this through enough.  Does it work to instead keep a shared (possibly per method?) count of the number of running interpreters, together with a shared bit (tested on backward branches) asking them to stop?  You only modify the code if no interpreters are running (in that method).  Getting this right is still nontrivial, but the races are restricted to well-defined atomic variables, which is fine.

Hans

> +
> +   and when we write a pair we do this:
> +
> +      lock
> +        value = v
> +        write barrier
> +        insn = i
> +      unlock
> +
> +   There is a read barrier in NEXT_INSN which ensures that we don't
> +   read a rewritten value with a stale insn.
> +
> +

  parent reply	other threads:[~2008-09-04 18:37 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-21 13:31 Andrew Haley
2008-08-21 21:54 ` Andrew Haley
2008-08-22 12:12   ` gij: more thread-safety fixes Andrew Haley
2008-08-22 12:51 ` Remove data race in libgcj interpreter Bryce McKinlay
2008-08-24  1:46   ` Andrew Haley
2008-09-04 16:00 ` Andrew Haley
2008-09-04 16:12   ` David Daney
2008-09-04 16:25     ` Andrew Haley
2008-09-04 18:37       ` David Daney
2008-09-05  9:39   ` Boehm, Hans [this message]
2008-09-05 11:28     ` Andrew Haley
2008-09-06  9:26       ` Hans Boehm
2008-09-08 17:42         ` Andrew Haley
2008-09-22 14:25           ` Andrew Haley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=238A96A773B3934685A7269CC8A8D0423152AF178E@GVW0436EXB.americas.hpqcorp.net \
    --to=hans.boehm@hp.com \
    --cc=aph@redhat.com \
    --cc=java-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).