summaryrefslogtreecommitdiffstats
path: root/timer
diff options
context:
space:
mode:
authorStiver <stiver.mail@gmail.com>2014-03-04 15:13:11 +0100
committerStiver <stiver.mail@gmail.com>2014-03-04 15:13:11 +0100
commite2d0f5d9c38561d67f23754c00addb4a3547efb2 (patch)
tree1832f16037c086b48266b8566aecc61f45f4e5f1 /timer
downloadfernflower-e2d0f5d9c38561d67f23754c00addb4a3547efb2.tar
fernflower-e2d0f5d9c38561d67f23754c00addb4a3547efb2.tar.gz
fernflower-e2d0f5d9c38561d67f23754c00addb4a3547efb2.tar.lz
fernflower-e2d0f5d9c38561d67f23754c00addb4a3547efb2.tar.xz
fernflower-e2d0f5d9c38561d67f23754c00addb4a3547efb2.zip
initial commit
Diffstat (limited to 'timer')
-rw-r--r--timer/HRTimerResolution.java68
-rw-r--r--timer/SystemTimerResolution.java31
-rw-r--r--timer/com/vladium/utils/timing/ITimer.java54
-rw-r--r--timer/com/vladium/utils/timing/ITimerConstants.java31
-rw-r--r--timer/com/vladium/utils/timing/JavaSystemTimer.java74
-rw-r--r--timer/com/vladium/utils/timing/TimerFactory.java74
-rw-r--r--timer/native/com_vladium_utils_timing_HRTimer.c71
-rw-r--r--timer/native/com_vladium_utils_timing_HRTimer.h22
8 files changed, 425 insertions, 0 deletions
diff --git a/timer/HRTimerResolution.java b/timer/HRTimerResolution.java
new file mode 100644
index 0000000..318694f
--- /dev/null
+++ b/timer/HRTimerResolution.java
@@ -0,0 +1,68 @@
+import java.text.DecimalFormat;
+
+import com.vladium.utils.timing.ITimer;
+import com.vladium.utils.timing.TimerFactory;
+
+// ----------------------------------------------------------------------------
+/**
+ * A demo class to show off the higher resolution available from HRTimer class
+ * and to investigate the resolution offered by Java "time-related"
+ * methods other than System.currentTimeMillis().<P>
+ *
+ * Make sure that hrtlib.dll JNI lib is in java.library.path or TimerFactory
+ * will fall back to the Java system timer:
+ * <PRE>
+ * >java -Djava.library.path=(dir containing hrtlib.dll) HRTimerResolution
+ * </PRE>
+ *
+ * @author (C) <a href="mailto:vroubtsov@illinoisalumni.org">Vlad Roubtsov</a>, 2002
+ */
+public class HRTimerResolution
+{
+ // public: ................................................................
+
+ public static void main (final String [] args) throws Exception
+ {
+ final DecimalFormat format = new DecimalFormat ();
+ format.setMinimumFractionDigits (3);
+ format.setMaximumFractionDigits (3);
+
+ // create an ITimer using the Factory class:
+ final ITimer timer = TimerFactory.newTimer ();
+
+ // JIT/hotspot warmup:
+ for (int i = 0; i < 3000; ++ i)
+ {
+ timer.start ();
+ timer.stop ();
+ timer.getDuration ();
+ timer.reset ();
+ }
+
+ final Object lock = new Object (); // this is used by monitor.wait() below
+
+ for (int i = 0; i < 5; ++ i)
+ {
+ timer.start ();
+
+ // uncomment various lines below to see the resolution
+ // offered by other Java time-related methods; with all
+ // lines commented out this loop reports time elapsed
+ // between successive calls to t.start() and t.stop(), thus
+ // providing an estimate for timer's raw resolution
+
+ synchronized (lock) { lock.wait (1); }
+ //Thread.currentThread ().sleep (1);
+ //Thread.currentThread ().sleep (0, 500);
+ //Thread.currentThread ().join (1);
+
+ timer.stop ();
+
+ System.out.println ("duration = "
+ + format.format (timer.getDuration ()) + " ms");
+ timer.reset ();
+ }
+ }
+
+} // end of class
+// ----------------------------------------------------------------------------
diff --git a/timer/SystemTimerResolution.java b/timer/SystemTimerResolution.java
new file mode 100644
index 0000000..56ececd
--- /dev/null
+++ b/timer/SystemTimerResolution.java
@@ -0,0 +1,31 @@
+// ----------------------------------------------------------------------------
+/**
+ * A simple class to see what the Java system timer resolution is on your
+ * system.
+ *
+ * @author (C) <a href="mailto:vroubtsov@illinoisalumni.org">Vlad Roubtsov</a>, 2002
+ */
+public class SystemTimerResolution
+{
+ // public: ................................................................
+
+ public static void main (final String [] args)
+ {
+ // JIT/hotspot warmup:
+ for (int r = 0; r < 3000; ++ r) System.currentTimeMillis ();
+
+ long time = System.currentTimeMillis (), time_prev = time;
+
+ for (int i = 0; i < 5; ++ i)
+ {
+ // busy wait until system time changes:
+ while (time == time_prev)
+ time = System.currentTimeMillis ();
+
+ System.out.println ("delta = " + (time - time_prev) + " ms");
+ time_prev = time;
+ }
+ }
+
+} // end of class
+// ----------------------------------------------------------------------------
diff --git a/timer/com/vladium/utils/timing/ITimer.java b/timer/com/vladium/utils/timing/ITimer.java
new file mode 100644
index 0000000..98029b1
--- /dev/null
+++ b/timer/com/vladium/utils/timing/ITimer.java
@@ -0,0 +1,54 @@
+
+package com.vladium.utils.timing;
+
+// ----------------------------------------------------------------------------
+/**
+ * A simple interface for measuring time intervals. An instance of this goes
+ * through the following lifecycle states:
+ * <DL>
+ * <DT> <EM>ready</EM>
+ * <DD> timer is ready to start a new measurement
+ * <DT> <EM>started</EM>
+ * <DD> timer has recorded the starting time interval point
+ * <DT> <EM>stopped</EM>
+ * <DD> timer has recorded the ending time interval point
+ * </DL>
+ * See individual methods for details.<P>
+ *
+ * If this library has been compiled with {@link ITimerConstants#DO_STATE_CHECKS}
+ * set to 'true' the implementation will enforce this lifecycle model and throw
+ * IllegalStateException when it is violated.
+ *
+ * @author (C) <a href="mailto:vroubtsov@illinoisalumni.org">Vlad Roubtsov</a>, 2002
+ */
+public interface ITimer
+{
+ // public: ................................................................
+
+ /**
+ * Starts a new time interval and advances this timer instance to 'started'
+ * state. This method can be called from 'ready' state only. */
+ void start ();
+
+ /**
+ * Terminates the current time interval and advances this timer instance to
+ * 'stopped' state. Interval duration will be available via
+ * {@link #getDuration()} method. This method can be called from 'started'
+ * state only. */
+ void stop ();
+
+ /**
+ * Returns the duration of the time interval that elapsed between the last
+ * calls to {@link #start()} and {@link #stop()}. This method can be called
+ * any number of times from 'stopped' state and will return the same value
+ * each time.<P>
+ * * @return interval duration in milliseconds */
+ double getDuration ();
+
+ /**
+ * This method can be called from any state and will reset this timer
+ * instance back to 'ready' state. */
+ void reset ();
+
+} // end of interface
+// ----------------------------------------------------------------------------
diff --git a/timer/com/vladium/utils/timing/ITimerConstants.java b/timer/com/vladium/utils/timing/ITimerConstants.java
new file mode 100644
index 0000000..29435ae
--- /dev/null
+++ b/timer/com/vladium/utils/timing/ITimerConstants.java
@@ -0,0 +1,31 @@
+
+package com.vladium.utils.timing;
+
+// ----------------------------------------------------------------------------
+/**
+ * A package-private collection of constants used by {@link ITimer} implementations
+ * in <code>HRTimer</code> and <code>JavaSystemTimer</code> classes.
+ *
+ * @author (C) <a href="mailto:vroubtsov@illinoisalumni.org">Vlad Roubtsov</a>, 2002
+ */
+interface ITimerConstants
+{
+ // public: ................................................................
+
+ /**
+ * Conditional compilation flag to enable/disable state checking in timer
+ * implementations. Just about the only reason you might want to disable
+ * this is to reduce the timer overhead, but in practice the gain is very
+ * small. */
+ static final boolean DO_STATE_CHECKS = true;
+
+ /**
+ * Timer state enumeration. */
+ static final int STATE_READY = 0, STATE_STARTED = 1, STATE_STOPPED = 2;
+
+ /**
+ * User-friendly timer state names indexed by their state values. */
+ static final String [] STATE_NAMES = {"READY", "STARTED", "STOPPED"};
+
+} // end of interface
+// ----------------------------------------------------------------------------
diff --git a/timer/com/vladium/utils/timing/JavaSystemTimer.java b/timer/com/vladium/utils/timing/JavaSystemTimer.java
new file mode 100644
index 0000000..e3f3b48
--- /dev/null
+++ b/timer/com/vladium/utils/timing/JavaSystemTimer.java
@@ -0,0 +1,74 @@
+
+package com.vladium.utils.timing;
+
+// ----------------------------------------------------------------------------
+/**
+ * A package-private implementation of {@link ITimer} based around Java system
+ * timer [<code>System.currentTimeMillis()</code> method]. It is used when
+ * <code>HRTimer</code> implementation is unavailable.<P>
+ *
+ * {@link TimerFactory} acts as the Factory for this class.<P>
+ *
+ * MT-safety: an instance of this class is safe to be used within the same
+ * thread only.
+ *
+ * @author (C) <a href="mailto:vroubtsov@illinoisalumni.org">Vlad Roubtsov</a>, 2002
+ */
+final class JavaSystemTimer implements ITimer, ITimerConstants
+{
+ // public: ................................................................
+
+ public void start ()
+ {
+ if (DO_STATE_CHECKS)
+ {
+ if (m_state != STATE_READY)
+ throw new IllegalStateException (this + ": start() must be called from READY state, current state is " + STATE_NAMES [m_state]);
+ }
+
+ if (DO_STATE_CHECKS) m_state = STATE_STARTED;
+ m_data = System.currentTimeMillis ();
+ }
+
+ public void stop ()
+ {
+ // latch stop time in a local var before doing anything else:
+ final long data = System.currentTimeMillis ();
+
+ if (DO_STATE_CHECKS)
+ {
+ if (m_state != STATE_STARTED)
+ throw new IllegalStateException (this + ": stop() must be called from STARTED state, current state is " + STATE_NAMES [m_state]);
+ }
+
+ m_data = data - m_data;
+ if (DO_STATE_CHECKS) m_state = STATE_STOPPED;
+ }
+
+ public double getDuration ()
+ {
+ if (DO_STATE_CHECKS)
+ {
+ if (m_state != STATE_STOPPED)
+ throw new IllegalStateException (this + ": getDuration() must be called from STOPPED state, current state is " + STATE_NAMES [m_state]);
+ }
+
+ return m_data;
+ }
+
+ public void reset ()
+ {
+ if (DO_STATE_CHECKS) m_state = STATE_READY;
+ }
+
+ // protected: .............................................................
+
+ // package: ...............................................................
+
+ // private: ...............................................................
+
+ private int m_state; // used to keep track of timer state
+ private long m_data; // timing data
+
+} // end of class
+// ----------------------------------------------------------------------------
diff --git a/timer/com/vladium/utils/timing/TimerFactory.java b/timer/com/vladium/utils/timing/TimerFactory.java
new file mode 100644
index 0000000..ae127c5
--- /dev/null
+++ b/timer/com/vladium/utils/timing/TimerFactory.java
@@ -0,0 +1,74 @@
+
+package com.vladium.utils.timing;
+
+// ----------------------------------------------------------------------------
+/**
+ * This non-instantiable non-extendible class acts as a Factory for {@link ITimer}
+ * implementations.
+ *
+ * @author (C) <a href="mailto:vroubtsov@illinoisalumni.org">Vlad Roubtsov</a>, 2002
+ */
+public abstract class TimerFactory
+{
+ // public: ................................................................
+
+ private static final String HRTIMER_LIB = "hrtlib";
+
+ /**
+ * Creates a new instance of {@link ITimer} which is returned in 'ready'
+ * state. If the JNI-based/high-resolution implementation is not available
+ * this will return an instance of <code>JavaSystemTimer</code>, so this
+ * method is guaranteed not to fail.
+ *
+ * @return ITimer a new timer instance in 'ready' state [never null] */
+
+ public static void initialize(String path) {
+
+ UnsatisfiedLinkError exception = null;
+
+ try {
+ System.loadLibrary (HRTIMER_LIB);
+ } catch (UnsatisfiedLinkError e) {
+ if(path != null) {
+ try {
+ System.load(path);
+ } catch (UnsatisfiedLinkError ex) {
+ exception = ex;
+ }
+ } else {
+ exception = e;
+ }
+ }
+
+ if(exception != null) {
+ System.out.println ("native lib '" + HRTIMER_LIB
+ + "' not found in 'java.library.path': "
+ + System.getProperty ("java.library.path")
+ +path==null?"":(" or in "+path));
+
+ throw exception; // re-throw
+ }
+ }
+
+ public static ITimer newTimer ()
+ {
+// try
+// {
+ return new HRTimer ();
+// }
+// catch (Throwable t)
+// {
+// return new JavaSystemTimer ();
+// }
+ }
+
+ // protected: .............................................................
+
+ // package: ...............................................................
+
+ // private: ...............................................................
+
+ private TimerFactory () {} // prevent subclassing
+
+} // end of class
+// ----------------------------------------------------------------------------
diff --git a/timer/native/com_vladium_utils_timing_HRTimer.c b/timer/native/com_vladium_utils_timing_HRTimer.c
new file mode 100644
index 0000000..647837d
--- /dev/null
+++ b/timer/native/com_vladium_utils_timing_HRTimer.c
@@ -0,0 +1,71 @@
+/* ------------------------------------------------------------------------- */
+/*
+ * A win32 implementation of JNI methods in com.vladium.utils.timing.HRTimer
+ * class. The author compiled it using Microsoft Visual C++ but the code
+ * should be easy to use with any compiler for win32 platform.
+ *
+ * For simplicity, this implementaion assumes JNI 1.2+ and omits error handling.
+ *
+ * (C) 2002, Vladimir Roubtsov [vroubtsov@illinoisalumni.org]
+ */
+/* ------------------------------------------------------------------------- */
+
+#if !defined NDEBUG
+#include <stdio.h>
+#endif // NDEBUG
+
+#include <windows.h>
+
+#include "com_vladium_utils_timing_HRTimer.h"
+
+// scale factor for converting a performancce counter reading into milliseconds:
+static jdouble s_scaleFactor;
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * This method was added in JNI 1.2. It is executed once before any other
+ * methods are called and is ostensibly for negotiating JNI spec versions, but
+ * can also be conveniently used for initializing variables that will not
+ * change throughout the lifetime of this process.
+ */
+JNIEXPORT jint JNICALL
+JNI_OnLoad (JavaVM * vm, void * reserved)
+{
+ LARGE_INTEGER counterFrequency;
+
+ QueryPerformanceFrequency (& counterFrequency);
+
+ // NOTE: counterFrequency will be zero for a machine that does not have
+ // support for a high-resolution counter. This is only likely for very
+ // old hardware but for a robust implementation you should handle this
+ // case.
+
+#if !defined NDEBUG
+ printf ("PCFrequency called: %I64d\n", counterFrequency.QuadPart);
+#endif
+
+ s_scaleFactor = counterFrequency.QuadPart / 1000.0;
+
+
+ return JNI_VERSION_1_2;
+}
+/* ......................................................................... */
+
+/*
+ * Class: com_vladium_utils_timing_HRTimer
+ * Method: getTime
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_com_vladium_utils_timing_HRTimer_getTime (JNIEnv * e, jclass cls)
+{
+ LARGE_INTEGER counterReading;
+
+ QueryPerformanceCounter (& counterReading);
+
+ return counterReading.QuadPart / s_scaleFactor;
+}
+
+/* ------------------------------------------------------------------------- */
+/* end of file */
diff --git a/timer/native/com_vladium_utils_timing_HRTimer.h b/timer/native/com_vladium_utils_timing_HRTimer.h
new file mode 100644
index 0000000..357db0d
--- /dev/null
+++ b/timer/native/com_vladium_utils_timing_HRTimer.h
@@ -0,0 +1,22 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_vladium_utils_timing_HRTimer */
+
+#ifndef _Included_com_vladium_utils_timing_HRTimer
+#define _Included_com_vladium_utils_timing_HRTimer
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Class: com_vladium_utils_timing_HRTimer
+ * Method: getTime
+ * Signature: ()D
+ */
+JNIEXPORT jdouble JNICALL
+Java_com_vladium_utils_timing_HRTimer_getTime (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif