/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 "classfile/javaClasses.hpp"
#include "runtime/handles.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/objectMonitor.hpp"
#include "runtime/objectMonitor.inline.hpp"
#include "runtime/perfData.hpp"
#include "services/management.hpp"
#include "services/serviceUtil.hpp"
class OopClosure;
class ThreadDumpResult;
class ThreadStackTrace;
class ThreadSnapshot;
class StackFrameInfo;
class ThreadConcurrentLocks;
class DeadlockCycle;
// VM monitoring and management support for the thread and
// synchronization subsystem
//
// Thread contention monitoring is disabled by default.
// When enabled, the VM will begin measuring the accumulated
// elapsed time a thread blocked on synchronization.
//
private:
// These counters could be moved to Threads class
// These 2 counters are atomically incremented once the thread is exiting.
// They will be atomically decremented when ThreadService::remove_thread is called.
static volatile int _exiting_threads_count;
static volatile int _exiting_daemon_threads_count;
static bool _thread_monitoring_contention_enabled;
static bool _thread_cpu_time_enabled;
static bool _thread_allocated_memory_enabled;
// Need to keep the list of thread dump result that
// keep references to methodOop since thread dump can be
// requested by multiple threads concurrently.
public:
static void init();
static bool set_thread_monitoring_contention(bool flag);
static bool set_thread_cpu_time_enabled(bool flag);
static bool set_thread_allocated_memory_enabled(bool flag);
static jlong get_live_thread_count() { return _live_threads_count->get_value() - _exiting_threads_count; }
static jlong get_daemon_thread_count() { return _daemon_threads_count->get_value() - _exiting_daemon_threads_count; }
// Support for thread dump
// This function is called by JVM_DumpThreads.
int num_threads, TRAPS);
static void reset_peak_thread_count();
// GC support
static void oops_do(OopClosure* f);
};
// Per-thread Statistics for synchronization
private:
// The following contention statistics are only updated by
// the thread owning these statistics when contention occurs.
// These two reset flags are set to true when another thread
// requests to reset the statistics. The actual statistics
// are reset when the thread contention occurs and attempts
// to update the statistics.
bool _count_pending_reset;
bool _timer_pending_reset;
// Keep accurate times for potentially recursive class operations
// utility functions
void check_and_reset_count() {
if (!_count_pending_reset) return;
_monitor_wait_count = 0;
_sleep_count = 0;
_count_pending_reset = 0;
}
void check_and_reset_timer() {
if (!_timer_pending_reset) return;
_timer_pending_reset = 0;
}
public:
jlong contended_enter_ticks() { return (_timer_pending_reset ? 0 : _contended_enter_timer.active_ticks()); }
jlong monitor_wait_ticks() { return (_timer_pending_reset ? 0 : _monitor_wait_timer.active_ticks()); }
};
// Thread snapshot to represent the thread state and statistics
private:
bool _is_ext_suspended;
bool _is_in_native;
public:
// Dummy snapshot
ThreadSnapshot() : _thread(NULL), _threadObj(NULL), _stack_trace(NULL), _concurrent_locks(NULL), _next(NULL),
~ThreadSnapshot();
void oops_do(OopClosure* f);
};
private:
bool _with_locked_monitors;
public:
~ThreadStackTrace();
void dump_stack_at_safepoint(int max_depth);
void oops_do(OopClosure* f);
int num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); }
};
// StackFrameInfo for keeping methodOop and bci during
// stack walking for later construction of StackTraceElement[]
// Java instances
private:
int _bci;
public:
~StackFrameInfo() {
if (_locked_monitors != NULL) {
delete _locked_monitors;
}
};
void oops_do(OopClosure* f);
};
private:
public:
void add_lock(instanceOop o);
void oops_do(OopClosure* f);
};
private:
bool _retain_map_on_free;
public:
ConcurrentLocksDump(bool retain_map_on_free) : _map(NULL), _last(NULL), _retain_map_on_free(retain_map_on_free) {};
void dump_at_safepoint();
};
private:
int _num_threads;
int _num_snapshots;
public:
ThreadDumpResult(int num_threads);
~ThreadDumpResult();
void oops_do(OopClosure* f);
};
private:
bool _is_deadlock;
public:
~DeadlockCycle();
};
// Utility class to get list of java threads.
private:
public:
bool include_jvmti_agent_threads = false,
bool include_jni_attaching_threads = true);
};
// abstract utility class to set new thread states, and restore previous after the block exits
private:
bool _is_alive;
if (is_alive()) {
}
}
public:
}
if (is_alive()) {
}
}
}
}
}
}
bool is_alive() {
return _is_alive;
}
};
// Change status to waiting on an object (timed or indefinite)
private:
bool _active;
public:
if (is_alive()) {
_stat->monitor_wait();
if (_active) {
}
} else {
_active = false;
}
}
if (_active) {
}
}
};
// Change status to parked (timed or indefinite)
private:
bool _active;
public:
if (is_alive()) {
_stat->monitor_wait();
if (_active) {
}
} else {
_active = false;
}
}
if (_active) {
}
}
};
// Change status to blocked on (re-)entering a synchronization block
private:
bool _active;
stat->contended_enter();
if (active) {
}
return active;
}
public:
// java_thread is waiting thread being blocked on monitor reenter.
// Current thread is the notifying thread which holds the monitor.
bool active = false;
}
return active;
}
if (active) {
}
}
// Change thread status and collect contended enter stats for monitor contended
// enter done for external java world objects and it is contended. All other cases
// like for vm internal objects and for external objects which are not contended
// thread status is not changed and contended enter stat is not collected.
_active = false;
}
}
if (_active) {
}
}
};
// Change status to sleeping
private:
bool _active;
public:
if (is_alive()) {
_stat->thread_sleep();
if (_active) {
}
} else {
_active = false;
}
}
~JavaThreadSleepState() {
if (_active) {
}
}
};
#endif // SHARE_VM_SERVICES_THREADSERVICE_HPP