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: Bernd Edlinger <bernd dot edlinger at hotmail dot de>
- To: Mike Stump <mikestump at comcast dot net>
- Cc: Jakub Jelinek <jakub at redhat dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 4 Jan 2015 22:48:17 +0100
- 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>,<18CD1660-7BFC-4E97-85E2-B523365E8E86 at comcast dot net>
On Sun, 4 Jan 2015 11:04:34, Mike Stump wrote:
>
> Ah, even more curious. So, for testing, it would be best if we had a way to synchronize the threads so that they reliably can show what you want to show, and reliably pick which thread will run first and which second and so on. The problem is of course, the synchronization primitives can’t get in the way (be seen by) of normal tsan functioning. I’m thinking asm() can so obscure arbitrary things, but I’m not sure I can’t think of a way to do that with anything less. sleep is close, and, at least portable and simple. What it isn’t is bullet proof. The tsan test cases would be enhanced if we could find a way to synchronize the threads invisibly to tsan. I’d like to think that someone can propose a better scheme than sleep. My thought would be something like:
>
> int order = 0;
>
> void sync(int i) {
> while (++order != i) { /* atomic inc */
> --order; /* atomic dec */
> sleep(1); /* or some type of operative yield */
> }
> }
>
>
>
> thread 1:
> asm (“call sync(1)”);
> action1;
> asm (“call sync(3)”);
> action3;
>
> thread 2:
>
> asm (“call sync(2)”);
> action2;
>
> where the order executed would be action1, action2, action3. The asm hides all details of the synchronization from everyone, optimizer, tsan.
>
> Now, why go to all this work? Simply, determinism in gcc and the test suite, is, well, nice. I understand that user programs won’t be so nice, and that in the wild, it won’t be 100%.
Hmm,,,,
that could work....
I would need a way to link the test case two helper functions, that are not compiled with -fsanitize=thread
like tsan-helper.C
void set(int * a , int b)
{
*a = b;
}
int get(int *a)
{
return *a;
}
uint64_t Global[2];
int z=0;
int get(int*);
void set(int*,int);
void *Thread1(void *x) {
/* We have to sleep here, to make it somewhat easier for tsan to
detect the race condition. */
while (get(&z) == 0);
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++;
set(&z,1);
return NULL;
}
I tried, it and it works 10.000 times without one failure.
But I have no idea how to do that in our test framework.
Bernd.