Merge pull request #2713 from gregoryyoung/master
[mono.git] / mono / unit-tests / test-conc-hashtable.c
index ed09d593b6ba19db889d7863654272b182737e14..32d859c50d56cee18c92a9518db37a9c762a0597 100644 (file)
@@ -3,24 +3,14 @@
  *
  * Copyright (C) 2014 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.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include "config.h"
 
 #include "utils/mono-threads.h"
 #include "utils/mono-conc-hashtable.h"
+#include "utils/checked-build.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -36,12 +26,24 @@ single_writer_single_reader (void)
        MonoConcurrentHashTable *h;
        int res = 0;
 
-       mono_mutex_init (&mutex);
-       h = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_os_mutex_init (&mutex);
+       h = mono_conc_hashtable_new (NULL, NULL);
+
+       mono_os_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (10), GUINT_TO_POINTER (20));
+       mono_os_mutex_unlock (&mutex);
+
+       mono_os_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (30), GUINT_TO_POINTER (40));
+       mono_os_mutex_unlock (&mutex);
+
+       mono_os_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (50), GUINT_TO_POINTER (60));
+       mono_os_mutex_unlock (&mutex);
+
+       mono_os_mutex_lock (&mutex);
        mono_conc_hashtable_insert (h, GUINT_TO_POINTER (2), GUINT_TO_POINTER (3));
+       mono_os_mutex_unlock (&mutex);
 
        if (mono_conc_hashtable_lookup (h, GUINT_TO_POINTER (30)) != GUINT_TO_POINTER (40))
                res = 1;
@@ -53,13 +55,14 @@ single_writer_single_reader (void)
                res = 4;
 
        mono_conc_hashtable_destroy (h);
-       mono_mutex_destroy (&mutex);
+       mono_os_mutex_destroy (&mutex);
        if (res)
                printf ("SERIAL TEST FAILED %d\n", res);
        return res;
 }
 
 static MonoConcurrentHashTable *hash;
+static mono_mutex_t global_mutex;
 
 static void*
 pw_sr_thread (void *arg)
@@ -67,8 +70,11 @@ pw_sr_thread (void *arg)
        int i, idx = 1000 * GPOINTER_TO_INT (arg);
        mono_thread_info_attach ((gpointer)&arg);
 
-       for (i = 0; i < 1000; ++i)
+       for (i = 0; i < 1000; ++i) {
+               mono_os_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + idx), GINT_TO_POINTER (i + 1));
+               mono_os_mutex_unlock (&global_mutex);
+       }
        return NULL;
 }
 
@@ -76,11 +82,10 @@ static int
 parallel_writer_single_reader (void)
 {
        pthread_t a,b,c;
-       mono_mutex_t mutex;
        int i, j, res = 0;
 
-       mono_mutex_init (&mutex);
-       hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_os_mutex_init (&global_mutex);
+       hash = mono_conc_hashtable_new (NULL, NULL);
 
        pthread_create (&a, NULL, pw_sr_thread, GINT_TO_POINTER (1));
        pthread_create (&b, NULL, pw_sr_thread, GINT_TO_POINTER (2));
@@ -101,7 +106,7 @@ parallel_writer_single_reader (void)
 
 done:
        mono_conc_hashtable_destroy (hash);
-       mono_mutex_destroy (&mutex);
+       mono_os_mutex_destroy (&global_mutex);
        if (res)
                printf ("PAR_WRITER_SINGLE_READER TEST FAILED %d\n", res);
        return res;
@@ -129,22 +134,29 @@ static int
 single_writer_parallel_reader (void)
 {
        pthread_t a,b,c;
-       mono_mutex_t mutex;
        gpointer ra, rb, rc;
        int i, res = 0;
        ra = rb = rc = GINT_TO_POINTER (1);
 
-       mono_mutex_init (&mutex);
-       hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_os_mutex_init (&global_mutex);
+       hash = mono_conc_hashtable_new (NULL, NULL);
 
        pthread_create (&a, NULL, pr_sw_thread, GINT_TO_POINTER (0));
        pthread_create (&b, NULL, pr_sw_thread, GINT_TO_POINTER (1));
        pthread_create (&c, NULL, pr_sw_thread, GINT_TO_POINTER (2));
 
        for (i = 0; i < 100; ++i) {
+               mono_os_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i +   0 + 1), GINT_TO_POINTER ((i +   0) * 2 + 1));
+               mono_os_mutex_unlock (&global_mutex);
+
+               mono_os_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 100 + 1), GINT_TO_POINTER ((i + 100) * 2 + 1));
+               mono_os_mutex_unlock (&global_mutex);
+
+               mono_os_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 200 + 1), GINT_TO_POINTER ((i + 200) * 2 + 1));
+               mono_os_mutex_unlock (&global_mutex);
        }
 
        pthread_join (a, &ra);
@@ -153,7 +165,7 @@ single_writer_parallel_reader (void)
        res = GPOINTER_TO_INT (ra) + GPOINTER_TO_INT (rb) + GPOINTER_TO_INT (rc);
 
        mono_conc_hashtable_destroy (hash);
-       mono_mutex_destroy (&mutex);
+       mono_os_mutex_destroy (&global_mutex);
        if (res)
                printf ("SINGLE_WRITER_PAR_READER TEST FAILED %d\n", res);
        return res;
@@ -189,8 +201,11 @@ pw_pr_w_add_thread (void *arg)
 
        mono_thread_info_attach ((gpointer)&arg);
 
-       for (i = idx; i < idx + 1000; i++)
+       for (i = idx; i < idx + 1000; i++) {
+               mono_os_mutex_lock (&global_mutex);
                mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 1), GINT_TO_POINTER (i + 1));
+               mono_os_mutex_unlock (&global_mutex);
+       }
        return NULL;
 }
 
@@ -201,8 +216,11 @@ pw_pr_w_del_thread (void *arg)
 
        mono_thread_info_attach ((gpointer)&arg);
 
-       for (i = idx; i < idx + 1000; i++)
+       for (i = idx; i < idx + 1000; i++) {
+               mono_os_mutex_lock (&global_mutex);
                mono_conc_hashtable_remove (hash, GINT_TO_POINTER (i + 1));
+               mono_os_mutex_unlock (&global_mutex);
+       }
        return NULL;
 }
 
@@ -210,14 +228,13 @@ static int
 parallel_writer_parallel_reader (void)
 {
        pthread_t wa, wb, wc, ra, rb, rc;
-       mono_mutex_t mutex;
        gpointer a, b, c;
        int res = 0, i;
 
        srand(time(NULL));
 
-       mono_mutex_init (&mutex);
-       hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       mono_os_mutex_init (&global_mutex);
+       hash = mono_conc_hashtable_new (NULL, NULL);
 
        for (i = 0; i < 2; i++) {
                running = 1;
@@ -256,23 +273,22 @@ parallel_writer_parallel_reader (void)
                printf ("PAR_WRITER_PAR_READER TEST FAILED %d %d %d\n", GPOINTER_TO_INT (a), GPOINTER_TO_INT (b), GPOINTER_TO_INT (c));
 
        mono_conc_hashtable_destroy (hash);
-       mono_mutex_destroy (&mutex);
+       mono_os_mutex_destroy (&global_mutex);
 
        return res;
 }
 
-static void
+static void G_GNUC_UNUSED
 benchmark_conc (void)
 {
-       mono_mutex_t mutex;
        MonoConcurrentHashTable *h;
        int i, j;
 
-       mono_mutex_init (&mutex);
-       h = mono_conc_hashtable_new (&mutex, NULL, NULL);
+       h = mono_conc_hashtable_new (NULL, NULL);
 
-       for (i = 1; i < 10 * 1000; ++i)
+       for (i = 1; i < 10 * 1000; ++i) {
                mono_conc_hashtable_insert (h, GUINT_TO_POINTER (i), GUINT_TO_POINTER (i));
+       }
 
 
        for (j = 0; j < 100000; ++j)
@@ -280,11 +296,9 @@ benchmark_conc (void)
                        mono_conc_hashtable_lookup (h, GUINT_TO_POINTER (i));
 
        mono_conc_hashtable_destroy (h);
-       mono_mutex_destroy (&mutex);
-
 }
 
-static void
+static void G_GNUC_UNUSED
 benchmark_glib (void)
 {
        GHashTable *h;
@@ -303,13 +317,25 @@ benchmark_glib (void)
        g_hash_table_destroy (h);
 }
 
+static void
+thread_state_init (MonoThreadUnwindState *ctx)
+{
+}
+
+
 int
 main (void)
 {
        MonoThreadInfoCallbacks cb = { NULL };
+       MonoThreadInfoRuntimeCallbacks ticallbacks;
        int res = 0;
 
+       CHECKED_MONO_INIT ();
        mono_threads_init (&cb, sizeof (MonoThreadInfo));
+       memset (&ticallbacks, 0, sizeof (ticallbacks));
+       ticallbacks.thread_state_init = thread_state_init;
+       mono_threads_runtime_init (&ticallbacks);
+
        mono_thread_info_attach ((gpointer)&cb);
 
        // benchmark_conc ();
@@ -321,4 +347,4 @@ main (void)
        res += parallel_writer_parallel_reader ();
 
        return res;
-}
\ No newline at end of file
+}