Path: blob/master/runtime/gc_realtime/OSInterface.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 "omrport.h"2526#include <string.h>27#include <math.h>2829#if defined(AIXPPC)30#include <builtins.h>31#endif3233#if defined(LINUX)34#include <time.h>35#include <errno.h>36#include <sys/time.h>37#endif /* #if defined(LINUX) */3839#if defined(LINUX) && !defined(J9ZTPF)40#include <linux/rtc.h>41#include <sys/syscall.h>42#include <sys/signal.h>43#elif defined(J9ZTPF)44#include <signal.h>45#endif /* defined(LINUX) && !defined(J9ZTPF) */4647#include "ProcessorInfo.hpp"48#include "EnvironmentBase.hpp"49#include "GCExtensionsBase.hpp"50#include "modronnls.h"5152#include "OSInterface.hpp"53/**54* Initialization.55*/56MM_OSInterface*57MM_OSInterface::newInstance(MM_EnvironmentBase *env)58{59MM_OSInterface *osInterface = (MM_OSInterface *)env->getForge()->allocate(sizeof(MM_OSInterface), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());60if (osInterface) {61new(osInterface) MM_OSInterface();62if (!osInterface->initialize(env)) {63osInterface->kill(env);64osInterface = NULL;65}66}67return osInterface;68}6970/**71* Initialization.72*/73bool74MM_OSInterface::initialize(MM_EnvironmentBase *env)75{76OMRPORT_ACCESS_FROM_ENVIRONMENT(env);7778_vm = env->getOmrVM();79_extensions = MM_GCExtensionsBase::getExtensions(env->getOmrVM());80_numProcessors = omrsysinfo_get_number_CPUs_by_type(OMRPORT_CPU_ONLINE);81_physicalMemoryBytes = omrsysinfo_get_physical_memory();8283_omrtime_hires_clock_nanoSecondMultiplyFactor = 1000000000 / omrtime_hires_frequency();84_omrtime_hires_clock_nanoSecondDivideFactor = omrtime_hires_frequency() / 1000000000;8586if (NULL == (_processorInfo = MM_ProcessorInfo::newInstance(env))) {87return false;88}8990_ticksPerMicroSecond = (U_64)(_processorInfo->_freq / 1e6);9192if (_extensions->verbose >= 1) {93if (0 == _ticksPerMicroSecond) {94omrtty_printf("Use OS high resolution timer instead of CPU tick-based timer\n");95} else {96omrtty_printf("ticksPerMicro = %llu\n", _ticksPerMicroSecond);97}98}99return true;100}101102/**103* Initialization.104*/105void106MM_OSInterface::kill(MM_EnvironmentBase *env)107{108tearDown(env);109env->getForge()->free(this);110}111112/**113* Teardown114*/115void116MM_OSInterface::tearDown(MM_EnvironmentBase *env)117{118if (NULL != _processorInfo) {119_processorInfo->kill(env);120}121}122123bool124MM_OSInterface::rtcTimerAvailable() {125#if defined(LINUX)126return true;127#else128return false;129#endif130}131132bool133MM_OSInterface::itTimerAvailable() {134#if defined(WIN32)135return true;136#else137return false;138#endif139}140141/**142* hiresTimerAvailable143* On Linux or AIX, return true if the realtime clock resolution is better than144* the high resolution timer period, false otherwise.145* On Windows, return false.146* Other platforms will fail to compile until they have an implementation.147* @ingroup GC_Metronome methodGroup148*/149bool150MM_OSInterface::hiresTimerAvailable() {151#if (defined(LINUX) && !defined(J9ZTPF)) || defined (AIXPPC)152OMRPORT_ACCESS_FROM_OMRVM(_vm);153struct timespec ts;154if (clock_getres(CLOCK_REALTIME, &ts)) {155if (_extensions->verbose >= 2) {156omrtty_printf("POSIX High Resolution Clock not available\n");157}158return false;159} else {160if (_extensions->verbose >= 2) {161omrtty_printf("POSIX High Resolution Clock has resolution %d nanoseconds\n", ts.tv_nsec);162}163bool returnValue = ((ts.tv_sec == 0) && ((uintptr_t)ts.tv_nsec < (_extensions->hrtPeriodMicro * 1000)));164if (!returnValue && _extensions->overrideHiresTimerCheck) {165omrnls_printf(J9NLS_INFO, J9NLS_GC_IGNORE_OS_REPORTED_HIGHRES_VALUES);166returnValue = true;167}168return returnValue;169}170#elif defined(WIN32)171/* On Win32, we don't have a HRT and it is safe to use our ITimer implementation so we can return false */172return false;173#else174/* No high res time available so try your luck with ITAlarm instead */175return false;176#endif /* #if (defined(LINUX) && !defined(J9ZTPF)) || defined (AIXPPC) */177}178179U_64180MM_OSInterface::nanoTime()181{182OMRPORT_ACCESS_FROM_OMRVM(_vm);183U_64 hiresTime = omrtime_hires_clock();184if (_omrtime_hires_clock_nanoSecondMultiplyFactor != 0) {185return hiresTime * _omrtime_hires_clock_nanoSecondMultiplyFactor;186}187return hiresTime / _omrtime_hires_clock_nanoSecondDivideFactor;188}189190void191MM_OSInterface::maskSignals()192{193#if defined(LINUX)194/* mask any further signals - useful for signal handlers */195sigset_t mask_set;/* used to set a signal masking set. */196sigfillset(&mask_set);197sigprocmask(SIG_SETMASK, &mask_set, NULL);198#endif /* LINUX */199}200201202203