Path: blob/master/runtime/gc_realtime/Timer.cpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2019 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include "omr.h"23#include "omrcfg.h"24#include "omrutilbase.h"2526#include "EnvironmentRealtime.hpp"27#include "OSInterface.hpp"2829#include "Timer.hpp"3031/**32* Create a new instance of the MM_Timer class.33* @param timerDesc String describing the relative timer, should be static!34*/35MM_Timer*36MM_Timer::newInstance(MM_EnvironmentBase* env, MM_OSInterface* osInterface)37{38MM_Timer* timer;3940timer = (MM_Timer*)env->getForge()->allocate(sizeof(MM_Timer), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());41if (NULL != timer) {42new(timer) MM_Timer();43if (!timer->initialize(env, osInterface)) {44timer->kill(env);45timer = NULL;46}47}48return timer;49}5051/**52* Kill an instance of the MM_Timer class.53*/54void55MM_Timer::kill(MM_EnvironmentBase *env)56{57tearDown(env);58env->getForge()->free(this);59}6061/**62* Teardown an instance of the MM_Timer class.63*/64void65MM_Timer::tearDown(MM_EnvironmentBase *env)66{67}686970/**71* Initialize an instance of the MM_Timer class.72*/73bool74MM_Timer::initialize(MM_EnvironmentBase* env, MM_OSInterface* osInterface)75{76_osInterface = osInterface;77reset();78return true;79}8081/**82* Get the actual time in nanoseconds.83*/84U_6485MM_Timer::getTimeInNanos()86{87return _osInterface->nanoTime();88}8990/**91* Reset the timer to the current time in nanoseconds92*/93void94MM_Timer::reset()95{96rebaseTime();97}9899/**100* Get the approximate time in nanoseconds using the TSC.101* If too much time as elapsed, or time has gone backwards since102* the last call to this function the Timer will rebase the time to103* the actual time in nanoseconds.104*/105U_64106MM_Timer::nanoTime()107{108#if defined(AIXPPC) || defined(WIN32)109return getTimeInNanos();110#else111U_64 delta = J9CONST64(0);112U_64 timeInNanos = _sytemTimeBase;113U_64 ticks = getTimebase();114115if (ticks > _tickBase) {116delta = ticks - _tickBase;117if (delta > CLOCK_SWITCH_TICK_THRESHOLD) {118timeInNanos = rebaseTime();119} else {120timeInNanos = _sytemTimeBase + ((1000 * delta) / _osInterface->_ticksPerMicroSecond);121}122} else {123timeInNanos = rebaseTime();124}125126return timeInNanos;127#endif /* AIXPPC */128}129130/**131* Return the elapsed time since timerBase132* @param timerBase - The time to get elapsed from133*/134U_64135MM_Timer::peekElapsedTime(U_64 timerBase)136{137U_64 currentTime = nanoTime();138U_64 delta = J9CONST64(0);139140if (currentTime > timerBase) {141delta = currentTime - timerBase;142}143144return delta;145}146147/**148* Rebase the timer with the current TSC value and the actual149* time in nanoseconds.150*/151U_64152MM_Timer::rebaseTime()153{154_sytemTimeBase = _osInterface->nanoTime();155_tickBase = getTimebase();156157return _sytemTimeBase;158}159160/**161* Has timeToWaitInNanos time elapsed since the last call to reset().162*/163bool164MM_Timer::hasTimeElapsed(U_64 startTimeInNanos, U_64 timeToWaitInNanos)165{166U_64 currentTimeInNanos = nanoTime();167U_64 elapsedTimeInNanos = J9CONST64(0);168if (currentTimeInNanos > startTimeInNanos) {169elapsedTimeInNanos = currentTimeInNanos - startTimeInNanos;170}171if (elapsedTimeInNanos > timeToWaitInNanos) {172return true;173}174return false;175}176177178