diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2021-10-02 00:45:22 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2021-10-02 10:18:05 +0300 |
commit | a3df481b84bc5a2d36b6d996f3ed590dbad3b726 (patch) | |
tree | eced1d58ffeb2e755cce08deedbc5f92d1e3491a /tests | |
parent | 5d07c3f884c66be2e5a3c7f34982ee4652c92de7 (diff) | |
download | bdwgc-a3df481b84bc5a2d36b6d996f3ed590dbad3b726.tar.gz |
Do not fail tests if pthread_create returns resource unavailable error
Issue #342 (bdwgc).
* tests/disclaim_test.c [GC_PTHREADS]: Include errno.h.
* tests/disclaim_weakmap_test.c [GC_PTHREADS]: Likewise.
* tests/subthread_create.c [GC_PTHREADS]: Likewise.
* tests/test.c [GC_PTHREADS]: Likewise.
* tests/thread_leak_test.c [GC_PTHREADS]: Likewise.
* tests/threadkey_test.c [GC_PTHREADS]: Likewise.
* tests/disclaim_test.c [GC_PTHREADS] (main): Declare n local variable;
iterate in the 2nd loop only up to the amount of created threads.
* tests/subthread_create.c (main): Likewise.
* tests/thread_leak_test.c [GC_PTHREADS && NTHREADS>0] (main):
Likewise.
* tests/disclaim_test.c [GC_PTHREADS] (main): If i>1 and pthread_create
result is EAGAIN then break the loop of threads creation.
* tests/disclaim_weakmap_test.c [GC_PTHREADS] (main): Likewise.
* tests/thread_leak_test.c [GC_PTHREADS && NTHREADS>0] (main):
Likewise.
* tests/subthread_create.c [GC_PTHREADS] (entry): Do not exit if
pthread_create result is EAGAIN; do not call pthread_detach if
pthread_create failed.
* tests/subthread_create.c (main): Declare th_nums[] local variable;
increment thread_created_cnt atomically and set th_nums[i]; print
th_nums[i] (instead of i) in error messages of pthread_create and
pthread_join (or CreateThread).
* tests/subthread_create.c [GC_PTHREADS] (main): If i>0 and
pthread_create result is EAGAIN then break the loop of threads
creation.
* tests/test.c [GC_PTHREADS && NTHREADS>0] (main): Likewise.
* tests/threadkey_test.c [GC_PTHREADS] (main): Likewise.
* tests/test.c [GC_PTHREADS && NTHREADS>0] (main): Declare nthreads;
iterate in the loop with pthread_join only up to the amount of created
threads; call run_one_test() NTHREADS-nthreads+1 times (instead of
once).
Diffstat (limited to 'tests')
-rw-r--r-- | tests/disclaim_test.c | 7 | ||||
-rw-r--r-- | tests/disclaim_weakmap_test.c | 8 | ||||
-rw-r--r-- | tests/subthread_create.c | 34 | ||||
-rw-r--r-- | tests/test.c | 16 | ||||
-rw-r--r-- | tests/thread_leak_test.c | 8 | ||||
-rw-r--r-- | tests/threadkey_test.c | 2 |
6 files changed, 48 insertions, 27 deletions
diff --git a/tests/disclaim_test.c b/tests/disclaim_test.c index bd236fb3..d7d238d1 100644 --- a/tests/disclaim_test.c +++ b/tests/disclaim_test.c @@ -184,6 +184,7 @@ pair_check_rec(pair_t p) # ifndef NTHREADS # define NTHREADS 6 # endif +# include <errno.h> /* for EAGAIN */ # include <pthread.h> #else # undef NTHREADS @@ -229,7 +230,7 @@ int main(void) { # if NTHREADS > 1 pthread_t th[NTHREADS]; - int i; + int i, n; # endif GC_set_all_interior_pointers(0); /* for a stricter test */ @@ -253,10 +254,12 @@ int main(void) if (err) { fprintf(stderr, "Thread #%d creation failed: %s\n", i, strerror(err)); + if (i > 1 && EAGAIN == err) break; exit(1); } } - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { int err = pthread_join(th[i], NULL); if (err) { fprintf(stderr, "Thread #%d join failed: %s\n", diff --git a/tests/disclaim_weakmap_test.c b/tests/disclaim_weakmap_test.c index 5bd86799..0039ef5d 100644 --- a/tests/disclaim_weakmap_test.c +++ b/tests/disclaim_weakmap_test.c @@ -30,7 +30,7 @@ # ifndef NTHREADS # define NTHREADS 8 # endif -# include <errno.h> /* for EBUSY */ +# include <errno.h> /* for EAGAIN, EBUSY */ # include <pthread.h> # include "private/gc_atomic_ops.h" /* for AO_t and AO_fetch_and_add1 */ #else @@ -419,7 +419,7 @@ int main(void) { unsigned weakobj_kind; # ifdef GC_PTHREADS - int i; + int i, n; pthread_t th[NTHREADS]; # endif @@ -447,10 +447,12 @@ int main(void) if (err != 0) { fprintf(stderr, "Thread #%d creation failed: %s\n", i, strerror(err)); + if (i > 1 && EAGAIN == err) break; exit(1); } } - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { int err = pthread_join(th[i], NULL); if (err != 0) { fprintf(stderr, "Thread #%d join failed: %s\n", i, strerror(err)); diff --git a/tests/subthread_create.c b/tests/subthread_create.c index e2961b49..02d2572b 100644 --- a/tests/subthread_create.c +++ b/tests/subthread_create.c @@ -18,6 +18,7 @@ #ifdef AO_HAVE_fetch_and_add1 #ifdef GC_PTHREADS +# include <errno.h> /* for EAGAIN */ # include <pthread.h> # include <string.h> #else @@ -74,16 +75,18 @@ volatile AO_t thread_ended_cnt = 0; err = pthread_create(&th, NULL, entry, (void *)my_depth); if (err != 0) { - fprintf(stderr, - "Thread #%d creation failed from other thread: %s\n", - thread_num, strerror(err)); + fprintf(stderr, + "Thread #%d creation failed from other thread: %s\n", + thread_num, strerror(err)); + if (err != EAGAIN) exit(2); - } - err = pthread_detach(th); - if (err != 0) { + } else { + err = pthread_detach(th); + if (err != 0) { fprintf(stderr, "Thread #%d detach failed: %s\n", thread_num, strerror(err)); exit(2); + } } # else HANDLE th; @@ -106,41 +109,44 @@ volatile AO_t thread_ended_cnt = 0; int main(void) { #if NTHREADS > 0 - int i; + int i, n; # ifdef GC_PTHREADS int err; pthread_t th[NTHREADS_INNER]; # else HANDLE th[NTHREADS_INNER]; # endif + int th_nums[NTHREADS_INNER]; GC_INIT(); for (i = 0; i < NTHREADS_INNER; ++i) { + th_nums[i] = (int)AO_fetch_and_add1(&thread_created_cnt); # ifdef GC_PTHREADS err = pthread_create(&th[i], NULL, entry, 0); if (err) { fprintf(stderr, "Thread #%d creation failed: %s\n", - i, strerror(err)); + th_nums[i], strerror(err)); + if (i > 0 && EAGAIN == err) break; exit(1); } # else DWORD thread_id; th[i] = CreateThread(NULL, 0, entry, 0, 0, &thread_id); if (th[i] == NULL) { - fprintf(stderr, "Thread creation failed, errcode= %d\n", - (int)GetLastError()); + fprintf(stderr, "Thread #%d creation failed, errcode= %d\n", + th_nums[i], (int)GetLastError()); exit(1); } # endif } - - for (i = 0; i < NTHREADS_INNER; ++i) { + n = i; + for (i = 0; i < n; ++i) { # ifdef GC_PTHREADS void *res; err = pthread_join(th[i], &res); if (err) { fprintf(stderr, "Thread #%d join failed: %s\n", - i, strerror(err)); + th_nums[i], strerror(err)); # if defined(__HAIKU__) /* The error is just ignored (and the test is ended) to */ /* workaround some bug in Haiku pthread_join. */ @@ -152,7 +158,7 @@ int main(void) # else if (WaitForSingleObject(th[i], INFINITE) != WAIT_OBJECT_0) { fprintf(stderr, "Thread #%d join failed, errcode= %d\n", - i, (int)GetLastError()); + th_nums[i], (int)GetLastError()); CloseHandle(th[i]); exit(1); } diff --git a/tests/test.c b/tests/test.c index ded68d1d..8a7c7437 100644 --- a/tests/test.c +++ b/tests/test.c @@ -2319,6 +2319,8 @@ int test(void) #endif #if defined(GC_PTHREADS) +# include <errno.h> /* for EAGAIN */ + void * thr_run_one_test(void * arg GC_ATTR_UNUSED) { run_one_test(); @@ -2333,7 +2335,7 @@ int main(void) { # if NTHREADS > 0 pthread_t th[NTHREADS]; - int i; + int i, nthreads; # endif pthread_attr_t attr; int code; @@ -2393,18 +2395,22 @@ int main(void) for (i = 0; i < NTHREADS; ++i) { if ((code = pthread_create(th+i, &attr, thr_run_one_test, 0)) != 0) { GC_printf("Thread #%d creation failed, errno= %d\n", i, code); + if (i > 0 && EAGAIN == code) + break; /* Resource temporarily unavailable */ FAIL; } } -# endif - run_one_test(); -# if NTHREADS > 0 - for (i = 0; i < NTHREADS; ++i) { + nthreads = i; + for (; i <= NTHREADS; i++) + run_one_test(); + for (i = 0; i < nthreads; ++i) { if ((code = pthread_join(th[i], 0)) != 0) { GC_printf("Thread #%d join failed, errno= %d\n", i, code); FAIL; } } +# else + run_one_test(); # endif run_single_threaded_test(); check_heap_stats(); diff --git a/tests/thread_leak_test.c b/tests/thread_leak_test.c index 03341467..cbdf8cca 100644 --- a/tests/thread_leak_test.c +++ b/tests/thread_leak_test.c @@ -11,6 +11,7 @@ #include "leak_detector.h" #ifdef GC_PTHREADS +# include <errno.h> /* for EAGAIN */ # include <pthread.h> # include <string.h> #else @@ -51,7 +52,7 @@ int main(void) { # if NTHREADS > 0 - int i; + int i, n; # ifdef GC_PTHREADS pthread_t t[NTHREADS]; # else @@ -72,6 +73,7 @@ int main(void) { if (code != 0) { fprintf(stderr, "Thread #%d creation failed: %s\n", i, strerror(code)); + if (i > 1 && EAGAIN == code) break; exit(2); } # else @@ -83,8 +85,8 @@ int main(void) { } # endif } - - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { # ifdef GC_PTHREADS code = pthread_join(t[i], 0); # else diff --git a/tests/threadkey_test.c b/tests/threadkey_test.c index 93b28098..5e93a945 100644 --- a/tests/threadkey_test.c +++ b/tests/threadkey_test.c @@ -32,6 +32,7 @@ int main(void) #else +#include <errno.h> /* for EAGAIN */ #include <pthread.h> #include <string.h> @@ -106,6 +107,7 @@ int main(void) if (code != 0) { fprintf(stderr, "Thread #%d creation failed: %s\n", i, strerror(code)); + if (i > 0 && EAGAIN == code) break; exit(2); } |