Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

replace rt.qsort with libc wrapper #427

Merged
merged 3 commits into from

3 participants

@MartinNowak
Collaborator

No description provided.

@alexrp
Collaborator

What's with the Darwin failures?

@MartinNowak
Collaborator

What's with the Darwin failures?

I'll have to investigate them.

@andralex andralex merged commit 9a35cc7 into D-Programming-Language:master
@MartinNowak MartinNowak deleted the MartinNowak:qsort2 branch
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 6, 2013
  1. @MartinNowak
  2. @MartinNowak
Commits on Mar 7, 2013
  1. @MartinNowak

    use reentrant qsort_r where available

    MartinNowak authored
    - this avoids one TLS access per comparison
This page is out of date. Refresh to see the latest.
Showing with 65 additions and 191 deletions.
  1. +0 −1  mak/MANIFEST
  2. +65 −118 src/rt/qsort.d
  3. +0 −72 src/rt/qsort2.d
View
1  mak/MANIFEST
@@ -180,7 +180,6 @@ MANIFEST=\
src\rt\monitor_.d \
src\rt\obj.d \
src\rt\qsort.d \
- src\rt\qsort2.d \
src\rt\sections.d \
src\rt\sections_freebsd.d \
src\rt\sections_linux.d \
View
183 src/rt/qsort.d
@@ -1,135 +1,86 @@
-/*
- Portions of this file are:
- Copyright Prototronics, 1987
- Totem Lake P.O. 8117
- Kirkland, Washington 98034
- (206) 820-1972
- Licensed to Digital Mars.
-
- June 11, 1987 from Ray Gardner's
- Denver, Colorado) public domain version
-
- Use qsort2.d instead of this file if a redistributable version of
- _adSort() is required.
-*/
-
+/**
+ * This is a public domain version of qsort.d. All it does is call C's
+ * qsort().
+ *
+ * Copyright: Copyright Digital Mars 2000 - 2010.
+ * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors: Walter Bright, Martin Nowak
+ */
+
+/* Copyright Digital Mars 2000 - 2010.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
module rt.qsort;
-/*
-** Sorts an array starting at base, of length nbr_elements, each
-** element of size width_bytes, ordered via compare_function; which
-** is called as (*comp_fp)(ptr_to_element1, ptr_to_element2)
-** and returns < 0 if element1 < element2, 0 if element1 = element2,
-** > 0 if element1 > element2. Most of the refinements are due to
-** R. Sedgewick. See "Implementing Quicksort Programs", Comm. ACM,
-** Oct. 1978, and Corrigendum, Comm. ACM, June 1979.
-*/
-
-//debug=qsort; // uncomment to turn on debugging printf's
-
-import core.stdc.stdlib;
-
+//debug=qsort;
+private import core.stdc.stdlib;
-private const int _maxspan = 7; // subarrays of _maxspan or fewer elements
- // will be sorted by a simple insertion sort
-
-/* Adjust _maxspan according to relative cost of a swap and a compare. Reduce
-_maxspan (not less than 1) if a swap is very expensive such as when you have
-an array of large structures to be sorted, rather than an array of pointers to
-structures. The default value is optimized for a high cost for compares. */
-
-
-extern (C) void[] _adSort(void[] a, TypeInfo ti)
+version (linux)
{
- byte*[40] stackbuf = void; // initial stack buffer
- auto stack = stackbuf[0..$]; // stack
- auto sp = stack.ptr; // stack pointer
+ alias extern (C) int function(const void *, const void *, void *) Cmp;
+ extern (C) void qsort_r(void *base, size_t nmemb, size_t size, Cmp cmp, void *arg);
- auto width = ti.tsize;
- auto base = cast(byte *)a.ptr;
- auto thresh = _maxspan * width; // size of _maxspan elements in bytes
- auto limit = base + a.length * width; // pointer past end of array
- while (1) // repeat until done then return
- {
- while (limit - base > thresh) // if more than _maxspan elements
+ extern (C) void[] _adSort(void[] a, TypeInfo ti)
{
- //swap middle, base
- ti.swap((cast(uint)(limit - base) >> 1) -
- (((cast(uint)(limit - base) >> 1)) % width) + base, base);
-
- auto i = base + width; // i scans from left to right
- auto j = limit - width; // j scans from right to left
-
- if (ti.compare(i, j) > 0) // Sedgewick's
- ti.swap(i, j); // three-element sort
- if (ti.compare(base, j) > 0) // sets things up
- ti.swap(base, j); // so that
- if (ti.compare(i, base) > 0) // *i <= *base <= *j
- ti.swap(i, base); // *base is the pivot element
+ extern (C) int cmp(in void* p1, in void* p2, void* ti)
+ {
+ return (cast(TypeInfo)ti).compare(p1, p2);
+ }
+ qsort_r(a.ptr, a.length, ti.tsize, &cmp, cast(void*)ti);
+ return a;
+ }
+}
+else version (FreeBSD)
+{
+ alias extern (C) int function(void *, const void *, const void *) Cmp;
+ extern (C) void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, Cmp cmp);
- while (1)
- {
- do // move i right until *i >= pivot
- i += width;
- while (ti.compare(i, base) < 0);
- do // move j left until *j <= pivot
- j -= width;
- while (ti.compare(j, base) > 0);
- if (i > j) // break loop if pointers crossed
- break;
- ti.swap(i, j); // else swap elements, keep scanning
- }
- ti.swap(base, j); // move pivot into correct place
- if (j - base > limit - i) // if left subarray is larger...
- {
- sp[0] = base; // stack left subarray base
- sp[1] = j; // and limit
- base = i; // sort the right subarray
- }
- else // else right subarray is larger
- {
- sp[0] = i; // stack right subarray base
- sp[1] = limit; // and limit
- limit = j; // sort the left subarray
- }
- sp += 2; // increment stack pointer
- if (sp == stack.ptr + stack.length)
- {
- // Double the size of stack[]
- auto newstack = cast(byte**)alloca(stack.length * 2 * (*sp).sizeof);
- newstack[0..stack.length] = stack[];
- sp = &newstack[stack.length];
- stack = newstack[0..stack.length * 2];
- }
+ extern (C) void[] _adSort(void[] a, TypeInfo ti)
+ {
+ extern (C) int cmp(void* ti, in void* p1, in void* p2)
+ {
+ return (cast(TypeInfo)ti).compare(p1, p2);
+ }
+ qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);
+ return a;
}
+}
+else version (OSX)
+{
+ alias extern (C) int function(void *, const void *, const void *) Cmp;
+ extern (C) void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, Cmp cmp);
- // Insertion sort on remaining subarray
- auto i = base + width;
- while (i < limit)
+ extern (C) void[] _adSort(void[] a, TypeInfo ti)
{
- auto j = i;
- while (j > base && ti.compare(j - width, j) > 0)
- {
- ti.swap(j - width, j);
- j -= width;
- }
- i += width;
+ extern (C) int cmp(void* ti, in void* p1, in void* p2)
+ {
+ return (cast(TypeInfo)ti).compare(p1, p2);
+ }
+ qsort_r(a.ptr, a.length, ti.tsize, cast(void*)ti, &cmp);
+ return a;
}
+}
+else
+{
+ private TypeInfo tiglobal;
- if (sp > stack.ptr) // if any entries on stack...
+ extern (C) void[] _adSort(void[] a, TypeInfo ti)
{
- sp -= 2; // pop the base and limit
- base = sp[0];
- limit = sp[1];
+ extern (C) int cmp(in void* p1, in void* p2)
+ {
+ return tiglobal.compare(p1, p2);
+ }
+ tiglobal = ti;
+ qsort(a.ptr, a.length, ti.tsize, &cmp);
+ return a;
}
- else // else stack empty, all done
- return *cast(void[]*)(&a);
- }
- assert(0);
}
+
unittest
{
debug(qsort) printf("array.sort.unittest()\n");
@@ -155,8 +106,4 @@ unittest
//printf(" %d %d\n", a[i], a[i + 1]);
assert(a[i] <= a[i + 1]);
}
-
- auto b = new uint[0xFF_FFFF];
- b.sort;
}
-
View
72 src/rt/qsort2.d
@@ -1,72 +0,0 @@
-/**
- * This is a public domain version of qsort.d. All it does is call C's
- * qsort(), but runs a little slower since it needs to synchronize a global
- * variable.
- *
- * Copyright: Copyright Digital Mars 2000 - 2010.
- * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
- * Authors: Walter Bright
- */
-
-/* Copyright Digital Mars 2000 - 2010.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-module rt.qsort2;
-
-//debug=qsort;
-
-private import core.stdc.stdlib;
-
-struct Array
-{
- size_t length;
- void* ptr;
-}
-
-private TypeInfo tiglobal;
-
-extern (C) int cmp(in void* p1, in void* p2)
-{
- return tiglobal.compare(p1, p2);
-}
-
-extern (C) void[] _adSort(void[] a, TypeInfo ti)
-{
- synchronized
- {
- tiglobal = ti;
- qsort(a.ptr, a.length, cast(size_t)ti.tsize, &cmp);
- }
- return a;
-}
-
-
-
-unittest
-{
- debug(qsort) printf("array.sort.unittest()\n");
-
- int a[] = new int[10];
-
- a[0] = 23;
- a[1] = 1;
- a[2] = 64;
- a[3] = 5;
- a[4] = 6;
- a[5] = 5;
- a[6] = 17;
- a[7] = 3;
- a[8] = 0;
- a[9] = -1;
-
- a.sort;
-
- for (int i = 0; i < a.length - 1; i++)
- {
- //printf("i = %d", i);
- //printf(" %d %d\n", a[i], a[i + 1]);
- assert(a[i] <= a[i + 1]);
- }
-}
Something went wrong with that request. Please try again.