/*
* Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved.
*
* This file is part of the Lock Contention Tracing Subsystem for the HotSpot
* Virtual Machine, which is developed at Christian Doppler Laboratory on
* Monitoring and Evolution of Very-Large-Scale Software Systems. Please
* contact us at if you need additional information
* or have any questions.
*
* 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, see .
*
*/
#include "evtrace/traceReaderThread.hpp"
#include "evtrace/traceManager.hpp"
#include "runtime/javaCalls.hpp"
TraceReaderThread::TraceReaderThread(oop obj)
: JavaThread(trace_reader_thread_entry),
_object(obj),
_is_polling_queue(false)
{
}
TraceReaderThread::~TraceReaderThread() {
TraceManager::thread_is_exiting(this);
}
void TraceReaderThread::trace_reader_thread_entry(JavaThread* thread, TRAPS) {
TraceReaderThread *self = (TraceReaderThread *) thread;
JavaValue result(T_VOID);
Klass* klass = SystemDictionary::resolve_or_fail(vmSymbols::sun_evtracing_TraceReaderThread(), true, CHECK);
JavaCalls::call_virtual(&result,
self->_object,
klass,
vmSymbols::run_method_name(),
vmSymbols::void_method_signature(),
CHECK);
}
TraceReaderThread* TraceReaderThread::start(Handle flushq, Handle freeq, TRAPS) {
Klass* rt_klass = SystemDictionary::resolve_or_fail(vmSymbols::sun_evtracing_TraceReaderThread(), true, CHECK_NULL);
instanceKlassHandle rt_khandle(THREAD, rt_klass);
rt_khandle->initialize(CHECK_NULL);
instanceHandle rt_obj = rt_khandle->allocate_instance_handle(CHECK_NULL);
JavaValue result(T_VOID);
JavaCalls::call_special(&result,
rt_obj,
rt_khandle,
vmSymbols::object_initializer_name(),
vmSymbols::TraceReaderThread_constructor_signature(),
flushq,
freeq,
CHECK_NULL);
Klass* t_klass = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
instanceKlassHandle t_khandle(THREAD, t_klass);
instanceHandle t_obj = t_khandle->allocate_instance_handle(CHECK_NULL);
const char thread_name[] = "Trace Reader Thread";
Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
// Initialize thread_oop to put it into the system threadGroup
Handle thread_group(THREAD, Universe::system_thread_group());
JavaCalls::call_special(&result,
t_obj,
t_khandle,
vmSymbols::object_initializer_name(),
vmSymbols::threadgroup_string_void_signature(),
thread_group,
string,
CHECK_NULL);
TraceReaderThread *trt = NULL;
{
MutexLocker mu(Threads_lock);
trt = new TraceReaderThread(rt_obj());
if (trt == NULL || trt->osthread() == NULL) {
vm_exit_during_initialization("java.lang.OutOfMemoryError", "unable to create new native thread");
}
java_lang_Thread::set_thread(t_obj(), trt);
java_lang_Thread::set_daemon(t_obj());
trt->set_threadObj(t_obj());
Threads::add(trt);
Thread::start(trt);
}
return trt;
}
void TraceReaderThread::shutdown(TRAPS) {
Klass* rt_klass = SystemDictionary::resolve_or_fail(vmSymbols::sun_evtracing_TraceReaderThread(), true, CHECK);
instanceKlassHandle rt_khandle(THREAD, rt_klass);
JavaValue result(T_VOID);
JavaCalls::call_virtual(&result,
Handle(_object),
rt_khandle,
vmSymbols::shutdown_method_name(),
vmSymbols::void_method_signature(),
CHECK);
}
void TraceReaderThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
JavaThread::oops_do(f, cld_f, cf);
f->do_oop(&_object);
}