From 85b27432bb994e34bd8ba9ebbf608b587ba13dbb Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Sun, 4 Dec 2022 11:55:06 +0100 Subject: [PATCH] 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. --- tccrun.c | 54 ++++++++++++++++++++++++++---------------- tests/libtcc_test_mt.c | 6 ++++- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/tccrun.c b/tccrun.c index 51b9a10d..07d9dbd6 100644 --- a/tccrun.c +++ b/tccrun.c @@ -147,31 +147,41 @@ static void run_cdtors(TCCState *s1, const char *start, const char *end, #define NR_AT_EXIT 32 -static int exit_called = 0; -static int nr_exit = 0; -static void (*exitfunc[NR_AT_EXIT])(int, void *); -static void *exitarg[NR_AT_EXIT]; +static struct exit_context { + int exit_called; + int nr_exit; + void (*exitfunc[NR_AT_EXIT])(int, void *); + void *exitarg[NR_AT_EXIT]; #ifndef CONFIG_TCC_BACKTRACE -static jmp_buf run_jmp_buf; + jmp_buf run_jmp_buf; #endif +} g_exit_context; static void init_exit(void) { - exit_called = 0; - nr_exit = 0; + struct exit_context *e = &g_exit_context; + + e->exit_called = 0; + e->nr_exit = 0; } static void call_exit(int ret) { - while (nr_exit--) - exitfunc[nr_exit](ret, exitarg[nr_exit]); + struct exit_context *e = &g_exit_context; + + 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)) { - if (nr_exit < NR_AT_EXIT) { - exitfunc[nr_exit] = (void (*)(int, void *))function; - exitarg[nr_exit++] = NULL; + struct exit_context *e = &g_exit_context; + + 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 1; @@ -179,9 +189,11 @@ static int rt_atexit(void (*function)(void)) static int rt_on_exit(void (*function)(int, void *), void *arg) { - if (nr_exit < NR_AT_EXIT) { - exitfunc[nr_exit] = function; - exitarg[nr_exit++] = arg; + struct exit_context *e = &g_exit_context; + + if (e->nr_exit < NR_AT_EXIT) { + e->exitfunc[e->nr_exit] = function; + e->exitarg[e->nr_exit++] = arg; return 0; } return 1; @@ -189,11 +201,13 @@ static int rt_on_exit(void (*function)(int, void *), void *arg) static void run_exit(int code) { - exit_called = 1; + struct exit_context *e = &g_exit_context; + + e->exit_called = 1; #ifdef CONFIG_TCC_BACKTRACE - longjmp(g_rtctxt.jmp_buf, code ? code : 256); + longjmp((&g_rtctxt)->jmp_buf, code ? code : 256); #else - longjmp(run_jmp_buf, code ? code : 256); + longjmp(e->run_jmp_buf, code ? code : 256); #endif } @@ -277,7 +291,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) #ifdef CONFIG_TCC_BACKTRACE if (!(ret = setjmp(rc->jmp_buf))) #else - if (!(ret = setjmp(run_jmp_buf))) + if (!(ret = setjmp((&g_exit_context)->run_jmp_buf))) #endif { ret = prog_main(argc, argv, envp); @@ -286,7 +300,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) call_exit(ret); if ((s1->dflag & 16) && ret) 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); return ret; } diff --git a/tests/libtcc_test_mt.c b/tests/libtcc_test_mt.c index 6892bfef..1e5a3860 100644 --- a/tests/libtcc_test_mt.c +++ b/tests/libtcc_test_mt.c @@ -288,6 +288,9 @@ int main(int argc, char **argv) #else #include + +unsigned int sleep(unsigned int seconds); + int fib(n) { return (n <= 2) ? 1 : fib(n-1) + fib(n-2); @@ -295,7 +298,8 @@ int fib(n) int main(int argc, char **argv) { - printf(" %d", fib(atoi(argv[1]), 2)); + sleep(1); + printf(" %d", fib(atoi(argv[1]))); return 0; } #endif