Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_realtime/OSInterface.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 "omrport.h"
26
27
#include <string.h>
28
#include <math.h>
29
30
#if defined(AIXPPC)
31
#include <builtins.h>
32
#endif
33
34
#if defined(LINUX)
35
#include <time.h>
36
#include <errno.h>
37
#include <sys/time.h>
38
#endif /* #if defined(LINUX) */
39
40
#if defined(LINUX) && !defined(J9ZTPF)
41
#include <linux/rtc.h>
42
#include <sys/syscall.h>
43
#include <sys/signal.h>
44
#elif defined(J9ZTPF)
45
#include <signal.h>
46
#endif /* defined(LINUX) && !defined(J9ZTPF) */
47
48
#include "ProcessorInfo.hpp"
49
#include "EnvironmentBase.hpp"
50
#include "GCExtensionsBase.hpp"
51
#include "modronnls.h"
52
53
#include "OSInterface.hpp"
54
/**
55
* Initialization.
56
*/
57
MM_OSInterface*
58
MM_OSInterface::newInstance(MM_EnvironmentBase *env)
59
{
60
MM_OSInterface *osInterface = (MM_OSInterface *)env->getForge()->allocate(sizeof(MM_OSInterface), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());
61
if (osInterface) {
62
new(osInterface) MM_OSInterface();
63
if (!osInterface->initialize(env)) {
64
osInterface->kill(env);
65
osInterface = NULL;
66
}
67
}
68
return osInterface;
69
}
70
71
/**
72
* Initialization.
73
*/
74
bool
75
MM_OSInterface::initialize(MM_EnvironmentBase *env)
76
{
77
OMRPORT_ACCESS_FROM_ENVIRONMENT(env);
78
79
_vm = env->getOmrVM();
80
_extensions = MM_GCExtensionsBase::getExtensions(env->getOmrVM());
81
_numProcessors = omrsysinfo_get_number_CPUs_by_type(OMRPORT_CPU_ONLINE);
82
_physicalMemoryBytes = omrsysinfo_get_physical_memory();
83
84
_omrtime_hires_clock_nanoSecondMultiplyFactor = 1000000000 / omrtime_hires_frequency();
85
_omrtime_hires_clock_nanoSecondDivideFactor = omrtime_hires_frequency() / 1000000000;
86
87
if (NULL == (_processorInfo = MM_ProcessorInfo::newInstance(env))) {
88
return false;
89
}
90
91
_ticksPerMicroSecond = (U_64)(_processorInfo->_freq / 1e6);
92
93
if (_extensions->verbose >= 1) {
94
if (0 == _ticksPerMicroSecond) {
95
omrtty_printf("Use OS high resolution timer instead of CPU tick-based timer\n");
96
} else {
97
omrtty_printf("ticksPerMicro = %llu\n", _ticksPerMicroSecond);
98
}
99
}
100
return true;
101
}
102
103
/**
104
* Initialization.
105
*/
106
void
107
MM_OSInterface::kill(MM_EnvironmentBase *env)
108
{
109
tearDown(env);
110
env->getForge()->free(this);
111
}
112
113
/**
114
* Teardown
115
*/
116
void
117
MM_OSInterface::tearDown(MM_EnvironmentBase *env)
118
{
119
if (NULL != _processorInfo) {
120
_processorInfo->kill(env);
121
}
122
}
123
124
bool
125
MM_OSInterface::rtcTimerAvailable() {
126
#if defined(LINUX)
127
return true;
128
#else
129
return false;
130
#endif
131
}
132
133
bool
134
MM_OSInterface::itTimerAvailable() {
135
#if defined(WIN32)
136
return true;
137
#else
138
return false;
139
#endif
140
}
141
142
/**
143
* hiresTimerAvailable
144
* On Linux or AIX, return true if the realtime clock resolution is better than
145
* the high resolution timer period, false otherwise.
146
* On Windows, return false.
147
* Other platforms will fail to compile until they have an implementation.
148
* @ingroup GC_Metronome methodGroup
149
*/
150
bool
151
MM_OSInterface::hiresTimerAvailable() {
152
#if (defined(LINUX) && !defined(J9ZTPF)) || defined (AIXPPC)
153
OMRPORT_ACCESS_FROM_OMRVM(_vm);
154
struct timespec ts;
155
if (clock_getres(CLOCK_REALTIME, &ts)) {
156
if (_extensions->verbose >= 2) {
157
omrtty_printf("POSIX High Resolution Clock not available\n");
158
}
159
return false;
160
} else {
161
if (_extensions->verbose >= 2) {
162
omrtty_printf("POSIX High Resolution Clock has resolution %d nanoseconds\n", ts.tv_nsec);
163
}
164
bool returnValue = ((ts.tv_sec == 0) && ((uintptr_t)ts.tv_nsec < (_extensions->hrtPeriodMicro * 1000)));
165
if (!returnValue && _extensions->overrideHiresTimerCheck) {
166
omrnls_printf(J9NLS_INFO, J9NLS_GC_IGNORE_OS_REPORTED_HIGHRES_VALUES);
167
returnValue = true;
168
}
169
return returnValue;
170
}
171
#elif defined(WIN32)
172
/* On Win32, we don't have a HRT and it is safe to use our ITimer implementation so we can return false */
173
return false;
174
#else
175
/* No high res time available so try your luck with ITAlarm instead */
176
return false;
177
#endif /* #if (defined(LINUX) && !defined(J9ZTPF)) || defined (AIXPPC) */
178
}
179
180
U_64
181
MM_OSInterface::nanoTime()
182
{
183
OMRPORT_ACCESS_FROM_OMRVM(_vm);
184
U_64 hiresTime = omrtime_hires_clock();
185
if (_omrtime_hires_clock_nanoSecondMultiplyFactor != 0) {
186
return hiresTime * _omrtime_hires_clock_nanoSecondMultiplyFactor;
187
}
188
return hiresTime / _omrtime_hires_clock_nanoSecondDivideFactor;
189
}
190
191
void
192
MM_OSInterface::maskSignals()
193
{
194
#if defined(LINUX)
195
/* mask any further signals - useful for signal handlers */
196
sigset_t mask_set;/* used to set a signal masking set. */
197
sigfillset(&mask_set);
198
sigprocmask(SIG_SETMASK, &mask_set, NULL);
199
#endif /* LINUX */
200
}
201
202
203