Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 1 | #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 | |
| 13 | void barrier_init(pthread_barrier_t *barrier, unsigned count) { |
Pirama Arumuga Nainar | 7c91505 | 2015-04-08 08:58:29 -0700 | [diff] [blame] | 14 | #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 Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 20 | if (barrier_wait == 0) { |
Pirama Arumuga Nainar | 7c91505 | 2015-04-08 08:58:29 -0700 | [diff] [blame] | 21 | void *h = dlopen(libpthread_name, RTLD_LAZY); |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 22 | if (h == 0) { |
Pirama Arumuga Nainar | 7c91505 | 2015-04-08 08:58:29 -0700 | [diff] [blame] | 23 | fprintf(stderr, "failed to dlopen %s, exiting\n", libpthread_name); |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 24 | 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. |
| 36 | pthread_barrier_t barrier; |
| 37 | |
| 38 | void 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 | } |