preload/posix/generate: Replace spaces with tab
[libfiu.git] / tests / test-parallel-wildcard.c
blob3aaa13623d36828d78578bab48e01924ee36f152
2 /* Test creation and removal of wildcarded failure points while checking them
3 * on a different thread.
5 * This test will have a thread enabling and disabling failure points like
6 * point:number:1:*, point:number:2:*, ...
8 * Then it has two threads checking:
9 * point:number:1:1, point:number:1:2, ...,
10 * point:number:2:1, point:number:2:2, ...
12 * Please note this is a non-deterministic test. */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <stdbool.h>
17 #include <unistd.h>
18 #include <pthread.h>
19 #include <assert.h>
21 #include <fiu.h>
22 #include <fiu-control.h>
24 /* Be careful with increasing these numbers, as the memory usage is directly
25 * related to them. */
26 #define NHIGH 1000
27 #define NLOW 1000
29 /* Maximum number of a failure point's name */
30 #define MAX_FPNAME 32
32 /* How many seconds to run the test */
33 #define TEST_TIME 5
35 /* Signal for the threads to stop. */
36 bool stop_threads = false;
38 /* The name of each final point. */
39 char final_point_name[NHIGH][NLOW][MAX_FPNAME];
41 /* The name of each wildcarded point. */
42 char wildcard_point_name[NHIGH][MAX_FPNAME];
44 char *make_final_point_name(char *name, int high, int low)
46 sprintf(name, "point/number/%d/%d", high, low);
47 return name;
50 char *make_wildcard_point_name(char *name, int high)
52 sprintf(name, "point/number/%d/*", high);
53 return name;
56 /* Calls all the final points all the time. */
57 unsigned long long no_check_caller_count = 0;
58 void *no_check_caller(void *unused)
60 int high, low;
62 for (;;) {
63 for (high = 0; high < NHIGH; high++) {
64 for (low = 0; low < NLOW; low++) {
65 fiu_fail(final_point_name[high][low]);
66 no_check_caller_count++;
68 if (stop_threads)
69 return NULL;
73 return NULL;
76 bool rand_bool(void) {
77 return (rand() % 2) == 0;
80 /* Used too know if a point is enabled or not. */
81 bool enabled[NHIGH];
82 pthread_rwlock_t enabled_lock;
85 /* Calls all the *enabled* points all the time. */
86 unsigned long long checking_caller_count = 0;
87 void *checking_caller(void *unused)
89 int high, low;
90 int failed;
92 for (;;) {
93 for (high = 0; high < NHIGH; high++) {
94 pthread_rwlock_rdlock(&enabled_lock);
95 if (!enabled[high]) {
96 pthread_rwlock_unlock(&enabled_lock);
97 continue;
100 for (low = 0; low < NLOW; low++) {
101 failed = fiu_fail(
102 final_point_name[high][low]) != 0;
103 if (!failed) {
104 printf("ERROR: %d:%d did not fail\n",
105 high, low);
106 assert(false);
108 checking_caller_count++;
110 pthread_rwlock_unlock(&enabled_lock);
112 if (stop_threads)
113 return NULL;
117 return NULL;
120 /* Enable and disable wildcarded points all the time. */
121 unsigned long long enabler_count = 0;
122 void *enabler(void *unused)
124 int high;
126 for (;;) {
127 for (high = 0; high < NHIGH; high++) {
128 /* 50% chance of flipping this point. */
129 if (rand_bool())
130 continue;
132 pthread_rwlock_wrlock(&enabled_lock);
133 if (enabled[high]) {
134 assert(fiu_disable(wildcard_point_name[high])
135 == 0);
136 enabled[high] = false;
137 } else {
138 assert(
139 fiu_enable(
140 wildcard_point_name[high],
141 1, NULL, 0) == 0);
142 enabled[high] = true;
144 pthread_rwlock_unlock(&enabled_lock);
145 enabler_count++;
147 if (stop_threads)
148 return NULL;
152 return NULL;
155 void disable_all()
157 int high;
159 pthread_rwlock_wrlock(&enabled_lock);
160 for (high = 0; high < NHIGH; high++) {
161 /* Note this could fail as we don't check if they're active or
162 * not, but here we don't care. */
163 fiu_disable(wildcard_point_name[high]);
165 pthread_rwlock_unlock(&enabled_lock);
168 int main(void)
170 int high, low;
172 pthread_t t1, t2, t3;
174 fiu_init(0);
176 for (high = 0; high < NHIGH; high++) {
177 make_wildcard_point_name(wildcard_point_name[high], high);
179 for (low = 0; low < NLOW; low++) {
180 make_final_point_name(final_point_name[high][low],
181 high, low);
185 pthread_rwlock_init(&enabled_lock, NULL);
187 pthread_create(&t1, NULL, no_check_caller, NULL);
188 pthread_create(&t2, NULL, checking_caller, NULL);
189 pthread_create(&t3, NULL, enabler, NULL);
191 sleep(TEST_TIME);
193 stop_threads = 1;
195 pthread_join(t1, NULL);
196 pthread_join(t2, NULL);
197 pthread_join(t3, NULL);
199 disable_all();
201 pthread_rwlock_destroy(&enabled_lock);
203 printf("wildcard nc: %-8llu c: %-8llu e: %-8llu t: %llu\n",
204 no_check_caller_count, checking_caller_count,
205 enabler_count,
206 no_check_caller_count + checking_caller_count
207 + enabler_count);
209 return 0;