001 package net.sf.cpsolver.ifs.util;
002
003 import java.lang.management.ManagementFactory;
004 import java.lang.management.ThreadMXBean;
005
006 import org.apache.log4j.Logger;
007
008 /**
009 * CPU time measurement. <s>JAVA profiling extension is used. Java needs to be
010 * executed with -Xrunjprof. When the java is executed outside this profiler,
011 * {@link System#currentTimeMillis()} is used.</s> Using {@link ThreadMXBean}
012 * to get the current thread CPU time, if supported. Using {@link System#nanoTime()}
013 * otherwise.
014 *
015 * @version IFS 1.2 (Iterative Forward Search)<br>
016 * Copyright (C) 2006 - 2010 Tomas Muller<br>
017 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
018 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
019 * <br>
020 * This library is free software; you can redistribute it and/or modify
021 * it under the terms of the GNU Lesser General Public License as
022 * published by the Free Software Foundation; either version 3 of the
023 * License, or (at your option) any later version. <br>
024 * <br>
025 * This library is distributed in the hope that it will be useful, but
026 * WITHOUT ANY WARRANTY; without even the implied warranty of
027 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
028 * Lesser General Public License for more details. <br>
029 * <br>
030 * You should have received a copy of the GNU Lesser General Public
031 * License along with this library; if not see
032 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
033 */
034 public class JProf {
035 private static Mode sMode = Mode.wall;
036 private static enum Mode {
037 cpu, wall, user
038 }
039 private static boolean sInitialized = false;
040
041 /** Enable / disable the thread CPU timing, if needed */
042 private synchronized static void init() {
043 if (sInitialized) return;
044 sMode = Mode.valueOf(System.getProperty("jprof", sMode.name()));
045 if (sMode != Mode.wall) {
046 try {
047 ThreadMXBean bean = ManagementFactory.getThreadMXBean();
048 if (!bean.isCurrentThreadCpuTimeSupported()) {
049 Logger.getLogger(JProf.class).warn("Measuring " + sMode.name() + " time is not supported, falling back to wall time.");
050 sMode = Mode.wall;
051 }
052 if (!bean.isThreadCpuTimeEnabled())
053 bean.setThreadCpuTimeEnabled(true);
054 } catch (UnsupportedOperationException e) {
055 Logger.getLogger(JProf.class).error("Unable to measure " + sMode.name() + " time, falling back to wall time: " + e.getMessage());
056 sMode = Mode.wall;
057 sMode = Mode.wall;
058 }
059 }
060 Logger.getLogger(JProf.class).info("Using " + sMode.name() + " time.");
061 sInitialized = true;
062 }
063
064 /** Current CPU time of this thread in seconds */
065 public static double currentTimeSec() {
066 init();
067 try {
068 switch (sMode) {
069 case cpu :
070 return ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() / 1e9;
071 case user :
072 return ManagementFactory.getThreadMXBean().getCurrentThreadUserTime() / 1e9;
073 case wall :
074 default:
075 return System.nanoTime() / 1e9;
076 }
077 } catch (UnsupportedOperationException e) {
078 Logger.getLogger(JProf.class).error("Unable to measure " + sMode.name() + " time, falling back to wall time: " + e.getMessage());
079 sMode = Mode.wall;
080 return System.nanoTime() / 1e9;
081 }
082 }
083
084 /** Current CPU time of this thread in milliseconds */
085 public static long currentTimeMillis() {
086 init();
087 try {
088 switch (sMode) {
089 case cpu :
090 return ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() / 1000000;
091 case user :
092 return ManagementFactory.getThreadMXBean().getCurrentThreadUserTime() / 1000000;
093 case wall :
094 default:
095 return System.currentTimeMillis();
096 }
097 } catch (UnsupportedOperationException e) {
098 Logger.getLogger(JProf.class).error("Unable to measure " + sMode.name() + " time, falling back to wall time: " + e.getMessage());
099 sMode = Mode.wall;
100 return System.currentTimeMillis();
101 }
102 }
103 }