blob: 4e877f6d8dfd3f81bf5f2d653dd86273904a78ea [file] [log] [blame]
Stephen Hines86277eb2015-03-23 12:06:32 -07001#include <pthread.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <dlfcn.h>
6#include <stddef.h>
7
8// TSan-invisible barrier.
9// Tests use it to establish necessary execution order in a way that does not
10// interfere with tsan (does not establish synchronization between threads).
11__typeof(pthread_barrier_wait) *barrier_wait;
12
13void barrier_init(pthread_barrier_t *barrier, unsigned count) {
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -070014#if defined(__FreeBSD__)
15 static const char libpthread_name[] = "libpthread.so";
16#else
17 static const char libpthread_name[] = "libpthread.so.0";
18#endif
19
Stephen Hines86277eb2015-03-23 12:06:32 -070020 if (barrier_wait == 0) {
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -070021 void *h = dlopen(libpthread_name, RTLD_LAZY);
Stephen Hines86277eb2015-03-23 12:06:32 -070022 if (h == 0) {
Pirama Arumuga Nainar7c915052015-04-08 08:58:29 -070023 fprintf(stderr, "failed to dlopen %s, exiting\n", libpthread_name);
Stephen Hines86277eb2015-03-23 12:06:32 -070024 exit(1);
25 }
26 barrier_wait = (__typeof(barrier_wait))dlsym(h, "pthread_barrier_wait");
27 if (barrier_wait == 0) {
28 fprintf(stderr, "failed to resolve pthread_barrier_wait, exiting\n");
29 exit(1);
30 }
31 }
32 pthread_barrier_init(barrier, 0, count);
33}
34
35// Default instance of the barrier, but a test can declare more manually.
36pthread_barrier_t barrier;
37
38void print_address(void *address) {
39// On FreeBSD, the %p conversion specifier works as 0x%x and thus does not match
40// to the format used in the diagnotic message.
41#ifdef __x86_64__
42 fprintf(stderr, "0x%012lx", (unsigned long) address);
43#elif defined(__mips64)
44 fprintf(stderr, "0x%010lx", (unsigned long) address);
45#endif
46}