diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-04-17 15:22:30 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-04-17 15:22:30 +0300 |
commit | 0077860118df1511ab5b2e653b90d3ace0b9e96a (patch) | |
tree | 3ef03ecaf6237ebcd2ef156571cd919697ff7035 /tests | |
parent | 5d2775378c29cb71a1f2f0076bca6ff584babbc6 (diff) | |
download | bdwgc-0077860118df1511ab5b2e653b90d3ace0b9e96a.tar.gz |
Test manual self-suspend in gctest
* tests/gctest.c [THREADS && GC_ENABLE_SUSPEND_THREAD]: Include
javaxfc.h before tiny_reverse_test() definition.
* tests/gctest.c [THREADS] (tiny_reverse_test): Rename arg argument to
p_resumed and remove GC_ATTR_UNUSED.
* tests/gctest.c [THREADS && GC_ENABLE_SUSPEND_THREAD
&& !GC_OSF1_THREADS && SIGNAL_BASED_STOP_WORLD] (tiny_reverse_test):
If p_resumed is non-null then call GC_suspend_thread(pthread_self())
and set *p_resumed to true atomically.
* tests/gctest.c [THREADS && GC_PTHREADS && GC_ENABLE_SUSPEND_THREAD]
(fork_a_thread): Declare and use forked_cnt static variable; declare
and use p_resumed local variable; pass p_resumed to pthread_create().
* tests/gctest.c [THREADS && GC_PTHREADS && GC_ENABLE_SUSPEND_THREAD
&& !GC_OSF1_THREADS && SIGNAL_BASED_STOP_WORLD] (fork_a_thread): Do not
fail if first GC_is_thread_suspended(t) returns true but p_resumed is
non-null; update comment; repeat first GC_resume_thread() while
p_resumed is non-null and *p_resumed is false; call GC_suspend_thread()
and GC_resume_thread() once more but with a preceding call of
GC_collect_a_little().
Diffstat (limited to 'tests')
-rw-r--r-- | tests/gctest.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/tests/gctest.c b/tests/gctest.c index 5c27ab33..5949494f 100644 --- a/tests/gctest.c +++ b/tests/gctest.c @@ -585,6 +585,9 @@ void check_marks_int_list(sexpr x) * A tiny list reversal test to check thread creation. */ #ifdef THREADS +# if defined(GC_ENABLE_SUSPEND_THREAD) +# include "gc/javaxfc.h" +# endif # ifdef VERY_SMALL_CONFIG # define TINY_REVERSE_UPPER_VALUE 4 @@ -593,12 +596,25 @@ void check_marks_int_list(sexpr x) # endif # if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) - DWORD __stdcall tiny_reverse_test(void * arg GC_ATTR_UNUSED) + DWORD __stdcall # else - void * tiny_reverse_test(void * arg GC_ATTR_UNUSED) + void* # endif -{ + tiny_reverse_test(void *p_resumed) + { int i; + +# if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_OSF1_THREADS) \ + && defined(SIGNAL_BASED_STOP_WORLD) + if (p_resumed != NULL) { + /* Test self-suspend. */ + GC_suspend_thread(pthread_self()); + AO_store_release((volatile AO_t *)p_resumed, (AO_t)TRUE); + } +# else + (void)p_resumed; +# endif + for (i = 0; i < 5; ++i) { check_ints(reverse(reverse(ints(1, TINY_REVERSE_UPPER_VALUE))), 1, TINY_REVERSE_UPPER_VALUE); @@ -608,42 +624,63 @@ void check_marks_int_list(sexpr x) GC_gcollect(); # endif return 0; -} + } # if defined(GC_PTHREADS) -# if defined(GC_ENABLE_SUSPEND_THREAD) -# include "gc/javaxfc.h" -# endif - void fork_a_thread(void) { pthread_t t; int code; +# ifdef GC_ENABLE_SUSPEND_THREAD + static volatile AO_t forked_cnt = 0; + volatile AO_t *p_resumed = NULL; - code = pthread_create(&t, NULL, tiny_reverse_test, 0); + if ((AO_fetch_and_add1(&forked_cnt) % 2) == 0) { + p_resumed = GC_NEW(AO_t); + CHECK_OUT_OF_MEMORY(p_resumed); + AO_fetch_and_add1(&collectable_count); + } +# else +# define p_resumed NULL +# endif + code = pthread_create(&t, NULL, tiny_reverse_test, (void*)p_resumed); if (code != 0) { GC_printf("Small thread creation failed %d\n", code); FAIL; } # if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_OSF1_THREADS) \ && defined(SIGNAL_BASED_STOP_WORLD) - if (GC_is_thread_suspended(t)) { + if (GC_is_thread_suspended(t) && NULL == p_resumed) { GC_printf("Running thread should be not suspended\n"); FAIL; } - /* Thread could be running or already terminated (but not joined). */ - GC_suspend_thread(t); + GC_suspend_thread(t); /* might be already self-suspended */ if (!GC_is_thread_suspended(t)) { GC_printf("Thread expected to be suspended\n"); FAIL; } GC_suspend_thread(t); /* should be no-op */ - GC_resume_thread(t); + for (;;) { + GC_resume_thread(t); + if (NULL == p_resumed || AO_load_acquire(p_resumed)) + break; + GC_collect_a_little(); + } if (GC_is_thread_suspended(t)) { GC_printf("Resumed thread should be not suspended\n"); FAIL; } GC_resume_thread(t); /* should be no-op */ + if (NULL == p_resumed) + GC_collect_a_little(); + /* Thread could be running or already terminated (but not joined). */ + GC_suspend_thread(t); + GC_collect_a_little(); + if (!GC_is_thread_suspended(t)) { + GC_printf("Thread expected to be suspended\n"); + FAIL; + } + GC_resume_thread(t); # endif if ((code = pthread_join(t, 0)) != 0) { GC_printf("Small thread join failed, errno= %d\n", code); |