--- /dev/null 2017-05-06 11:51:59.176144595 +0200 +++ new/src/share/vm/runtime/highLatencyKiller.cpp 2017-05-26 15:03:17.720713174 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/highLatencyKiller.hpp" +#include "runtime/task.hpp" +#include "runtime/safepoint.hpp" + +// PeriodicTasks do not participate in safepoint protocol, and therefore +// can fire when application threads are stopped. This task samples the +// time spent in a single safepoint, and aborts VM if timeout was reached. +class HighLatencyKillerTask : public PeriodicTask { +public: + HighLatencyKillerTask(size_t interval_time) : + PeriodicTask(interval_time), _last_safepoint(-1), _first_time(0), _last_time(0) {} + + jlong _first_time; + jlong _last_time; + int _last_safepoint; + + virtual void task() { + if (SafepointSynchronize::is_synchronizing() || + SafepointSynchronize::is_at_safepoint()) { + jlong ct = os::javaTimeMillis(); + + // TODO: Make sure this operation is safe without acquiring Thread_lock + int current = SafepointSynchronize::safepoint_counter(); + if (current == _last_safepoint) { + _last_time = ct; + + size_t delay = (size_t)(_last_time - _first_time); + if (delay > HighLatencyKillerTimeout) { + // TODO: Print VM operation in progress + report_fatal("", -1, "High Latency detected: " SIZE_FORMAT " ms (actual) > " SIZE_FORMAT " ms (threshold). Killing VM.", + delay, HighLatencyKillerTimeout); + } + } else { + _first_time = ct; + _last_time = ct; + _last_safepoint = current; + } + } + } +}; + +HighLatencyKiller::HighLatencyKiller() { + // TODO: Handle HighLatencyKillerPeriod > HighLatencyKillerTimeout + HighLatencyKillerTask* task = new HighLatencyKillerTask(HighLatencyKillerPeriod); + task->enroll(); +} + +void HighLatencyKiller::create() { + _killer = new HighLatencyKiller(); +}; + +// TODO: Destructors and proper cleanup + +HighLatencyKiller *HighLatencyKiller::_killer = NULL; +