001package net.sf.cpsolver.ifs.util; 002 003import java.lang.management.ManagementFactory; 004import java.lang.management.ThreadMXBean; 005 006import 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 Tomáš Müller<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 */ 034public 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}