package ifs.util;

/** CPU time measurement. JAVA profiling extension is used.
 * Java needs to be executed with -Xrunjprof. When the java is executed outside
 * this profiler, {@link System#currentTimeMillis()} is used.
 *
 * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomas Muller</a>
 * @version 1.0
 */
public class JProf {
    private static boolean sPrecise = true;
    
    /** Current CPU time of this thread in seconds */
    public static double currentTimeSec() {
        return (sPrecise?((double)getCurrentThreadCpuTime())/1e9:((double)System.currentTimeMillis())/1e3);
    }
    /** Measurement is based on profiler extension (precise CPU time is returned). 
     * If false, {@link System#currentTimeMillis()} is used in {@link JProf#currentTimeSec()}.
     */
    public static boolean isPrecise() { return sPrecise; }

    /** Current CPU time of this thread (will fail when jprof is not loaded). Use {@link JProf#currentTimeSec()}.*/
    public static native long getCurrentThreadCpuTime();

    static {
        try {
            System.loadLibrary("jprof");
            if (getCurrentThreadCpuTime()==0l) {
            	int j=0;
            	for (int i=0;i<10000000;i++) j+=i;
            	if (getCurrentThreadCpuTime()==0l) {
            	    sPrecise = false;
            	    org.apache.log4j.Logger.getLogger(JProf.class).warn("Unable to mesure time in precise -- using System.currentTimeMillis().");
            	}
            }
        } catch (Throwable e) {
            org.apache.log4j.Logger.getLogger(JProf.class).warn("Unable to mesure time in precise -- using System.currentTimeMillis().");
            sPrecise = false;
        }	
    }
}
