Mercurial > hg > heapstats
view agent/src/heapstats-engines/gcWatcher.cpp @ 236:84f67233da38
Bug 3406: [TEST]Add race condition tests for core components
Reviewed-by: yasuenag
https://github.com/HeapStats/heapstats/pull/103
author | KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> |
---|---|
date | Thu, 22 Jun 2017 09:55:19 +0900 |
parents | 31f4aed852e6 |
children | 1885f234b75b |
line wrap: on
line source
/*! * \file gcWatcher.cpp * \brief This file is used to take snapshot when finish garbage collection. * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "globals.hpp" #include "gcWatcher.hpp" /*! * \brief TGCWatcher constructor. * \param postGCFunc [in] Callback is called after GC. * \param info [in] JVM running performance information. */ TGCWatcher::TGCWatcher(TPostGCFunc postGCFunc, TJvmInfo *info) : TAgentThread("HeapStats GC Watcher") { /* Sanity check. */ if (postGCFunc == NULL) { throw "Event callback is NULL."; } if (info == NULL) { throw "TJvmInfo is NULL."; } /* Setting parameter. */ this->_postGCFunc = postGCFunc; this->pJvmInfo = info; this->_FGC = 0; } /*! * \brief TGCWatcher destructor. */ TGCWatcher::~TGCWatcher(void) { /* Do nothing. */ } /*! * \brief JThread entry point. * \param jvmti [in] JVMTI environment object. * \param jni [in] JNI environment object. * \param data [in] Pointer of user data. */ void JNICALL TGCWatcher::entryPoint(jvmtiEnv *jvmti, JNIEnv *jni, void *data) { /* Get self. */ TGCWatcher *controller = (TGCWatcher *)data; /* Change running state. */ controller->_isRunning = true; /* Loop for agent run. */ while (!controller->_terminateRequest) { /* Variable for notification flag. */ bool needProcess = false; ENTER_PTHREAD_SECTION(&controller->mutex) { /* If no exists request. */ if (likely(controller->_numRequests == 0)) { /* Wait for notification or termination. */ pthread_cond_wait(&controller->mutexCond, &controller->mutex); } RACE_COND_DEBUG_POINT: /* If waiting finished by notification. */ if (likely(controller->_numRequests > 0)) { controller->_numRequests--; needProcess = true; } } EXIT_PTHREAD_SECTION(&controller->mutex) /* If waiting finished by notification. */ if (needProcess) { /* Call event callback. */ (*controller->_postGCFunc)(jvmti, jni, GC); } } /* Change running state. */ controller->_isRunning = false; } /*! * \brief Make and begin Jthread. * \param jvmti [in] JVMTI environment object. * \param env [in] JNI environment object. */ void TGCWatcher::start(jvmtiEnv *jvmti, JNIEnv *env) { /* Check JVM information. */ if (this->pJvmInfo->getFGCCount() < 0) { logger->printWarnMsg("All GC accept as youngGC."); } else { /* Reset now full gc count. */ this->_FGC = this->pJvmInfo->getFGCCount(); } /* Start jThread. */ TAgentThread::start(jvmti, env, TGCWatcher::entryPoint, this, JVMTI_THREAD_MAX_PRIORITY); }