|
| 1 | +/* |
| 2 | + * Copyright (c) 2021, 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 | +import jdk.test.lib.process.OutputAnalyzer; |
| 25 | +import jdk.test.lib.Platform; |
| 26 | +import jdk.test.lib.process.ProcessTools; |
| 27 | + |
| 28 | +/* |
| 29 | + * @test |
| 30 | + * @bug 8226416 |
| 31 | + * @summary Test the MonitorUsedDeflationThreshold and NoAsyncDeflationProgressMax options. |
| 32 | + * @modules java.base/jdk.internal.misc |
| 33 | + * @library /test/lib |
| 34 | + * @run driver MonitorUsedDeflationThresholdTest |
| 35 | + */ |
| 36 | + |
| 37 | +public class MonitorUsedDeflationThresholdTest { |
| 38 | + public static final int DELAY_SECS = 10; |
| 39 | + public static int inflate_count = 0; |
| 40 | + public static Object[] monitors; |
| 41 | + |
| 42 | + public static void do_work(int count) { |
| 43 | + System.out.println("Recursion count=" + count); |
| 44 | + if (count > inflate_count) { |
| 45 | + System.out.println("Exceeded inflate_count=" + inflate_count); |
| 46 | + |
| 47 | + System.out.println("Delaying for " + DELAY_SECS + " secs."); |
| 48 | + try { |
| 49 | + Thread.sleep(DELAY_SECS * 1000); |
| 50 | + } catch (InterruptedException ie) { |
| 51 | + // ignore InterruptedException |
| 52 | + } |
| 53 | + System.out.println("Done delaying for " + DELAY_SECS + " secs."); |
| 54 | + return; |
| 55 | + } |
| 56 | + |
| 57 | + synchronized(monitors[count]) { |
| 58 | + try { |
| 59 | + monitors[count].wait(1); // force inflation |
| 60 | + } catch (InterruptedException ie) { |
| 61 | + // ignore InterruptedException |
| 62 | + } |
| 63 | + do_work(count + 1); |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + public static void usage() { |
| 68 | + System.err.println("Usage: java " + |
| 69 | + "MonitorUsedDeflationThresholdTest inflate_count"); |
| 70 | + } |
| 71 | + |
| 72 | + public static void main(String[] args) throws Exception { |
| 73 | + if (args.length == 0) { |
| 74 | + // Without args we invoke the test in a java sub-process: |
| 75 | + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( |
| 76 | + // Test doesn't need much Java heap: |
| 77 | + "-Xmx100M", |
| 78 | + // AvgMonitorsPerThreadEstimate == 1 means we'll start with |
| 79 | + // an in_use_list_ceiling of <n-threads> plus a couple of |
| 80 | + // of monitors for threads that call Object.wait(). |
| 81 | + "-XX:+UnlockDiagnosticVMOptions", |
| 82 | + "-XX:AvgMonitorsPerThreadEstimate=1", |
| 83 | + // Enable monitorinflation logging so we can see that |
| 84 | + // MonitorUsedDeflationThreshold and |
| 85 | + // NoAsyncDeflationProgressMaxoption are working. |
| 86 | + "-Xlog:monitorinflation=info", |
| 87 | + // Enable some safepoint logging for diagnostic purposes. |
| 88 | + "-Xlog:safepoint+cleanup=info", |
| 89 | + "-Xlog:safepoint+stats=debug", |
| 90 | + // Run the test with inflate_count == 33 since that |
| 91 | + // reproduced the bug with JDK13. Anything above the |
| 92 | + // in_use_list_ceiling will do the trick. |
| 93 | + "MonitorUsedDeflationThresholdTest", "33"); |
| 94 | + |
| 95 | + OutputAnalyzer output_detail = new OutputAnalyzer(pb.start()); |
| 96 | + |
| 97 | + // This mesg means: |
| 98 | + // - AvgMonitorsPerThreadEstimate == 1 reduced in_use_list_ceiling |
| 99 | + // to a small number. |
| 100 | + // - and we crossed MonitorUsedDeflationThreshold: |
| 101 | + output_detail.shouldMatch("begin deflating: .*"); |
| 102 | + System.out.println("Found beginning of a deflation cycle."); |
| 103 | + |
| 104 | + // This mesg means we hit NoAsyncDeflationProgressMax and |
| 105 | + // had to adjust the in_use_list_ceiling: |
| 106 | + String too_many = output_detail.firstMatch("Too many deflations without progress; .*", 0); |
| 107 | + if (too_many == null) { |
| 108 | + output_detail.reportDiagnosticSummary(); |
| 109 | + throw new RuntimeException("Did not find too_many string in output.\n"); |
| 110 | + } |
| 111 | + System.out.println("too_many='" + too_many + "'"); |
| 112 | + |
| 113 | + System.out.println("PASSED."); |
| 114 | + return; |
| 115 | + } |
| 116 | + // else we are the exec'd java subprocess, so run the actual test: |
| 117 | + |
| 118 | + try { |
| 119 | + inflate_count = Integer.decode(args[0]); |
| 120 | + } catch (NumberFormatException nfe) { |
| 121 | + usage(); |
| 122 | + throw new RuntimeException("ERROR: '" + args[0] + |
| 123 | + "': bad inflate_count."); |
| 124 | + } |
| 125 | + |
| 126 | + System.out.println("Hello from MonitorUsedDeflationThresholdTest!"); |
| 127 | + System.out.println("inflate_count=" + inflate_count); |
| 128 | + |
| 129 | + monitors = new Object[inflate_count + 1]; |
| 130 | + for (int i = 1; i <= inflate_count; i++) { |
| 131 | + monitors[i] = new Object(); |
| 132 | + } |
| 133 | + do_work(1); |
| 134 | + } |
| 135 | +} |
0 commit comments