1 /*
   2  * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved.
   3  *
   4  * This file is part of the Lock Contention Tracing Subsystem for the HotSpot
   5  * Virtual Machine, which is developed at Christian Doppler Laboratory on
   6  * Monitoring and Evolution of Very-Large-Scale Software Systems. Please
   7  * contact us at <http://mevss.jku.at/> if you need additional information
   8  * or have any questions.
   9  *
  10  * This code is free software; you can redistribute it and/or modify it
  11  * under the terms of the GNU General Public License version 2 only, as
  12  * published by the Free Software Foundation.
  13  *
  14  * This code is distributed in the hope that it will be useful, but WITHOUT
  15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17  * version 2 for more details (a copy is included in the LICENSE file that
  18  * accompanied this code).
  19  *
  20  * You should have received a copy of the GNU General Public License version
  21  * 2 along with this work. If not, see <http://www.gnu.org/licenses/>.
  22  *
  23  */
  24 
  25 #include "evtrace/traceReaderThread.hpp"
  26 
  27 #include "evtrace/traceManager.hpp"
  28 
  29 #include "runtime/javaCalls.hpp"
  30 
  31 TraceReaderThread::TraceReaderThread(oop obj)
  32 : JavaThread(trace_reader_thread_entry),
  33   _object(obj),
  34   _is_polling_queue(false)
  35 {
  36 }
  37 
  38 TraceReaderThread::~TraceReaderThread() {
  39   TraceManager::thread_is_exiting(this);
  40 }
  41 
  42 void TraceReaderThread::trace_reader_thread_entry(JavaThread* thread, TRAPS) {
  43   TraceReaderThread *self = (TraceReaderThread *) thread;
  44   JavaValue result(T_VOID);
  45   Klass* klass = SystemDictionary::resolve_or_fail(vmSymbols::sun_evtracing_TraceReaderThread(), true, CHECK);
  46   JavaCalls::call_virtual(&result,
  47                           self->_object,
  48                           klass,
  49                           vmSymbols::run_method_name(),
  50                           vmSymbols::void_method_signature(),
  51                           CHECK);
  52 }
  53 
  54 TraceReaderThread* TraceReaderThread::start(Handle flushq, Handle freeq, TRAPS) {
  55   Klass* rt_klass = SystemDictionary::resolve_or_fail(vmSymbols::sun_evtracing_TraceReaderThread(), true, CHECK_NULL);
  56   instanceKlassHandle rt_khandle(THREAD, rt_klass);
  57   rt_khandle->initialize(CHECK_NULL);
  58   instanceHandle rt_obj = rt_khandle->allocate_instance_handle(CHECK_NULL);
  59 
  60   JavaValue result(T_VOID);
  61   JavaCalls::call_special(&result,
  62                           rt_obj,
  63                           rt_khandle,
  64                           vmSymbols::object_initializer_name(),
  65                           vmSymbols::TraceReaderThread_constructor_signature(),
  66                           flushq,
  67                           freeq,
  68                           CHECK_NULL);
  69 
  70   Klass* t_klass = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
  71   instanceKlassHandle t_khandle(THREAD, t_klass);
  72   instanceHandle t_obj = t_khandle->allocate_instance_handle(CHECK_NULL);
  73 
  74   const char thread_name[] = "Trace Reader Thread";
  75   Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
  76 
  77   // Initialize thread_oop to put it into the system threadGroup
  78   Handle thread_group(THREAD, Universe::system_thread_group());
  79   JavaCalls::call_special(&result,
  80                           t_obj,
  81                           t_khandle,
  82                           vmSymbols::object_initializer_name(),
  83                           vmSymbols::threadgroup_string_void_signature(),
  84                           thread_group,
  85                           string,
  86                           CHECK_NULL);
  87 
  88   TraceReaderThread *trt = NULL;
  89   {
  90     MutexLocker mu(Threads_lock);
  91     trt = new TraceReaderThread(rt_obj());
  92 
  93     if (trt == NULL || trt->osthread() == NULL) {
  94       vm_exit_during_initialization("java.lang.OutOfMemoryError", "unable to create new native thread");
  95     }
  96     java_lang_Thread::set_thread(t_obj(), trt);
  97     java_lang_Thread::set_daemon(t_obj());
  98 
  99     trt->set_threadObj(t_obj());
 100     Threads::add(trt);
 101     Thread::start(trt);
 102   }
 103   return trt;
 104 }
 105 
 106 void TraceReaderThread::shutdown(TRAPS) {
 107   Klass* rt_klass = SystemDictionary::resolve_or_fail(vmSymbols::sun_evtracing_TraceReaderThread(), true, CHECK);
 108   instanceKlassHandle rt_khandle(THREAD, rt_klass);
 109 
 110   JavaValue result(T_VOID);
 111   JavaCalls::call_virtual(&result,
 112                           Handle(_object),
 113                           rt_khandle,
 114                           vmSymbols::shutdown_method_name(),
 115                           vmSymbols::void_method_signature(),
 116                           CHECK);
 117 }
 118 
 119 void TraceReaderThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
 120   JavaThread::oops_do(f, cld_f, cf);
 121 
 122   f->do_oop(&_object);
 123 }