On Wed, 7 Jan 2015 18:00:27, Jakub Jelinek wrote: > > On Wed, Jan 07, 2015 at 08:58:04AM -0800, Mike Stump wrote: >> On Jan 7, 2015, at 12:23 AM, Jakub Jelinek <ja...@redhat.com> wrote: >>> But I really don't like the busy waiting. >> >> We’ve already determined that sched_sleep isn’t intercepted and can be used >> to non-busy wait. Any reason not to use it? >> >>> As tsan is only supported on x86_64-linux >> >> So, I hate hardening the code to be overly non-portable when it doesn’t have >> to be that. There is something enticing to me about the simplicity of >> sched_sleep. > > Well, pthread_barrier_wait and dlopen/dlsym are already used by libtsan and > therefore have to be supported on all the architectures that support tsan. > So that method is as portable as libtsan itself. > > Jakub
Ok, just for completeness, I've got the dlopen finally working: RTLD_NOLOAD is not working, but RTLD_LAZY or RTLD_NOW does. The test case is passing reliably with this method too. I am however not sure if I can always use -ldl or have to use some target-dependencies here. Index: aligned_vs_unaligned_race.C =================================================================== --- aligned_vs_unaligned_race.C (revision 219198) +++ aligned_vs_unaligned_race.C (working copy) @@ -1,11 +1,17 @@ /* { dg-shouldfail "tsan" } */ +/* { dg-additional-options "-ldl" } */ #include <pthread.h> +#include <sched.h> #include <stdio.h> #include <stdint.h> +#include "barrier.h" +static pthread_barrier_t barrier; + uint64_t Global[2]; void *Thread1(void *x) { + barrier_wait(&barrier); Global[1]++; return NULL; } @@ -15,10 +21,12 @@ struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; }; u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1); (*p4).val++; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); Index: barrier.h =================================================================== --- barrier.h (revision 0) +++ barrier.h (working copy) @@ -0,0 +1,12 @@ +#include <dlfcn.h> + +static __typeof(pthread_barrier_wait) *barrier_wait; + +static +void barrier_init (pthread_barrier_t *barrier) +{ + void *h = dlopen ("libpthread.so.0", RTLD_LAZY); + barrier_wait = (__typeof (pthread_barrier_wait) *) + dlsym (h, "pthread_barrier_wait"); + pthread_barrier_init (barrier, NULL, 2); +} Thanks Bernd.