From 0ccf1379e1c57efa0533ce02546fe45c8868958f Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 20 Sep 2011 11:58:56 +0400 Subject: [PATCH] Adjust subthread_create test. * tests/subthread_create.c: Skip test if AO_fetch_and_add is missing. * tests/subthread_create.c: Implement for Win32 threads (include windows.h instead of pthread.h unless GC_PTHREADS). * tests/subthread_create.c (entry, main): Likewise. * tests/subthread_create.c (MAX_SUBTHREAD_DEPTH, MAX_SUBTHREAD_COUNT, INITIAL_THREAD_COUNT): Define only if INITIAL_THREAD_COUNT undefined. * tests/subthread_create.c (MAX_ALIVE_THREAD_COUNT): New macro. * tests/subthread_create.c (DECAY_NUMER, DECAY_DENOM): Define only if DECAY_NUMER is undefined. * tests/subthread_create.c (INITIAL_THREAD_COUNT, MAX_SUBTHREAD_DEPTH, MAX_SUBTHREAD_COUNT): Make the values smaller. * tests/subthread_create.c (thread_created_cnt): Move out of entry(); make volatile. * tests/subthread_create.c (thread_ended_cnt): New AO variable. * tests/subthread_create.c (entry): Use "arg" value (instead of address); adjust thread_ended_cnt on function exit; print thread number in case of failure; limit the number of concurrently running threads (by MAX_ALIVE_THREAD_COUNT). * tests/subthread_create.c (main): Print threads creation statistic on exit; exit with code 1 (instead of 69) in case of failure. --- tests/subthread_create.c | 132 +++++++++++++++++++++++++++++++-------- 1 file changed, 106 insertions(+), 26 deletions(-) diff --git a/tests/subthread_create.c b/tests/subthread_create.c index a4d78826..bff545b7 100644 --- a/tests/subthread_create.c +++ b/tests/subthread_create.c @@ -1,55 +1,135 @@ -#define GC_NO_THREAD_REDIRECTS + #ifndef GC_THREADS -# define GC_THREADS +# define GC_THREADS #endif + #include "gc.h" #include -#include +#include + +#ifdef AO_HAVE_fetch_and_add + +#ifdef GC_PTHREADS +# include +#else +# include +#endif + #include #include -#include -#define MAX_SUBTHREAD_DEPTH 16 -#define MAX_SUBTHREAD_COUNT 2048 -#define INITIAL_THREAD_COUNT 128 -#define DECAY_NUMER 15 -#define DECAY_DENOM 16 +#ifndef MAX_SUBTHREAD_DEPTH +# define INITIAL_THREAD_COUNT 31 +# define MAX_ALIVE_THREAD_COUNT 55 +# define MAX_SUBTHREAD_DEPTH 7 +# define MAX_SUBTHREAD_COUNT 200 +#endif + +#ifndef DECAY_NUMER +# define DECAY_NUMER 15 +# define DECAY_DENOM 16 +#endif + +volatile AO_t thread_created_cnt = 0; +volatile AO_t thread_ended_cnt = 0; -void *entry(void *arg) +#ifdef GC_PTHREADS + void *entry(void *arg) +#else + DWORD WINAPI entry(LPVOID arg) +#endif { - static AO_t thread_count = (AO_t)0; - pthread_t th; - int thread_num = AO_fetch_and_add(&thread_count, 1); - int my_depth = *(int *)arg + 1; - if (my_depth < MAX_SUBTHREAD_DEPTH + int thread_num = AO_fetch_and_add(&thread_created_cnt, 1); + GC_word my_depth = (GC_word)arg + 1; + + if (my_depth <= MAX_SUBTHREAD_DEPTH && thread_num < MAX_SUBTHREAD_COUNT - && (thread_num % DECAY_DENOM) < DECAY_NUMER) - GC_pthread_create(&th, NULL, entry, &my_depth); - return arg; + && (thread_num % DECAY_DENOM) < DECAY_NUMER + && (int)(thread_num - AO_load(&thread_ended_cnt)) + <= MAX_ALIVE_THREAD_COUNT) { +# ifdef GC_PTHREADS + int err; + pthread_t th; + err = pthread_create(&th, NULL, entry, (void *)my_depth); + if (err) { + fprintf(stderr, "Thread #%d creation failed: %s", thread_num, + strerror(err)); + exit(2); + } +# else + HANDLE th; + DWORD thread_id; + th = CreateThread(NULL, 0, entry, (LPVOID)my_depth, 0, &thread_id); + if (th == NULL) { + printf("Thread #%d creation failed: %d\n", thread_num, + (int)GetLastError()); + exit(2); + } + CloseHandle(th); +# endif + } + + AO_fetch_and_add(&thread_ended_cnt, 1); + return 0; } int main(void) { - int i, err; - GC_INIT(); + int i; +# ifdef GC_PTHREADS + int err; pthread_t th[INITIAL_THREAD_COUNT]; - int my_depth = 0; +# else + HANDLE th[INITIAL_THREAD_COUNT]; +# endif + GC_INIT(); for (i = 0; i < INITIAL_THREAD_COUNT; ++i) { - err = GC_pthread_create(&th[i], NULL, entry, &my_depth); +# ifdef GC_PTHREADS + err = pthread_create(&th[i], NULL, entry, 0); if (err) { fprintf(stderr, "Thread creation failed: %s", strerror(err)); - exit(69); + exit(1); } +# else + DWORD thread_id; + th[i] = CreateThread(NULL, 0, entry, 0, 0, &thread_id); + if (th[i] == NULL) { + printf("Thread creation failed: %d\n", (int)GetLastError()); + exit(1); + } +# endif } + for (i = 0; i < INITIAL_THREAD_COUNT; ++i) { +# ifdef GC_PTHREADS void *res; - err = GC_pthread_join(th[i], &res); + err = pthread_join(th[i], &res); if (err) { fprintf(stderr, "Failed to join thread: %s", strerror(err)); - exit(69); + exit(1); } +# else + if (WaitForSingleObject(th[i], INFINITE) != WAIT_OBJECT_0) { + printf("Failed to join thread: %d\n", (int)GetLastError()); + CloseHandle(th[i]); + exit(1); + } + CloseHandle(th[i]); +# endif } - return 0; + printf("subthread_create: created %d threads (%d ended)\n", + (int)AO_load(&thread_created_cnt), (int)AO_load(&thread_ended_cnt)); + return 0; +} + +#else + +int main(void) +{ + printf("subthread_create test skipped\n"); + return 0; } + +#endif /* !AO_HAVE_fetch_and_add */ -- 2.40.0