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 17static 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 23void dejagnu_pass (const char* fmt, ...); 24void dejagnu_fail (const char* fmt, ...); 25void 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 30inline void 31pass (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 45inline void 46fail (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 60inline void 61note (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 94struct thread_data 95{ 96 pthread_t m_tid; 97 const struct testcase *m_testcase; 98}; 99 100static const char *argv0; 101 102void * 103run_threaded_test (void *data) 104{ 105 struct thread_data *thread = (struct thread_data *)data; 106 int i; 107 108 for (i = 0; i < 5; i++) 109 { 110 gcc_jit_context *ctxt; 111 gcc_jit_result *result; 112 113 note ("run_threaded_test: %s iteration: %d", 114 thread->m_testcase->m_name, i); 115 116 ctxt = gcc_jit_context_acquire (); 117 118 set_options (ctxt, argv0); 119 120 thread->m_testcase->m_hook_to_create_code (ctxt, NULL); 121 122 result = gcc_jit_context_compile (ctxt); 123 124 thread->m_testcase->m_hook_to_verify_code (ctxt, result); 125 126 gcc_jit_context_release (ctxt); 127 128 /* Once we're done with the code, this unloads the built .so file: */ 129 gcc_jit_result_release (result); 130 } 131 132 return NULL; 133} 134 135int 136main (int argc, char **argv) 137{ 138 int i; 139 140 snprintf (test, sizeof (test), 141 "%s", 142 extract_progname (argv[0])); 143 144 argv0 = argv[0]; 145 146 /* The individual testcases are not thread-safe (some have their own 147 global variables), so we have one thread per test-case. */ 148 struct thread_data *threads = 149 calloc (num_testcases, sizeof (struct thread_data)); 150 151 /* Start a thread per test-case. */ 152 for (i = 0; i < num_testcases; i++) 153 { 154 struct thread_data *thread = &threads[i]; 155 thread->m_testcase = &testcases[i]; 156 pthread_create (&thread->m_tid, 157 NULL, 158 run_threaded_test, 159 thread); 160 } 161 162 /* Wait for all the threads to be done. */ 163 for (i = 0; i < num_testcases; i++) 164 { 165 struct thread_data *thread = &threads[i]; 166 (void)pthread_join (thread->m_tid, NULL); 167 } 168 169 totals (); 170 171 return 0; 172} 173