2 * Multi-thread Test for libtcc
12 #define M 20 /* number of states */
13 #define F(n) (n % 20 + 2) /* fib argument */
17 #define TF_TYPE(func, param) DWORD WINAPI func(void *param)
18 typedef TF_TYPE(ThreadFunc
, x
);
20 void create_thread(ThreadFunc f
, int n
)
23 hh
[n
] = CreateThread(NULL
, 0, f
, (void*)(size_t)n
, 0, &tid
);
25 void wait_threads(int n
)
27 WaitForMultipleObjects(n
, hh
, TRUE
, INFINITE
);
31 void sleep_ms(unsigned n
)
39 #define TF_TYPE(func, param) void* func(void *param)
40 typedef TF_TYPE(ThreadFunc
, x
);
42 void create_thread(ThreadFunc f
, int n
)
44 pthread_create(&hh
[n
], NULL
, f
, (void*)(size_t)n
);
46 void wait_threads(int n
)
49 pthread_join(hh
[--n
], NULL
);
52 void sleep_ms(unsigned n
)
58 void handle_error(void *opaque
, const char *msg
)
60 fprintf(opaque
, "%s\n", msg
);
63 /* this function is called by the generated code */
70 #define str(s) _str(s)
71 /* as a trick, prepend #line directive for better error/warning messages */
73 char lbl[] = "#line " str(__LINE__) " " str(__FILE__) "\n\n"
76 "#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
77 "int add(int a, int b);\n"
83 " return add(fib(n-1),fib(n-2));\n"
86 "void bar(void) { *(void**)0 = 0; }\n"
90 " printf(\" %d\", fib(n));\n"
91 " if (n >= N_CRASH && n < N_CRASH + 8)\n"
94 "# warning is this the correct file:line...\n"
97 int g_argc
; char **g_argv
;
99 void parse_args(TCCState
*s
)
102 /* if tcclib.h and libtcc1.a are not installed, where can we find them */
103 for (i
= 1; i
< g_argc
; ++i
) {
107 tcc_set_lib_path(s
, a
+2);
108 else if (a
[1] == 'I')
109 tcc_add_include_path(s
, a
+2);
110 else if (a
[1] == 'L')
111 tcc_add_library_path(s
, a
+2);
112 else if (a
[1] == 'D')
113 tcc_define_symbol(s
, a
+2, NULL
);
127 printf("\n *** %p %s %s:%d in '%s'",
133 return 1; // want more backtrace levels
135 //printf(" [%d]", *(int*)ud);
137 return 0; // cancel backtrace
141 TCCState
*new_state(int w
)
143 TCCState
*s
= tcc_new();
145 fprintf(stderr
, __FILE__
": could not create tcc state\n");
148 tcc_set_error_func(s
, stdout
, handle_error
);
151 tcc_set_options(s
, "-w");
153 tcc_set_options(s
, "-bt");
154 tcc_define_symbol(s
, "N_CRASH", str(M
/2));
156 tcc_define_symbol(s
, "N_CRASH", "-1000");
157 tcc_set_output_type(s
, TCC_OUTPUT_MEMORY
);
161 void *reloc_state(TCCState
*s
, const char *entry
)
164 tcc_add_symbol(s
, "add", add
);
165 if (tcc_relocate(s
) < 0) {
166 fprintf(stderr
, __FILE__
": could not relocate tcc state.\n");
169 func
= tcc_get_symbol(s
, entry
);
171 fprintf(stderr
, __FILE__
": could not get entry symbol.\n");
175 /* work with several states at the same time */
176 int state_test(int w
)
179 int (*funcs
[M
])(int);
183 for (n
= 0; n
< M
+ 4; ++n
) {
184 unsigned a
= n
, b
= n
- 1, c
= n
- 2, d
= n
- 3, e
= n
- 4;
188 if (tcc_compile_string(s
[b
], my_program
) == -1)
191 funcs
[c
] = reloc_state(s
[c
], "foo");
192 if (d
< M
&& funcs
[d
]) {
193 tcc_set_backtrace_func(s
[d
], &d
, backtrace_func
);
194 if (0 == tcc_setjmp(s
[d
], jb
, funcs
[d
]))
203 /* simple compilation in threads */
204 TF_TYPE(thread_test_simple
, vn
)
212 s
= new_state(0); /* '2' for exceptions */
214 ret
= tcc_compile_string(s
, my_program
);
217 func
= reloc_state(s
, "foo");
218 tcc_set_backtrace_func(s
, &n
, backtrace_func
);
220 if (0 == tcc_setjmp(s
, jb
, func
))
228 /* more complex compilation in threads */
229 TF_TYPE(thread_test_complex
, vn
)
234 char *argv
[30], b
[10];
237 sprintf(b
, "%d", F(n
));
239 for (i
= 1; i
< g_argc
; ++i
) argv
[argc
++] = g_argv
[i
];
241 argv
[argc
++] = "-run";
242 for (i
= 1; i
< g_argc
; ++i
) argv
[argc
++] = g_argv
[i
];
244 argv
[argc
++] = "-DFIB";
245 argv
[argc
++] = "-run";
246 argv
[argc
++] = __FILE__
;
252 ret
= tcc_add_file(s
, argv
[0]);
255 tcc_run(s
, argc
, argv
);
261 void time_tcc(int n
, const char *src
)
267 printf(" %d", i
), fflush(stdout
);
268 ret
= tcc_add_file(s
, src
);
275 static unsigned getclock_ms(void)
278 return GetTickCount();
281 gettimeofday(&tv
, NULL
);
282 return tv
.tv_sec
*1000 + (tv
.tv_usec
+500)/1000;
286 int main(int argc
, char **argv
)
295 fprintf(stderr
, "usage: libtcc_test_mt tcc.c <options>\n");
300 printf("running fib with mixed calls\n "), fflush(stdout
);
303 printf("\n (%u ms)\n", getclock_ms() - t
);
306 printf("producing some exceptions (!)\n "), fflush(stdout
);
309 printf("\n (%u ms)\n", getclock_ms() - t
);
312 //{ int i; for (i = 0; i < 100; ++i) { printf("(%d) ", i);
313 printf("running fib in threads\n "), fflush(stdout
);
315 for (n
= 0; n
< M
; ++n
)
316 create_thread(thread_test_simple
, n
);
318 printf("\n (%u ms)\n", getclock_ms() - t
);
322 printf("running tcc.c in threads to run fib\n "), fflush(stdout
);
324 for (n
= 0; n
< M
; ++n
)
325 create_thread(thread_test_complex
, n
);
327 printf("\n (%u ms)\n", getclock_ms() - t
);
330 printf("compiling tcc.c 10 times\n "), fflush(stdout
);
332 time_tcc(10, argv
[1]);
333 printf("\n (%u ms)\n", getclock_ms() - t
), fflush(stdout
);
341 unsigned int sleep(unsigned int seconds
);
345 return (n
<= 2) ? 1 : fib(n
-1) + fib(n
-2);
348 int main(int argc
, char **argv
)
351 printf(" %d", fib(atoi(argv
[1])));