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. */
25 #include <sys/param.h>
28 #include "DbeSession.h"
29 #include "Experiment.h"
30 #include "Expression.h"
36 BaseMetricTreeNode::BaseMetricTreeNode ()
42 BaseMetricTreeNode::BaseMetricTreeNode (BaseMetric
*item
)
46 name
= dbe_strdup (bm
->get_cmd ());
47 uname
= dbe_strdup (bm
->get_username ());
48 unit
= NULL
; //YXXX populate from base_metric (requires updating base_metric)
52 BaseMetricTreeNode::BaseMetricTreeNode (const char *_name
, const char *_uname
,
53 const char *_unit
, const char *_unit_uname
)
56 name
= dbe_strdup (_name
);
57 uname
= dbe_strdup (_uname
);
58 unit
= dbe_strdup (_unit
);
59 unit_uname
= dbe_strdup (_unit_uname
);
63 BaseMetricTreeNode::init_vars ()
71 children
= new Vector
<BaseMetricTreeNode
*>;
72 isCompositeMetric
= false;
75 num_registered_descendents
= 0;
78 BaseMetricTreeNode::~BaseMetricTreeNode ()
89 BaseMetricTreeNode::register_metric (BaseMetric
*item
)
91 BaseMetricTreeNode
*found
= root
->find (item
->get_cmd ());
94 switch (item
->get_type ())
96 case BaseMetric::CP_TOTAL
:
97 found
= root
->find (L_CP_TOTAL
);
99 case BaseMetric::CP_TOTAL_CPU
:
100 found
= root
->find (L_CP_TOTAL_CPU
);
103 if (found
&& found
->bm
== NULL
)
108 switch (item
->get_type ())
110 case BaseMetric::HEAP_ALLOC_BYTES
:
111 case BaseMetric::HEAP_ALLOC_CNT
:
112 case BaseMetric::HEAP_LEAK_BYTES
:
113 case BaseMetric::HEAP_LEAK_CNT
:
114 found
= root
->find (get_prof_data_type_name (DATA_HEAP
));
116 case BaseMetric::CP_KERNEL_CPU
:
117 case BaseMetric::CP_TOTAL
:
118 found
= root
->find (get_prof_data_type_name (DATA_CLOCK
));
120 case BaseMetric::CP_LMS_DFAULT
:
121 case BaseMetric::CP_LMS_TFAULT
:
122 case BaseMetric::CP_LMS_KFAULT
:
123 case BaseMetric::CP_LMS_STOPPED
:
124 case BaseMetric::CP_LMS_WAIT_CPU
:
125 case BaseMetric::CP_LMS_SLEEP
:
126 case BaseMetric::CP_LMS_USER_LOCK
:
127 case BaseMetric::CP_TOTAL_CPU
:
128 found
= root
->find (L_CP_TOTAL
);
130 case BaseMetric::CP_LMS_USER
:
131 case BaseMetric::CP_LMS_SYSTEM
:
132 case BaseMetric::CP_LMS_TRAP
:
133 found
= root
->find (L_CP_TOTAL_CPU
);
135 case BaseMetric::HWCNTR
:
136 found
= root
->find ((item
->get_flavors () & BaseMetric::DATASPACE
) != 0 ?
137 L2_HWC_DSPACE
: L2_HWC_GENERAL
);
139 case BaseMetric::SYNC_WAIT_TIME
:
140 case BaseMetric::SYNC_WAIT_COUNT
:
141 found
= root
->find (get_prof_data_type_name (DATA_SYNCH
));
143 case BaseMetric::OMP_WORK
:
144 case BaseMetric::OMP_WAIT
:
145 case BaseMetric::OMP_OVHD
:
146 found
= root
->find (get_prof_data_type_name (DATA_OMP
));
148 case BaseMetric::IO_READ_TIME
:
149 case BaseMetric::IO_READ_BYTES
:
150 case BaseMetric::IO_READ_CNT
:
151 case BaseMetric::IO_WRITE_TIME
:
152 case BaseMetric::IO_WRITE_BYTES
:
153 case BaseMetric::IO_WRITE_CNT
:
154 case BaseMetric::IO_OTHER_TIME
:
155 case BaseMetric::IO_OTHER_CNT
:
156 case BaseMetric::IO_ERROR_TIME
:
157 case BaseMetric::IO_ERROR_CNT
:
158 found
= root
->find (get_prof_data_type_name (DATA_IOTRACE
));
160 case BaseMetric::ONAME
:
161 case BaseMetric::SIZES
:
162 case BaseMetric::ADDRESS
:
163 found
= root
->find (L1_STATIC
);
166 found
= root
->find (L1_OTHER
);
169 assert (found
!= NULL
);
170 switch (item
->get_type ())
172 case BaseMetric::CP_TOTAL
:
173 case BaseMetric::CP_TOTAL_CPU
:
174 found
->isCompositeMetric
= true;
177 found
= found
->add_child (item
);
179 register_node (found
);
184 BaseMetricTreeNode::register_node (BaseMetricTreeNode
*node
)
186 if (!node
->registered
)
188 node
->registered
= true;
189 BaseMetricTreeNode
*tmp
= node
->parent
;
192 tmp
->num_registered_descendents
++;
199 BaseMetricTreeNode::find (const char *_name
)
201 BaseMetricTreeNode
*found
= NULL
;
202 if (dbe_strcmp (get_name (), _name
) == 0)
204 if (bm
&& dbe_strcmp (bm
->get_cmd (), _name
) == 0)
206 BaseMetricTreeNode
*child
;
209 Vec_loop (BaseMetricTreeNode
*, children
, index
, child
)
211 found
= child
->find (_name
);
219 int_get_registered_descendents (BaseMetricTreeNode
* curr
,
220 Vector
<BaseMetricTreeNode
*> *dest
, bool nearest_only
)
224 if (curr
->is_registered ())
228 return; // soon as we hit a live node, stop following branch
231 BaseMetricTreeNode
*child
;
233 Vec_loop (BaseMetricTreeNode
*, curr
->get_children (), index
, child
)
235 int_get_registered_descendents (child
, dest
, nearest_only
);
240 BaseMetricTreeNode::get_nearest_registered_descendents (Vector
<BaseMetricTreeNode
*> *dest
)
242 if (!dest
|| dest
->size () != 0)
244 bool nearest_only
= true;
245 int_get_registered_descendents (this, dest
, nearest_only
);
249 BaseMetricTreeNode::get_all_registered_descendents (Vector
<BaseMetricTreeNode
*> *dest
)
251 if (!dest
|| dest
->size () != 0)
253 bool nearest_only
= false;
254 int_get_registered_descendents (this, dest
, nearest_only
);
258 BaseMetricTreeNode::get_description ()
262 Hwcentry
* hw_ctr
= bm
->get_hw_ctr ();
264 return hw_ctr
->short_desc
;
270 BaseMetricTreeNode::build_basic_tree ()
272 #define TREE_INSERT_DATA_TYPE(t) add_child(get_prof_data_type_name (t), get_prof_data_type_uname (t))
273 BaseMetricTreeNode
*level1
, *level2
;
274 // register L1_DURATION here because it has a value but is not a true metric
275 register_node (add_child (L1_DURATION
, L1_DURATION_UNAME
, UNIT_SECONDS
,
276 UNIT_SECONDS_UNAME
));
277 register_node (add_child (L1_GCDURATION
, L1_GCDURATION_UNAME
, UNIT_SECONDS
,
278 UNIT_SECONDS_UNAME
));
279 TREE_INSERT_DATA_TYPE (DATA_HEAP
);
280 level1
= TREE_INSERT_DATA_TYPE (DATA_CLOCK
);
281 level1
= level1
->add_child (L_CP_TOTAL
, GTXT ("XXX Total Thread Time"));
282 level1
->isCompositeMetric
= true;
283 level2
= level1
->add_child (L_CP_TOTAL_CPU
, GTXT ("XXX Total CPU Time"));
284 level2
->isCompositeMetric
= true;
286 add_child (L1_OTHER
, L1_OTHER_UNAME
);
287 level1
= TREE_INSERT_DATA_TYPE (DATA_HWC
);
288 level1
->add_child (L2_HWC_DSPACE
, L2_HWC_DSPACE_UNAME
);
289 level1
->add_child (L2_HWC_GENERAL
, L2_HWC_GENERAL_UNAME
);
290 TREE_INSERT_DATA_TYPE (DATA_SYNCH
);
291 TREE_INSERT_DATA_TYPE (DATA_OMP
);
292 TREE_INSERT_DATA_TYPE (DATA_IOTRACE
);
293 add_child (L1_STATIC
, L1_STATIC_UNAME
);
297 BaseMetricTreeNode::add_child (BaseMetric
*item
)
299 return add_child (new BaseMetricTreeNode (item
));
303 BaseMetricTreeNode::add_child (const char * _name
, const char *_uname
,
304 const char * _unit
, const char * _unit_uname
)
306 return add_child (new BaseMetricTreeNode (_name
, _uname
, _unit
, _unit_uname
));
310 BaseMetricTreeNode::add_child (BaseMetricTreeNode
*new_node
)
312 new_node
->parent
= this;
313 new_node
->root
= root
;
314 children
->append (new_node
);
319 BaseMetricTreeNode::dump ()
322 char *s
= bm
? bm
->dump () : dbe_strdup ("<no base metric>");
323 char *msg
= dbe_sprintf ("%s\n%*c %*c unit='%s' unit_uname='%s' uname='%s' name='%s'\n",
324 STR (s
), len
, ' ', len
, ' ',
325 STR (get_unit_uname ()), STR (get_unit ()),
326 STR (get_user_name ()), STR (get_name ()));