mono/tests/cas/linkdemand/Makefile
mono/tests/cas/threads/Makefile
mono/tests/gc-descriptors/Makefile
+mono/unit-tests/Makefile
mono/benchmark/Makefile
mono/monograph/Makefile
mono/io-layer/Makefile
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \
done;
else
-SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis monograph tests benchmark profiler
+SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis monograph tests unit-tests benchmark profiler
endif
endif
-DIST_SUBDIRS = arch utils io-layer cil metadata interpreter mini dis monograph tests benchmark profiler
+DIST_SUBDIRS = arch utils io-layer cil metadata interpreter mini dis monograph tests unit-tests benchmark profiler
Makefile.am: Makefile.am.in
cp $< $@
endif
-
-if !CROSS_COMPILING
-if !HOST_WIN32
-if SUPPORT_BOEHM
-
-test_sgen_qsort_SOURCES = test-sgen-qsort.c
-test_sgen_qsort_CFLAGS = $(SGEN_DEFINES)
-test_sgen_qsort_LDADD = libmonoruntimesgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
- $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV)
-if PLATFORM_DARWIN
-test_sgen_qsort_LDFLAGS=-framework CoreFoundation -framework Foundation
-endif
-
-test_gc_memfuncs_SOURCES = test-gc-memfuncs.c
-test_gc_memfuncs_CFLAGS = $(SGEN_DEFINES)
-test_gc_memfuncs_LDADD = libmonoruntimesgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
- $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV)
-if PLATFORM_DARWIN
-test_gc_memfuncs_LDFLAGS=-framework CoreFoundation -framework Foundation
-endif
-
-test_mono_linked_list_set_SOURCES = test-mono-linked-list-set.c
-test_mono_linked_list_set_CFLAGS = $(AM_CFLAGS)
-test_mono_linked_list_set_LDADD = libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
- $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV) $(PEDUMP_DTRACE_OBJECT)
-
-if PLATFORM_DARWIN
-test_mono_linked_list_set_LDFLAGS=-framework CoreFoundation -framework Foundation
-endif
-
-noinst_PROGRAMS = test-sgen-qsort test-gc-memfuncs test-mono-linked-list-set
-
-TESTS = test-sgen-qsort test-gc-memfuncs test-mono-linked-list-set
-
-endif SUPPORT_BOEHM
-endif !HOST_WIN32
-endif !CROSS_COMPILING
+++ /dev/null
-/*
- * test-sgen-qsort.c: Unit test for our own bzero/memmove.
- *
- * Copyright (C) 2013 Xamarin Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License 2.0 as published by the Free Software Foundation;
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License 2.0 along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "config.h"
-
-#include "metadata/gc-internal.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-
-#define POOL_SIZE 2048
-#define START_OFFSET 128
-
-#define BZERO_OFFSETS 64
-#define BZERO_SIZES 256
-
-#define MEMMOVE_SRC_OFFSETS 32
-#define MEMMOVE_DEST_OFFSETS 32
-#define MEMMOVE_SIZES 256
-#define MEMMOVE_NONOVERLAP_START 1024
-
-int
-main (void)
-{
- unsigned char *random_mem = malloc (POOL_SIZE);
- unsigned char *reference = malloc (POOL_SIZE);
- unsigned char *playground = malloc (POOL_SIZE);
- long *long_random_mem;
- int i, offset, size, src_offset, dest_offset;
-
- srandom (time (NULL));
-
- /* init random memory */
- long_random_mem = (long*)random_mem;
- for (i = 0; i < POOL_SIZE / sizeof (long); ++i)
- long_random_mem [i] = random ();
-
- /* test bzero */
- for (offset = 0; offset <= BZERO_OFFSETS; ++offset) {
- for (size = 0; size <= BZERO_SIZES; ++size) {
- memcpy (reference, random_mem, POOL_SIZE);
- memcpy (playground, random_mem, POOL_SIZE);
-
- bzero (reference + START_OFFSET + offset, size);
- mono_gc_bzero_atomic (playground + START_OFFSET + offset, size);
-
- assert (!memcmp (reference, playground, POOL_SIZE));
- }
- }
-
- /* test memmove */
- for (src_offset = -MEMMOVE_SRC_OFFSETS; src_offset <= MEMMOVE_SRC_OFFSETS; ++src_offset) {
- for (dest_offset = -MEMMOVE_DEST_OFFSETS; dest_offset <= MEMMOVE_DEST_OFFSETS; ++dest_offset) {
- for (size = 0; size <= MEMMOVE_SIZES; ++size) {
- /* overlapping */
- memcpy (reference, random_mem, POOL_SIZE);
- memcpy (playground, random_mem, POOL_SIZE);
-
- memmove (reference + START_OFFSET + dest_offset, reference + START_OFFSET + src_offset, size);
- mono_gc_memmove_atomic (playground + START_OFFSET + dest_offset, playground + START_OFFSET + src_offset, size);
-
- assert (!memcmp (reference, playground, POOL_SIZE));
-
- /* non-overlapping with dest < src */
- memcpy (reference, random_mem, POOL_SIZE);
- memcpy (playground, random_mem, POOL_SIZE);
-
- memmove (reference + START_OFFSET + dest_offset, reference + MEMMOVE_NONOVERLAP_START + src_offset, size);
- mono_gc_memmove_atomic (playground + START_OFFSET + dest_offset, playground + MEMMOVE_NONOVERLAP_START + src_offset, size);
-
- assert (!memcmp (reference, playground, POOL_SIZE));
-
- /* non-overlapping with dest > src */
- memcpy (reference, random_mem, POOL_SIZE);
- memcpy (playground, random_mem, POOL_SIZE);
-
- memmove (reference + MEMMOVE_NONOVERLAP_START + dest_offset, reference + START_OFFSET + src_offset, size);
- mono_gc_memmove_atomic (playground + MEMMOVE_NONOVERLAP_START + dest_offset, playground + START_OFFSET + src_offset, size);
-
- assert (!memcmp (reference, playground, POOL_SIZE));
- }
- }
- }
-
- return 0;
-}
+++ /dev/null
-#include <assert.h>
-#include <pthread.h>
-
-#include <config.h>
-#include <mono/metadata/metadata.h>
-#include <mono/utils/mono-threads.h>
-#include <mono/utils/hazard-pointer.h>
-#include <mono/utils/mono-linked-list-set.h>
-#include <mono/utils/atomic.h>
-
-static MonoLinkedListSet lls;
-
-enum {
- STATE_OUT,
- STATE_BUSY,
- STATE_IN
-};
-
-#define N 23
-#define NUM_ITERS 1000000
-#define NUM_THREADS 8
-
-typedef struct {
- MonoLinkedListSetNode node;
- int state;
-} node_t;
-
-typedef struct {
- int skip;
- int num_adds;
- int num_removes;
- pthread_t thread;
-} thread_data_t;
-
-static node_t nodes [N];
-
-static inline void
-mono_hazard_pointer_clear_all (MonoThreadHazardPointers *hp, int retain)
-{
- if (retain != 0)
- mono_hazard_pointer_clear (hp, 0);
- if (retain != 1)
- mono_hazard_pointer_clear (hp, 1);
- if (retain != 2)
- mono_hazard_pointer_clear (hp, 2);
-}
-
-static void
-free_node (void *n)
-{
- node_t *node = n;
- assert (node->state == STATE_BUSY);
- node->state = STATE_OUT;
-}
-
-static void*
-worker (void *arg)
-{
- thread_data_t *thread_data = arg;
- MonoThreadHazardPointers *hp;
- int skip = thread_data->skip;
- int i, j;
- gboolean result;
-
- mono_thread_info_register_small_id ();
-
- hp = mono_hazard_pointer_get ();
-
- i = 0;
- for (j = 0; j < NUM_ITERS; ++j) {
- switch (nodes [i].state) {
- case STATE_BUSY:
- mono_thread_hazardous_try_free_some ();
- break;
- case STATE_OUT:
- if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
- result = mono_lls_find (&lls, hp, i);
- assert (!result);
- mono_hazard_pointer_clear_all (hp, -1);
-
- result = mono_lls_insert (&lls, hp, &nodes [i].node);
- mono_hazard_pointer_clear_all (hp, -1);
-
- assert (nodes [i].state == STATE_BUSY);
- nodes [i].state = STATE_IN;
-
- ++thread_data->num_adds;
- }
- break;
- case STATE_IN:
- if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
- result = mono_lls_find (&lls, hp, i);
- assert (result);
- assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
- mono_hazard_pointer_clear_all (hp, -1);
-
- result = mono_lls_remove (&lls, hp, &nodes [i].node);
- mono_hazard_pointer_clear_all (hp, -1);
-
- ++thread_data->num_removes;
- }
- break;
- default:
- assert (FALSE);
- }
-
- i += skip;
- if (i >= N)
- i -= N;
- }
-
- return NULL;
-}
-
-int
-main (int argc, char *argv [])
-{
- int primes [] = { 1, 2, 3, 5, 7, 11, 13, 17 };
- MonoThreadInfoCallbacks thread_callbacks;
- thread_data_t thread_data [NUM_THREADS];
- int i;
-
- memset (&thread_callbacks, 0, sizeof (thread_callbacks));
-
- mono_metadata_init ();
-
- mono_threads_init (&thread_callbacks, 0);
-
- mono_thread_smr_init ();
- mono_lls_init (&lls, free_node);
-
- for (i = 0; i < N; ++i) {
- nodes [i].node.key = i;
- nodes [i].state = STATE_OUT;
- }
-
- for (i = 0; i < NUM_THREADS; ++i) {
- int result;
-
- thread_data [i].num_adds = thread_data [i].num_removes = 0;
- thread_data [i].skip = primes [i];
- result = pthread_create (&thread_data [i].thread, NULL, worker, &thread_data [i]);
- assert (!result);
- }
-
- for (i = 0; i < NUM_THREADS; ++i) {
- int result = pthread_join (thread_data [i].thread, NULL);
- assert (!result);
- printf ("thread %d adds %d removes %d\n", i, thread_data [i].num_adds, thread_data [i].num_removes);
- }
-
- return 0;
-}
+++ /dev/null
-/*
- * test-sgen-qsort.c: Unit test for quicksort.
- *
- * Copyright (C) 2013 Xamarin Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License 2.0 as published by the Free Software Foundation;
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License 2.0 along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "config.h"
-
-#include "metadata/sgen-gc.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-
-static int
-compare_ints (const void *pa, const void *pb)
-{
- int a = *(const int*)pa;
- int b = *(const int*)pb;
- if (a < b)
- return -1;
- if (a == b)
- return 0;
- return 1;
-}
-
-typedef struct {
- int key;
- int val;
-} teststruct_t;
-
-static int
-compare_teststructs (const void *pa, const void *pb)
-{
- int a = ((const teststruct_t*)pa)->key;
- int b = ((const teststruct_t*)pb)->key;
- if (a < b)
- return -1;
- if (a == b)
- return 0;
- return 1;
-}
-
-static void
-compare_sorts (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*))
-{
- size_t len = nel * width;
- void *b1 = malloc (len);
- void *b2 = malloc (len);
-
- memcpy (b1, base, len);
- memcpy (b2, base, len);
-
- qsort (b1, nel, width, compar);
- sgen_qsort (b2, nel, width, compar);
-
- assert (!memcmp (b1, b2, len));
-
- free (b1);
- free (b2);
-}
-
-int
-main (void)
-{
- int i;
- for (i = 1; i < 4000; ++i) {
- int a [i];
- int j;
-
- for (j = 0; j < i; ++j)
- a [j] = i - j - 1;
- compare_sorts (a, i, sizeof (int), compare_ints);
- }
-
- srandom (time (NULL));
- for (i = 0; i < 2000; ++i) {
- teststruct_t a [200];
- int j;
- for (j = 0; j < 200; ++j) {
- a [j].key = random ();
- a [j].val = random ();
- }
-
- compare_sorts (a, 200, sizeof (teststruct_t), compare_teststructs);
- }
-
- return 0;
-}
--- /dev/null
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/mono $(LIBGC_CPPFLAGS) $(GLIB_CFLAGS) -DMONO_BINDIR=\"$(bindir)/\" -DMONO_ASSEMBLIES=\"$(assembliesdir)\" -DMONO_CFG_DIR=\"$(confdir)\"
+
+if !CROSS_COMPILING
+if !HOST_WIN32
+if SUPPORT_BOEHM
+
+test_sgen_qsort_SOURCES = test-sgen-qsort.c
+test_sgen_qsort_CFLAGS = $(SGEN_DEFINES)
+test_sgen_qsort_LDADD = ../metadata/libmonoruntimesgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
+ $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV)
+if PLATFORM_DARWIN
+test_sgen_qsort_LDFLAGS=-framework CoreFoundation -framework Foundation
+endif
+
+test_gc_memfuncs_SOURCES = test-gc-memfuncs.c
+test_gc_memfuncs_CFLAGS = $(SGEN_DEFINES)
+test_gc_memfuncs_LDADD = ../metadata/libmonoruntimesgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
+ $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV)
+if PLATFORM_DARWIN
+test_gc_memfuncs_LDFLAGS=-framework CoreFoundation -framework Foundation
+endif
+
+test_mono_linked_list_set_SOURCES = test-mono-linked-list-set.c
+test_mono_linked_list_set_CFLAGS = $(AM_CFLAGS)
+test_mono_linked_list_set_LDADD = ../metadata/libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
+ $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV) $(PEDUMP_DTRACE_OBJECT)
+
+if PLATFORM_DARWIN
+test_mono_linked_list_set_LDFLAGS=-framework CoreFoundation -framework Foundation
+endif
+
+noinst_PROGRAMS = test-sgen-qsort test-gc-memfuncs test-mono-linked-list-set
+
+TESTS = test-sgen-qsort test-gc-memfuncs test-mono-linked-list-set
+
+endif SUPPORT_BOEHM
+endif !HOST_WIN32
+endif !CROSS_COMPILING
--- /dev/null
+/*
+ * test-sgen-qsort.c: Unit test for our own bzero/memmove.
+ *
+ * Copyright (C) 2013 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+
+#include "metadata/gc-internal.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+
+#define POOL_SIZE 2048
+#define START_OFFSET 128
+
+#define BZERO_OFFSETS 64
+#define BZERO_SIZES 256
+
+#define MEMMOVE_SRC_OFFSETS 32
+#define MEMMOVE_DEST_OFFSETS 32
+#define MEMMOVE_SIZES 256
+#define MEMMOVE_NONOVERLAP_START 1024
+
+int
+main (void)
+{
+ unsigned char *random_mem = malloc (POOL_SIZE);
+ unsigned char *reference = malloc (POOL_SIZE);
+ unsigned char *playground = malloc (POOL_SIZE);
+ long *long_random_mem;
+ int i, offset, size, src_offset, dest_offset;
+
+ srandom (time (NULL));
+
+ /* init random memory */
+ long_random_mem = (long*)random_mem;
+ for (i = 0; i < POOL_SIZE / sizeof (long); ++i)
+ long_random_mem [i] = random ();
+
+ /* test bzero */
+ for (offset = 0; offset <= BZERO_OFFSETS; ++offset) {
+ for (size = 0; size <= BZERO_SIZES; ++size) {
+ memcpy (reference, random_mem, POOL_SIZE);
+ memcpy (playground, random_mem, POOL_SIZE);
+
+ bzero (reference + START_OFFSET + offset, size);
+ mono_gc_bzero_atomic (playground + START_OFFSET + offset, size);
+
+ assert (!memcmp (reference, playground, POOL_SIZE));
+ }
+ }
+
+ /* test memmove */
+ for (src_offset = -MEMMOVE_SRC_OFFSETS; src_offset <= MEMMOVE_SRC_OFFSETS; ++src_offset) {
+ for (dest_offset = -MEMMOVE_DEST_OFFSETS; dest_offset <= MEMMOVE_DEST_OFFSETS; ++dest_offset) {
+ for (size = 0; size <= MEMMOVE_SIZES; ++size) {
+ /* overlapping */
+ memcpy (reference, random_mem, POOL_SIZE);
+ memcpy (playground, random_mem, POOL_SIZE);
+
+ memmove (reference + START_OFFSET + dest_offset, reference + START_OFFSET + src_offset, size);
+ mono_gc_memmove_atomic (playground + START_OFFSET + dest_offset, playground + START_OFFSET + src_offset, size);
+
+ assert (!memcmp (reference, playground, POOL_SIZE));
+
+ /* non-overlapping with dest < src */
+ memcpy (reference, random_mem, POOL_SIZE);
+ memcpy (playground, random_mem, POOL_SIZE);
+
+ memmove (reference + START_OFFSET + dest_offset, reference + MEMMOVE_NONOVERLAP_START + src_offset, size);
+ mono_gc_memmove_atomic (playground + START_OFFSET + dest_offset, playground + MEMMOVE_NONOVERLAP_START + src_offset, size);
+
+ assert (!memcmp (reference, playground, POOL_SIZE));
+
+ /* non-overlapping with dest > src */
+ memcpy (reference, random_mem, POOL_SIZE);
+ memcpy (playground, random_mem, POOL_SIZE);
+
+ memmove (reference + MEMMOVE_NONOVERLAP_START + dest_offset, reference + START_OFFSET + src_offset, size);
+ mono_gc_memmove_atomic (playground + MEMMOVE_NONOVERLAP_START + dest_offset, playground + START_OFFSET + src_offset, size);
+
+ assert (!memcmp (reference, playground, POOL_SIZE));
+ }
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+#include <assert.h>
+#include <pthread.h>
+
+#include <config.h>
+#include <mono/metadata/metadata.h>
+#include <mono/utils/mono-threads.h>
+#include <mono/utils/hazard-pointer.h>
+#include <mono/utils/mono-linked-list-set.h>
+#include <mono/utils/atomic.h>
+
+static MonoLinkedListSet lls;
+
+enum {
+ STATE_OUT,
+ STATE_BUSY,
+ STATE_IN
+};
+
+#define N 23
+#define NUM_ITERS 1000000
+#define NUM_THREADS 8
+
+typedef struct {
+ MonoLinkedListSetNode node;
+ int state;
+} node_t;
+
+typedef struct {
+ int skip;
+ int num_adds;
+ int num_removes;
+ pthread_t thread;
+} thread_data_t;
+
+static node_t nodes [N];
+
+static inline void
+mono_hazard_pointer_clear_all (MonoThreadHazardPointers *hp, int retain)
+{
+ if (retain != 0)
+ mono_hazard_pointer_clear (hp, 0);
+ if (retain != 1)
+ mono_hazard_pointer_clear (hp, 1);
+ if (retain != 2)
+ mono_hazard_pointer_clear (hp, 2);
+}
+
+static void
+free_node (void *n)
+{
+ node_t *node = n;
+ assert (node->state == STATE_BUSY);
+ node->state = STATE_OUT;
+}
+
+static void*
+worker (void *arg)
+{
+ thread_data_t *thread_data = arg;
+ MonoThreadHazardPointers *hp;
+ int skip = thread_data->skip;
+ int i, j;
+ gboolean result;
+
+ mono_thread_info_register_small_id ();
+
+ hp = mono_hazard_pointer_get ();
+
+ i = 0;
+ for (j = 0; j < NUM_ITERS; ++j) {
+ switch (nodes [i].state) {
+ case STATE_BUSY:
+ mono_thread_hazardous_try_free_some ();
+ break;
+ case STATE_OUT:
+ if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
+ result = mono_lls_find (&lls, hp, i);
+ assert (!result);
+ mono_hazard_pointer_clear_all (hp, -1);
+
+ result = mono_lls_insert (&lls, hp, &nodes [i].node);
+ mono_hazard_pointer_clear_all (hp, -1);
+
+ assert (nodes [i].state == STATE_BUSY);
+ nodes [i].state = STATE_IN;
+
+ ++thread_data->num_adds;
+ }
+ break;
+ case STATE_IN:
+ if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
+ result = mono_lls_find (&lls, hp, i);
+ assert (result);
+ assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
+ mono_hazard_pointer_clear_all (hp, -1);
+
+ result = mono_lls_remove (&lls, hp, &nodes [i].node);
+ mono_hazard_pointer_clear_all (hp, -1);
+
+ ++thread_data->num_removes;
+ }
+ break;
+ default:
+ assert (FALSE);
+ }
+
+ i += skip;
+ if (i >= N)
+ i -= N;
+ }
+
+ return NULL;
+}
+
+int
+main (int argc, char *argv [])
+{
+ int primes [] = { 1, 2, 3, 5, 7, 11, 13, 17 };
+ MonoThreadInfoCallbacks thread_callbacks;
+ thread_data_t thread_data [NUM_THREADS];
+ int i;
+
+ memset (&thread_callbacks, 0, sizeof (thread_callbacks));
+
+ mono_metadata_init ();
+
+ mono_threads_init (&thread_callbacks, 0);
+
+ mono_thread_smr_init ();
+ mono_lls_init (&lls, free_node);
+
+ for (i = 0; i < N; ++i) {
+ nodes [i].node.key = i;
+ nodes [i].state = STATE_OUT;
+ }
+
+ for (i = 0; i < NUM_THREADS; ++i) {
+ int result;
+
+ thread_data [i].num_adds = thread_data [i].num_removes = 0;
+ thread_data [i].skip = primes [i];
+ result = pthread_create (&thread_data [i].thread, NULL, worker, &thread_data [i]);
+ assert (!result);
+ }
+
+ for (i = 0; i < NUM_THREADS; ++i) {
+ int result = pthread_join (thread_data [i].thread, NULL);
+ assert (!result);
+ printf ("thread %d adds %d removes %d\n", i, thread_data [i].num_adds, thread_data [i].num_removes);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * test-sgen-qsort.c: Unit test for quicksort.
+ *
+ * Copyright (C) 2013 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+
+#include <metadata/sgen-gc.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+
+static int
+compare_ints (const void *pa, const void *pb)
+{
+ int a = *(const int*)pa;
+ int b = *(const int*)pb;
+ if (a < b)
+ return -1;
+ if (a == b)
+ return 0;
+ return 1;
+}
+
+typedef struct {
+ int key;
+ int val;
+} teststruct_t;
+
+static int
+compare_teststructs (const void *pa, const void *pb)
+{
+ int a = ((const teststruct_t*)pa)->key;
+ int b = ((const teststruct_t*)pb)->key;
+ if (a < b)
+ return -1;
+ if (a == b)
+ return 0;
+ return 1;
+}
+
+static void
+compare_sorts (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*))
+{
+ size_t len = nel * width;
+ void *b1 = malloc (len);
+ void *b2 = malloc (len);
+
+ memcpy (b1, base, len);
+ memcpy (b2, base, len);
+
+ qsort (b1, nel, width, compar);
+ sgen_qsort (b2, nel, width, compar);
+
+ assert (!memcmp (b1, b2, len));
+
+ free (b1);
+ free (b2);
+}
+
+int
+main (void)
+{
+ int i;
+ for (i = 1; i < 4000; ++i) {
+ int a [i];
+ int j;
+
+ for (j = 0; j < i; ++j)
+ a [j] = i - j - 1;
+ compare_sorts (a, i, sizeof (int), compare_ints);
+ }
+
+ srandom (time (NULL));
+ for (i = 0; i < 2000; ++i) {
+ teststruct_t a [200];
+ int j;
+ for (j = 0; j < 200; ++j) {
+ a [j].key = random ();
+ a [j].val = random ();
+ }
+
+ compare_sorts (a, 200, sizeof (teststruct_t), compare_teststructs);
+ }
+
+ return 0;
+}