]> Git Repo - binutils.git/blob - gprofng/src/BaseMetricTreeNode.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / BaseMetricTreeNode.cc
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2    Contributed by Oracle.
3
4    This file is part of GNU Binutils.
5
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)
9    any later version.
10
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.
15
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.  */
20
21 #include "config.h"
22 #include <stdio.h>
23 #include <strings.h>
24 #include <limits.h>
25 #include <sys/param.h>
26
27 #include "hwcentry.h"
28 #include "DbeSession.h"
29 #include "Experiment.h"
30 #include "Expression.h"
31 #include "Metric.h"
32 #include "Table.h"
33 #include "i18n.h"
34 #include "debug.h"
35
36 BaseMetricTreeNode::BaseMetricTreeNode ()
37 {
38   init_vars ();
39   build_basic_tree ();
40 }
41
42 BaseMetricTreeNode::BaseMetricTreeNode (BaseMetric *item)
43 {
44   init_vars ();
45   bm = 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)
49   unit_uname = NULL;
50 }
51
52 BaseMetricTreeNode::BaseMetricTreeNode (const char *_name, const char *_uname,
53                                     const char *_unit, const char *_unit_uname)
54 {
55   init_vars ();
56   name = dbe_strdup (_name);
57   uname = dbe_strdup (_uname);
58   unit = dbe_strdup (_unit);
59   unit_uname = dbe_strdup (_unit_uname);
60 }
61
62 void
63 BaseMetricTreeNode::init_vars ()
64 {
65   name = NULL;
66   uname = NULL;
67   unit = NULL;
68   unit_uname = NULL;
69   root = this;
70   parent = NULL;
71   children = new Vector<BaseMetricTreeNode*>;
72   isCompositeMetric = false;
73   bm = NULL;
74   registered = false;
75   num_registered_descendents = 0;
76 }
77
78 BaseMetricTreeNode::~BaseMetricTreeNode ()
79 {
80   children->destroy ();
81   delete children;
82   free (name);
83   free (uname);
84   free (unit);
85   free (unit_uname);
86 }
87
88 BaseMetricTreeNode *
89 BaseMetricTreeNode::register_metric (BaseMetric *item)
90 {
91   BaseMetricTreeNode *found = root->find (item->get_cmd ());
92   if (!found)
93     {
94       switch (item->get_type ())
95         {
96         case BaseMetric::CP_TOTAL:
97           found = root->find (L_CP_TOTAL);
98           break;
99         case BaseMetric::CP_TOTAL_CPU:
100           found = root->find (L_CP_TOTAL_CPU);
101           break;
102         }
103       if (found && found->bm == NULL)
104         found->bm = item;
105     }
106   if (!found)
107     {
108       switch (item->get_type ())
109         {
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));
115           break;
116         case BaseMetric::CP_KERNEL_CPU:
117         case BaseMetric::CP_TOTAL:
118           found = root->find (get_prof_data_type_name (DATA_CLOCK));
119           break;
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);
129           break;
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);
134           break;
135         case BaseMetric::HWCNTR:
136           found = root->find ((item->get_flavors () & BaseMetric::DATASPACE) != 0 ?
137                               L2_HWC_DSPACE : L2_HWC_GENERAL);
138           break;
139         case BaseMetric::SYNC_WAIT_TIME:
140         case BaseMetric::SYNC_WAIT_COUNT:
141           found = root->find (get_prof_data_type_name (DATA_SYNCH));
142           break;
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));
147           break;
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));
159           break;
160         case BaseMetric::ONAME:
161         case BaseMetric::SIZES:
162         case BaseMetric::ADDRESS:
163           found = root->find (L1_STATIC);
164           break;
165         default:
166           found = root->find (L1_OTHER);
167           break;
168         }
169       assert (found != NULL);
170       switch (item->get_type ())
171         {
172         case BaseMetric::CP_TOTAL:
173         case BaseMetric::CP_TOTAL_CPU:
174           found->isCompositeMetric = true;
175           break;
176         }
177       found = found->add_child (item);
178     }
179   register_node (found);
180   return found;
181 }
182
183 void
184 BaseMetricTreeNode::register_node (BaseMetricTreeNode *node)
185 {
186   if (!node->registered)
187     {
188       node->registered = true;
189       BaseMetricTreeNode *tmp = node->parent;
190       while (tmp)
191         {
192           tmp->num_registered_descendents++;
193           tmp = tmp->parent;
194         }
195     }
196 }
197
198 BaseMetricTreeNode *
199 BaseMetricTreeNode::find (const char *_name)
200 {
201   BaseMetricTreeNode *found = NULL;
202   if (dbe_strcmp (get_name (), _name) == 0)
203     return this;
204   if (bm && dbe_strcmp (bm->get_cmd (), _name) == 0)
205     return this;
206   BaseMetricTreeNode *child;
207   int index;
208
209   Vec_loop (BaseMetricTreeNode*, children, index, child)
210   {
211     found = child->find (_name);
212     if (found)
213       return found;
214   }
215   return NULL;
216 }
217
218 static void
219 int_get_registered_descendents (BaseMetricTreeNode* curr,
220                           Vector<BaseMetricTreeNode*> *dest, bool nearest_only)
221 {
222   if (!curr)
223     return;
224   if (curr->is_registered ())
225     {
226       dest->append (curr);
227       if (nearest_only)
228         return; // soon as we hit a live node, stop following branch
229     }
230   int index;
231   BaseMetricTreeNode *child;
232
233   Vec_loop (BaseMetricTreeNode*, curr->get_children (), index, child)
234   {
235     int_get_registered_descendents (child, dest, nearest_only);
236   }
237 }
238
239 void
240 BaseMetricTreeNode::get_nearest_registered_descendents (Vector<BaseMetricTreeNode*> *dest)
241 {
242   if (!dest || dest->size () != 0)
243     abort ();
244   bool nearest_only = true;
245   int_get_registered_descendents (this, dest, nearest_only);
246 }
247
248 void
249 BaseMetricTreeNode::get_all_registered_descendents (Vector<BaseMetricTreeNode*> *dest)
250 {
251   if (!dest || dest->size () != 0)
252     abort ();
253   bool nearest_only = false;
254   int_get_registered_descendents (this, dest, nearest_only);
255 }
256
257 char *
258 BaseMetricTreeNode::get_description ()
259 {
260   if (bm)
261     {
262       Hwcentry* hw_ctr = bm->get_hw_ctr ();
263       if (hw_ctr)
264         return hw_ctr->short_desc;
265     }
266   return NULL;
267 }
268
269 void
270 BaseMetricTreeNode::build_basic_tree ()
271 {
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;
285
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);
294 }
295
296 BaseMetricTreeNode *
297 BaseMetricTreeNode::add_child (BaseMetric *item)
298 {
299   return add_child (new BaseMetricTreeNode (item));
300 }
301
302 BaseMetricTreeNode *
303 BaseMetricTreeNode::add_child (const char * _name, const char *_uname,
304                                const char * _unit, const char * _unit_uname)
305 {
306   return add_child (new BaseMetricTreeNode (_name, _uname, _unit, _unit_uname));
307 }
308
309 BaseMetricTreeNode *
310 BaseMetricTreeNode::add_child (BaseMetricTreeNode *new_node)
311 {
312   new_node->parent = this;
313   new_node->root = root;
314   children->append (new_node);
315   return new_node;
316 }
317
318 char *
319 BaseMetricTreeNode::dump ()
320 {
321   int len = 4;
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 ()));
327   free (s);
328   return msg;
329 }
This page took 0.042082 seconds and 4 git commands to generate.