/* * Created on Jan 25, 2013 * Created by Paul Gardner * * Copyright 2013 Azureus Software, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ package com.aelitis.azureus.core.networkmanager.impl.utp; import java.util.Random; import org.gudy.azureus2.core3.util.RandomUtils; import org.gudy.azureus2.core3.util.SystemTime; public class UTPUtils { static long startPerformanceCounter; static long startGetTickCount; // MSVC 6 standard doesn't like division with uint64s static long counterPerMicrosecond; static long last_micros = 0; static long last_counter = 0; static long last_tick = 0; static long frequency = 0; static long monoOffset = 0; static boolean bork_logged = false; static Random random = new Random( RandomUtils.SECURE_RANDOM.nextLong()); static int UTP_Random() { return( random.nextInt()); } static long UTP_GetMilliseconds() { return( System.currentTimeMillis()); } static{ startGetTickCount = System.currentTimeMillis(); startPerformanceCounter = System.nanoTime(); counterPerMicrosecond = 1000; } static long abs64(long x) { return x < 0 ? -x : x; } //static long last_log_tick; //static int log_count = 0; //static long[] counter_history = new long[16]; //static long[] tick_history = new long[16]; //static int history_index; static long UTP_GetMicroseconds() { long counter = SystemTime.getHighPrecisionCounter(); long tick = System.currentTimeMillis(); // unfortunately, QueryPerformanceCounter is not guaranteed // to be monotonic. Make it so. long ret = (counter - startPerformanceCounter) / counterPerMicrosecond; // if the QPC clock leaps more than one second off GetTickCount64() // something is seriously fishy. Adjust QPC to stay monotonic long tick_diff = tick - startGetTickCount; //tick_history[history_index] = tick; //counter_history[history_index] = counter; //history_index++; //if ( history_index == 16 ){ // history_index = 0; //} if (abs64(ret / 100000 - tick_diff / 100) > 10 ) { startPerformanceCounter -= (tick_diff * 1000 - ret) * counterPerMicrosecond; ret = (counter - startPerformanceCounter) / counterPerMicrosecond; monoOffset = 0; } /* if ( ret < last_micros ){ System.out.println( "micros went backwards" ); } */ last_counter = counter; last_tick = tick; ret += monoOffset; if ( ret < last_micros ){ monoOffset += (last_micros - ret ); ret = last_micros; } last_micros = ret; return ret; } public static void main( String[] args ) { while( true ){ long milli = UTP_GetMilliseconds(); long micro = UTP_GetMicroseconds(); System.out.println( milli + " / " + micro ); try{ Thread.sleep( 100 ); }catch( Throwable e ){ } } } }