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 <[email protected]> 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.