1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "gc/g1/workerDataArray.inline.hpp" 26 #include "memory/resourceArea.hpp" 27 #include "unittest.hpp" 28 #include "utilities/ostream.hpp" 29 30 static const double epsilon = 0.0001; 31 32 template<typename T> 33 class WorkerDataArrayTest : public ::testing::Test { 34 protected: 35 WorkerDataArrayTest() : 36 title("Test array"), 37 array(3, title), 38 sub_item_title("Sub item array"), 39 sub_item(3, sub_item_title) { 40 41 array.link_thread_work_items(&sub_item); 42 } 43 44 const char* print_summary() { 45 stringStream out; 46 array.print_summary_on(&out); 47 return out.as_string(); 48 } 49 50 const char* print_details() { 51 stringStream out; 52 array.print_details_on(&out); 53 return out.as_string(); 54 } 55 56 const char* print_expected_summary() { 57 return prepend_with(title, expected_summary()); 58 } 59 60 const char* print_expected_details() { 61 return prepend_with("", expected_details()); 62 } 63 64 // returns expected summary for array without uninitialized elements 65 // used it because string representation of double depends on locale 66 static const char* format_summary( 67 T min, double avg, T max, T diff, T sum, size_t workers); 68 69 const char* title; 70 WorkerDataArray<T> array; 71 72 const char* sub_item_title; 73 WorkerDataArray<size_t> sub_item; 74 75 private: 76 virtual const char* expected_summary() = 0; 77 virtual const char* expected_details() = 0; 78 79 static const char* prepend_with(const char* str, const char* orig) { 80 stringStream out; 81 out.print("%-25s", str); 82 out.print("%s", orig); 83 return out.as_string(); 84 } 85 86 ResourceMark rm; 87 }; 88 89 template<> 90 const char* WorkerDataArrayTest<size_t>::format_summary( 91 size_t min, double avg, size_t max, size_t diff, size_t sum, size_t workers) { 92 93 stringStream out; 94 out.print(" Min: " SIZE_FORMAT 95 ", Avg: %4.1lf, Max: " SIZE_FORMAT 96 ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT 97 ", Workers: " SIZE_FORMAT "\n", 98 min, avg, max, diff, sum, workers); 99 return out.as_string(); 100 } 101 102 template<> 103 const char* WorkerDataArrayTest<double>::format_summary( 104 double min, double avg, double max, double diff, double sum, size_t workers) { 105 106 stringStream out; 107 out.print(" Min: %4.1lf" 108 ", Avg: %4.1lf, Max: %4.1lf" 109 ", Diff: %4.1lf, Sum: %4.1lf" 110 ", Workers: " SIZE_FORMAT "\n", 111 min, avg, max, diff, sum, workers); 112 return out.as_string(); 113 } 114 115 class BasicWorkerDataArrayTest : public WorkerDataArrayTest<size_t> { 116 protected: 117 BasicWorkerDataArrayTest() { 118 array.set(0, 5); 119 array.set(1, 3); 120 array.set(2, 7); 121 122 array.set_thread_work_item(0, 1); 123 array.set_thread_work_item(1, 2); 124 array.set_thread_work_item(2, 3); 125 } 126 127 private: 128 virtual const char* expected_summary() { 129 return format_summary(3, 5.0, 7, 4, 15, 3); 130 } 131 132 virtual const char* expected_details() { 133 return " 5 3 7\n"; 134 } 135 }; 136 137 TEST_VM_F(BasicWorkerDataArrayTest, sum_test) { 138 ASSERT_EQ(15u, array.sum()); 139 ASSERT_EQ(6u, array.thread_work_items(0)->sum()); 140 } 141 142 TEST_VM_F(BasicWorkerDataArrayTest, average_test) { 143 ASSERT_NEAR(5.0, array.average(), epsilon); 144 ASSERT_NEAR(2.0, array.thread_work_items(0)->average(), epsilon); 145 } 146 147 TEST_VM_F(BasicWorkerDataArrayTest, print_summary_on_test) { 148 ASSERT_STREQ(print_expected_summary(), print_summary()); 149 } 150 151 TEST_VM_F(BasicWorkerDataArrayTest, print_details_on_test) { 152 ASSERT_STREQ(print_expected_details(), print_details()); 153 } 154 155 class AddWorkerDataArrayTest : public WorkerDataArrayTest<size_t> { 156 protected: 157 AddWorkerDataArrayTest() { 158 array.set(0, 5); 159 array.set(1, 3); 160 array.set(2, 7); 161 162 for (uint i = 0; i < 3; i++) { 163 array.add(i, 1); 164 } 165 166 WorkerDataArray<size_t>* sub_items = array.thread_work_items(0); 167 168 sub_items->set(0, 1); 169 sub_items->set(1, 2); 170 sub_items->set(2, 3); 171 172 for (uint i = 0; i < 3; i++) { 173 array.add_thread_work_item(i, 1); 174 } 175 } 176 177 private: 178 virtual const char* expected_summary() { 179 return format_summary(4, 6.0, 8, 4, 18, 3); 180 } 181 182 virtual const char* expected_details() { 183 return " 6 4 8\n"; 184 } 185 }; 186 187 TEST_VM_F(AddWorkerDataArrayTest, sum_test) { 188 ASSERT_EQ(18u, array.sum()); 189 ASSERT_EQ(9u, array.thread_work_items(0)->sum()); 190 } 191 192 TEST_VM_F(AddWorkerDataArrayTest, average_test) { 193 ASSERT_NEAR(6.0, array.average(), epsilon); 194 ASSERT_NEAR(3.0, array.thread_work_items(0)->average(), epsilon); 195 } 196 197 TEST_VM_F(AddWorkerDataArrayTest, print_summary_on_test) { 198 ASSERT_STREQ(print_expected_summary(), print_summary()); 199 } 200 201 TEST_VM_F(AddWorkerDataArrayTest, print_details_on_test) { 202 ASSERT_STREQ(print_expected_details(), print_details()); 203 } 204 205 class UninitializedElementWorkerDataArrayTest : public WorkerDataArrayTest<size_t> { 206 protected: 207 UninitializedElementWorkerDataArrayTest() { 208 array.set(0, 5); 209 array.set(1, WorkerDataArray<size_t>::uninitialized()); 210 array.set(2, 7); 211 } 212 213 private: 214 virtual const char* expected_summary() { 215 return format_summary(5, 6.0, 7, 2, 12, 2); 216 } 217 218 virtual const char* expected_details() { 219 return " 5 - 7\n"; 220 } 221 }; 222 223 TEST_VM_F(UninitializedElementWorkerDataArrayTest, sum_test) { 224 ASSERT_EQ(12u, array.sum()); 225 } 226 227 TEST_VM_F(UninitializedElementWorkerDataArrayTest, average_test) { 228 ASSERT_NEAR(6.0, array.average(), epsilon); 229 } 230 231 TEST_VM_F(UninitializedElementWorkerDataArrayTest, print_summary_on_test) { 232 ASSERT_STREQ(print_expected_summary(), print_summary()); 233 } 234 235 TEST_VM_F(UninitializedElementWorkerDataArrayTest, print_details_on_test) { 236 ASSERT_STREQ(print_expected_details(), print_details()); 237 } 238 239 class UninitializedWorkerDataArrayTest : public WorkerDataArrayTest<size_t> { 240 protected: 241 UninitializedWorkerDataArrayTest() { 242 array.set(0, WorkerDataArray<size_t>::uninitialized()); 243 array.set(1, WorkerDataArray<size_t>::uninitialized()); 244 array.set(2, WorkerDataArray<size_t>::uninitialized()); 245 } 246 247 private: 248 virtual const char* expected_summary() { 249 return " skipped\n"; 250 } 251 252 virtual const char* expected_details() { 253 return " - - -\n"; 254 } 255 }; 256 257 TEST_VM_F(UninitializedWorkerDataArrayTest, sum_test) { 258 ASSERT_EQ(0u, array.sum()); 259 } 260 261 TEST_VM_F(UninitializedWorkerDataArrayTest, average_test) { 262 ASSERT_NEAR(0.0, array.average(), epsilon); 263 } 264 265 TEST_VM_F(UninitializedWorkerDataArrayTest, print_summary_on_test) { 266 ASSERT_STREQ(print_expected_summary(), print_summary()); 267 } 268 269 TEST_VM_F(UninitializedWorkerDataArrayTest, print_details_on_test) { 270 ASSERT_STREQ(print_expected_details(), print_details()); 271 } 272 273 class UninitializedDoubleElementWorkerDataArrayTest : public WorkerDataArrayTest<double> { 274 protected: 275 UninitializedDoubleElementWorkerDataArrayTest() { 276 array.set(0, 5.1 / MILLIUNITS); 277 array.set(1, WorkerDataArray<double>::uninitialized()); 278 array.set(2, 7.2 / MILLIUNITS); 279 } 280 281 private: 282 virtual const char* expected_summary() { 283 return format_summary(5.1, 6.1, 7.2, 2.1, 12.3, 2); 284 } 285 286 virtual const char* expected_details() { 287 stringStream out; 288 out.print(" %4.1lf - %4.1lf\n", 5.1, 7.2); 289 return out.as_string(); 290 } 291 }; 292 293 TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, sum_test) { 294 ASSERT_NEAR(12.3 / MILLIUNITS, array.sum(), epsilon); 295 } 296 297 TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, average_test) { 298 ASSERT_NEAR(6.15 / MILLIUNITS, array.average(), epsilon); 299 } 300 301 TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, print_summary_on_test) { 302 ASSERT_STREQ(print_expected_summary(), print_summary()); 303 } 304 305 TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, print_details_on_test) { 306 ASSERT_STREQ(print_expected_details(), print_details()); 307 }