]>
Commit | Line | Data |
---|---|---|
2077db1b CT |
1 | #include <stdlib.h> |
2 | #include <dlfcn.h> | |
3 | #include <stdio.h> | |
4 | ||
5 | #include "vtv_utils.h" | |
6 | #include "vtv_rts.h" | |
7 | #include "pthread.h" | |
8 | ||
9 | #define NUM_REPEATS 10 | |
10 | #define NUM_THREADS 10 | |
11 | #define NUM_SOS 100 | |
12 | #define NUM_SOS_PER_THREAD (NUM_SOS/NUM_THREADS) | |
13 | ||
14 | typedef void (*voidfn)(void); | |
15 | ||
16 | int failures = 0; | |
17 | ||
18 | void | |
19 | __vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer) | |
20 | { | |
21 | failures++; | |
22 | return; | |
23 | } | |
24 | ||
25 | ||
26 | void do_dlopen(int so_num) | |
27 | { | |
28 | char so_name [sizeof("soxxx.so")]; | |
29 | sprintf(so_name, "so%d.so", so_num); | |
30 | // printf("dl-opening %s\n", so_name); | |
31 | void * dlhandle = dlopen(so_name, RTLD_NOW); | |
32 | if (!dlhandle) | |
33 | { | |
34 | fprintf(stderr, "dlopen so:%s error: %s\n", so_name, dlerror()); | |
35 | exit(1); | |
36 | } | |
37 | char so_entry [sizeof("so_entry_xxx")]; | |
38 | sprintf(so_entry, "so_entry_%d", so_num); | |
39 | voidfn so_entry_fn = (voidfn)dlsym(dlhandle, so_entry); | |
40 | if (!so_entry_fn) | |
41 | { | |
42 | fprintf(stderr, "so:%s dlsym error: %s\n", so_name, dlerror()); | |
43 | exit(2); | |
44 | } | |
45 | ||
46 | so_entry_fn(); | |
47 | ||
48 | dlclose(dlhandle); | |
49 | } | |
50 | ||
51 | volatile int threads_completed_it = 0; | |
52 | volatile int current_wave = -1; | |
53 | ||
54 | void * do_dlopens(void * ptid) | |
55 | { | |
56 | for (int k = 0; k < NUM_REPEATS; k++) | |
57 | { | |
58 | ||
59 | for (int i = 0; i < NUM_SOS_PER_THREAD; i++) | |
60 | { | |
61 | while (current_wave < (k*NUM_SOS_PER_THREAD + i)) /* from 0 to 99 */ | |
62 | ; | |
63 | ||
64 | do_dlopen((NUM_SOS_PER_THREAD * *(int *)ptid) + i); | |
65 | ||
66 | int old_value; | |
67 | do { | |
68 | old_value = threads_completed_it; | |
69 | } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1)); | |
70 | ||
71 | if (old_value == (NUM_THREADS - 1)) // Only one thread will do this. | |
72 | { | |
73 | threads_completed_it = 0; | |
74 | printf("%c%d", 13, current_wave + 1); | |
75 | fflush(stdout); | |
76 | current_wave++; | |
77 | } | |
78 | } | |
79 | } | |
80 | ||
81 | return NULL; | |
82 | } | |
83 | ||
84 | ||
85 | int main() | |
86 | { | |
87 | pthread_t thread_ids[NUM_THREADS]; | |
88 | int thread_nids[NUM_THREADS]; | |
89 | ||
90 | for (int t = 0; t < NUM_THREADS; t++ ) | |
91 | { | |
92 | thread_nids[t] = t; | |
93 | if (pthread_create(&thread_ids[t], NULL, do_dlopens, &thread_nids[t]) != 0) | |
94 | { | |
95 | printf("failed pthread_create\n"); | |
96 | exit(1); | |
97 | } | |
98 | } | |
99 | ||
100 | current_wave = 0; // start the work on the other threads | |
101 | ||
102 | for (int t = 0; t < NUM_THREADS; t++) | |
103 | if (pthread_join(thread_ids[t], NULL) != 0) | |
104 | { | |
105 | printf("failed pthread_join\n"); | |
106 | exit(2); | |
107 | } | |
108 | ||
109 | printf("\n"); | |
110 | ||
111 | return 0; | |
112 | } |