public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Mike Stump <mikestump@comcast.net>
To: Bernd Edlinger <bernd.edlinger@hotmail.de>
Cc: Jakub Jelinek <jakub@redhat.com>, "H.J. Lu" <hjl.tools@gmail.com>,
	"gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
	Dmitry Vyukov <dvyukov@google.com>
Subject: Re: [PATCH] Fix sporadic failure in g++.dg/tsan/aligned_vs_unaligned_race.C
Date: Mon, 05 Jan 2015 20:58:00 -0000	[thread overview]
Message-ID: <E67B07D7-6ABA-48C1-B58B-B804144D91C2@comcast.net> (raw)
In-Reply-To: <DUB118-W286F157F7B8B1EE05ED51FE4580@phx.gbl>

On Jan 5, 2015, at 12:49 AM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote:
> On Sun, 4 Jan 2015 14:18:59, Mike Stump wrote:
>> 
>>> But tsan still gets at least 90% chance to spot that. As a matter of fact, the tsan runtime is just _incredibly_ fast,
>>> and catches errors, with a very high reliability. But it is racy by design.
>> 
>> You say by design. I’m skeptical of that. Can you quote the email or the code were they said I wanted to design a system that wasn’t 100% reliable, because the best they could do was 2% slower, and they didn’t want it to be 2% slower? I tend to think someone didn’t figure out they could atomically, locklessly do the update, or they didn’t understand the performance hit on the lockless code was small, or worse, they had no clue it was racy. I’d be curious to know. Maybe, there are other complications that prevent it from being non-racy.
> 
> see for instance this thread "Is TSan an exact tool?":
> https://groups.google.com/forum/#!topic/thread-sanitizer/mB73m6Nltaw

Yeah, that’s not the issue.  The issue is, in this one narrow case, was is possible to use a lockless method of updating the data so that the tool would be slightly better.  That post doesn’t address this question.  For example, if a patch were submitted to locklessly update so both can notice who is first, was it rejected and why?  Anyway, that’s a side issue, and we can safely ignore it.  I’m fine with making testing reliable with how it works today.

> Nevertheless I would prefer to silence the test now with sleep(1),

> And come back later with a follow-up patch to use a un-instrumented and
> non-interceptable synchronization primitive in all tsan tests. As it is at least
> not obvious how to do that in the test suite.  But it must be possible.

I thought the code was posted, I thought how to put it in a file was posted.  I think it is a 2 minute endeavor to put all those pieces together and run a test case?  You do know how to run just 1 tsan test case with make RUNTESTFLAGS=tsan.exp=aligned_vs_unaligned_race.C check-g++ sort of thing?  This can shorten the testing time from hours per iteration to seconds per iteration.  Slightly non-obvious, but very handy when developing some types of test cases.

So, to help you out, I tried my hand at wiring up the extra library code:

gcc/gcc/testsuite/gcc.dg/tsan$ cat test1.c
/* { dg-additional-options "-O2" } */
/* { dg-additional-sources "lib.c" } */

void sync(int);

int main(int argc, char**argv) {
  sync(1);
  sync(2);
  sync(3);
}
gcc/gcc/testsuite/gcc.dg/tsan$ cat lib.c
/* { dg-do compile } */
#include <stdlib.h>

volatile int serial;

__attribute__((no_sanitize_address))
void sync(int i) {
  while (serial != i-1) ;
  while (1) {
    if (++serial == i)
      return;
    --serial;
    sleep ();
  }
}

and it ran just fine.  The options are for both files.  I read some of the tsan documentation, and they seem to claim you can have tsan not process a function by merely asking.  I did that.  I don’t know if that is enough to hide all the semantics that need to be hidden.

In the above code, the ++ and -- should be an atomic increment/decrement.

The idea is that can can introduce a deterministic ordering to the execution of the code by adding sync(n), where n is the step number, whose range starts at 1.

So, for example, here is the test case, with the bits added, so you can see how I transformed what would have been the sleep into the use of the synchronizing primitive from the library.

/* { dg-additional-sources "lib.c" } */
/* { dg-shouldfail "tsan" } */

#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>

void sync(int);

uint64_t Global[2];

void *Thread1(void *x) {
  sync (2);
  Global[1]++;
  return NULL;
}

void *Thread2(void *x) {
  char *p1 = reinterpret_cast<char *>(&Global[0]);
  struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; };
  u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1);
  (*p4).val++;
  sync (1);
  return NULL;
}

int main() {
  pthread_t t[2];
  pthread_create(&t[0], NULL, Thread1, NULL);
  pthread_create(&t[1], NULL, Thread2, NULL);
  pthread_join(t[0], NULL);
  pthread_join(t[1], NULL);
  printf("Pass\n");
  /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
  /* { dg-output "Pass.*" } */
  return 0;
}

The question is, does this 100% reliably solve the problem?

  reply	other threads:[~2015-01-05 20:58 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-03  9:01 Bernd Edlinger
2015-01-03  9:51 ` Mike Stump
2015-01-03 11:20   ` Bernd Edlinger
2015-01-04 17:00     ` Bernd Edlinger
2015-01-04 19:07       ` Mike Stump
2015-01-04 19:17         ` Jakub Jelinek
2015-01-04 19:44           ` Bernd Edlinger
2015-01-04 22:19             ` Mike Stump
2015-01-05  8:49               ` Bernd Edlinger
2015-01-05 20:58                 ` Mike Stump [this message]
2015-01-05 22:02                   ` Mike Stump
2015-01-06  1:07                     ` Bernd Edlinger
2015-01-06  9:08                       ` Bernd Edlinger
2015-01-06  9:16                         ` Jakub Jelinek
2015-01-06  9:38                           ` Bernd Edlinger
2015-01-06 17:45                           ` Bernd Edlinger
2015-01-06 19:48                             ` Mike Stump
2015-01-06 23:22                               ` Bernd Edlinger
2015-01-07  0:33                                 ` Mike Stump
2015-01-07  7:17                                   ` Bernd Edlinger
2015-01-07  8:23                                     ` Jakub Jelinek
2015-01-07 14:55                                       ` Bernd Edlinger
2015-01-07 15:04                                         ` Jakub Jelinek
2015-01-07 16:58                                       ` Mike Stump
2015-01-07 17:00                                         ` Jakub Jelinek
2015-01-07 18:21                                           ` Bernd Edlinger
2015-01-07 18:32                                             ` Jakub Jelinek
2015-01-07 22:44                                               ` Bernd Edlinger
2015-01-08 19:24                                                 ` Mike Stump
2015-01-08 19:29                                                   ` Jakub Jelinek
2015-01-08 21:07                                                     ` Mike Stump
2015-01-08 21:27                                                       ` Jakub Jelinek
2015-01-08 22:06                                                         ` Mike Stump
2015-01-08 22:23                                                           ` Bernd Edlinger
2015-01-09 15:36                                                         ` Bernd Edlinger
2015-01-09 15:37                                                           ` Jakub Jelinek
2015-01-19  8:53                                                             ` Dmitry Vyukov
2015-01-19 15:16                                                               ` Mike Stump
2015-01-21  8:52                                                                 ` Dmitry Vyukov
2015-01-21  9:02                                                                   ` Jakub Jelinek
2015-01-21  9:07                                                                     ` Dmitry Vyukov
2015-01-08 19:10                                       ` Mike Stump
2015-01-07 16:36                                     ` Mike Stump
2015-01-06 21:29                       ` Mike Stump
2015-01-04 19:05     ` Mike Stump
2015-01-04 19:15       ` Jakub Jelinek
2015-01-04 21:48       ` Bernd Edlinger
2015-01-04 21:58         ` Mike Stump
2015-01-04 22:20           ` Bernd Edlinger

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=E67B07D7-6ABA-48C1-B58B-B804144D91C2@comcast.net \
    --to=mikestump@comcast.net \
    --cc=bernd.edlinger@hotmail.de \
    --cc=dvyukov@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hjl.tools@gmail.com \
    --cc=jakub@redhat.com \
    /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).