summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-07-11 21:55:25 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-07-11 21:59:13 +0300
commit3159afddb6788cc6f5d584b1ad2a7ec379c43ed0 (patch)
tree65dfd0cd7ee9c1db3a277c6207b81d9f4210b769 /tests
parent63937439da0f9206563a262bbf2b98f167fbf385 (diff)
downloadbdwgc-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.c38
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;