![JAR search and dependency download from the Maven repository](/logo.png)
net.openhft.ticker.impl.JNIClock Maven / Gradle / Ivy
/*
* Copyright 2016 higherfrequencytrading.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package net.openhft.ticker.impl;
import net.openhft.ticker.ITicker;
import software.chronicle.enterprise.internals.impl.NativeAffinity;
import java.util.logging.Logger;
/**
* JNI-based implementation, trying to use rdtsc() system call
* to access the most precise timer available
*
* @author cheremin
* @since 29.12.11, 18:56
*/
public enum JNIClock implements ITicker {
INSTANCE;
public static final boolean LOADED;
private static final Logger LOGGER = Logger.getLogger(JNIClock.class.getName());
private static final int FACTOR_BITS = 17;
private static final long START;
private static long RDTSC_FACTOR = 1 << FACTOR_BITS;
private static double RDTSC_MICRO_FACTOR = 1e-3;
private static long CPU_FREQUENCY = 1000;
static {
boolean loaded;
long start;
try {
// ensure it is loaded.
NativeAffinity.INSTANCE.getCpu();
estimateFrequency(50);
estimateFrequency(200);
LOGGER.info("Estimated clock frequency was " + CPU_FREQUENCY + " MHz");
start = rdtsc0();
loaded = true;
} catch (UnsatisfiedLinkError ule) {
LOGGER.fine("Unable to find libCEInternals in [" + System.getProperty("java.library.path") + "] " + ule);
start = 0;
loaded = false;
}
LOADED = loaded;
START = start;
}
static long tscToNano(final long tsc) {
return (tsc * RDTSC_FACTOR) >> FACTOR_BITS;
}
private static void estimateFrequency(int factor) {
final long start = System.nanoTime();
long now;
while ((now = System.nanoTime()) == start) {
}
long end = start + factor * 1000000;
final long start0 = rdtsc0();
while ((now = System.nanoTime()) < end) {
}
long end0 = rdtsc0();
end = now;
RDTSC_FACTOR = ((end - start) << FACTOR_BITS) / (end0 - start0) - 1;
RDTSC_MICRO_FACTOR = 1e-3 * (end - start) / (end0 - start0);
CPU_FREQUENCY = (end0 - start0 + 1) * 1000 / (end - start);
}
native static long rdtsc0();
public long nanoTime() {
return tscToNano(rdtsc0() - START);
}
@Override
public long ticks() {
return rdtsc0();
}
@Override
public long toNanos(long ticks) {
return tscToNano(ticks);
}
@Override
public double toMicros(double ticks) {
return ticks * RDTSC_MICRO_FACTOR;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy