[libc-commits] [libc] [libc] Bound the worst-case stack usage in qsort(). (PR #110849)

Simon Tatham via libc-commits libc-commits at lists.llvm.org
Thu Oct 3 01:16:25 PDT 2024


================
@@ -59,17 +59,33 @@ static size_t partition(const Array &array) {
   }
 }
 
-LIBC_INLINE void quick_sort(const Array &array) {
-  const size_t array_size = array.size();
-  if (array_size <= 1)
-    return;
-  size_t split_index = partition(array);
-  if (array_size <= 2) {
-    // The partition operation sorts the two element array.
-    return;
+LIBC_INLINE void quick_sort(Array array) {
+  while (true) {
+    const size_t array_size = array.size();
+    if (array_size <= 1)
+      return;
+    size_t split_index = partition(array);
+    if (array_size <= 2) {
+      // The partition operation sorts the two element array.
+      return;
+    }
+
+    // Make Arrays describing the two sublists that still need sorting.
+    Array left = array.make_array(0, split_index);
+    Array right = array.make_array(split_index, array.size() - split_index);
+
+    // Recurse to sort the smaller of the two, and then loop round within this
+    // function to sort the larger. This way, recursive call depth is bounded
+    // by log2 of the total array size, because every recursive call is sorting
+    // a list at most half the length of the one in its caller.
+    if (left.size() < right.size()) {
+      quick_sort(left, depth + 1);
----------------
statham-arm wrote:

Yikes! Yes, that's a piece of diagnostic code that escaped into the wild.

(I'm happy to share the diagnostic code in a more organised way if anyone does want it, but I hadn't intended to share a small fragment of it here :-)

https://github.com/llvm/llvm-project/pull/110849


More information about the libc-commits mailing list