1 /*
2  * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #ifndef SHARE_JFR_SUPPORT_JFRTHREADLOCAL_HPP
26 #define SHARE_JFR_SUPPORT_JFRTHREADLOCAL_HPP
27 
28 #include "jfr/utilities/jfrBlob.hpp"
29 #include "jfr/utilities/jfrTypes.hpp"
30 
31 class JavaThread;
32 class JfrBuffer;
33 class JfrStackFrame;
34 class Thread;
35 
36 class JfrThreadLocal {
37  private:
38   jobject _java_event_writer;
39   mutable JfrBuffer* _java_buffer;
40   mutable JfrBuffer* _native_buffer;
41   JfrBuffer* _shelved_buffer;
42   JfrBuffer* _load_barrier_buffer_epoch_0;
43   JfrBuffer* _load_barrier_buffer_epoch_1;
44   mutable JfrStackFrame* _stackframes;
45   mutable traceid _trace_id;
46   JfrBlobHandle _thread;
47   u8 _data_lost;
48   traceid _stack_trace_id;
49   jlong _user_time;
50   jlong _cpu_time;
51   jlong _wallclock_time;
52   unsigned int _stack_trace_hash;
53   mutable u4 _stackdepth;
54   volatile jint _entering_suspend_flag;
55   bool _excluded;
56   bool _dead;
57   traceid _parent_trace_id;
58 
59   JfrBuffer* install_native_buffer() const;
60   JfrBuffer* install_java_buffer() const;
61   JfrStackFrame* install_stackframes() const;
62   void release(Thread* t);
63   static void release(JfrThreadLocal* tl, Thread* t);
64 
65  public:
66   JfrThreadLocal();
67 
native_buffer() const68   JfrBuffer* native_buffer() const {
69     return _native_buffer != NULL ? _native_buffer : install_native_buffer();
70   }
71 
has_native_buffer() const72   bool has_native_buffer() const {
73     return _native_buffer != NULL;
74   }
75 
set_native_buffer(JfrBuffer * buffer)76   void set_native_buffer(JfrBuffer* buffer) {
77     _native_buffer = buffer;
78   }
79 
java_buffer() const80   JfrBuffer* java_buffer() const {
81     return _java_buffer != NULL ? _java_buffer : install_java_buffer();
82   }
83 
has_java_buffer() const84   bool has_java_buffer() const {
85     return _java_buffer != NULL;
86   }
87 
set_java_buffer(JfrBuffer * buffer)88   void set_java_buffer(JfrBuffer* buffer) {
89     _java_buffer = buffer;
90   }
91 
shelved_buffer() const92   JfrBuffer* shelved_buffer() const {
93     return _shelved_buffer;
94   }
95 
shelve_buffer(JfrBuffer * buffer)96   void shelve_buffer(JfrBuffer* buffer) {
97     _shelved_buffer = buffer;
98   }
99 
has_java_event_writer() const100   bool has_java_event_writer() const {
101     return _java_event_writer != NULL;
102   }
103 
java_event_writer()104   jobject java_event_writer() {
105     return _java_event_writer;
106   }
107 
set_java_event_writer(jobject java_event_writer)108   void set_java_event_writer(jobject java_event_writer) {
109     _java_event_writer = java_event_writer;
110   }
111 
stackframes() const112   JfrStackFrame* stackframes() const {
113     return _stackframes != NULL ? _stackframes : install_stackframes();
114   }
115 
set_stackframes(JfrStackFrame * frames)116   void set_stackframes(JfrStackFrame* frames) {
117     _stackframes = frames;
118   }
119 
120   u4 stackdepth() const;
121 
set_stackdepth(u4 depth)122   void set_stackdepth(u4 depth) {
123     _stackdepth = depth;
124   }
125 
thread_id() const126   traceid thread_id() const {
127     return _trace_id;
128   }
129 
set_thread_id(traceid thread_id)130   void set_thread_id(traceid thread_id) {
131     _trace_id = thread_id;
132   }
133 
parent_thread_id() const134   traceid parent_thread_id() const {
135     return _parent_trace_id;
136   }
137 
set_cached_stack_trace_id(traceid id,unsigned int hash=0)138   void set_cached_stack_trace_id(traceid id, unsigned int hash = 0) {
139     _stack_trace_id = id;
140     _stack_trace_hash = hash;
141   }
142 
has_cached_stack_trace() const143   bool has_cached_stack_trace() const {
144     return _stack_trace_id != max_julong;
145   }
146 
clear_cached_stack_trace()147   void clear_cached_stack_trace() {
148     _stack_trace_id = max_julong;
149     _stack_trace_hash = 0;
150   }
151 
cached_stack_trace_id() const152   traceid cached_stack_trace_id() const {
153     return _stack_trace_id;
154   }
155 
cached_stack_trace_hash() const156   unsigned int cached_stack_trace_hash() const {
157     return _stack_trace_hash;
158   }
159 
set_trace_block()160   void set_trace_block() {
161     _entering_suspend_flag = 1;
162   }
163 
clear_trace_block()164   void clear_trace_block() {
165     _entering_suspend_flag = 0;
166   }
167 
is_trace_block() const168   bool is_trace_block() const {
169     return _entering_suspend_flag != 0;
170   }
171 
data_lost() const172   u8 data_lost() const {
173     return _data_lost;
174   }
175 
176   u8 add_data_lost(u8 value);
177 
get_user_time() const178   jlong get_user_time() const {
179     return _user_time;
180   }
181 
set_user_time(jlong user_time)182   void set_user_time(jlong user_time) {
183     _user_time = user_time;
184   }
185 
get_cpu_time() const186   jlong get_cpu_time() const {
187     return _cpu_time;
188   }
189 
set_cpu_time(jlong cpu_time)190   void set_cpu_time(jlong cpu_time) {
191     _cpu_time = cpu_time;
192   }
193 
get_wallclock_time() const194   jlong get_wallclock_time() const {
195     return _wallclock_time;
196   }
197 
set_wallclock_time(jlong wallclock_time)198   void set_wallclock_time(jlong wallclock_time) {
199     _wallclock_time = wallclock_time;
200   }
201 
trace_id() const202   traceid trace_id() const {
203     return _trace_id;
204   }
205 
trace_id_addr() const206   traceid* const trace_id_addr() const {
207     return &_trace_id;
208   }
209 
set_trace_id(traceid id) const210   void set_trace_id(traceid id) const {
211     _trace_id = id;
212   }
213 
is_excluded() const214   bool is_excluded() const {
215     return _excluded;
216   }
217 
is_dead() const218   bool is_dead() const {
219     return _dead;
220   }
221 
222   bool has_thread_blob() const;
223   void set_thread_blob(const JfrBlobHandle& handle);
224   const JfrBlobHandle& thread_blob() const;
225 
226   static void exclude(Thread* t);
227   static void include(Thread* t);
228 
229   static void on_start(Thread* t);
230   static void on_exit(Thread* t);
231 
232   // Code generation
233   static ByteSize trace_id_offset();
234   static ByteSize java_event_writer_offset();
235 
236   template <typename>
237   friend class JfrEpochQueueKlassPolicy;
238 };
239 
240 #endif // SHARE_JFR_SUPPORT_JFRTHREADLOCAL_HPP
241