blob: 0d14bd6d3a883de3383c1132c460e009fe0d49f6 [file] [log] [blame]
/*
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package nsk.monitoring.share.thread;
import nsk.share.log.Log;
import nsk.share.TestFailure;
import java.lang.management.LockInfo;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
public final class ThreadUtils {
private ThreadUtils() {
}
/**
* Obtain human readable string representation of lock info.
*
* @param info lock ingo
* @return string representation of info
*/
public static String strLockInfo(LockInfo info) {
if (info == null)
return "LockInfo: " + null;
else
return "LockInfo: className: " + info.getClassName() + " identityHashCode: " + info.getIdentityHashCode();
}
/**
* Obtain human readable string representation of monitor info.
*
* @param info monitor info
* @return string representation of info
*/
public static String strMonitorInfo(MonitorInfo info) {
if (info == null)
return "MonitorInfo: null";
else
return "MonitorInfo: lockedStackDepth: " + info.getLockedStackDepth() + " lockedStackFrame: " + info.getLockedStackFrame() + strLockInfo(info);
}
/**
* Obtain human readable string representation of array of lock info.
*
* @param infos array of lock info
* @return string representation of infos
*/
public static String strLockInfoArr(LockInfo[] infos) {
String s = "";
for (LockInfo info : infos)
s += strLockInfo(info) + " ";
return s;
}
/**
* Obtain human readable string representation of array of monitor info.
*
* @param infos array of monitor info
* @return string representation of infos
*/
public static String strMonitorInfoArr(MonitorInfo[] infos) {
String s = "";
for (MonitorInfo info : infos)
s += strMonitorInfo(info) + " ";
return s;
}
/**
* Print monitor information.
*
* @param log log
* @param monitorInfo monitor info
*/
public static void printMonitorInfo(Log log, MonitorInfo monitorInfo) {
log.info(strMonitorInfo(monitorInfo));
}
/**
* Print monitor information array.
*
* @param log log
* @param monitorInfos array of monitor info
*/
public static void printMonitorInfo(Log log, MonitorInfo[] monitorInfos) {
for (MonitorInfo monitorInfo : monitorInfos)
printMonitorInfo(log, monitorInfo);
}
/**
* Print lock information.
*
* @param log log
* @param lockInfo lock info
*/
public static void printLockInfo(Log log, LockInfo lockInfo) {
log.info(strLockInfo(lockInfo));
}
/**
* Print lock information array.
*
* @param log log
* @param lockInfo array of lock info
*/
public static void printLockInfo(Log log, LockInfo[] lockInfos) {
for (LockInfo lockInfo : lockInfos)
printLockInfo(log, lockInfo);
}
public static final String INDENT = " ";
/**
* Print all thread information for given ThreadInfo.
*
* @param log log
* @param ti thread info
*/
public static void threadInfo(Log log, ThreadInfo info) {
//log.info("Thread info: thread " + info.getThreadId() + " " + info.getThreadName() " state: " + info.getThreadState());
threadDump(log, info);
log.info("Blocked count: " + info.getBlockedCount() + " time: " + info.getBlockedTime());
log.info("Waited count: " + info.getWaitedCount() + " time: " + info.getWaitedTime());
LockInfo lockInfo = info.getLockInfo();
log.info("Lock: " + strLockInfo(lockInfo));
log.info("Lock name: " + info.getLockName() + " ownerId: " + info.getLockOwnerId() + " ownerName: " + info.getLockOwnerName());
MonitorInfo[] monitorInfo = info.getLockedMonitors();
log.info("Locked monitors: total " + monitorInfo.length);
printMonitorInfo(log, info.getLockedMonitors());
LockInfo[] lockInfos = info.getLockedSynchronizers();
log.info("Locked synchronizers: total " + lockInfos.length);
printLockInfo(log, lockInfos);
}
/**
* Print thread dump information for given ThreadInfo.
*
* @param log log
* @param ti thread info
*/
public static void threadDump(Log log, ThreadInfo ti) {
String s = "";
s += "\"";
s += ti.getThreadName();
s += "\"";
s += " Id=" + ti.getThreadId();
s += " in " + ti.getThreadState();
if (ti.getLockName() != null) {
s += " on lock=" + ti.getLockName();
}
if (ti.isSuspended()) {
s += " (suspended)";
}
if (ti.isInNative()) {
s += " (running in native)";
}
if (ti.getLockOwnerName() != null)
s += " owned by " + ti.getLockOwnerName() + " Id=" + ti.getLockOwnerId();
log.info(s);
printStackTrace(log, ti);
}
/**
* Print stack trace information.
*
* @param log log
* @param ti thread info
*/
public static void printStackTrace(Log log, ThreadInfo ti) {
StackTraceElement[] stacktrace = ti.getStackTrace();
MonitorInfo[] monitors = ti.getLockedMonitors();
for (int i = 0; i < stacktrace.length; i++) {
StackTraceElement ste = stacktrace[i];
log.info(INDENT + "at " + ste.toString());
for (MonitorInfo mi : monitors) {
if (mi.getLockedStackDepth() == i) {
log.info(INDENT + " - locked " + mi);
}
}
}
System.out.println();
}
/**
* Dump information about threads.
*
* @param log log
* @param tinfos array of thread information
*/
public static void threadDump(Log log, ThreadInfo[] tinfos) {
log.info("Java thread dump");
for (ThreadInfo ti : tinfos) {
threadDump(log, ti);
LockInfo[] syncs = ti.getLockedSynchronizers();
printLockInfo(log, syncs);
}
}
public final static int waitThreadStateRetries = 10;
public final static long waitThreadStateSleepTime = 100;
public static void waitThreadState(Thread thread, Thread.State state) {
int retries = 0;
long ctime = System.currentTimeMillis();
while (thread.getState() != state) {
if (retries++ > waitThreadStateRetries)
throw new TestFailure("Thread " + thread + " with current state " + thread.getState() + " did not reach state " + state + " with number of retries: " + retries + ", time: " + (System.currentTimeMillis() - ctime));
try {
Thread.sleep(waitThreadStateSleepTime);
} catch (InterruptedException e) {
}
}
}
/**
* Verify condition and throw TestFailure if it does not hold.
*
* @param condition boolean condition
* @param message TestFailure message
*/
public static void verify(boolean condition, String message) {
if (!condition)
throw new TestFailure(message);
}
/**
* Obtain human readable string representation of array of thread ids.
*
* @param ids array of ids
* @return string representation of ids
*/
public static String strIds(long[] ids) {
if (ids == null)
return null;
String s = "";
for (int i = 0; i < ids.length; ++i) {
s += ids[i];
s += ' ';
}
return s;
}
}