/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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 org.kie.karaf.itest.util; import java.util.concurrent.TimeUnit; /** * Utility class providing methods for coping with timing issues, such as * {@link Thread#sleep(long, int)} inaccuracy, on certain OS. * <p/> * Inspired by http://stackoverflow.com/questions/824110/accurate-sleep-for-java-on-windows * and http://andy-malakov.blogspot.cz/2010/06/alternative-to-threadsleep.html. */ public class TimerUtils { private static final long SLEEP_PRECISION = Long.valueOf(System.getProperty("TIMER_SLEEP_PRECISION", "50000")); private static final long SPIN_YIELD_PRECISION = Long.valueOf(System.getProperty("TIMER_YIELD_PRECISION", "30000")); private TimerUtils() { } /** * Sleeps for specified amount of time in milliseconds. * * @param duration the amount of milliseconds to wait * @throws InterruptedException if the current thread gets interrupted */ public static void sleepMillis(final long duration) throws InterruptedException { sleepNanos(TimeUnit.MILLISECONDS.toNanos(duration)); } /** * Sleeps for specified amount of time in nanoseconds. * * @param nanoDuration the amount of nanoseconds to wait * @throws InterruptedException if the current thread gets interrupted */ public static void sleepNanos(final long nanoDuration) throws InterruptedException { final long end = System.nanoTime() + nanoDuration; long timeLeft = nanoDuration; do { if (timeLeft > SLEEP_PRECISION) { Thread.sleep(1); } else if (timeLeft > SPIN_YIELD_PRECISION) { Thread.yield(); } timeLeft = end - System.nanoTime(); } while (timeLeft > 0); } }