Merge pull request #3806 from BrzVlad/feature-parallel-gc-final
[mono.git] / mono / unit-tests / test-sgen-qsort.c
index 3fe33bba991b867e14fc41eebb6b3ee7f7ed3027..ca539fb398083b13ad5fb45fa3c7503e1ff4798c 100644 (file)
@@ -3,23 +3,13 @@
  *
  * 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.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include "config.h"
 
-#include <metadata/sgen-gc.h>
+#include <sgen/sgen-gc.h>
+#include <sgen/sgen-qsort.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -55,6 +45,20 @@ compare_teststructs (const void *pa, const void *pb)
        return 1;
 }
 
+static int
+compare_teststructs2 (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;
+}
+
+DEF_QSORT_INLINE(test_struct, teststruct_t*, compare_teststructs)
+
 static void
 compare_sorts (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*))
 {
@@ -68,12 +72,38 @@ compare_sorts (void *base, size_t nel, size_t width, int (*compar) (const void*,
        qsort (b1, nel, width, compar);
        sgen_qsort (b2, nel, width, compar);
 
-       assert (!memcmp (b1, b2, len));
+       /* We can't assert that qsort and sgen_qsort produce the same results
+        * because qsort is not guaranteed to be stable, so they will tend to differ
+        * in adjacent equal elements. Instead, we assert that the array is sorted
+        * according to the comparator.
+        */
+       for (size_t i = 0; i < nel - 1; ++i)
+               assert (compar ((char *)b2 + i * width, (char *)b2 + (i + 1) * width) <= 0);
 
        free (b1);
        free (b2);
 }
 
+static void
+compare_sorts2 (void *base, size_t nel)
+{
+       size_t width = sizeof (teststruct_t*);
+       size_t len = nel * width;
+       void *b1 = malloc (len);
+       void *b2 = malloc (len);
+
+       memcpy (b1, base, len);
+       memcpy (b2, base, len);
+
+       qsort (b1, nel, sizeof (teststruct_t*), compare_teststructs2);
+       qsort_test_struct ((teststruct_t **)b2, nel);
+
+       for (size_t i = 0; i < nel - 1; ++i)
+               assert (compare_teststructs2 ((char *)b2 + i * width, (char *)b2 + (i + 1) * width) <= 0);
+
+       free (b1);
+       free (b2);
+}
 int
 main (void)
 {
@@ -99,5 +129,18 @@ main (void)
                compare_sorts (a, 200, sizeof (teststruct_t), compare_teststructs);
        }
 
+       srandom (time (NULL));
+       for (i = 0; i < 2000; ++i) {
+               teststruct_t a [200];
+               teststruct_t *b [200];
+               int j;
+               for (j = 0; j < 200; ++j) {
+                       a [j].key = random ();
+                       a [j].val = random ();
+                       b [j] = &a[j];
+               }
+
+               compare_sorts2 (b, 200);
+       }
        return 0;
 }