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.
                                          

Reply via email to