1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 #include "CallStack.h"
23 #include "DbeSession.h"
24 #include "Exp_Layout.h"
25 #include "Experiment.h"
28 #include "dbe_types.h"
32 * PrUsage is a class which wraps access to the values of prusage
33 * system structure. It was expanded to 64 bit entities in 2.7
34 * (experiment version 6 & 7).
38 pr_tstamp
= pr_create
= pr_term
= pr_rtime
= (hrtime_t
) 0;
39 pr_utime
= pr_stime
= pr_ttime
= pr_tftime
= pr_dftime
= (hrtime_t
) 0;
40 pr_kftime
= pr_ltime
= pr_slptime
= pr_wtime
= pr_stoptime
= (hrtime_t
) 0;
42 pr_minf
= pr_majf
= pr_nswap
= pr_inblk
= pr_oublk
= 0;
43 pr_msnd
= pr_mrcv
= pr_sigs
= pr_vctx
= pr_ictx
= pr_sysc
= pr_ioch
= 0;
47 * Resource usage. /proc/<pid>/usage /proc/<pid>/lwp/<lwpid>/lwpusage
50 { /* v8 timestruc_t */
51 uint32_t tv_sec
; /* seconds */
52 uint32_t tv_nsec
; /* and nanoseconds */
55 typedef struct ana_prusage
57 id_t pr_lwpid
; /* lwp id. 0: process or defunct */
58 int pr_count
; /* number of contributing lwps */
59 timestruc_32 pr_tstamp
; /* current time stamp */
60 timestruc_32 pr_create
; /* process/lwp creation time stamp */
61 timestruc_32 pr_term
; /* process/lwp termination time stamp */
62 timestruc_32 pr_rtime
; /* total lwp real (elapsed) time */
63 timestruc_32 pr_utime
; /* user level cpu time */
64 timestruc_32 pr_stime
; /* system call cpu time */
65 timestruc_32 pr_ttime
; /* other system trap cpu time */
66 timestruc_32 pr_tftime
; /* text page fault sleep time */
67 timestruc_32 pr_dftime
; /* data page fault sleep time */
68 timestruc_32 pr_kftime
; /* kernel page fault sleep time */
69 timestruc_32 pr_ltime
; /* user lock wait sleep time */
70 timestruc_32 pr_slptime
; /* all other sleep time */
71 timestruc_32 pr_wtime
; /* wait-cpu (latency) time */
72 timestruc_32 pr_stoptime
; /* stopped time */
73 timestruc_32 filltime
[6]; /* filler for future expansion */
74 uint32_t pr_minf
; /* minor page faults */
75 uint32_t pr_majf
; /* major page faults */
76 uint32_t pr_nswap
; /* swaps */
77 uint32_t pr_inblk
; /* input blocks */
78 uint32_t pr_oublk
; /* output blocks */
79 uint32_t pr_msnd
; /* messages sent */
80 uint32_t pr_mrcv
; /* messages received */
81 uint32_t pr_sigs
; /* signals received */
82 uint32_t pr_vctx
; /* voluntary context switches */
83 uint32_t pr_ictx
; /* involuntary context switches */
84 uint32_t pr_sysc
; /* system calls */
85 uint32_t pr_ioch
; /* chars read and written */
86 uint32_t filler
[10]; /* filler for future expansion */
90 PrUsage::bind32Size ()
92 uint64_t bindSize
= sizeof (raw_prusage_32
);
96 #define timestruc2hr(x) ((hrtime_t)(x).tv_sec*NANOSEC + (hrtime_t)(x).tv_nsec)
99 PrUsage::bind32 (void *p
, bool need_swap_endian
)
103 raw_prusage_32 pu
, *tmp
= (raw_prusage_32
*) p
;
104 if (need_swap_endian
)
108 SWAP_ENDIAN (pu
.pr_tstamp
.tv_sec
);
109 SWAP_ENDIAN (pu
.pr_tstamp
.tv_nsec
);
110 SWAP_ENDIAN (pu
.pr_create
.tv_sec
);
111 SWAP_ENDIAN (pu
.pr_create
.tv_nsec
);
112 SWAP_ENDIAN (pu
.pr_term
.tv_sec
);
113 SWAP_ENDIAN (pu
.pr_term
.tv_nsec
);
114 SWAP_ENDIAN (pu
.pr_rtime
.tv_sec
);
115 SWAP_ENDIAN (pu
.pr_rtime
.tv_nsec
);
116 SWAP_ENDIAN (pu
.pr_utime
.tv_sec
);
117 SWAP_ENDIAN (pu
.pr_utime
.tv_nsec
);
118 SWAP_ENDIAN (pu
.pr_stime
.tv_sec
);
119 SWAP_ENDIAN (pu
.pr_stime
.tv_nsec
);
120 SWAP_ENDIAN (pu
.pr_ttime
.tv_sec
);
121 SWAP_ENDIAN (pu
.pr_ttime
.tv_nsec
);
122 SWAP_ENDIAN (pu
.pr_tftime
.tv_sec
);
123 SWAP_ENDIAN (pu
.pr_tftime
.tv_nsec
);
124 SWAP_ENDIAN (pu
.pr_dftime
.tv_sec
);
125 SWAP_ENDIAN (pu
.pr_dftime
.tv_nsec
);
126 SWAP_ENDIAN (pu
.pr_kftime
.tv_sec
);
127 SWAP_ENDIAN (pu
.pr_kftime
.tv_nsec
);
128 SWAP_ENDIAN (pu
.pr_ltime
.tv_sec
);
129 SWAP_ENDIAN (pu
.pr_ltime
.tv_nsec
);
130 SWAP_ENDIAN (pu
.pr_slptime
.tv_sec
);
131 SWAP_ENDIAN (pu
.pr_slptime
.tv_nsec
);
132 SWAP_ENDIAN (pu
.pr_wtime
.tv_sec
);
133 SWAP_ENDIAN (pu
.pr_wtime
.tv_nsec
);
134 SWAP_ENDIAN (pu
.pr_stoptime
.tv_sec
);
135 SWAP_ENDIAN (pu
.pr_stoptime
.tv_nsec
);
136 SWAP_ENDIAN (pu
.pr_minf
);
137 SWAP_ENDIAN (pu
.pr_majf
);
138 SWAP_ENDIAN (pu
.pr_nswap
);
139 SWAP_ENDIAN (pu
.pr_inblk
);
140 SWAP_ENDIAN (pu
.pr_oublk
);
141 SWAP_ENDIAN (pu
.pr_msnd
);
142 SWAP_ENDIAN (pu
.pr_mrcv
);
143 SWAP_ENDIAN (pu
.pr_sigs
);
144 SWAP_ENDIAN (pu
.pr_vctx
);
145 SWAP_ENDIAN (pu
.pr_ictx
);
146 SWAP_ENDIAN (pu
.pr_sysc
);
147 SWAP_ENDIAN (pu
.pr_ioch
);
149 pr_tstamp
= timestruc2hr (tmp
->pr_tstamp
);
150 pr_create
= timestruc2hr (tmp
->pr_create
);
151 pr_term
= timestruc2hr (tmp
->pr_term
);
152 pr_rtime
= timestruc2hr (tmp
->pr_rtime
);
153 pr_utime
= timestruc2hr (tmp
->pr_utime
);
154 pr_stime
= timestruc2hr (tmp
->pr_stime
);
155 pr_ttime
= timestruc2hr (tmp
->pr_ttime
);
156 pr_tftime
= timestruc2hr (tmp
->pr_tftime
);
157 pr_dftime
= timestruc2hr (tmp
->pr_dftime
);
158 pr_kftime
= timestruc2hr (tmp
->pr_kftime
);
159 pr_ltime
= timestruc2hr (tmp
->pr_ltime
);
160 pr_slptime
= timestruc2hr (tmp
->pr_slptime
);
161 pr_wtime
= timestruc2hr (tmp
->pr_wtime
);
162 pr_stoptime
= timestruc2hr (tmp
->pr_stoptime
);
163 pr_minf
= tmp
->pr_minf
;
164 pr_majf
= tmp
->pr_majf
;
165 pr_nswap
= tmp
->pr_nswap
;
166 pr_inblk
= tmp
->pr_inblk
;
167 pr_oublk
= tmp
->pr_oublk
;
168 pr_msnd
= tmp
->pr_msnd
;
169 pr_mrcv
= tmp
->pr_mrcv
;
170 pr_sigs
= tmp
->pr_sigs
;
171 pr_vctx
= tmp
->pr_vctx
;
172 pr_ictx
= tmp
->pr_ictx
;
173 pr_sysc
= tmp
->pr_sysc
;
174 pr_ioch
= tmp
->pr_ioch
;
179 { /* 64-bit timestruc_t */
180 uint64_t tv_sec
; /* seconds */
181 uint64_t tv_nsec
; /* and nanoseconds */
186 id_t pr_lwpid
; /* lwp id. 0: process or defunct */
187 int pr_count
; /* number of contributing lwps */
188 timestruc_64 pr_tstamp
; /* current time stamp */
189 timestruc_64 pr_create
; /* process/lwp creation time stamp */
190 timestruc_64 pr_term
; /* process/lwp termination time stamp */
191 timestruc_64 pr_rtime
; /* total lwp real (elapsed) time */
192 timestruc_64 pr_utime
; /* user level cpu time */
193 timestruc_64 pr_stime
; /* system call cpu time */
194 timestruc_64 pr_ttime
; /* other system trap cpu time */
195 timestruc_64 pr_tftime
; /* text page fault sleep time */
196 timestruc_64 pr_dftime
; /* data page fault sleep time */
197 timestruc_64 pr_kftime
; /* kernel page fault sleep time */
198 timestruc_64 pr_ltime
; /* user lock wait sleep time */
199 timestruc_64 pr_slptime
; /* all other sleep time */
200 timestruc_64 pr_wtime
; /* wait-cpu (latency) time */
201 timestruc_64 pr_stoptime
; /* stopped time */
202 timestruc_64 filltime
[6]; /* filler for future expansion */
203 uint64_t pr_minf
; /* minor page faults */
204 uint64_t pr_majf
; /* major page faults */
205 uint64_t pr_nswap
; /* swaps */
206 uint64_t pr_inblk
; /* input blocks */
207 uint64_t pr_oublk
; /* output blocks */
208 uint64_t pr_msnd
; /* messages sent */
209 uint64_t pr_mrcv
; /* messages received */
210 uint64_t pr_sigs
; /* signals received */
211 uint64_t pr_vctx
; /* voluntary context switches */
212 uint64_t pr_ictx
; /* involuntary context switches */
213 uint64_t pr_sysc
; /* system calls */
214 uint64_t pr_ioch
; /* chars read and written */
215 uint64_t filler
[10]; /* filler for future expansion */
219 PrUsage::bind64Size ()
221 uint64_t bindSize
= sizeof (raw_prusage_64
);
226 PrUsage::bind64 (void *p
, bool need_swap_endian
)
232 raw_prusage_64 pu
, *tmp
= (raw_prusage_64
*) p
;
233 if (need_swap_endian
)
237 SWAP_ENDIAN (pu
.pr_tstamp
.tv_sec
);
238 SWAP_ENDIAN (pu
.pr_tstamp
.tv_nsec
);
239 SWAP_ENDIAN (pu
.pr_create
.tv_sec
);
240 SWAP_ENDIAN (pu
.pr_create
.tv_nsec
);
241 SWAP_ENDIAN (pu
.pr_term
.tv_sec
);
242 SWAP_ENDIAN (pu
.pr_term
.tv_nsec
);
243 SWAP_ENDIAN (pu
.pr_rtime
.tv_sec
);
244 SWAP_ENDIAN (pu
.pr_rtime
.tv_nsec
);
245 SWAP_ENDIAN (pu
.pr_utime
.tv_sec
);
246 SWAP_ENDIAN (pu
.pr_utime
.tv_nsec
);
247 SWAP_ENDIAN (pu
.pr_stime
.tv_sec
);
248 SWAP_ENDIAN (pu
.pr_stime
.tv_nsec
);
249 SWAP_ENDIAN (pu
.pr_ttime
.tv_sec
);
250 SWAP_ENDIAN (pu
.pr_ttime
.tv_nsec
);
251 SWAP_ENDIAN (pu
.pr_tftime
.tv_sec
);
252 SWAP_ENDIAN (pu
.pr_tftime
.tv_nsec
);
253 SWAP_ENDIAN (pu
.pr_dftime
.tv_sec
);
254 SWAP_ENDIAN (pu
.pr_dftime
.tv_nsec
);
255 SWAP_ENDIAN (pu
.pr_kftime
.tv_sec
);
256 SWAP_ENDIAN (pu
.pr_kftime
.tv_nsec
);
257 SWAP_ENDIAN (pu
.pr_ltime
.tv_sec
);
258 SWAP_ENDIAN (pu
.pr_ltime
.tv_nsec
);
259 SWAP_ENDIAN (pu
.pr_slptime
.tv_sec
);
260 SWAP_ENDIAN (pu
.pr_slptime
.tv_nsec
);
261 SWAP_ENDIAN (pu
.pr_wtime
.tv_sec
);
262 SWAP_ENDIAN (pu
.pr_wtime
.tv_nsec
);
263 SWAP_ENDIAN (pu
.pr_stoptime
.tv_sec
);
264 SWAP_ENDIAN (pu
.pr_stoptime
.tv_nsec
);
265 SWAP_ENDIAN (pu
.pr_minf
);
266 SWAP_ENDIAN (pu
.pr_majf
);
267 SWAP_ENDIAN (pu
.pr_nswap
);
268 SWAP_ENDIAN (pu
.pr_inblk
);
269 SWAP_ENDIAN (pu
.pr_oublk
);
270 SWAP_ENDIAN (pu
.pr_msnd
);
271 SWAP_ENDIAN (pu
.pr_mrcv
);
272 SWAP_ENDIAN (pu
.pr_sigs
);
273 SWAP_ENDIAN (pu
.pr_vctx
);
274 SWAP_ENDIAN (pu
.pr_ictx
);
275 SWAP_ENDIAN (pu
.pr_sysc
);
276 SWAP_ENDIAN (pu
.pr_ioch
);
279 pr_tstamp
= timestruc2hr (tmp
->pr_tstamp
);
280 pr_create
= timestruc2hr (tmp
->pr_create
);
281 pr_term
= timestruc2hr (tmp
->pr_term
);
282 pr_rtime
= timestruc2hr (tmp
->pr_rtime
);
283 pr_utime
= timestruc2hr (tmp
->pr_utime
);
284 pr_stime
= timestruc2hr (tmp
->pr_stime
);
285 pr_ttime
= timestruc2hr (tmp
->pr_ttime
);
286 pr_tftime
= timestruc2hr (tmp
->pr_tftime
);
287 pr_dftime
= timestruc2hr (tmp
->pr_dftime
);
288 pr_kftime
= timestruc2hr (tmp
->pr_kftime
);
289 pr_ltime
= timestruc2hr (tmp
->pr_ltime
);
290 pr_slptime
= timestruc2hr (tmp
->pr_slptime
);
291 pr_wtime
= timestruc2hr (tmp
->pr_wtime
);
292 pr_stoptime
= timestruc2hr (tmp
->pr_stoptime
);
293 pr_minf
= tmp
->pr_minf
;
294 pr_majf
= tmp
->pr_majf
;
295 pr_nswap
= tmp
->pr_nswap
;
296 pr_inblk
= tmp
->pr_inblk
;
297 pr_oublk
= tmp
->pr_oublk
;
298 pr_msnd
= tmp
->pr_msnd
;
299 pr_mrcv
= tmp
->pr_mrcv
;
300 pr_sigs
= tmp
->pr_sigs
;
301 pr_vctx
= tmp
->pr_vctx
;
302 pr_ictx
= tmp
->pr_ictx
;
303 pr_sysc
= tmp
->pr_sysc
;
304 pr_ioch
= tmp
->pr_ioch
;
309 PrUsage::getMstateValues ()
311 const PrUsage
*prusage
= this;
312 Vector
<long long> *states
= new Vector
<long long>;
313 states
->store (0, prusage
->pr_utime
);
314 states
->store (1, prusage
->pr_stime
);
315 states
->store (2, prusage
->pr_ttime
);
316 states
->store (3, prusage
->pr_tftime
);
317 states
->store (4, prusage
->pr_dftime
);
318 states
->store (5, prusage
->pr_kftime
);
319 states
->store (6, prusage
->pr_ltime
);
320 states
->store (7, prusage
->pr_slptime
);
321 states
->store (8, prusage
->pr_wtime
);
322 states
->store (9, prusage
->pr_stoptime
);
323 assert (LMS_NUM_SOLARIS_MSTATES
== states
->size ());
327 void* CommonPacket::jvm_overhead
= NULL
;
329 CommonPacket::CommonPacket ()
331 for (int i
= 0; i
< NTAGS
; i
++)
342 CommonPacket::cmp (const void *a
, const void *b
)
344 if ((*(CommonPacket
**) a
)->tstamp
> (*(CommonPacket
**) b
)->tstamp
)
346 else if ((*(CommonPacket
**) a
)->tstamp
< (*(CommonPacket
**) b
)->tstamp
)
353 CommonPacket::getStack (VMode view_mode
)
355 if (view_mode
== VMODE_MACHINE
)
357 else if (view_mode
== VMODE_USER
)
359 if (jthread_TBR
== JTHREAD_NONE
|| (jthread_TBR
&& jthread_TBR
->is_system ()))
362 else if (view_mode
== VMODE_EXPERT
)
364 Histable
*hist
= CallStack::getStackPC (user_stack
, 0);
365 if (hist
->get_type () == Histable::INSTR
)
367 DbeInstr
*instr
= (DbeInstr
*) hist
;
368 if (instr
->func
== dbeSession
->get_JUnknown_Function ())
371 else if (hist
->get_type () == Histable::LINE
)
373 DbeLine
*line
= (DbeLine
*) hist
;
374 if (line
->func
== dbeSession
->get_JUnknown_Function ())
382 CommonPacket::getStackPC (int n
, VMode view_mode
)
384 return CallStack::getStackPC (getStack (view_mode
), n
);
388 CommonPacket::getStackPCs (VMode view_mode
)
390 return CallStack::getStackPCs (getStack (view_mode
));
394 getStack (VMode view_mode
, DataView
*dview
, long idx
)
397 if (view_mode
== VMODE_MACHINE
)
398 stack
= dview
->getObjValue (PROP_MSTACK
, idx
);
399 else if (view_mode
== VMODE_USER
)
400 stack
= dview
->getObjValue (PROP_USTACK
, idx
);
401 else if (view_mode
== VMODE_EXPERT
)
402 stack
= dview
->getObjValue (PROP_XSTACK
, idx
);
407 stackSize (VMode view_mode
, DataView
*dview
, long idx
)
409 return CallStack::stackSize (getStack (view_mode
, dview
, idx
));
413 getStackPC (int n
, VMode view_mode
, DataView
*dview
, long idx
)
415 return CallStack::getStackPC (getStack (view_mode
, dview
, idx
), n
);
419 getStackPCs (VMode view_mode
, DataView
*dview
, long idx
)
421 return CallStack::getStackPCs (getStack (view_mode
, dview
, idx
));