]> granicus.if.org Git - gc/commitdiff
Adjust subthread_create test.
authorIvan Maidanski <ivmai@mail.ru>
Tue, 20 Sep 2011 07:58:56 +0000 (11:58 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 20 Sep 2011 07:58:56 +0000 (11:58 +0400)
* 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

index a4d788268b79b139fb36d5f6642bb8a434be10ad..bff545b74226f5367883eb666359aaa2f69c8784 100644 (file)
-#define GC_NO_THREAD_REDIRECTS
+
 #ifndef GC_THREADS
-#  define GC_THREADS
+# define GC_THREADS
 #endif
+
 #include "gc.h"
 #include <atomic_ops.h>
 
-#include <pthread.h>
+#include <stdio.h>
+
+#ifdef AO_HAVE_fetch_and_add
+
+#ifdef GC_PTHREADS
+# include <pthread.h>
+#else
+# include <windows.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 
-#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 */