test/runtime/Thread/TestThreadDumpMonitorContention.java

Fri, 22 Jul 2016 16:53:17 +0800

author
aoqi
date
Fri, 22 Jul 2016 16:53:17 +0800
changeset 39
72830a7941b2
parent 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Added MIPS support in hotspot/test/test_env.sh

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 /*
aoqi@0 25 * @test
aoqi@0 26 * @bug 8036823
aoqi@0 27 * @bug 8046287
aoqi@0 28 * @summary Creates two threads contending for the same lock and checks
aoqi@0 29 * whether jstack reports "locked" by more than one thread.
aoqi@0 30 *
aoqi@0 31 * @library /testlibrary
aoqi@0 32 * @run main/othervm TestThreadDumpMonitorContention
aoqi@0 33 */
aoqi@0 34
aoqi@0 35 import java.io.BufferedReader;
aoqi@0 36 import java.io.InputStreamReader;
aoqi@0 37 import java.lang.management.ManagementFactory;
aoqi@0 38 import java.lang.management.RuntimeMXBean;
aoqi@0 39 import java.util.ArrayList;
aoqi@0 40 import java.util.List;
aoqi@0 41 import java.util.regex.Matcher;
aoqi@0 42 import java.util.regex.Pattern;
aoqi@0 43
aoqi@0 44 import com.oracle.java.testlibrary.*;
aoqi@0 45
aoqi@0 46 public class TestThreadDumpMonitorContention {
aoqi@0 47 // jstack tends to be closely bound to the VM that we are running
aoqi@0 48 // so use getTestJDKTool() instead of getCompileJDKTool() or even
aoqi@0 49 // getJDKTool() which can fall back to "compile.jdk".
aoqi@0 50 final static String JSTACK = JDKToolFinder.getTestJDKTool("jstack");
aoqi@0 51 final static String PID = getPid();
aoqi@0 52
aoqi@0 53 // looking for header lines with these patterns:
aoqi@0 54 // "ContendingThread-1" #19 prio=5 os_prio=64 tid=0x000000000079c000 nid=0x23 runnable [0xffff80ffb8b87000]
aoqi@0 55 // "ContendingThread-2" #21 prio=5 os_prio=64 tid=0x0000000000780000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
aoqi@0 56 // "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
aoqi@0 57 final static Pattern HEADER_PREFIX_PATTERN = Pattern.compile(
aoqi@0 58 "^\"ContendingThread-.*");
aoqi@0 59 final static Pattern HEADER_WAITING_PATTERN1 = Pattern.compile(
aoqi@0 60 "^\"ContendingThread-.* waiting for monitor entry .*");
aoqi@0 61 final static Pattern HEADER_WAITING_PATTERN2 = Pattern.compile(
aoqi@0 62 "^\"ContendingThread-.* waiting on condition .*");
aoqi@0 63 final static Pattern HEADER_RUNNABLE_PATTERN = Pattern.compile(
aoqi@0 64 "^\"ContendingThread-.* runnable .*");
aoqi@0 65
aoqi@0 66 // looking for thread state lines with these patterns:
aoqi@0 67 // java.lang.Thread.State: RUNNABLE
aoqi@0 68 // java.lang.Thread.State: BLOCKED (on object monitor)
aoqi@0 69 final static Pattern THREAD_STATE_PREFIX_PATTERN = Pattern.compile(
aoqi@0 70 " *java\\.lang\\.Thread\\.State: .*");
aoqi@0 71 final static Pattern THREAD_STATE_BLOCKED_PATTERN = Pattern.compile(
aoqi@0 72 " *java\\.lang\\.Thread\\.State: BLOCKED \\(on object monitor\\)");
aoqi@0 73 final static Pattern THREAD_STATE_RUNNABLE_PATTERN = Pattern.compile(
aoqi@0 74 " *java\\.lang\\.Thread\\.State: RUNNABLE");
aoqi@0 75
aoqi@0 76 // looking for duplicates of this pattern:
aoqi@0 77 // - locked <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1)
aoqi@0 78 final static Pattern LOCK_PATTERN = Pattern.compile(
aoqi@0 79 ".* locked \\<.*\\(a TestThreadDumpMonitorContention.*");
aoqi@0 80
aoqi@0 81 // sanity checking header and thread state lines associated
aoqi@0 82 // with this pattern:
aoqi@0 83 // - waiting to lock <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1)
aoqi@0 84 final static Pattern WAITING_PATTERN = Pattern.compile(
aoqi@0 85 ".* waiting to lock \\<.*\\(a TestThreadDumpMonitorContention.*");
aoqi@0 86
aoqi@0 87 final static Object barrier = new Object();
aoqi@0 88 volatile static boolean done = false;
aoqi@0 89
aoqi@0 90 static int barrier_cnt = 0;
aoqi@0 91 static int blank_line_match_cnt = 0;
aoqi@0 92 static int error_cnt = 0;
aoqi@0 93 static boolean have_header_line = false;
aoqi@0 94 static boolean have_thread_state_line = false;
aoqi@0 95 static String header_line = null;
aoqi@0 96 static int header_prefix_match_cnt = 0;
aoqi@0 97 static int locked_line_match_cnt = 0;
aoqi@0 98 static String[] locked_match_list = new String[2];
aoqi@0 99 static int n_samples = 15;
aoqi@0 100 static int sum_both_running_cnt = 0;
aoqi@0 101 static int sum_both_waiting_cnt = 0;
aoqi@0 102 static int sum_contended_cnt = 0;
aoqi@0 103 static int sum_locked_hdr_runnable_cnt = 0;
aoqi@0 104 static int sum_locked_hdr_waiting1_cnt = 0;
aoqi@0 105 static int sum_locked_hdr_waiting2_cnt = 0;
aoqi@0 106 static int sum_locked_thr_state_blocked_cnt = 0;
aoqi@0 107 static int sum_locked_thr_state_runnable_cnt = 0;
aoqi@0 108 static int sum_one_waiting_cnt = 0;
aoqi@0 109 static int sum_uncontended_cnt = 0;
aoqi@0 110 static int sum_waiting_hdr_waiting1_cnt = 0;
aoqi@0 111 static int sum_waiting_thr_state_blocked_cnt = 0;
aoqi@0 112 static String thread_state_line = null;
aoqi@0 113 static boolean verbose = false;
aoqi@0 114 static int waiting_line_match_cnt = 0;
aoqi@0 115
aoqi@0 116 public static void main(String[] args) throws Exception {
aoqi@0 117 if (args.length != 0) {
aoqi@0 118 int arg_i = 0;
aoqi@0 119 if (args[arg_i].equals("-v")) {
aoqi@0 120 verbose = true;
aoqi@0 121 arg_i++;
aoqi@0 122 }
aoqi@0 123
aoqi@0 124 try {
aoqi@0 125 n_samples = Integer.parseInt(args[arg_i]);
aoqi@0 126 } catch (NumberFormatException nfe) {
aoqi@0 127 System.err.println(nfe);
aoqi@0 128 usage();
aoqi@0 129 }
aoqi@0 130 }
aoqi@0 131
aoqi@0 132 Runnable runnable = new Runnable() {
aoqi@0 133 public void run() {
aoqi@0 134 synchronized (barrier) {
aoqi@0 135 // let the main thread know we're running
aoqi@0 136 barrier_cnt++;
aoqi@0 137 barrier.notify();
aoqi@0 138 }
aoqi@0 139 while (!done) {
aoqi@0 140 synchronized (this) { }
aoqi@0 141 }
aoqi@0 142 }
aoqi@0 143 };
aoqi@0 144 Thread[] thread_list = new Thread[2];
aoqi@0 145 thread_list[0] = new Thread(runnable, "ContendingThread-1");
aoqi@0 146 thread_list[1] = new Thread(runnable, "ContendingThread-2");
aoqi@0 147 synchronized (barrier) {
aoqi@0 148 thread_list[0].start();
aoqi@0 149 thread_list[1].start();
aoqi@0 150
aoqi@0 151 // Wait until the contending threads are running so that
aoqi@0 152 // we don't sample any thread init states.
aoqi@0 153 while (barrier_cnt < 2) {
aoqi@0 154 barrier.wait();
aoqi@0 155 }
aoqi@0 156 }
aoqi@0 157
aoqi@0 158 doSamples();
aoqi@0 159
aoqi@0 160 done = true;
aoqi@0 161
aoqi@0 162 thread_list[0].join();
aoqi@0 163 thread_list[1].join();
aoqi@0 164
aoqi@0 165 if (error_cnt == 0) {
aoqi@0 166 System.out.println("Test PASSED.");
aoqi@0 167 } else {
aoqi@0 168 System.out.println("Test FAILED.");
aoqi@0 169 throw new AssertionError("error_cnt=" + error_cnt);
aoqi@0 170 }
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 // Reached a blank line which is the end of the
aoqi@0 174 // stack trace without matching either LOCK_PATTERN
aoqi@0 175 // or WAITING_PATTERN. Rare, but it's not an error.
aoqi@0 176 //
aoqi@0 177 // Example:
aoqi@0 178 // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
aoqi@0 179 // java.lang.Thread.State: RUNNABLE
aoqi@0 180 // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
aoqi@0 181 // at java.lang.Thread.run(Thread.java:745)
aoqi@0 182 //
aoqi@0 183 static boolean checkBlankLine(String line) {
aoqi@0 184 if (line.length() == 0) {
aoqi@0 185 blank_line_match_cnt++;
aoqi@0 186 have_header_line = false;
aoqi@0 187 have_thread_state_line = false;
aoqi@0 188 return true;
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 return false;
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 // Process the locked line here if we found one.
aoqi@0 195 //
aoqi@0 196 // Example 1:
aoqi@0 197 // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
aoqi@0 198 // java.lang.Thread.State: RUNNABLE
aoqi@0 199 // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
aoqi@0 200 // - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
aoqi@0 201 // at java.lang.Thread.run(Thread.java:745)
aoqi@0 202 //
aoqi@0 203 // Example 2:
aoqi@0 204 // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
aoqi@0 205 // java.lang.Thread.State: BLOCKED (on object monitor)
aoqi@0 206 // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
aoqi@0 207 // - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
aoqi@0 208 // at java.lang.Thread.run(Thread.java:745)
aoqi@0 209 //
aoqi@0 210 // Example 3:
aoqi@0 211 // "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
aoqi@0 212 // java.lang.Thread.State: RUNNABLE
aoqi@0 213 // JavaThread state: _thread_blocked
aoqi@0 214 // Thread: 0x0000000000ec8800 [0x31] State: _at_safepoint _has_called_back 0 _at_poll_safepoint 0
aoqi@0 215 // JavaThread state: _thread_blocked
aoqi@0 216 // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
aoqi@0 217 // - locked <0xfffffd7e6d03eb28> (a TestThreadDumpMonitorContention$1)
aoqi@0 218 // at java.lang.Thread.run(Thread.java:745)
aoqi@0 219 //
aoqi@0 220 static boolean checkLockedLine(String line) {
aoqi@0 221 Matcher matcher = LOCK_PATTERN.matcher(line);
aoqi@0 222 if (matcher.matches()) {
aoqi@0 223 if (verbose) {
aoqi@0 224 System.out.println("locked_line='" + line + "'");
aoqi@0 225 }
aoqi@0 226 locked_match_list[locked_line_match_cnt] = new String(line);
aoqi@0 227 locked_line_match_cnt++;
aoqi@0 228
aoqi@0 229 matcher = HEADER_RUNNABLE_PATTERN.matcher(header_line);
aoqi@0 230 if (matcher.matches()) {
aoqi@0 231 sum_locked_hdr_runnable_cnt++;
aoqi@0 232 } else {
aoqi@0 233 // It's strange, but a locked line can also
aoqi@0 234 // match the HEADER_WAITING_PATTERN{1,2}.
aoqi@0 235 matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
aoqi@0 236 if (matcher.matches()) {
aoqi@0 237 sum_locked_hdr_waiting1_cnt++;
aoqi@0 238 } else {
aoqi@0 239 matcher = HEADER_WAITING_PATTERN2.matcher(header_line);
aoqi@0 240 if (matcher.matches()) {
aoqi@0 241 sum_locked_hdr_waiting2_cnt++;
aoqi@0 242 } else {
aoqi@0 243 System.err.println();
aoqi@0 244 System.err.println("ERROR: header line does " +
aoqi@0 245 "not match runnable or waiting patterns.");
aoqi@0 246 System.err.println("ERROR: header_line='" +
aoqi@0 247 header_line + "'");
aoqi@0 248 System.err.println("ERROR: locked_line='" + line +
aoqi@0 249 "'");
aoqi@0 250 error_cnt++;
aoqi@0 251 }
aoqi@0 252 }
aoqi@0 253 }
aoqi@0 254
aoqi@0 255 matcher = THREAD_STATE_RUNNABLE_PATTERN.matcher(thread_state_line);
aoqi@0 256 if (matcher.matches()) {
aoqi@0 257 sum_locked_thr_state_runnable_cnt++;
aoqi@0 258 } else {
aoqi@0 259 // It's strange, but a locked line can also
aoqi@0 260 // match the THREAD_STATE_BLOCKED_PATTERN.
aoqi@0 261 matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(
aoqi@0 262 thread_state_line);
aoqi@0 263 if (matcher.matches()) {
aoqi@0 264 sum_locked_thr_state_blocked_cnt++;
aoqi@0 265 } else {
aoqi@0 266 System.err.println();
aoqi@0 267 System.err.println("ERROR: thread state line does not " +
aoqi@0 268 "match runnable or waiting patterns.");
aoqi@0 269 System.err.println("ERROR: " + "thread_state_line='" +
aoqi@0 270 thread_state_line + "'");
aoqi@0 271 System.err.println("ERROR: locked_line='" + line + "'");
aoqi@0 272 error_cnt++;
aoqi@0 273 }
aoqi@0 274 }
aoqi@0 275
aoqi@0 276 // Have everything we need from this thread stack
aoqi@0 277 // that matches the LOCK_PATTERN.
aoqi@0 278 have_header_line = false;
aoqi@0 279 have_thread_state_line = false;
aoqi@0 280 return true;
aoqi@0 281 }
aoqi@0 282
aoqi@0 283 return false;
aoqi@0 284 }
aoqi@0 285
aoqi@0 286 // Process the waiting line here if we found one.
aoqi@0 287 //
aoqi@0 288 // Example:
aoqi@0 289 // "ContendingThread-2" #22 prio=5 os_prio=64 tid=0x00000000007b9800 nid=0x30 waiting for monitor entry [0xfffffd7fc1010000]
aoqi@0 290 // java.lang.Thread.State: BLOCKED (on object monitor)
aoqi@0 291 // at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
aoqi@0 292 // - waiting to lock <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
aoqi@0 293 // at java.lang.Thread.run(Thread.java:745)
aoqi@0 294 //
aoqi@0 295 static boolean checkWaitingLine(String line) {
aoqi@0 296 Matcher matcher = WAITING_PATTERN.matcher(line);
aoqi@0 297 if (matcher.matches()) {
aoqi@0 298 waiting_line_match_cnt++;
aoqi@0 299 if (verbose) {
aoqi@0 300 System.out.println("waiting_line='" + line + "'");
aoqi@0 301 }
aoqi@0 302
aoqi@0 303 matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
aoqi@0 304 if (matcher.matches()) {
aoqi@0 305 sum_waiting_hdr_waiting1_cnt++;
aoqi@0 306 } else {
aoqi@0 307 System.err.println();
aoqi@0 308 System.err.println("ERROR: header line does " +
aoqi@0 309 "not match a waiting pattern.");
aoqi@0 310 System.err.println("ERROR: header_line='" + header_line + "'");
aoqi@0 311 System.err.println("ERROR: waiting_line='" + line + "'");
aoqi@0 312 error_cnt++;
aoqi@0 313 }
aoqi@0 314
aoqi@0 315 matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(thread_state_line);
aoqi@0 316 if (matcher.matches()) {
aoqi@0 317 sum_waiting_thr_state_blocked_cnt++;
aoqi@0 318 } else {
aoqi@0 319 System.err.println();
aoqi@0 320 System.err.println("ERROR: thread state line " +
aoqi@0 321 "does not match a waiting pattern.");
aoqi@0 322 System.err.println("ERROR: thread_state_line='" +
aoqi@0 323 thread_state_line + "'");
aoqi@0 324 System.err.println("ERROR: waiting_line='" + line + "'");
aoqi@0 325 error_cnt++;
aoqi@0 326 }
aoqi@0 327
aoqi@0 328 // Have everything we need from this thread stack
aoqi@0 329 // that matches the WAITING_PATTERN.
aoqi@0 330 have_header_line = false;
aoqi@0 331 have_thread_state_line = false;
aoqi@0 332 return true;
aoqi@0 333 }
aoqi@0 334
aoqi@0 335 return false;
aoqi@0 336 }
aoqi@0 337
aoqi@0 338 static void doSamples() throws Exception {
aoqi@0 339 for (int count = 0; count < n_samples; count++) {
aoqi@0 340 blank_line_match_cnt = 0;
aoqi@0 341 header_prefix_match_cnt = 0;
aoqi@0 342 locked_line_match_cnt = 0;
aoqi@0 343 waiting_line_match_cnt = 0;
aoqi@0 344 // verbose mode or an error has a lot of output so add more space
aoqi@0 345 if (verbose || error_cnt > 0) System.out.println();
aoqi@0 346 System.out.println("Sample #" + count);
aoqi@0 347
aoqi@0 348 // We don't use the ProcessTools, OutputBuffer or
aoqi@0 349 // OutputAnalyzer classes from the testlibrary because
aoqi@0 350 // we have a complicated multi-line parse to perform
aoqi@0 351 // on a narrow subset of the JSTACK output.
aoqi@0 352 //
aoqi@0 353 // - we only care about stack traces that match
aoqi@0 354 // HEADER_PREFIX_PATTERN; only two should match
aoqi@0 355 // - we care about at most three lines from each stack trace
aoqi@0 356 // - if both stack traces match LOCKED_PATTERN, then that's
aoqi@0 357 // a failure and we report it
aoqi@0 358 // - for a stack trace that matches LOCKED_PATTERN, we verify:
aoqi@0 359 // - the header line matches HEADER_RUNNABLE_PATTERN
aoqi@0 360 // or HEADER_WAITING_PATTERN{1,2}
aoqi@0 361 // - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
aoqi@0 362 // or THREAD_STATE_RUNNABLE_PATTERN
aoqi@0 363 // - we report any mismatches as failures
aoqi@0 364 // - for a stack trace that matches WAITING_PATTERN, we verify:
aoqi@0 365 // - the header line matches HEADER_WAITING_PATTERN1
aoqi@0 366 // - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
aoqi@0 367 // - we report any mismatches as failures
aoqi@0 368 // - the stack traces that match HEADER_PREFIX_PATTERN may
aoqi@0 369 // not match either LOCKED_PATTERN or WAITING_PATTERN
aoqi@0 370 // because we might observe the thread outside of
aoqi@0 371 // monitor operations; this is not considered a failure
aoqi@0 372 //
aoqi@0 373 // When we do observe LOCKED_PATTERN or WAITING_PATTERN,
aoqi@0 374 // then we are checking the header and thread state patterns
aoqi@0 375 // that occurred earlier in the current stack trace that
aoqi@0 376 // matched HEADER_PREFIX_PATTERN. We don't use data from
aoqi@0 377 // stack traces that don't match HEADER_PREFIX_PATTERN and
aoqi@0 378 // we don't mix data between the two stack traces that do
aoqi@0 379 // match HEADER_PREFIX_PATTERN.
aoqi@0 380 //
aoqi@0 381 Process process = new ProcessBuilder(JSTACK, PID)
aoqi@0 382 .redirectErrorStream(true).start();
aoqi@0 383
aoqi@0 384 BufferedReader reader = new BufferedReader(new InputStreamReader(
aoqi@0 385 process.getInputStream()));
aoqi@0 386 String line;
aoqi@0 387 while ((line = reader.readLine()) != null) {
aoqi@0 388 Matcher matcher = null;
aoqi@0 389
aoqi@0 390 // process the header line here
aoqi@0 391 if (!have_header_line) {
aoqi@0 392 matcher = HEADER_PREFIX_PATTERN.matcher(line);
aoqi@0 393 if (matcher.matches()) {
aoqi@0 394 header_prefix_match_cnt++;
aoqi@0 395 if (verbose) {
aoqi@0 396 System.out.println();
aoqi@0 397 System.out.println("header='" + line + "'");
aoqi@0 398 }
aoqi@0 399 header_line = new String(line);
aoqi@0 400 have_header_line = true;
aoqi@0 401 continue;
aoqi@0 402 }
aoqi@0 403 continue; // skip until have a header line
aoqi@0 404 }
aoqi@0 405
aoqi@0 406 // process the thread state line here
aoqi@0 407 if (!have_thread_state_line) {
aoqi@0 408 matcher = THREAD_STATE_PREFIX_PATTERN.matcher(line);
aoqi@0 409 if (matcher.matches()) {
aoqi@0 410 if (verbose) {
aoqi@0 411 System.out.println("thread_state='" + line + "'");
aoqi@0 412 }
aoqi@0 413 thread_state_line = new String(line);
aoqi@0 414 have_thread_state_line = true;
aoqi@0 415 continue;
aoqi@0 416 }
aoqi@0 417 continue; // skip until we have a thread state line
aoqi@0 418 }
aoqi@0 419
aoqi@0 420 // process the locked line here if we find one
aoqi@0 421 if (checkLockedLine(line)) {
aoqi@0 422 continue;
aoqi@0 423 }
aoqi@0 424
aoqi@0 425 // process the waiting line here if we find one
aoqi@0 426 if (checkWaitingLine(line)) {
aoqi@0 427 continue;
aoqi@0 428 }
aoqi@0 429
aoqi@0 430 // process the blank line here if we find one
aoqi@0 431 if (checkBlankLine(line)) {
aoqi@0 432 continue;
aoqi@0 433 }
aoqi@0 434 }
aoqi@0 435 process.waitFor();
aoqi@0 436
aoqi@0 437 if (header_prefix_match_cnt != 2) {
aoqi@0 438 System.err.println();
aoqi@0 439 System.err.println("ERROR: should match exactly two headers.");
aoqi@0 440 System.err.println("ERROR: header_prefix_match_cnt=" +
aoqi@0 441 header_prefix_match_cnt);
aoqi@0 442 error_cnt++;
aoqi@0 443 }
aoqi@0 444
aoqi@0 445 if (locked_line_match_cnt == 2) {
aoqi@0 446 if (locked_match_list[0].equals(locked_match_list[1])) {
aoqi@0 447 System.err.println();
aoqi@0 448 System.err.println("ERROR: matching lock lines:");
aoqi@0 449 System.err.println("ERROR: line[0]'" +
aoqi@0 450 locked_match_list[0] + "'");
aoqi@0 451 System.err.println("ERROR: line[1]'" +
aoqi@0 452 locked_match_list[1] + "'");
aoqi@0 453 error_cnt++;
aoqi@0 454 }
aoqi@0 455 }
aoqi@0 456
aoqi@0 457 if (locked_line_match_cnt == 1) {
aoqi@0 458 // one thread has the lock
aoqi@0 459 if (waiting_line_match_cnt == 1) {
aoqi@0 460 // and the other contended for it
aoqi@0 461 sum_contended_cnt++;
aoqi@0 462 } else {
aoqi@0 463 // and the other is just running
aoqi@0 464 sum_uncontended_cnt++;
aoqi@0 465 }
aoqi@0 466 } else if (waiting_line_match_cnt == 1) {
aoqi@0 467 // one thread is waiting
aoqi@0 468 sum_one_waiting_cnt++;
aoqi@0 469 } else if (waiting_line_match_cnt == 2) {
aoqi@0 470 // both threads are waiting
aoqi@0 471 sum_both_waiting_cnt++;
aoqi@0 472 } else {
aoqi@0 473 // both threads are running
aoqi@0 474 sum_both_running_cnt++;
aoqi@0 475 }
aoqi@0 476
aoqi@0 477 // slight delay between jstack launches
aoqi@0 478 Thread.sleep(500);
aoqi@0 479 }
aoqi@0 480
aoqi@0 481 if (error_cnt != 0) {
aoqi@0 482 // skip summary info since there were errors
aoqi@0 483 return;
aoqi@0 484 }
aoqi@0 485
aoqi@0 486 System.out.println("INFO: Summary for all samples:");
aoqi@0 487 System.out.println("INFO: both_running_cnt=" + sum_both_running_cnt);
aoqi@0 488 System.out.println("INFO: both_waiting_cnt=" + sum_both_waiting_cnt);
aoqi@0 489 System.out.println("INFO: contended_cnt=" + sum_contended_cnt);
aoqi@0 490 System.out.println("INFO: one_waiting_cnt=" + sum_one_waiting_cnt);
aoqi@0 491 System.out.println("INFO: uncontended_cnt=" + sum_uncontended_cnt);
aoqi@0 492 System.out.println("INFO: locked_hdr_runnable_cnt=" +
aoqi@0 493 sum_locked_hdr_runnable_cnt);
aoqi@0 494 System.out.println("INFO: locked_hdr_waiting1_cnt=" +
aoqi@0 495 sum_locked_hdr_waiting1_cnt);
aoqi@0 496 System.out.println("INFO: locked_hdr_waiting2_cnt=" +
aoqi@0 497 sum_locked_hdr_waiting2_cnt);
aoqi@0 498 System.out.println("INFO: locked_thr_state_blocked_cnt=" +
aoqi@0 499 sum_locked_thr_state_blocked_cnt);
aoqi@0 500 System.out.println("INFO: locked_thr_state_runnable_cnt=" +
aoqi@0 501 sum_locked_thr_state_runnable_cnt);
aoqi@0 502 System.out.println("INFO: waiting_hdr_waiting1_cnt=" +
aoqi@0 503 sum_waiting_hdr_waiting1_cnt);
aoqi@0 504 System.out.println("INFO: waiting_thr_state_blocked_cnt=" +
aoqi@0 505 sum_waiting_thr_state_blocked_cnt);
aoqi@0 506
aoqi@0 507 if (sum_contended_cnt == 0) {
aoqi@0 508 System.err.println("WARNING: the primary scenario for 8036823" +
aoqi@0 509 " has not been exercised by this test run.");
aoqi@0 510 }
aoqi@0 511 }
aoqi@0 512
aoqi@0 513 // This helper relies on RuntimeMXBean.getName() returning a string
aoqi@0 514 // that looks like this: 5436@mt-haku
aoqi@0 515 //
aoqi@0 516 // The testlibrary has tryFindJvmPid(), but that uses a separate
aoqi@0 517 // process which is much more expensive for finding out your own PID.
aoqi@0 518 //
aoqi@0 519 static String getPid() {
aoqi@0 520 RuntimeMXBean runtimebean = ManagementFactory.getRuntimeMXBean();
aoqi@0 521 String vmname = runtimebean.getName();
aoqi@0 522 int i = vmname.indexOf('@');
aoqi@0 523 if (i != -1) {
aoqi@0 524 vmname = vmname.substring(0, i);
aoqi@0 525 }
aoqi@0 526 return vmname;
aoqi@0 527 }
aoqi@0 528
aoqi@0 529 static void usage() {
aoqi@0 530 System.err.println("Usage: " +
aoqi@0 531 "java TestThreadDumpMonitorContention [-v] [n_samples]");
aoqi@0 532 System.exit(1);
aoqi@0 533 }
aoqi@0 534 }

mercurial