1 /* ThreadMXBeanImpl.java - Implementation of a thread bean 2 Copyright (C) 2006 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package gnu.java.lang.management; 39 40 import gnu.classpath.SystemProperties; 41 42 import java.lang.management.ThreadInfo; 43 import java.lang.management.ThreadMXBean; 44 45 import javax.management.NotCompliantMBeanException; 46 47 /** 48 * Provides access to information about the threads 49 * of the virtual machine. An instance of this bean is 50 * obtained by calling 51 * {@link ManagementFactory#getThreadMXBean()}. 52 * See {@link java.lang.management.ThreadMXBean} for 53 * full documentation. 54 * 55 * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 56 * @since 1.5 57 */ 58 public final class ThreadMXBeanImpl 59 extends BeanImpl 60 implements ThreadMXBean 61 { 62 63 /** 64 * Constant for current thread time support. 65 */ 66 private static final String CURRENT_THREAD_TIME_SUPPORT = 67 "gnu.java.lang.management.CurrentThreadTimeSupport"; 68 69 /** 70 * Constant for thread time support. 71 */ 72 private static final String THREAD_TIME_SUPPORT = 73 "gnu.java.lang.management.ThreadTimeSupport"; 74 75 /** 76 * Constant for thread contention support. 77 */ 78 private static final String CONTENTION_SUPPORT = 79 "gnu.java.lang.management.ThreadContentionSupport"; 80 81 /** 82 * Constant for initial value of thread time support. 83 */ 84 private static final String TIME_ENABLED = 85 "gnu.java.lang.management.ThreadTimeInitallyEnabled"; 86 87 /** 88 * Constant for monitor usage monitoring support. 89 */ 90 private static final String MONITOR_SUPPORT = 91 "gnu.java.lang.management.MonitorUsageMonitoringSupport"; 92 93 /** 94 * Constant for ownable synchronizer usage monitoring support. 95 */ 96 private static final String SYNCHRONIZER_SUPPORT = 97 "gnu.java.lang.management.OwnableSynchronizerUsageMonitoringSupport"; 98 99 /** 100 * Flag to indicate whether time monitoring is enabled or not. 101 */ 102 private boolean timeEnabled; 103 104 /** 105 * Flag to indicate whether contention monitoring is enabled or not. 106 */ 107 private boolean contentionEnabled; 108 109 /** 110 * Default constructor to set up flag states. The 111 * VM has to specify whether time monitoring is initially 112 * enabled or not. 113 * 114 * @throws NotCompliantMBeanException if this class doesn't implement 115 * the interface or a method appears 116 * in the interface that doesn't comply 117 * with the naming conventions. 118 */ ThreadMXBeanImpl()119 public ThreadMXBeanImpl() 120 throws NotCompliantMBeanException 121 { 122 super(ThreadMXBean.class); 123 timeEnabled = Boolean.parseBoolean(SystemProperties.getProperty(TIME_ENABLED)); 124 contentionEnabled = false; 125 } 126 dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers)127 public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, 128 boolean lockedSynchronizers) 129 { 130 return getThreadInfo(getAllThreadIds(), lockedMonitors, 131 lockedSynchronizers); 132 } 133 findDeadlockedThreads()134 public long[] findDeadlockedThreads() 135 { 136 checkMonitorPermissions(); 137 if (!isSynchronizerUsageSupported()) 138 throw new UnsupportedOperationException("Ownable synchronizer usage " + 139 "monitoring is not provided " + 140 "by this VM."); 141 return VMThreadMXBeanImpl.findDeadlockedThreads(); 142 } 143 findMonitorDeadlockedThreads()144 public long[] findMonitorDeadlockedThreads() 145 { 146 checkMonitorPermissions(); 147 return VMThreadMXBeanImpl.findMonitorDeadlockedThreads(); 148 } 149 getAllThreadIds()150 public long[] getAllThreadIds() 151 { 152 checkMonitorPermissions(); 153 return VMThreadMXBeanImpl.getAllThreadIds(); 154 } 155 getCurrentThreadCpuTime()156 public long getCurrentThreadCpuTime() 157 { 158 if (!isCurrentThreadCpuTimeSupported()) 159 throw new UnsupportedOperationException("Current thread CPU " + 160 "time not supported."); 161 if (!timeEnabled) 162 return -1; 163 return VMThreadMXBeanImpl.getCurrentThreadCpuTime(); 164 } 165 getCurrentThreadUserTime()166 public long getCurrentThreadUserTime() 167 { 168 if (!isCurrentThreadCpuTimeSupported()) 169 throw new UnsupportedOperationException("Current thread user " + 170 "time not supported."); 171 if (!timeEnabled) 172 return -1; 173 return VMThreadMXBeanImpl.getCurrentThreadUserTime(); 174 } 175 getDaemonThreadCount()176 public int getDaemonThreadCount() 177 { 178 return VMThreadMXBeanImpl.getDaemonThreadCount(); 179 } 180 getPeakThreadCount()181 public int getPeakThreadCount() 182 { 183 return VMThreadMXBeanImpl.getPeakThreadCount(); 184 } 185 getThreadCount()186 public int getThreadCount() 187 { 188 return VMThreadMXBeanImpl.getThreadCount(); 189 } 190 getThreadCpuTime(long id)191 public long getThreadCpuTime(long id) 192 { 193 if (!isThreadCpuTimeSupported()) 194 throw new UnsupportedOperationException("Thread CPU time not " + 195 "supported."); 196 if (id <= 0) 197 throw new IllegalArgumentException("Invalid thread id: " + id); 198 if (!timeEnabled) 199 return -1; 200 return VMThreadMXBeanImpl.getThreadCpuTime(id); 201 } 202 getThreadInfo(long id)203 public ThreadInfo getThreadInfo(long id) 204 { 205 return getThreadInfo(id, 0); 206 } 207 getThreadInfo(long[] ids)208 public ThreadInfo[] getThreadInfo(long[] ids) 209 { 210 return getThreadInfo(ids, 0); 211 } 212 getThreadInfo(long id, int maxDepth)213 public ThreadInfo getThreadInfo(long id, int maxDepth) 214 { 215 checkMonitorPermissions(); 216 if (id <= 0) 217 throw new IllegalArgumentException("Invalid thread id: " + id); 218 if (maxDepth < 0) 219 throw new IllegalArgumentException("Invalid depth: " + maxDepth); 220 return VMThreadMXBeanImpl.getThreadInfoForId(id, maxDepth); 221 } 222 getThreadInfo(long[] ids, int maxDepth)223 public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) 224 { 225 checkMonitorPermissions(); 226 if (maxDepth < 0) 227 throw new IllegalArgumentException("Invalid depth: " + maxDepth); 228 ThreadInfo[] infos = new ThreadInfo[ids.length]; 229 for (int a = 0; a < ids.length; ++a) 230 { 231 if (ids[a] <= 0) 232 throw new IllegalArgumentException("Invalid thread id " + a + 233 ": " + ids[a]); 234 infos[a] = VMThreadMXBeanImpl.getThreadInfoForId(ids[a], maxDepth); 235 } 236 return infos; 237 } 238 getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers)239 public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, 240 boolean lockedSynchronizers) 241 { 242 checkMonitorPermissions(); 243 if (lockedMonitors && !isObjectMonitorUsageSupported()) 244 throw new UnsupportedOperationException("Monitor usage monitoring is " + 245 "not provided by this VM."); 246 if (lockedSynchronizers && !isSynchronizerUsageSupported()) 247 throw new UnsupportedOperationException("Ownable synchronizer usage " + 248 "monitoring is not provided " + 249 "by this VM."); 250 ThreadInfo[] infos = getThreadInfo(ids, Integer.MAX_VALUE); 251 if (lockedMonitors) 252 for (ThreadInfo info : infos) 253 VMThreadMXBeanImpl.getMonitorInfo(info); 254 if (lockedSynchronizers) 255 for (ThreadInfo info : infos) 256 VMThreadMXBeanImpl.getLockInfo(info); 257 return infos; 258 } 259 getThreadUserTime(long id)260 public long getThreadUserTime(long id) 261 { 262 if (!isThreadCpuTimeSupported()) 263 throw new UnsupportedOperationException("Thread user time not " + 264 "supported."); 265 if (id <= 0) 266 throw new IllegalArgumentException("Invalid thread id: " + id); 267 if (!timeEnabled) 268 return -1; 269 return VMThreadMXBeanImpl.getThreadUserTime(id); 270 } 271 getTotalStartedThreadCount()272 public long getTotalStartedThreadCount() 273 { 274 return VMThreadMXBeanImpl.getTotalStartedThreadCount(); 275 } 276 isCurrentThreadCpuTimeSupported()277 public boolean isCurrentThreadCpuTimeSupported() 278 { 279 if (isThreadCpuTimeSupported()) 280 return true; 281 return SystemProperties.getProperty(CURRENT_THREAD_TIME_SUPPORT) != null; 282 } 283 isObjectMonitorUsageSupported()284 public boolean isObjectMonitorUsageSupported() 285 { 286 return SystemProperties.getProperty(MONITOR_SUPPORT) != null; 287 } 288 isSynchronizerUsageSupported()289 public boolean isSynchronizerUsageSupported() 290 { 291 return SystemProperties.getProperty(SYNCHRONIZER_SUPPORT) != null; 292 } 293 isThreadContentionMonitoringEnabled()294 public boolean isThreadContentionMonitoringEnabled() 295 { 296 if (isThreadContentionMonitoringSupported()) 297 return contentionEnabled; 298 else 299 throw new UnsupportedOperationException("Contention monitoring " + 300 "not supported."); 301 } 302 isThreadContentionMonitoringSupported()303 public boolean isThreadContentionMonitoringSupported() 304 { 305 return SystemProperties.getProperty(CONTENTION_SUPPORT) != null; 306 } 307 isThreadCpuTimeEnabled()308 public boolean isThreadCpuTimeEnabled() 309 { 310 if (isThreadCpuTimeSupported() || 311 isCurrentThreadCpuTimeSupported()) 312 return timeEnabled; 313 else 314 throw new UnsupportedOperationException("Thread time not " + 315 "supported."); 316 } 317 isThreadCpuTimeSupported()318 public boolean isThreadCpuTimeSupported() 319 { 320 return SystemProperties.getProperty(THREAD_TIME_SUPPORT) != null; 321 } 322 resetPeakThreadCount()323 public void resetPeakThreadCount() 324 { 325 checkControlPermissions(); 326 VMThreadMXBeanImpl.resetPeakThreadCount(); 327 } 328 setThreadContentionMonitoringEnabled(boolean enable)329 public void setThreadContentionMonitoringEnabled(boolean enable) 330 { 331 checkControlPermissions(); 332 if (isThreadContentionMonitoringSupported()) 333 contentionEnabled = enable; 334 else 335 throw new UnsupportedOperationException("Contention monitoring " + 336 "not supported."); 337 } 338 setThreadCpuTimeEnabled(boolean enable)339 public void setThreadCpuTimeEnabled(boolean enable) 340 { 341 checkControlPermissions(); 342 if (isThreadCpuTimeSupported() || 343 isCurrentThreadCpuTimeSupported()) 344 timeEnabled = enable; 345 else 346 throw new UnsupportedOperationException("Thread time not " + 347 "supported."); 348 } 349 350 } 351