initial commit
This commit is contained in:
68
timer/HRTimerResolution.java
Normal file
68
timer/HRTimerResolution.java
Normal file
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
31
timer/SystemTimerResolution.java
Normal file
31
timer/SystemTimerResolution.java
Normal file
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
54
timer/com/vladium/utils/timing/ITimer.java
Normal file
54
timer/com/vladium/utils/timing/ITimer.java
Normal file
@@ -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.
|
||||
31
timer/com/vladium/utils/timing/ITimerConstants.java
Normal file
31
timer/com/vladium/utils/timing/ITimerConstants.java
Normal file
@@ -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"};
|
||||
74
timer/com/vladium/utils/timing/JavaSystemTimer.java
Normal file
74
timer/com/vladium/utils/timing/JavaSystemTimer.java
Normal file
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
74
timer/com/vladium/utils/timing/TimerFactory.java
Normal file
74
timer/com/vladium/utils/timing/TimerFactory.java
Normal file
@@ -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
|
||||
71
timer/native/com_vladium_utils_timing_HRTimer.c
Normal file
71
timer/native/com_vladium_utils_timing_HRTimer.c
Normal file
@@ -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 */
|
||||
22
timer/native/com_vladium_utils_timing_HRTimer.h
Normal file
22
timer/native/com_vladium_utils_timing_HRTimer.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user