aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'boehm-gc/test.c')
-rw-r--r--boehm-gc/test.c163
1 files changed, 138 insertions, 25 deletions
diff --git a/boehm-gc/test.c b/boehm-gc/test.c
index 2fc51e1..43b0901 100644
--- a/boehm-gc/test.c
+++ b/boehm-gc/test.c
@@ -25,7 +25,7 @@
# include "gc.h"
# include "gc_typed.h"
# include "gc_priv.h" /* For output, locking, and some statistics */
-# include "config.h"
+# include "gcconfig.h"
# ifdef MSWIN32
# include <windows.h>
@@ -45,7 +45,7 @@
# include <synch.h>
# endif
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
# include <pthread.h>
# endif
@@ -53,9 +53,6 @@
# include <process.h>
static CRITICAL_SECTION incr_cs;
# endif
-# if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS)
-# define THREADS
-# endif
# ifdef AMIGA
long __stack = 200000;
@@ -266,6 +263,72 @@ struct {
#define a A.aa
/*
+ * A tiny list reversal test to check thread creation.
+ */
+#ifdef THREADS
+
+# ifdef WIN32_THREADS
+ unsigned __stdcall tiny_reverse_test(void * arg)
+# else
+ void * tiny_reverse_test(void * arg)
+# endif
+{
+ check_ints(reverse(reverse(ints(1,10))), 1, 10);
+ return 0;
+}
+
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+ || defined(SOLARIS_PTHREADS) || defined(HPUX_THREADS)
+ void fork_a_thread()
+ {
+ pthread_t t;
+ int code;
+ if ((code = pthread_create(&t, 0, tiny_reverse_test, 0)) != 0) {
+ (void)GC_printf1("Small thread creation failed %lu\n",
+ (unsigned long)code);
+ FAIL;
+ }
+ if ((code = pthread_join(t, 0)) != 0) {
+ (void)GC_printf1("Small thread join failed %lu\n",
+ (unsigned long)code);
+ FAIL;
+ }
+ }
+
+# elif defined(WIN32_THREADS)
+ void fork_a_thread()
+ {
+ unsigned thread_id;
+ HANDLE h;
+ h = (HANDLE)_beginthreadex(NULL, 0, tiny_reverse_test,
+ 0, 0, &thread_id);
+ if (h == (HANDLE)-1) {
+ (void)GC_printf1("Small thread creation failed %lu\n",
+ (unsigned long)GetLastError());
+ FAIL;
+ }
+ if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
+ (void)GC_printf1("Small thread wait failed %lu\n",
+ (unsigned long)GetLastError());
+ FAIL;
+ }
+ }
+
+/* # elif defined(SOLARIS_THREADS) */
+
+# else
+
+# define fork_a_thread()
+
+# endif
+
+#else
+
+# define fork_a_thread()
+
+#endif
+
+/*
* Repeatedly reverse lists built out of very different sized cons cells.
* Check that we didn't lose anything.
*/
@@ -296,14 +359,14 @@ void reverse_test()
d = uncollectable_ints(1, 100);
e = uncollectable_ints(1, 1);
/* Check that realloc updates object descriptors correctly */
- f = (sexpr *)GC_malloc(4 * sizeof(sexpr));
- f = (sexpr *)GC_realloc((GC_PTR)f, 6 * sizeof(sexpr));
+ f = (sexpr *)GC_MALLOC(4 * sizeof(sexpr));
+ f = (sexpr *)GC_REALLOC((GC_PTR)f, 6 * sizeof(sexpr));
f[5] = ints(1,17);
- g = (sexpr *)GC_malloc(513 * sizeof(sexpr));
- g = (sexpr *)GC_realloc((GC_PTR)g, 800 * sizeof(sexpr));
+ g = (sexpr *)GC_MALLOC(513 * sizeof(sexpr));
+ g = (sexpr *)GC_REALLOC((GC_PTR)g, 800 * sizeof(sexpr));
g[799] = ints(1,18);
- h = (sexpr *)GC_malloc(1025 * sizeof(sexpr));
- h = (sexpr *)GC_realloc((GC_PTR)h, 2000 * sizeof(sexpr));
+ h = (sexpr *)GC_MALLOC(1025 * sizeof(sexpr));
+ h = (sexpr *)GC_REALLOC((GC_PTR)h, 2000 * sizeof(sexpr));
h[1999] = ints(1,19);
/* Try to force some collections and reuse of small list elements */
for (i = 0; i < 10; i++) {
@@ -327,6 +390,7 @@ void reverse_test()
check_ints(b,1,50);
check_ints(a,1,49);
for (i = 0; i < 60; i++) {
+ if (i % 10 == 0) fork_a_thread();
/* This maintains the invariant that a always points to a list of */
/* 49 integers. Thus this is thread safe without locks, */
/* assuming atomic pointer assignments. */
@@ -386,7 +450,7 @@ VOLATILE int dropped_something = 0;
static mutex_t incr_lock;
mutex_lock(&incr_lock);
# endif
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&incr_lock);
# endif
@@ -404,7 +468,7 @@ VOLATILE int dropped_something = 0;
# ifdef SOLARIS_THREADS
mutex_unlock(&incr_lock);
# endif
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
pthread_mutex_unlock(&incr_lock);
# endif
# ifdef WIN32_THREADS
@@ -465,7 +529,8 @@ int n;
static mutex_t incr_lock;
mutex_lock(&incr_lock);
# endif
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+ || defined(HPUX_THREADS)
static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&incr_lock);
# endif
@@ -481,7 +546,8 @@ int n;
# ifdef SOLARIS_THREADS
mutex_unlock(&incr_lock);
# endif
-# if defined(IRIX_THREADS) || defined(LINUX_THREADS)
+# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
+ || defined(HPUX_THREADS)
pthread_mutex_unlock(&incr_lock);
# endif
# ifdef WIN32_THREADS
@@ -538,13 +604,13 @@ int n;
chktree(t -> rchild, n-1);
}
-# ifdef SOLARIS_THREADS
+# if defined(SOLARIS_THREADS) && !defined(_SOLARIS_PTHREADS)
thread_key_t fl_key;
void * alloc8bytes()
{
-# ifdef SMALL_CONFIG
- return(GC_malloc(8));
+# if defined(SMALL_CONFIG) || defined(GC_DEBUG)
+ return(GC_MALLOC(8));
# else
void ** my_free_list_ptr;
void * my_free_list;
@@ -575,7 +641,44 @@ void * alloc8bytes()
}
#else
-# define alloc8bytes() GC_MALLOC_ATOMIC(8)
+
+# if defined(_SOLARIS_PTHREADS) || defined(IRIX_THREADS) \
+ || defined(LINUX_THREADS) || defined(HPUX_THREADS)
+pthread_key_t fl_key;
+
+void * alloc8bytes()
+{
+# ifdef SMALL_CONFIG
+ return(GC_malloc(8));
+# else
+ void ** my_free_list_ptr;
+ void * my_free_list;
+
+ my_free_list_ptr = (void **)pthread_getspecific(fl_key);
+ if (my_free_list_ptr == 0) {
+ my_free_list_ptr = GC_NEW_UNCOLLECTABLE(void *);
+ if (pthread_setspecific(fl_key, my_free_list_ptr) != 0) {
+ (void)GC_printf0("pthread_setspecific failed\n");
+ FAIL;
+ }
+ }
+ my_free_list = *my_free_list_ptr;
+ if (my_free_list == 0) {
+ my_free_list = GC_malloc_many(8);
+ if (my_free_list == 0) {
+ (void)GC_printf0("alloc8bytes out of memory\n");
+ FAIL;
+ }
+ }
+ *my_free_list_ptr = GC_NEXT(my_free_list);
+ GC_NEXT(my_free_list) = 0;
+ return(my_free_list);
+# endif
+}
+
+# else
+# define alloc8bytes() GC_MALLOC_ATOMIC(8)
+# endif
#endif
void alloc_small(n)
@@ -753,6 +856,7 @@ void run_one_test()
(void)GC_printf0("GC_malloc_uncollectable(0) failed\n");
FAIL;
}
+ GC_FREE(0);
GC_is_valid_displacement_print_proc = fail_proc1;
GC_is_visible_print_proc = fail_proc1;
x = GC_malloc(16);
@@ -775,7 +879,7 @@ void run_one_test()
FAIL;
}
if (!TEST_FAIL_COUNT(1)) {
-# if!(defined(RS6000) || defined(POWERPC))
+# if!(defined(RS6000) || defined(POWERPC) || defined(IA64))
/* ON RS6000s function pointers point to a descriptor in the */
/* data segment, so there should have been no failures. */
(void)GC_printf0("GC_is_visible produced wrong failure indication\n");
@@ -826,7 +930,7 @@ void check_heap_stats()
int late_finalize_count = 0;
if (sizeof(char *) > 4) {
- max_heap_sz = 13000000;
+ max_heap_sz = 15000000;
} else {
max_heap_sz = 11000000;
}
@@ -926,7 +1030,8 @@ void SetMinimumStack(long minSize)
#if !defined(PCR) && !defined(SOLARIS_THREADS) && !defined(WIN32_THREADS) \
- && !defined(IRIX_THREADS) && !defined(LINUX_THREADS) || defined(LINT)
+ && !defined(IRIX_THREADS) && !defined(LINUX_THREADS) \
+ && !defined(HPUX_THREADS) || defined(LINT)
#ifdef MSWIN32
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n)
#else
@@ -980,6 +1085,9 @@ void SetMinimumStack(long minSize)
GC_set_max_heap_size, GC_get_bytes_since_gc,
GC_pre_incr, GC_post_incr);
# endif
+# ifdef MSWIN32
+ GC_win32_free_heap();
+# endif
return(0);
}
# endif
@@ -1054,7 +1162,8 @@ test()
}
#endif
-#if defined(SOLARIS_THREADS) || defined(IRIX_THREADS) || defined(LINUX_THREADS)
+#if defined(SOLARIS_THREADS) || defined(IRIX_THREADS) \
+ || defined(HPUX_THREADS) || defined(LINUX_THREADS)
void * thr_run_one_test(void * arg)
{
run_one_test();
@@ -1115,7 +1224,7 @@ main()
*((volatile char *)&code - 1024*1024) = 0; /* Require 1 Mb */
# endif /* IRIX_THREADS */
pthread_attr_init(&attr);
-# ifdef IRIX_THREADS
+# if defined(IRIX_THREADS) || defined(HPUX_THREADS)
pthread_attr_setstacksize(&attr, 1000000);
# endif
n_tests = 0;
@@ -1125,6 +1234,10 @@ main()
(void) GC_printf0("Emulating dirty bits with mprotect/signals\n");
# endif
(void) GC_set_warn_proc(warn_proc);
+ if ((code = pthread_key_create(&fl_key, 0)) != 0) {
+ (void)GC_printf1("Key creation failed %lu\n", (unsigned long)code);
+ FAIL;
+ }
if ((code = pthread_create(&th1, &attr, thr_run_one_test, 0)) != 0) {
(void)GC_printf1("Thread 1 creation failed %lu\n", (unsigned long)code);
FAIL;
@@ -1149,4 +1262,4 @@ main()
return(0);
}
#endif /* pthreads */
-#endif /* SOLARIS_THREADS || IRIX_THREADS || LINUX_THREADS */
+#endif /* SOLARIS_THREADS || IRIX_THREADS || LINUX_THREADS || HPUX_THREADS */