This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix sporadic failure in g++.dg/tsan/aligned_vs_unaligned_race.C
- From: Mike Stump <mikestump at comcast dot net>
- To: Bernd Edlinger <bernd dot edlinger at hotmail dot de>
- Cc: Jakub Jelinek <jakub at redhat dot com>, "H.J. Lu" <hjl dot tools at gmail dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Dmitry Vyukov <dvyukov at google dot com>
- Date: Mon, 5 Jan 2015 14:01:42 -0800
- Subject: Re: [PATCH] Fix sporadic failure in g++.dg/tsan/aligned_vs_unaligned_race.C
- Authentication-results: sourceware.org; auth=none
- References: <DUB118-W421A4A9D8D09CBAF5103DAE45A0 at phx dot gbl>,<3C12133C-DABF-40FA-94F7-9DB785F6E914 at comcast dot net>,<DUB118-W292D09896C48BED7B29B14E45A0 at phx dot gbl>,<DUB118-W8F5E63DE36A8DB2DA1DF6E45B0 at phx dot gbl>,<623A5348-6FC9-4F7B-A9BC-B2B098AF7D37 at comcast dot net>,<20150104191658 dot GK1667 at tucnak dot redhat dot com> <DUB118-W450ACE7162969EFB27F817E45B0 at phx dot gbl>,<8E43F8AA-96BA-47A3-A886-C058459B4108 at comcast dot net> <DUB118-W286F157F7B8B1EE05ED51FE4580 at phx dot gbl> <E67B07D7-6ABA-48C1-B58B-B804144D91C2 at comcast dot net>
On Jan 5, 2015, at 12:58 PM, Mike Stump <mikestump@comcast.net> wrote:
> So, to help you out, I tried my hand at wiring up the extra library code:
So, my tsan build finally finished, and I could try this with a real test case. I ran it 20 times, and got 11 fails with:
$ i=20; while let i--; do make RUNTESTFLAGS=tsan.exp=aligned_vs_unaligned_race.C check-g++ | grep FAIL; done
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O0 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O0 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O0 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O2 execution test
FAIL: g++.dg/tsan/aligned_vs_unaligned_race.C -O0 execution test
$
When I fixed the problem, I ran it 20 times:
$ i=20; while let i--; do make RUNTESTFLAGS=tsan.exp=aligned_vs_unaligned_race.C check-g++ | grep FAIL; done
$
and got 0 failures.
So, it seems to work. I’d like a tsan person to review it and we can go from there.
The only thing I would add to it would be a huge comment that explains that the tsan run time isn’t thread safe and they should use a lock free update to the shadow bits, but, they don’t. We introduce the step primitive to work around that bug. Ideally, the the problem should be filed into a bug database for the tsan code gen and when closed as not to be fixed, we can then change the word bug to design, but leave the bug reference so that others that want to completely understand the issue can go read up on it. If they actually fix the codegen to be thread safe, then we can simply remove all the step code.
To make this clang friendly, if one turns off inlining and obscures the semantics with weak from the optimizer and puts it into a header files and then #includes that header files, I think it would work. I’ll leave this to someone that might want to do that. If not, I’m fine with #ifdef clang/gcc and have the gcc test cases use step and the clang test cases, well, be unreliable.
$ svn diff
Index: g++.dg/tsan/aligned_vs_unaligned_race.C
===================================================================
--- g++.dg/tsan/aligned_vs_unaligned_race.C (revision 219198)
+++ g++.dg/tsan/aligned_vs_unaligned_race.C (working copy)
@@ -1,11 +1,17 @@
+/* { dg-additional-sources "lib.c" } */
/* { dg-shouldfail "tsan" } */
+
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
+#include <unistd.h>
+
+void step(int);
uint64_t Global[2];
void *Thread1(void *x) {
+ step (2);
Global[1]++;
return NULL;
}
@@ -15,6 +21,7 @@ void *Thread2(void *x) {
struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; };
u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1);
(*p4).val++;
+ step (1);
return NULL;
}
$ cat g++.dg/tsan/lib.c
/* { dg-do compile } */
#include <unistd.h>
volatile int serial;
__attribute__((no_sanitize_address))
void step(int i) {
while (serial != i-1) ;
while (1) {
if (++serial == i)
return;
--serial;
sleep (1);
}
}