annotate src/share/vm/utilities/quickSort.hpp @ 14649:f6301b007a16

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 3c648b9ad052
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3779
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
1 /*
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
4 *
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
7 * published by the Free Software Foundation.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
8 *
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
13 * accompanied this code).
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
14 *
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
18 *
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
21 * questions.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
22 *
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
23 */
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
24
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
25 #ifndef SHARE_VM_UTILITIES_QUICKSORT_HPP
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
26 #define SHARE_VM_UTILITIES_QUICKSORT_HPP
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
27
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
28 #include "memory/allocation.hpp"
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
29 #include "runtime/globals.hpp"
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
30 #include "utilities/debug.hpp"
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
31
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
32 class QuickSort : AllStatic {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
33
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
34 private:
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
35 template<class T>
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
36 static void swap(T* array, int x, int y) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
37 T tmp = array[x];
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
38 array[x] = array[y];
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
39 array[y] = tmp;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
40 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
41
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
42 // As pivot we use the median of the first, last and middle elements.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
43 // We swap in these three values at the right place in the array. This
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
44 // means that this method not only returns the index of the pivot
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
45 // element. It also alters the array so that:
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
46 // array[first] <= array[middle] <= array[last]
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
47 // A side effect of this is that arrays of length <= 3 are sorted.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
48 template<class T, class C>
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
49 static int find_pivot(T* array, int length, C comparator) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
50 assert(length > 1, "length of array must be > 0");
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
51
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
52 int middle_index = length / 2;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
53 int last_index = length - 1;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
54
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
55 if (comparator(array[0], array[middle_index]) == 1) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
56 swap(array, 0, middle_index);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
57 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
58 if (comparator(array[0], array[last_index]) == 1) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
59 swap(array, 0, last_index);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
60 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
61 if (comparator(array[middle_index], array[last_index]) == 1) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
62 swap(array, middle_index, last_index);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
63 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
64 // Now the value in the middle of the array is the median
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
65 // of the fist, last and middle values. Use this as pivot.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
66 return middle_index;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
67 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
68
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
69 template<class T, class C, bool idempotent>
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
70 static int partition(T* array, int pivot, int length, C comparator) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
71 int left_index = -1;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
72 int right_index = length;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
73 T pivot_val = array[pivot];
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
74
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
75 while (true) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
76 do {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
77 left_index++;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
78 } while (comparator(array[left_index], pivot_val) == -1);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
79 do {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
80 right_index--;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
81 } while (comparator(array[right_index], pivot_val) == 1);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
82
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
83 if (left_index < right_index) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
84 if (!idempotent || comparator(array[left_index], array[right_index]) != 0) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
85 swap(array, left_index, right_index);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
86 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
87 } else {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
88 return right_index;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
89 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
90 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
91
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
92 ShouldNotReachHere();
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
93 return 0;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
94 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
95
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
96 template<class T, class C, bool idempotent>
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
97 static void inner_sort(T* array, int length, C comparator) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
98 if (length < 2) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
99 return;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
100 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
101 int pivot = find_pivot(array, length, comparator);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
102 if (length < 4) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
103 // arrays up to length 3 will be sorted after finding the pivot
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
104 return;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
105 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
106 int split = partition<T, C, idempotent>(array, pivot, length, comparator);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
107 int first_part_length = split + 1;
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
108 inner_sort<T, C, idempotent>(array, first_part_length, comparator);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
109 inner_sort<T, C, idempotent>(&array[first_part_length], length - first_part_length, comparator);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
110 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
111
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
112 public:
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
113 // The idempotent parameter prevents the sort from
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
114 // reordering a previous valid sort by not swapping
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
115 // fields that compare as equal. This requires extra
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
116 // calls to the comparator, so the performance
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
117 // impact depends on the comparator.
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
118 template<class T, class C>
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
119 static void sort(T* array, int length, C comparator, bool idempotent) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
120 // Switch "idempotent" from function paramter to template parameter
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
121 if (idempotent) {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
122 inner_sort<T, C, true>(array, length, comparator);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
123 } else {
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
124 inner_sort<T, C, false>(array, length, comparator);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
125 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
126 }
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
127
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
128 // for unit testing
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
129 #ifndef PRODUCT
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
130 static void print_array(const char* prefix, int* array, int length);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
131 static bool compare_arrays(int* actual, int* expected, int length);
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
132 template <class C> static bool sort_and_compare(int* arrayToSort, int* expectedResult, int length, C comparator, bool idempotent = false);
4708
3c648b9ad052 7121373: Clean up CollectedHeap::is_in
stefank
parents: 3779
diff changeset
133 static void test_quick_sort();
3779
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
134 #endif
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
135 };
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
136
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
137
04760e41b01e 7016112: CMS: crash during promotion testing
brutisso
parents:
diff changeset
138 #endif //SHARE_VM_UTILITIES_QUICKSORT_HPP