Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_realtime/Timer.cpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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-exception
21
*******************************************************************************/
22
23
#include "omr.h"
24
#include "omrcfg.h"
25
#include "omrutilbase.h"
26
27
#include "EnvironmentRealtime.hpp"
28
#include "OSInterface.hpp"
29
30
#include "Timer.hpp"
31
32
/**
33
* Create a new instance of the MM_Timer class.
34
* @param timerDesc String describing the relative timer, should be static!
35
*/
36
MM_Timer*
37
MM_Timer::newInstance(MM_EnvironmentBase* env, MM_OSInterface* osInterface)
38
{
39
MM_Timer* timer;
40
41
timer = (MM_Timer*)env->getForge()->allocate(sizeof(MM_Timer), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());
42
if (NULL != timer) {
43
new(timer) MM_Timer();
44
if (!timer->initialize(env, osInterface)) {
45
timer->kill(env);
46
timer = NULL;
47
}
48
}
49
return timer;
50
}
51
52
/**
53
* Kill an instance of the MM_Timer class.
54
*/
55
void
56
MM_Timer::kill(MM_EnvironmentBase *env)
57
{
58
tearDown(env);
59
env->getForge()->free(this);
60
}
61
62
/**
63
* Teardown an instance of the MM_Timer class.
64
*/
65
void
66
MM_Timer::tearDown(MM_EnvironmentBase *env)
67
{
68
}
69
70
71
/**
72
* Initialize an instance of the MM_Timer class.
73
*/
74
bool
75
MM_Timer::initialize(MM_EnvironmentBase* env, MM_OSInterface* osInterface)
76
{
77
_osInterface = osInterface;
78
reset();
79
return true;
80
}
81
82
/**
83
* Get the actual time in nanoseconds.
84
*/
85
U_64
86
MM_Timer::getTimeInNanos()
87
{
88
return _osInterface->nanoTime();
89
}
90
91
/**
92
* Reset the timer to the current time in nanoseconds
93
*/
94
void
95
MM_Timer::reset()
96
{
97
rebaseTime();
98
}
99
100
/**
101
* Get the approximate time in nanoseconds using the TSC.
102
* If too much time as elapsed, or time has gone backwards since
103
* the last call to this function the Timer will rebase the time to
104
* the actual time in nanoseconds.
105
*/
106
U_64
107
MM_Timer::nanoTime()
108
{
109
#if defined(AIXPPC) || defined(WIN32)
110
return getTimeInNanos();
111
#else
112
U_64 delta = J9CONST64(0);
113
U_64 timeInNanos = _sytemTimeBase;
114
U_64 ticks = getTimebase();
115
116
if (ticks > _tickBase) {
117
delta = ticks - _tickBase;
118
if (delta > CLOCK_SWITCH_TICK_THRESHOLD) {
119
timeInNanos = rebaseTime();
120
} else {
121
timeInNanos = _sytemTimeBase + ((1000 * delta) / _osInterface->_ticksPerMicroSecond);
122
}
123
} else {
124
timeInNanos = rebaseTime();
125
}
126
127
return timeInNanos;
128
#endif /* AIXPPC */
129
}
130
131
/**
132
* Return the elapsed time since timerBase
133
* @param timerBase - The time to get elapsed from
134
*/
135
U_64
136
MM_Timer::peekElapsedTime(U_64 timerBase)
137
{
138
U_64 currentTime = nanoTime();
139
U_64 delta = J9CONST64(0);
140
141
if (currentTime > timerBase) {
142
delta = currentTime - timerBase;
143
}
144
145
return delta;
146
}
147
148
/**
149
* Rebase the timer with the current TSC value and the actual
150
* time in nanoseconds.
151
*/
152
U_64
153
MM_Timer::rebaseTime()
154
{
155
_sytemTimeBase = _osInterface->nanoTime();
156
_tickBase = getTimebase();
157
158
return _sytemTimeBase;
159
}
160
161
/**
162
* Has timeToWaitInNanos time elapsed since the last call to reset().
163
*/
164
bool
165
MM_Timer::hasTimeElapsed(U_64 startTimeInNanos, U_64 timeToWaitInNanos)
166
{
167
U_64 currentTimeInNanos = nanoTime();
168
U_64 elapsedTimeInNanos = J9CONST64(0);
169
if (currentTimeInNanos > startTimeInNanos) {
170
elapsedTimeInNanos = currentTimeInNanos - startTimeInNanos;
171
}
172
if (elapsedTimeInNanos > timeToWaitInNanos) {
173
return true;
174
}
175
return false;
176
}
177
178