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