| /* |
| * Copyright (c) 2012, 2019, Oracle and/or its affiliates. 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. |
| * |
| */ |
| |
| #ifndef SHARE_JFR_SUPPORT_JFRTHREADLOCAL_HPP |
| #define SHARE_JFR_SUPPORT_JFRTHREADLOCAL_HPP |
| |
| #include "jfr/utilities/jfrBlob.hpp" |
| #include "jfr/utilities/jfrTypes.hpp" |
| |
| class JavaThread; |
| class JfrBuffer; |
| class JfrStackFrame; |
| class Thread; |
| |
| class JfrThreadLocal { |
| private: |
| jobject _java_event_writer; |
| mutable JfrBuffer* _java_buffer; |
| mutable JfrBuffer* _native_buffer; |
| JfrBuffer* _shelved_buffer; |
| mutable JfrStackFrame* _stackframes; |
| mutable traceid _trace_id; |
| JfrBlobHandle _thread; |
| u8 _data_lost; |
| traceid _stack_trace_id; |
| jlong _user_time; |
| jlong _cpu_time; |
| jlong _wallclock_time; |
| unsigned int _stack_trace_hash; |
| mutable u4 _stackdepth; |
| volatile jint _entering_suspend_flag; |
| bool _excluded; |
| bool _dead; |
| |
| JfrBuffer* install_native_buffer() const; |
| JfrBuffer* install_java_buffer() const; |
| JfrStackFrame* install_stackframes() const; |
| void release(Thread* t); |
| static void release(JfrThreadLocal* tl, Thread* t); |
| |
| public: |
| JfrThreadLocal(); |
| |
| JfrBuffer* native_buffer() const { |
| return _native_buffer != NULL ? _native_buffer : install_native_buffer(); |
| } |
| |
| bool has_native_buffer() const { |
| return _native_buffer != NULL; |
| } |
| |
| void set_native_buffer(JfrBuffer* buffer) { |
| _native_buffer = buffer; |
| } |
| |
| JfrBuffer* java_buffer() const { |
| return _java_buffer != NULL ? _java_buffer : install_java_buffer(); |
| } |
| |
| bool has_java_buffer() const { |
| return _java_buffer != NULL; |
| } |
| |
| void set_java_buffer(JfrBuffer* buffer) { |
| _java_buffer = buffer; |
| } |
| |
| JfrBuffer* shelved_buffer() const { |
| return _shelved_buffer; |
| } |
| |
| void shelve_buffer(JfrBuffer* buffer) { |
| _shelved_buffer = buffer; |
| } |
| |
| bool has_java_event_writer() const { |
| return _java_event_writer != NULL; |
| } |
| |
| jobject java_event_writer() { |
| return _java_event_writer; |
| } |
| |
| void set_java_event_writer(jobject java_event_writer) { |
| _java_event_writer = java_event_writer; |
| } |
| |
| JfrStackFrame* stackframes() const { |
| return _stackframes != NULL ? _stackframes : install_stackframes(); |
| } |
| |
| void set_stackframes(JfrStackFrame* frames) { |
| _stackframes = frames; |
| } |
| |
| u4 stackdepth() const; |
| |
| void set_stackdepth(u4 depth) { |
| _stackdepth = depth; |
| } |
| |
| traceid thread_id() const { |
| return _trace_id; |
| } |
| |
| void set_thread_id(traceid thread_id) { |
| _trace_id = thread_id; |
| } |
| |
| void set_cached_stack_trace_id(traceid id, unsigned int hash = 0) { |
| _stack_trace_id = id; |
| _stack_trace_hash = hash; |
| } |
| |
| bool has_cached_stack_trace() const { |
| return _stack_trace_id != max_julong; |
| } |
| |
| void clear_cached_stack_trace() { |
| _stack_trace_id = max_julong; |
| _stack_trace_hash = 0; |
| } |
| |
| traceid cached_stack_trace_id() const { |
| return _stack_trace_id; |
| } |
| |
| unsigned int cached_stack_trace_hash() const { |
| return _stack_trace_hash; |
| } |
| |
| void set_trace_block() { |
| _entering_suspend_flag = 1; |
| } |
| |
| void clear_trace_block() { |
| _entering_suspend_flag = 0; |
| } |
| |
| bool is_trace_block() const { |
| return _entering_suspend_flag != 0; |
| } |
| |
| u8 data_lost() const { |
| return _data_lost; |
| } |
| |
| u8 add_data_lost(u8 value); |
| |
| jlong get_user_time() const { |
| return _user_time; |
| } |
| |
| void set_user_time(jlong user_time) { |
| _user_time = user_time; |
| } |
| |
| jlong get_cpu_time() const { |
| return _cpu_time; |
| } |
| |
| void set_cpu_time(jlong cpu_time) { |
| _cpu_time = cpu_time; |
| } |
| |
| jlong get_wallclock_time() const { |
| return _wallclock_time; |
| } |
| |
| void set_wallclock_time(jlong wallclock_time) { |
| _wallclock_time = wallclock_time; |
| } |
| |
| traceid trace_id() const { |
| return _trace_id; |
| } |
| |
| traceid* const trace_id_addr() const { |
| return &_trace_id; |
| } |
| |
| void set_trace_id(traceid id) const { |
| _trace_id = id; |
| } |
| |
| bool is_excluded() const { |
| return _excluded; |
| } |
| |
| bool is_dead() const { |
| return _dead; |
| } |
| |
| bool has_thread_blob() const; |
| void set_thread_blob(const JfrBlobHandle& handle); |
| const JfrBlobHandle& thread_blob() const; |
| |
| static void exclude(Thread* t); |
| static void include(Thread* t); |
| |
| static void on_start(Thread* t); |
| static void on_exit(Thread* t); |
| |
| // Code generation |
| static ByteSize trace_id_offset(); |
| static ByteSize java_event_writer_offset(); |
| }; |
| |
| #endif // SHARE_JFR_SUPPORT_JFRTHREADLOCAL_HPP |