diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-07-11 21:55:25 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-07-11 21:59:13 +0300 |
commit | 3159afddb6788cc6f5d584b1ad2a7ec379c43ed0 (patch) | |
tree | 65dfd0cd7ee9c1db3a277c6207b81d9f4210b769 /tests | |
parent | 63937439da0f9206563a262bbf2b98f167fbf385 (diff) | |
download | bdwgc-3159afddb6788cc6f5d584b1ad2a7ec379c43ed0.tar.gz |
Test world stop while other thread in deep recursion in gctest (pthreads)
* tests/gctest.c [GC_PTHREADS]: Add TODO item.
* tests/gctest.c [GC_PTHREADS] (do_gcollect,
collect_from_other_thread): New function.
* tests/gctest.c [GC_PTHREADS] (MAX_GCOLLECT_THREADS): New macro.
* tests/gctest.c [GC_PTHREADS] (gcollect_threads_cnt): New variable.
* tests/gctest.c [GC_PTHREADS] (ints): If up<0 and low>-up then
increment gcollect_threads_cnt atomically and call
collect_from_other_thread() instead of GC_gcollect_and_unmap unless
gcollect_threads_cnt exceeds limit (MAX_GCOLLECT_THREADS).
Diffstat (limited to 'tests')
-rw-r--r-- | tests/gctest.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/tests/gctest.c b/tests/gctest.c index ff7cd066..bf9da87a 100644 --- a/tests/gctest.c +++ b/tests/gctest.c @@ -461,10 +461,48 @@ sexpr reverse(sexpr x) return reverse1(x, nil); } +#ifdef GC_PTHREADS + /* TODO: Implement for Win32 */ + + void *do_gcollect(void *arg) + { + if (print_stats) + GC_log_printf("Collect from a standalone thread\n"); + GC_gcollect(); + return arg; + } + + void collect_from_other_thread(void) + { + pthread_t t; + int code = pthread_create(&t, NULL, do_gcollect, NULL /* arg */); + + if (code != 0) { + GC_printf("gcollect thread creation failed, errno= %d\n", code); + FAIL; + } + code = pthread_join(t, NULL); + if (code != 0) { + GC_printf("gcollect thread join failed, errno= %d\n", code); + FAIL; + } + } + +# define MAX_GCOLLECT_THREADS ((NTHREADS+2)/3) + volatile AO_t gcollect_threads_cnt = 0; +#endif /* GC_PTHREADS */ + sexpr ints(int low, int up) { if (up < 0 ? low > -up : low > up) { if (up < 0) { +# ifdef GC_PTHREADS + if (AO_fetch_and_add1(&gcollect_threads_cnt) + 1 + <= MAX_GCOLLECT_THREADS) { + collect_from_other_thread(); + return nil; + } +# endif GC_gcollect_and_unmap(); } return nil; |