]> gcc.gnu.org Git - gcc.git/blob - gcc/testsuite/jit.dg/test-threads.c
Add test of handling arithmetic-overflow from JIT
[gcc.git] / gcc / testsuite / jit.dg / test-threads.c
1 /* test-threads.c
2
3 As per test-combination.c, construct a test case by combining other test
4 cases, to try to shake out state issues. However each test runs in a
5 separate thread. */
6
7 #include <pthread.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10
11 /* dejagnu.h isn't thread-safe; there's a shared "buffer", and the counts
12 of "passed"/"failed" etc are globals.
13
14 We get around this by putting a mutex around pass/fail calls.
15 */
16
17 static pthread_mutex_t dg_mutex = PTHREAD_MUTEX_INITIALIZER;
18
19 /* By defining MAKE_DEJAGNU_H_THREADSAFE before we include harness.h,
20 harness.h injects macros before including <dejagnu.h> so that the
21 pass/fail functions become "dejagnu_pass"/"dejagnu_fail" etc. */
22
23 void dejagnu_pass (const char* fmt, ...);
24 void dejagnu_fail (const char* fmt, ...);
25 void dejagnu_note (const char* fmt, ...);
26
27 /* We now provide our own implementations of "pass"/"fail"/"note", which
28 call the underlying dejagnu implementations, but with a mutex. */
29
30 inline void
31 pass (const char* fmt, ...)
32 {
33 va_list ap;
34 char buffer[512];
35
36 va_start (ap, fmt);
37 vsnprintf (buffer, sizeof (buffer), fmt, ap);
38 va_end (ap);
39
40 pthread_mutex_lock (&dg_mutex);
41 dejagnu_pass (buffer);
42 pthread_mutex_unlock (&dg_mutex);
43 }
44
45 inline void
46 fail (const char* fmt, ...)
47 {
48 va_list ap;
49 char buffer[512];
50
51 va_start (ap, fmt);
52 vsnprintf (buffer, sizeof (buffer), fmt, ap);
53 va_end (ap);
54
55 pthread_mutex_lock (&dg_mutex);
56 dejagnu_fail (buffer);
57 pthread_mutex_unlock (&dg_mutex);
58 }
59
60 inline void
61 note (const char* fmt, ...)
62 {
63 va_list ap;
64 char buffer[512];
65
66 va_start (ap, fmt);
67 vsnprintf (buffer, sizeof (buffer), fmt, ap);
68 va_end (ap);
69
70 pthread_mutex_lock (&dg_mutex);
71 dejagnu_note (buffer);
72 pthread_mutex_unlock (&dg_mutex);
73 }
74
75 #define MAKE_DEJAGNU_H_THREADSAFE
76
77 /* We also need to provide our own version of TEST_NAME. */
78 #define TEST_NAME
79
80 /* We can now include all of the relevant selftests. */
81
82 #include "all-non-failing-tests.h"
83
84 #define TEST_PROVIDES_MAIN
85 #define TEST_ESCHEWS_TEST_JIT
86
87 /* Now construct a test case from all the other test cases.
88
89 We undefine COMBINED_TEST so that we can now include harness.h
90 "for real". */
91 #undef COMBINED_TEST
92 #include "harness.h"
93
94 struct testcase
95 {
96 const char *m_name;
97 void (*m_hook_to_create_code) (gcc_jit_context *ctxt,
98 void * user_data);
99 void (*m_hook_to_verify_code) (gcc_jit_context *ctxt,
100 gcc_jit_result *result);
101 };
102
103 const struct testcase testcases[] = {
104 {"accessing_struct",
105 create_code_accessing_struct,
106 verify_code_accessing_struct},
107 {"accessing_union",
108 create_code_accessing_union,
109 verify_code_accessing_union},
110 {"arith_overflow",
111 create_code_arith_overflow,
112 verify_code_arith_overflow},
113 {"array_as_pointer",
114 create_code_array_as_pointer,
115 verify_code_array_as_pointer},
116 {"arrays",
117 create_code_arrays,
118 verify_code_arrays},
119 {"calling_external_function",
120 create_code_calling_external_function,
121 verify_code_calling_external_function},
122 {"calling_function_ptr",
123 create_code_calling_function_ptr,
124 verify_code_calling_function_ptr},
125 {"dot_product",
126 create_code_dot_product,
127 verify_code_dot_product},
128 {"expressions",
129 create_code_expressions,
130 verify_code_expressions},
131 {"factorial",
132 create_code_factorial,
133 verify_code_factorial},
134 {"fibonacci",
135 create_code_fibonacci,
136 verify_code_fibonacci},
137 {"functions",
138 create_code_functions,
139 verify_code_functions},
140 {"hello_world",
141 create_code_hello_world,
142 verify_code_hello_world},
143 {"linked_list",
144 create_code_linked_list,
145 verify_code_linked_list},
146 {"long_names",
147 create_code_long_names,
148 verify_code_long_names},
149 {"quadratic",
150 create_code_quadratic,
151 verify_code_quadratic},
152 {"nested_loop",
153 create_code_nested_loop,
154 verify_code_nested_loop},
155 {"reading_struct ",
156 create_code_reading_struct ,
157 verify_code_reading_struct },
158 {"string_literal",
159 create_code_string_literal,
160 verify_code_string_literal},
161 {"sum_of_squares",
162 create_code_sum_of_squares,
163 verify_code_sum_of_squares},
164 {"types",
165 create_code_types,
166 verify_code_types},
167 {"using_global",
168 create_code_using_global,
169 verify_code_using_global},
170 {"volatile",
171 create_code_volatile,
172 verify_code_volatile}
173 };
174
175 const int num_testcases = (sizeof (testcases) / sizeof (testcases[0]));
176
177 struct thread_data
178 {
179 pthread_t m_tid;
180 const struct testcase *m_testcase;
181 };
182
183 static const char *argv0;
184
185 void *
186 run_threaded_test (void *data)
187 {
188 struct thread_data *thread = (struct thread_data *)data;
189 int i;
190
191 for (i = 0; i < 5; i++)
192 {
193 gcc_jit_context *ctxt;
194 gcc_jit_result *result;
195
196 note ("run_threaded_test: %s iteration: %d",
197 thread->m_testcase->m_name, i);
198
199 ctxt = gcc_jit_context_acquire ();
200
201 set_options (ctxt, argv0);
202
203 thread->m_testcase->m_hook_to_create_code (ctxt, NULL);
204
205 result = gcc_jit_context_compile (ctxt);
206
207 thread->m_testcase->m_hook_to_verify_code (ctxt, result);
208
209 gcc_jit_context_release (ctxt);
210
211 /* Once we're done with the code, this unloads the built .so file: */
212 gcc_jit_result_release (result);
213 }
214
215 return NULL;
216 }
217
218 int
219 main (int argc, char **argv)
220 {
221 int i;
222
223 snprintf (test, sizeof (test),
224 "%s",
225 extract_progname (argv[0]));
226
227 argv0 = argv[0];
228
229 /* The individual testcases are not thread-safe (some have their own
230 global variables), so we have one thread per test-case. */
231 struct thread_data *threads =
232 calloc (num_testcases, sizeof (struct thread_data));
233
234 /* Start a thread per test-case. */
235 for (i = 0; i < num_testcases; i++)
236 {
237 struct thread_data *thread = &threads[i];
238 thread->m_testcase = &testcases[i];
239 pthread_create (&thread->m_tid,
240 NULL,
241 run_threaded_test,
242 thread);
243 }
244
245 /* Wait for all the threads to be done. */
246 for (i = 0; i < num_testcases; i++)
247 {
248 struct thread_data *thread = &threads[i];
249 (void)pthread_join (thread->m_tid, NULL);
250 }
251
252 totals ();
253
254 return 0;
255 }
This page took 0.048247 seconds and 5 git commands to generate.