1 /*
   2  * Copyright (c) 2015, 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 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/workerDataArray.inline.hpp"
  27 #include "utilities/ostream.hpp"
  28 
  29 template <>
  30 void WorkerDataArray<double>::WDAPrinter::summary(outputStream* out, const char* title, double min, double avg, double max, double diff, double sum, bool print_sum) {
  31   out->print("%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf", title, min * MILLIUNITS, avg * MILLIUNITS, max * MILLIUNITS, diff* MILLIUNITS);
  32   if (print_sum) {
  33     out->print_cr(", Sum: %4.1lf", sum * MILLIUNITS);
  34   } else {
  35     out->cr();
  36   }
  37 }
  38 
  39 template <>
  40 void WorkerDataArray<size_t>::WDAPrinter::summary(outputStream* out, const char* title, size_t min, double avg, size_t max, size_t diff, size_t sum, bool print_sum) {
  41   out->print("%-25s Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT, title, min, avg, max, diff);
  42   if (print_sum) {
  43     out->print_cr(", Sum: " SIZE_FORMAT, sum);
  44   } else {
  45     out->cr();
  46   }
  47 }
  48 
  49 template <>
  50 void WorkerDataArray<double>::WDAPrinter::details(const WorkerDataArray<double>* phase, outputStream* out) {
  51   out->print("%-25s", "");
  52   for (uint i = 0; i < phase->_length; ++i) {
  53     double value = phase->get(i);
  54     if (value != phase->uninitialized()) {
  55       out->print(" %4.1lf", phase->get(i) * 1000.0);
  56     } else {
  57       out->print("   -");
  58     }
  59   }
  60   out->cr();
  61 }
  62 
  63 template <>
  64 void WorkerDataArray<size_t>::WDAPrinter::details(const WorkerDataArray<size_t>* phase, outputStream* out) {
  65   out->print("%-25s", "");
  66   for (uint i = 0; i < phase->_length; ++i) {
  67     size_t value = phase->get(i);
  68     if (value != phase->uninitialized()) {
  69       out->print("  " SIZE_FORMAT, phase->get(i));
  70     } else {
  71       out->print("  -");
  72     }
  73   }
  74   out->cr();
  75 }
  76 
  77 #ifndef PRODUCT
  78 
  79 #include "memory/resourceArea.hpp"
  80 
  81 void WorkerDataArray_test_basic() {
  82   const uint length = 3;
  83   const char* title = "Test array";
  84 
  85   WorkerDataArray<size_t> array(length, title);
  86   assert(strncmp(array.title(), title, strlen(title)) == 0 , "Expected titles to match");
  87 
  88   const size_t expected[length] = {5, 3, 7};
  89   for (uint i = 0; i < length; i++) {
  90     array.set(i, expected[i]);
  91   }
  92   for (uint i = 0; i < length; i++) {
  93     assert(array.get(i) == expected[i], "Expected elements to match");
  94   }
  95 
  96   assert(array.sum() == (5 + 3 + 7), "Expected sums to match");
  97   assert(array.average() == 5.0, "Expected averages to match");
  98 
  99   for (uint i = 0; i < length; i++) {
 100     array.add(i, 1);
 101   }
 102   for (uint i = 0; i < length; i++) {
 103     assert(array.get(i) == expected[i] + 1, "Expected add to increment values");
 104   }
 105 }
 106 
 107 void WorkerDataArray_test_with_uninitialized() {
 108   const uint length = 3;
 109   const size_t uninitilized = (size_t)-1;
 110   WorkerDataArray<size_t> array(length, "Test array");
 111 
 112   const size_t expected[length] = {5, uninitilized, 7};
 113   for (uint i = 0; i < length; i++) {
 114     array.set(i, expected[i]);
 115   }
 116   for (uint i = 0; i < length; i++) {
 117     assert(array.get(i) == expected[i], "Expected elements to match");
 118   }
 119 
 120   assert(array.sum() == (5 + 7), "Expected sums to match");
 121   assert(array.average() == 6.0, "Expected averages to match");
 122 }
 123 
 124 void WorkerDataArray_test_uninitialized() {
 125   const uint length = 3;
 126   const size_t uninitilized = (size_t)-1;
 127   WorkerDataArray<size_t> array(length, "Test array");
 128 
 129   for (uint i = 0; i < length; i++) {
 130     array.set(i, uninitilized);
 131   }
 132 
 133   assert(array.sum() == 0, "Sum should be 0 when no slots have been used.");
 134   assert(array.average() == 0.0, "Average should be 0.0 when no slots have been used.");
 135 }
 136 
 137 void WorkerDataArray_test_print_summary() {
 138   const uint length = 4;
 139   const size_t uninitilized = (size_t)-1;
 140   WorkerDataArray<size_t> array(length, "Test array");
 141 
 142   const size_t expected[length] = {5, uninitilized, 7, uninitilized};
 143   for (uint i = 0; i < length; i++) {
 144     array.set(i, expected[i]);
 145   }
 146 
 147   ResourceMark rm;
 148   stringStream out;
 149   array.print_summary_on(&out);
 150   const char* out_string = out.as_string();
 151   const char* expected_string = "Test array                Min: 5, Avg:  6,0, Max: 7, Diff: 2, Sum: 12\n";
 152   const size_t expected_len = strlen(expected_string);
 153   assert(expected_len == strlen(out_string), "Wrong string length, expected " SIZE_FORMAT " but got " SIZE_FORMAT, expected_len, strlen(out_string));
 154   assert(strncmp(expected_string, out_string, expected_len) == 0, "Expected '%s' but got: '%s'", expected_string, out_string);
 155 }
 156 
 157 void WorkerDataArray_test_print_details() {
 158   const uint length = 4;
 159   const size_t uninitilized = (size_t)-1;
 160   WorkerDataArray<size_t> array(length, "Test array");
 161 
 162   const size_t expected[length] = {5, uninitilized, 7, uninitilized};
 163   for (uint i = 0; i < length; i++) {
 164     array.set(i, expected[i]);
 165   }
 166 
 167   ResourceMark rm;
 168   stringStream out;
 169   array.print_details_on(&out);
 170   const char* out_string = out.as_string();
 171   const char* expected_string = "                           5  -  7  -\n";
 172   const size_t expected_len = strlen(expected_string);
 173   assert(expected_len == strlen(out_string), "Wrong string length, expected " SIZE_FORMAT " but got " SIZE_FORMAT, expected_len, strlen(out_string));
 174   assert(strncmp(expected_string, out_string, expected_len) == 0, "Expected '%s' but got: '%s'", expected_string, out_string);
 175 }
 176 
 177 void WorkerDataArray_test() {
 178   WorkerDataArray_test_basic();
 179   WorkerDataArray_test_with_uninitialized();
 180   WorkerDataArray_test_uninitialized();
 181   WorkerDataArray_test_print_summary();
 182   WorkerDataArray_test_print_details();
 183 }
 184 
 185 #endif