Fix libtcc_test_mt

The test failed because atexit/on_exit code was not correct.
Make it look more like the g_exit_context.
Added a sleep to libtcc_test_mt to allow overlap of threads to
detect this problem.
This commit is contained in:
herman ten brugge 2022-12-04 11:55:06 +01:00
parent e2db3a5e57
commit 85b27432bb
2 changed files with 39 additions and 21 deletions

View file

@ -147,31 +147,41 @@ static void run_cdtors(TCCState *s1, const char *start, const char *end,
#define NR_AT_EXIT 32 #define NR_AT_EXIT 32
static int exit_called = 0; static struct exit_context {
static int nr_exit = 0; int exit_called;
static void (*exitfunc[NR_AT_EXIT])(int, void *); int nr_exit;
static void *exitarg[NR_AT_EXIT]; void (*exitfunc[NR_AT_EXIT])(int, void *);
void *exitarg[NR_AT_EXIT];
#ifndef CONFIG_TCC_BACKTRACE #ifndef CONFIG_TCC_BACKTRACE
static jmp_buf run_jmp_buf; jmp_buf run_jmp_buf;
#endif #endif
} g_exit_context;
static void init_exit(void) static void init_exit(void)
{ {
exit_called = 0; struct exit_context *e = &g_exit_context;
nr_exit = 0;
e->exit_called = 0;
e->nr_exit = 0;
} }
static void call_exit(int ret) static void call_exit(int ret)
{ {
while (nr_exit--) struct exit_context *e = &g_exit_context;
exitfunc[nr_exit](ret, exitarg[nr_exit]);
while (e->nr_exit) {
e->nr_exit--;
e->exitfunc[e->nr_exit](ret, e->exitarg[e->nr_exit]);
}
} }
static int rt_atexit(void (*function)(void)) static int rt_atexit(void (*function)(void))
{ {
if (nr_exit < NR_AT_EXIT) { struct exit_context *e = &g_exit_context;
exitfunc[nr_exit] = (void (*)(int, void *))function;
exitarg[nr_exit++] = NULL; if (e->nr_exit < NR_AT_EXIT) {
e->exitfunc[e->nr_exit] = (void (*)(int, void *))function;
e->exitarg[e->nr_exit++] = NULL;
return 0; return 0;
} }
return 1; return 1;
@ -179,9 +189,11 @@ static int rt_atexit(void (*function)(void))
static int rt_on_exit(void (*function)(int, void *), void *arg) static int rt_on_exit(void (*function)(int, void *), void *arg)
{ {
if (nr_exit < NR_AT_EXIT) { struct exit_context *e = &g_exit_context;
exitfunc[nr_exit] = function;
exitarg[nr_exit++] = arg; if (e->nr_exit < NR_AT_EXIT) {
e->exitfunc[e->nr_exit] = function;
e->exitarg[e->nr_exit++] = arg;
return 0; return 0;
} }
return 1; return 1;
@ -189,11 +201,13 @@ static int rt_on_exit(void (*function)(int, void *), void *arg)
static void run_exit(int code) static void run_exit(int code)
{ {
exit_called = 1; struct exit_context *e = &g_exit_context;
e->exit_called = 1;
#ifdef CONFIG_TCC_BACKTRACE #ifdef CONFIG_TCC_BACKTRACE
longjmp(g_rtctxt.jmp_buf, code ? code : 256); longjmp((&g_rtctxt)->jmp_buf, code ? code : 256);
#else #else
longjmp(run_jmp_buf, code ? code : 256); longjmp(e->run_jmp_buf, code ? code : 256);
#endif #endif
} }
@ -277,7 +291,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
#ifdef CONFIG_TCC_BACKTRACE #ifdef CONFIG_TCC_BACKTRACE
if (!(ret = setjmp(rc->jmp_buf))) if (!(ret = setjmp(rc->jmp_buf)))
#else #else
if (!(ret = setjmp(run_jmp_buf))) if (!(ret = setjmp((&g_exit_context)->run_jmp_buf)))
#endif #endif
{ {
ret = prog_main(argc, argv, envp); ret = prog_main(argc, argv, envp);
@ -286,7 +300,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
call_exit(ret); call_exit(ret);
if ((s1->dflag & 16) && ret) if ((s1->dflag & 16) && ret)
fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp); fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp);
if ((s1->dflag & 16) == 0 && exit_called) if ((s1->dflag & 16) == 0 && (&g_exit_context)->exit_called)
exit(ret); exit(ret);
return ret; return ret;
} }

View file

@ -288,6 +288,9 @@ int main(int argc, char **argv)
#else #else
#include <tcclib.h> #include <tcclib.h>
unsigned int sleep(unsigned int seconds);
int fib(n) int fib(n)
{ {
return (n <= 2) ? 1 : fib(n-1) + fib(n-2); return (n <= 2) ? 1 : fib(n-1) + fib(n-2);
@ -295,7 +298,8 @@ int fib(n)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf(" %d", fib(atoi(argv[1]), 2)); sleep(1);
printf(" %d", fib(atoi(argv[1])));
return 0; return 0;
} }
#endif #endif