]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/src/BaseMetric.cc
gprofng: a new GNU profiler
[thirdparty/binutils-gdb.git] / gprofng / src / BaseMetric.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 <strings.h>
23 #include <stdlib.h>
24
25 #include "util.h"
26 #include "BaseMetric.h"
27 #include "DbeSession.h"
28 #include "Expression.h"
29
30 int BaseMetric::last_id = 0;
31
32 void
33 BaseMetric::init (Type t)
34 {
35 id = last_id++;
36 type = t;
37 aux = NULL;
38 cmd = NULL;
39 username = NULL;
40 hw_ctr = NULL;
41 cond = NULL;
42 val = NULL;
43 expr = NULL;
44 cond_spec = NULL;
45 val_spec = NULL;
46 expr_spec = NULL;
47 legend = NULL;
48 definition = NULL;
49 dependent_bm = NULL;
50 zeroThreshold = 0;
51 clock_unit = (Presentation_clock_unit) 0;
52 for (int ii = 0; ii < NSUBTYPES; ii++)
53 default_visbits[ii] = VAL_NA;
54 valtype = VT_DOUBLE;
55 precision = METRIC_HR_PRECISION;
56 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
57 value_styles = VAL_TIMEVAL | VAL_PERCENT;
58 }
59
60 BaseMetric::BaseMetric (Type t)
61 {
62 init (t);
63 switch (t)
64 {
65 case CP_LMS_USER:
66 case CP_LMS_SYSTEM:
67 case CP_LMS_WAIT_CPU:
68 case CP_LMS_USER_LOCK:
69 case CP_LMS_TFAULT:
70 case CP_LMS_DFAULT:
71 case OMP_MASTER_THREAD:
72 case CP_TOTAL:
73 case CP_TOTAL_CPU:
74 case CP_LMS_TRAP:
75 case CP_LMS_KFAULT:
76 case CP_LMS_SLEEP:
77 case CP_LMS_STOPPED:
78 case OMP_NONE:
79 case OMP_OVHD:
80 case OMP_WORK:
81 case OMP_IBAR:
82 case OMP_EBAR:
83 case OMP_WAIT:
84 case OMP_SERL:
85 case OMP_RDUC:
86 case OMP_LKWT:
87 case OMP_CTWT:
88 case OMP_ODWT:
89 case OMP_MSTR:
90 case OMP_SNGL:
91 case OMP_ORDD:
92 case CP_KERNEL_CPU:
93 // all of these are floating point, precision = clock profile tick
94 valtype = VT_DOUBLE;
95 precision = METRIC_SIG_PRECISION;
96 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
97 value_styles = VAL_TIMEVAL | VAL_PERCENT;
98 break;
99 case SYNC_WAIT_TIME:
100 case IO_READ_TIME:
101 case IO_WRITE_TIME:
102 case IO_OTHER_TIME:
103 case IO_ERROR_TIME:
104 // all of these are floating point, precision = hrtime tick
105 valtype = VT_DOUBLE;
106 precision = METRIC_HR_PRECISION;
107 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
108 value_styles = VAL_TIMEVAL | VAL_PERCENT;
109 break;
110 case SYNC_WAIT_COUNT:
111 case HEAP_ALLOC_CNT:
112 case HEAP_LEAK_CNT:
113 case IO_READ_CNT:
114 case IO_WRITE_CNT:
115 case IO_OTHER_CNT:
116 case IO_ERROR_CNT:
117 valtype = VT_LLONG;
118 precision = 1;
119 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
120 value_styles = VAL_VALUE | VAL_PERCENT;
121 break;
122 case RACCESS:
123 case DEADLOCKS:
124 // all of these are integer
125 valtype = VT_LLONG;
126 precision = 1;
127 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
128 value_styles = VAL_VALUE | VAL_PERCENT;
129 zeroThreshold = 1;
130 break;
131 case HEAP_ALLOC_BYTES:
132 case HEAP_LEAK_BYTES:
133 case IO_READ_BYTES:
134 case IO_WRITE_BYTES:
135 // all of these are longlong
136 valtype = VT_ULLONG;
137 precision = 1;
138 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
139 value_styles = VAL_VALUE | VAL_PERCENT;
140 break;
141 case SIZES:
142 valtype = VT_LLONG;
143 precision = 1;
144 flavors = STATIC;
145 value_styles = VAL_VALUE;
146 break;
147 case ADDRESS:
148 valtype = VT_ADDRESS;
149 precision = 1;
150 flavors = STATIC;
151 value_styles = VAL_VALUE;
152 break;
153 case ONAME:
154 valtype = VT_LABEL;
155 precision = 0;
156 flavors = STATIC;
157 value_styles = VAL_VALUE;
158 break;
159 case HWCNTR: // We should call the other constructor for hwc metric
160 default:
161 abort ();
162 }
163 specify ();
164 }
165
166 // Constructor for linked HW counters (base counter)
167 BaseMetric::BaseMetric (Hwcentry *ctr, const char* _aux, const char* _username,
168 int v_styles, BaseMetric* _dependent_bm)
169 {
170 hwc_init (ctr, _aux, _aux, _username, v_styles);
171 dependent_bm = _dependent_bm;
172 }
173
174 // Constructor for linked HW counters (derived counter)
175
176 BaseMetric::BaseMetric (Hwcentry *ctr, const char *_aux, const char *_cmdname,
177 const char *_username, int v_styles)
178 {
179 hwc_init (ctr, _aux, _cmdname, _username, v_styles);
180 }
181
182 void
183 BaseMetric::hwc_init (Hwcentry *ctr, const char* _aux, const char* _cmdname,
184 const char* _username, int v_styles)
185 {
186 init (HWCNTR);
187 aux = dbe_strdup (_aux); // HWC identifier
188 cmd = dbe_strdup (_cmdname); // may differ from _aux for cycles->time hwcs
189 username = dbe_strdup (_username);
190 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
191 value_styles = v_styles | VAL_PERCENT;
192 if ((value_styles & (VAL_TIMEVAL | VAL_VALUE)) == VAL_TIMEVAL)
193 valtype = VT_DOUBLE;
194 else
195 valtype = VT_ULLONG;
196 if (ABST_MEMSPACE_ENABLED (ctr->memop))
197 flavors |= DATASPACE; // only for ctrs with memop definitions
198 hw_ctr = ctr;
199 specify ();
200 }
201
202 // Constructor for derived metrics
203 BaseMetric::BaseMetric (const char *_cmd, const char *_username,
204 Definition *def)
205 {
206 init (DERIVED);
207 cmd = dbe_strdup (_cmd);
208 username = dbe_strdup (_username);
209 aux = dbe_strdup (_cmd);
210 definition = def;
211 flavors = EXCLUSIVE | INCLUSIVE | ATTRIBUTED;
212 clock_unit = CUNIT_NULL; // should it be CUNIT_TIME or 0 or something?
213
214 /* we're not going to process packets for derived metrics */
215 packet_type = (ProfData_type) (-1);
216 value_styles = VAL_VALUE;
217 valtype = VT_DOUBLE;
218 precision = 1000;
219 }
220
221 // Copy constructor
222 BaseMetric::BaseMetric (const BaseMetric& m)
223 {
224 id = m.id;
225 type = m.type;
226 aux = dbe_strdup (m.aux);
227 cmd = dbe_strdup (m.cmd);
228 username = dbe_strdup (m.username);
229 flavors = m.flavors;
230 value_styles = m.value_styles;
231 valtype = m.valtype;
232 precision = m.precision;
233 hw_ctr = m.hw_ctr;
234 packet_type = m.packet_type;
235 zeroThreshold = m.zeroThreshold;
236 clock_unit = m.clock_unit;
237 for (int ii = 0; ii < NSUBTYPES; ii++)
238 default_visbits[ii] = m.default_visbits[ii];
239 if (m.cond_spec)
240 {
241 cond_spec = strdup (m.cond_spec);
242 cond = m.cond->copy ();
243 }
244 else
245 {
246 cond = NULL;
247 cond_spec = NULL;
248 }
249 if (m.val_spec)
250 {
251 val_spec = strdup (m.val_spec);
252 val = m.val->copy ();
253 }
254 else
255 {
256 val = NULL;
257 val_spec = NULL;
258 }
259 if (m.expr_spec)
260 {
261 expr_spec = strdup (m.expr_spec);
262 expr = m.expr->copy ();
263 }
264 else
265 {
266 expr = NULL;
267 expr_spec = NULL;
268 }
269 legend = dbe_strdup (m.legend);
270 definition = NULL;
271 if (m.definition)
272 definition = Definition::add_definition (m.definition->def);
273 dependent_bm = m.dependent_bm;
274 }
275
276 BaseMetric::~BaseMetric ()
277 {
278 free (aux);
279 free (cmd);
280 free (cond_spec);
281 free (val_spec);
282 free (expr_spec);
283 free (legend);
284 free (username);
285 delete cond;
286 delete val;
287 delete expr;
288 delete definition;
289 }
290
291 bool
292 BaseMetric::is_internal ()
293 {
294 return (get_value_styles () & VAL_INTERNAL) != 0;
295 }
296
297 int
298 BaseMetric::get_default_visbits (SubType subtype)
299 {
300 int rc = VAL_NA;
301 switch (subtype)
302 {
303 case STATIC:
304 case EXCLUSIVE:
305 rc = default_visbits[0];
306 break;
307 case INCLUSIVE:
308 rc = default_visbits[1];
309 break;
310 default:
311 break;
312 }
313 return rc;
314 }
315
316 void
317 BaseMetric::set_default_visbits (SubType subtype, int _visbits)
318 {
319 switch (subtype)
320 {
321 case STATIC:
322 case EXCLUSIVE:
323 default_visbits[0] = _visbits;
324 break;
325 case INCLUSIVE:
326 default_visbits[1] = _visbits;
327 break;
328 default:
329 break;
330 }
331 }
332
333 void
334 BaseMetric::set_cond_spec (char *_cond_spec)
335 {
336 if (cond_spec)
337 {
338 free (cond_spec);
339 delete cond;
340 cond_spec = NULL;
341 cond = NULL;
342 }
343 if (_cond_spec)
344 {
345 cond = dbeSession->ql_parse (_cond_spec);
346 if (cond == NULL)
347 {
348 fprintf (stderr, GTXT ("Invalid expression in metric specification `%s'\n"), _cond_spec);
349 abort ();
350 }
351 cond_spec = dbe_strdup (_cond_spec);
352 }
353 }
354
355 void
356 BaseMetric::set_val_spec (char *_val_spec)
357 {
358 if (val_spec)
359 {
360 free (val_spec);
361 delete val;
362 val_spec = NULL;
363 val = NULL;
364 }
365 if (_val_spec)
366 {
367 val = dbeSession->ql_parse (_val_spec);
368 if (val == NULL)
369 {
370 fprintf (stderr, GTXT ("Invalid expression in metric specification `%s'\n"), _val_spec);
371 abort ();
372 }
373 val_spec = dbe_strdup (_val_spec);
374 }
375 }
376
377 void
378 BaseMetric::set_expr_spec (char *_expr_spec)
379 {
380 id = last_id++;
381 if (expr_spec)
382 {
383 free (expr_spec);
384 delete expr;
385 expr_spec = NULL;
386 expr = NULL;
387 }
388 if (_expr_spec)
389 {
390 expr = dbeSession->ql_parse (_expr_spec);
391 if (expr == NULL)
392 {
393 fprintf (stderr, GTXT ("Invalid expression in metric specification `%s'\n"), _expr_spec);
394 return;
395 }
396 expr_spec = dbe_strdup (_expr_spec);
397 }
398 }
399
400 void
401 BaseMetric::specify_mstate_metric (int st)
402 {
403 char buf[128];
404 snprintf (buf, sizeof (buf), NTXT ("MSTATE==%d"), st);
405 specify_prof_metric (buf);
406 }
407
408 void
409 BaseMetric::specify_ompstate_metric (int st)
410 {
411 char buf[128];
412 snprintf (buf, sizeof (buf), NTXT ("OMPSTATE==%d"), st);
413 specify_prof_metric (buf);
414 }
415
416 void
417 BaseMetric::specify_prof_metric (char *_cond_spec)
418 {
419 packet_type = DATA_CLOCK;
420 specify_metric (_cond_spec, NTXT ("NTICK_USEC")); // microseconds
421 }
422
423 void
424 BaseMetric::specify_metric (char *_cond_spec, char *_val_spec)
425 {
426 set_cond_spec (_cond_spec);
427 set_val_spec (_val_spec);
428 }
429
430 void
431 BaseMetric::specify ()
432 {
433 enum
434 {
435 IDLE_STATE_BITS =
436 (1 << OMP_IDLE_STATE) | (1 << OMP_IBAR_STATE) | (1 << OMP_EBAR_STATE) |
437 (1 << OMP_LKWT_STATE) | (1 << OMP_CTWT_STATE) | (1 << OMP_ODWT_STATE) |
438 (1 << OMP_ATWT_STATE) | (1 << OMP_TSKWT_STATE),
439 LMS_USER_BITS =
440 (1 << OMP_NO_STATE) | (1 << OMP_WORK_STATE) | (1 << OMP_SERL_STATE) |
441 (1 << OMP_RDUC_STATE)
442 };
443
444 char buf[256];
445 char buf2[256];
446 packet_type = (ProfData_type) - 1; // illegal value
447 clock_unit = CUNIT_TIME;
448 switch (type)
449 {
450 case SIZES:
451 username = dbe_strdup (GTXT ("Size"));
452 clock_unit = CUNIT_BYTES;
453 cmd = dbe_strdup (NTXT ("size"));
454 break;
455 case ADDRESS:
456 username = dbe_strdup (GTXT ("PC Address"));
457 cmd = dbe_strdup (NTXT ("address"));
458 break;
459 case ONAME:
460 username = dbe_strdup (GTXT ("Name"));
461 cmd = dbe_strdup (NTXT ("name"));
462 break;
463 case CP_LMS_SYSTEM:
464 username = dbe_strdup (GTXT ("System CPU Time"));
465 specify_mstate_metric (LMS_SYSTEM);
466 cmd = dbe_strdup (NTXT ("system"));
467 break;
468 case CP_TOTAL_CPU:
469 username = dbe_strdup (GTXT ("Total CPU Time"));
470 snprintf (buf, sizeof (buf),
471 "(MSTATE==%d)||(MSTATE==%d)||(MSTATE==%d)||(MSTATE==%d)",
472 LMS_USER, LMS_SYSTEM, LMS_TRAP, LMS_LINUX_CPU);
473 specify_prof_metric (buf);
474 cmd = dbe_strdup (NTXT ("totalcpu"));
475 break;
476 case CP_TOTAL:
477 username = dbe_strdup (GTXT ("Total Thread Time"));
478 snprintf (buf, sizeof (buf), NTXT ("(MSTATE!=%d)&&(MSTATE!=%d)"),
479 LMS_KERNEL_CPU, LMS_LINUX_CPU);
480 specify_prof_metric (buf);
481 cmd = dbe_strdup (NTXT ("total"));
482 break;
483 case CP_KERNEL_CPU:
484 username = dbe_strdup (GTXT ("Kernel CPU Time"));
485 specify_mstate_metric (LMS_KERNEL_CPU);
486 cmd = dbe_strdup (NTXT ("kcpu"));
487 break;
488 case OMP_MASTER_THREAD:
489 username = dbe_strdup (GTXT ("Master Thread Time"));
490 specify_prof_metric (NTXT ("LWPID==1"));
491 cmd = dbe_strdup (NTXT ("masterthread"));
492 break;
493 case CP_LMS_USER:
494 username = dbe_strdup (GTXT ("User CPU Time"));
495 specify_mstate_metric (LMS_USER);
496 cmd = dbe_strdup (NTXT ("user"));
497 break;
498 case CP_LMS_WAIT_CPU:
499 username = dbe_strdup (GTXT ("Wait CPU Time"));
500 specify_mstate_metric (LMS_WAIT_CPU);
501 cmd = dbe_strdup (NTXT ("wait"));
502 break;
503 case CP_LMS_USER_LOCK:
504 username = dbe_strdup (GTXT ("User Lock Time"));
505 specify_mstate_metric (LMS_USER_LOCK);
506 cmd = dbe_strdup (NTXT ("lock"));
507 break;
508 case CP_LMS_TFAULT:
509 username = dbe_strdup (GTXT ("Text Page Fault Time"));
510 specify_mstate_metric (LMS_TFAULT);
511 cmd = dbe_strdup (NTXT ("textpfault"));
512 break;
513 case CP_LMS_DFAULT:
514 username = dbe_strdup (GTXT ("Data Page Fault Time"));
515 specify_mstate_metric (LMS_DFAULT);
516 cmd = dbe_strdup (NTXT ("datapfault"));
517 break;
518 case CP_LMS_TRAP:
519 username = dbe_strdup (GTXT ("Trap CPU Time"));
520 specify_mstate_metric (LMS_TRAP);
521 cmd = dbe_strdup (NTXT ("trap"));
522 break;
523 case CP_LMS_KFAULT:
524 username = dbe_strdup (GTXT ("Kernel Page Fault Time"));
525 specify_mstate_metric (LMS_KFAULT);
526 cmd = dbe_strdup (NTXT ("kernelpfault"));
527 break;
528 case CP_LMS_SLEEP:
529 username = dbe_strdup (GTXT ("Sleep Time"));
530 specify_mstate_metric (LMS_SLEEP);
531 cmd = dbe_strdup (NTXT ("sleep"));
532 break;
533 case CP_LMS_STOPPED:
534 username = dbe_strdup (GTXT ("Stopped Time"));
535 specify_mstate_metric (LMS_STOPPED);
536 cmd = dbe_strdup (NTXT ("stop"));
537 break;
538 case OMP_OVHD:
539 username = dbe_strdup (GTXT ("OpenMP Overhead Time"));
540 specify_ompstate_metric (OMP_OVHD_STATE);
541 cmd = dbe_strdup (NTXT ("ompovhd"));
542 break;
543 case OMP_WORK:
544 username = dbe_strdup (GTXT ("OpenMP Work Time"));
545 snprintf (buf, sizeof (buf),
546 NTXT ("(OMPSTATE>=0) && (MSTATE==%d) && ((1<<OMPSTATE) & %d)"),
547 LMS_USER, LMS_USER_BITS);
548 specify_prof_metric (buf);
549 cmd = dbe_strdup (NTXT ("ompwork"));
550 break;
551 case OMP_WAIT:
552 username = dbe_strdup (GTXT ("OpenMP Wait Time"));
553 snprintf (buf, sizeof (buf),
554 "OMPSTATE>=0 && ((1<<OMPSTATE) & ((MSTATE!=%d) ? %d : %d))",
555 LMS_USER, (LMS_USER_BITS | IDLE_STATE_BITS), IDLE_STATE_BITS);
556 specify_prof_metric (buf);
557 cmd = dbe_strdup (NTXT ("ompwait"));
558 break;
559 case OMP_IBAR:
560 username = dbe_strdup (GTXT ("OpenMP Implicit Barrier Time"));
561 specify_ompstate_metric (OMP_IBAR_STATE);
562 cmd = dbe_strdup (NTXT ("ompibar"));
563 break;
564 case OMP_EBAR:
565 username = dbe_strdup (GTXT ("OpenMP Explicit Barrier Time"));
566 specify_ompstate_metric (OMP_EBAR_STATE);
567 cmd = dbe_strdup (NTXT ("ompebar"));
568 break;
569 case OMP_SERL:
570 username = dbe_strdup (GTXT ("OpenMP Serial Time"));
571 specify_ompstate_metric (OMP_SERL_STATE);
572 cmd = dbe_strdup (NTXT ("ompserl"));
573 break;
574 case OMP_RDUC:
575 username = dbe_strdup (GTXT ("OpenMP Reduction Time"));
576 specify_ompstate_metric (OMP_RDUC_STATE);
577 cmd = dbe_strdup (NTXT ("omprduc"));
578 break;
579 case OMP_LKWT:
580 username = dbe_strdup (GTXT ("OpenMP Lock Wait Time"));
581 specify_ompstate_metric (OMP_LKWT_STATE);
582 cmd = dbe_strdup (NTXT ("omplkwt"));
583 break;
584 case OMP_CTWT:
585 username = dbe_strdup (GTXT ("OpenMP Critical Section Wait Time"));
586 specify_ompstate_metric (OMP_CTWT_STATE);
587 cmd = dbe_strdup (NTXT ("ompctwt"));
588 break;
589 case OMP_ODWT:
590 username = dbe_strdup (GTXT ("OpenMP Ordered Section Wait Time"));
591 specify_ompstate_metric (OMP_ODWT_STATE);
592 cmd = dbe_strdup (NTXT ("ompodwt"));
593 break;
594 case SYNC_WAIT_TIME:
595 packet_type = DATA_SYNCH;
596 username = dbe_strdup (GTXT ("Sync Wait Time"));
597 snprintf (buf, sizeof (buf), NTXT ("(EVT_TIME)/%lld"),
598 (long long) (NANOSEC / METRIC_HR_PRECISION));
599 specify_metric (NULL, buf);
600 cmd = dbe_strdup (NTXT ("sync"));
601 break;
602 case SYNC_WAIT_COUNT:
603 packet_type = DATA_SYNCH;
604 username = dbe_strdup (GTXT ("Sync Wait Count"));
605 specify_metric (NULL, NTXT ("1"));
606 cmd = dbe_strdup (NTXT ("syncn"));
607 break;
608 case HEAP_ALLOC_CNT:
609 packet_type = DATA_HEAP;
610 username = dbe_strdup (GTXT ("Allocations"));
611 snprintf (buf, sizeof (buf), NTXT ("(HTYPE!=%d)&&(HTYPE!=%d)&&HVADDR"),
612 FREE_TRACE, MUNMAP_TRACE);
613 specify_metric (buf, NTXT ("1"));
614 cmd = dbe_strdup (NTXT ("heapalloccnt"));
615 break;
616 case HEAP_ALLOC_BYTES:
617 packet_type = DATA_HEAP;
618 username = dbe_strdup (GTXT ("Bytes Allocated"));
619 snprintf (buf, sizeof (buf), NTXT ("(HTYPE!=%d)&&(HTYPE!=%d)&&HVADDR"),
620 FREE_TRACE, MUNMAP_TRACE);
621 specify_metric (buf, NTXT ("HSIZE"));
622 cmd = dbe_strdup (NTXT ("heapallocbytes"));
623 break;
624 case HEAP_LEAK_CNT:
625 packet_type = DATA_HEAP;
626 username = dbe_strdup (GTXT ("Leaks"));
627 snprintf (buf, sizeof (buf), "(HTYPE!=%d)&&(HTYPE!=%d)&&HVADDR&&HLEAKED",
628 FREE_TRACE, MUNMAP_TRACE);
629 specify_metric (buf, NTXT ("1"));
630 cmd = dbe_strdup (NTXT ("heapleakcnt"));
631 break;
632 case HEAP_LEAK_BYTES:
633 packet_type = DATA_HEAP;
634 username = dbe_strdup (GTXT ("Bytes Leaked"));
635 snprintf (buf, sizeof (buf), NTXT ("(HTYPE!=%d)&&(HTYPE!=%d)&&HVADDR"),
636 FREE_TRACE, MUNMAP_TRACE);
637 specify_metric (buf, NTXT ("HLEAKED"));
638 cmd = dbe_strdup (NTXT ("heapleakbytes"));
639 break;
640
641 case IO_READ_CNT:
642 packet_type = DATA_IOTRACE;
643 username = dbe_strdup (GTXT ("Read Count"));
644 snprintf (buf, sizeof (buf), "(IOTYPE==%d)", READ_TRACE);
645 specify_metric (buf, NTXT ("1"));
646 cmd = dbe_strdup (NTXT ("ioreadcnt"));
647 break;
648 case IO_WRITE_CNT:
649 packet_type = DATA_IOTRACE;
650 username = dbe_strdup (GTXT ("Write Count"));
651 snprintf (buf, sizeof (buf), "(IOTYPE==%d)", WRITE_TRACE);
652 specify_metric (buf, NTXT ("1"));
653 cmd = dbe_strdup (NTXT ("iowritecnt"));
654 break;
655 case IO_OTHER_CNT:
656 packet_type = DATA_IOTRACE;
657 username = dbe_strdup (GTXT ("Other I/O Count"));
658 snprintf (buf, sizeof (buf), "(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)",
659 OPEN_TRACE, CLOSE_TRACE, OTHERIO_TRACE);
660 specify_metric (buf, NTXT ("1"));
661 cmd = dbe_strdup (NTXT ("ioothercnt"));
662 break;
663 case IO_ERROR_CNT:
664 packet_type = DATA_IOTRACE;
665 username = dbe_strdup (GTXT ("I/O Error Count"));
666 snprintf (buf, sizeof (buf),
667 "(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)",
668 READ_TRACE_ERROR, WRITE_TRACE_ERROR, OPEN_TRACE_ERROR,
669 CLOSE_TRACE_ERROR, OTHERIO_TRACE_ERROR);
670 specify_metric (buf, NTXT ("1"));
671 cmd = dbe_strdup (NTXT ("ioerrorcnt"));
672 break;
673 case IO_READ_BYTES:
674 packet_type = DATA_IOTRACE;
675 username = dbe_strdup (GTXT ("Read Bytes"));
676 snprintf (buf, sizeof (buf), NTXT ("(IOTYPE==%d)&&IONBYTE"),
677 READ_TRACE);
678 specify_metric (buf, NTXT ("IONBYTE"));
679 cmd = dbe_strdup (NTXT ("ioreadbytes"));
680 break;
681 case IO_WRITE_BYTES:
682 packet_type = DATA_IOTRACE;
683 username = dbe_strdup (GTXT ("Write Bytes"));
684 snprintf (buf, sizeof (buf), "(IOTYPE==%d)&&IONBYTE", WRITE_TRACE);
685 specify_metric (buf, NTXT ("IONBYTE"));
686 cmd = dbe_strdup (NTXT ("iowritebytes"));
687 break;
688 case IO_READ_TIME:
689 packet_type = DATA_IOTRACE;
690 username = dbe_strdup (GTXT ("Read Time"));
691 snprintf (buf, sizeof (buf), "(IOTYPE==%d)&&EVT_TIME", READ_TRACE);
692 snprintf (buf2, sizeof (buf2), NTXT ("(EVT_TIME)/%lld"),
693 (long long) (NANOSEC / METRIC_HR_PRECISION));
694 specify_metric (buf, buf2);
695 cmd = dbe_strdup (NTXT ("ioreadtime"));
696 break;
697 case IO_WRITE_TIME:
698 packet_type = DATA_IOTRACE;
699 username = dbe_strdup (GTXT ("Write Time"));
700 snprintf (buf, sizeof (buf), NTXT ("(IOTYPE==%d)&&EVT_TIME"),
701 WRITE_TRACE);
702 snprintf (buf2, sizeof (buf2), NTXT ("(EVT_TIME)/%lld"),
703 (long long) (NANOSEC / METRIC_HR_PRECISION));
704 specify_metric (buf, buf2);
705 cmd = dbe_strdup (NTXT ("iowritetime"));
706 break;
707 case IO_OTHER_TIME:
708 packet_type = DATA_IOTRACE;
709 username = dbe_strdup (GTXT ("Other I/O Time"));
710 snprintf (buf, sizeof (buf),
711 "(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)&&EVT_TIME",
712 OPEN_TRACE, CLOSE_TRACE, OTHERIO_TRACE);
713 snprintf (buf2, sizeof (buf2), NTXT ("(EVT_TIME)/%lld"),
714 (long long) (NANOSEC / METRIC_HR_PRECISION));
715 specify_metric (buf, buf2);
716 cmd = dbe_strdup (NTXT ("ioothertime"));
717 break;
718 case IO_ERROR_TIME:
719 packet_type = DATA_IOTRACE;
720 username = dbe_strdup (GTXT ("I/O Error Time"));
721 snprintf (buf, sizeof (buf),
722 "(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)||(IOTYPE==%d)&&EVT_TIME",
723 READ_TRACE_ERROR, WRITE_TRACE_ERROR, OPEN_TRACE_ERROR,
724 CLOSE_TRACE_ERROR, OTHERIO_TRACE_ERROR);
725 snprintf (buf2, sizeof (buf2), NTXT ("(EVT_TIME)/%lld"),
726 (long long) (NANOSEC / METRIC_HR_PRECISION));
727 specify_metric (buf, buf2);
728 cmd = dbe_strdup (NTXT ("ioerrortime"));
729 break;
730 case RACCESS:
731 packet_type = DATA_RACE;
732 username = dbe_strdup (GTXT ("Race Accesses"));
733 specify_metric (NULL, NTXT ("RCNT"));
734 cmd = dbe_strdup (NTXT ("raccess"));
735 break;
736 case DEADLOCKS:
737 packet_type = DATA_DLCK;
738 username = dbe_strdup (GTXT ("Deadlocks"));
739 specify_metric (NULL, NTXT ("1"));
740 cmd = dbe_strdup (NTXT ("deadlocks"));
741 break;
742 case HWCNTR:
743 packet_type = DATA_HWC;
744 // username, cmd, and aux set by hwc constructor
745 if (valtype == VT_DOUBLE)
746 {
747 if (hw_ctr->timecvt > 0) // CPU cycles
748 specify_metric (NULL, NTXT ("((HWCINT*1000000)/FREQ_MHZ)"));
749 else if (hw_ctr->timecvt < 0)
750 { // reference clock (frequency is -timecvt MHz)
751 snprintf (buf, sizeof (buf), NTXT ("((HWCINT*1000000)/%d)"), -hw_ctr->timecvt);
752 specify_metric (NULL, buf);
753 }
754 else // shouldn't happen
755 specify_metric (NULL, NTXT ("0"));
756 // resulting unit: seconds * 1e12
757 precision = 1000000LL * 1000000LL; // Seconds * 1e12
758 }
759 else
760 {
761 specify_metric (NULL, NTXT ("HWCINT"));
762 precision = 1;
763 }
764 break;
765 case OMP_MSTR:
766 case OMP_SNGL:
767 case OMP_ORDD:
768 case OMP_NONE:
769 default:
770 username = dbe_strdup (GTXT ("****"));
771 fprintf (stderr, "BaseMetric::init Undefined basemetric %s\n",
772 get_basetype_name ());
773 }
774 }
775
776 #define CASE_S(x) case x: s = (char *) #x; break
777 char *
778 BaseMetric::get_basetype_name ()
779 {
780 static char buf[128];
781 char *s;
782 switch (type)
783 {
784 CASE_S (CP_LMS_SYSTEM);
785 CASE_S (CP_TOTAL_CPU);
786 CASE_S (CP_TOTAL);
787 CASE_S (OMP_MASTER_THREAD);
788 CASE_S (CP_LMS_USER);
789 CASE_S (CP_LMS_WAIT_CPU);
790 CASE_S (CP_LMS_USER_LOCK);
791 CASE_S (CP_LMS_TFAULT);
792 CASE_S (CP_LMS_DFAULT);
793 CASE_S (CP_LMS_TRAP);
794 CASE_S (CP_LMS_KFAULT);
795 CASE_S (CP_LMS_SLEEP);
796 CASE_S (CP_LMS_STOPPED);
797 CASE_S (OMP_NONE);
798 CASE_S (OMP_OVHD);
799 CASE_S (OMP_WORK);
800 CASE_S (OMP_IBAR);
801 CASE_S (OMP_EBAR);
802 CASE_S (OMP_WAIT);
803 CASE_S (OMP_SERL);
804 CASE_S (OMP_RDUC);
805 CASE_S (OMP_LKWT);
806 CASE_S (OMP_CTWT);
807 CASE_S (OMP_ODWT);
808 CASE_S (OMP_MSTR);
809 CASE_S (OMP_SNGL);
810 CASE_S (OMP_ORDD);
811 CASE_S (CP_KERNEL_CPU);
812 CASE_S (SYNC_WAIT_TIME);
813 CASE_S (IO_READ_TIME);
814 CASE_S (IO_WRITE_TIME);
815 CASE_S (IO_OTHER_TIME);
816 CASE_S (IO_ERROR_TIME);
817 CASE_S (HWCNTR);
818 CASE_S (SYNC_WAIT_COUNT);
819 CASE_S (HEAP_ALLOC_CNT);
820 CASE_S (HEAP_LEAK_CNT);
821 CASE_S (IO_READ_CNT);
822 CASE_S (IO_WRITE_CNT);
823 CASE_S (IO_OTHER_CNT);
824 CASE_S (IO_ERROR_CNT);
825 CASE_S (RACCESS);
826 CASE_S (DEADLOCKS);
827 CASE_S (HEAP_ALLOC_BYTES);
828 CASE_S (HEAP_LEAK_BYTES);
829 CASE_S (IO_READ_BYTES);
830 CASE_S (IO_WRITE_BYTES);
831 CASE_S (SIZES);
832 CASE_S (ADDRESS);
833 CASE_S (ONAME);
834 CASE_S (DERIVED);
835 default:
836 s = NTXT ("???");
837 break;
838 }
839 snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, type);
840 buf[sizeof (buf) - 1] = 0;
841 return buf;
842 }
843
844 char *
845 BaseMetric::dump ()
846 {
847 int len = 4;
848 char *msg = dbe_sprintf (NTXT ("id=%d %s aux='%s' cmd='%s' user_name='%s' expr_spec='%s'\n"
849 "%*c cond_spec='%s' val_spec='%s'"),
850 id, get_basetype_name (), STR (aux), STR (cmd),
851 STR (username), STR (expr_spec),
852 len, ' ', STR (cond_spec), STR (val_spec));
853 return msg;
854 }
855
856 Histable *
857 BaseMetric::get_comparable_obj (Histable *obj)
858 {
859 if (obj == NULL || expr == NULL)
860 return obj;
861 if (strncmp (expr_spec, NTXT ("EXPGRID=="), 9) == 0)
862 {
863 int n = atoi (expr_spec + 9);
864 Vector<Histable *> *cmpObjs = obj->get_comparable_objs ();
865 if (cmpObjs && cmpObjs->size () >= n)
866 return cmpObjs->get (n - 1);
867 return NULL;
868 }
869 return obj;
870 }
871
872 Definition::Definition (opType _op)
873 {
874 op = _op;
875 bm = NULL;
876 arg1 = NULL;
877 arg2 = NULL;
878 def = NULL;
879 dependencies = NULL;
880 map = NULL;
881 index = 0;
882 }
883
884 Definition::~Definition ()
885 {
886 delete arg1;
887 delete arg2;
888 delete dependencies;
889 delete[] map;
890 }
891
892 Vector<BaseMetric *> *
893 Definition::get_dependencies ()
894 {
895 if (dependencies == NULL)
896 {
897 if (arg1 && arg1->bm && arg2 && arg2->bm)
898 {
899 dependencies = new Vector<BaseMetric *>(2);
900 arg1->index = dependencies->size ();
901 dependencies->append (arg1->bm);
902 arg2->index = dependencies->size ();
903 dependencies->append (arg2->bm);
904 map = new long[2];
905 }
906 }
907 return dependencies;
908 }
909
910 long *
911 Definition::get_map ()
912 {
913 get_dependencies ();
914 return map;
915 }
916
917 Definition *
918 Definition::add_definition (char *_def)
919 {
920 // parse the definition
921 char *op_ptr = strchr (_def, '/');
922 if (op_ptr == NULL)
923 {
924 // it's a primitive metric
925 BaseMetric *bm = dbeSession->find_base_reg_metric (_def);
926 if (bm)
927 {
928 Definition *p = new Definition (opPrimitive);
929 p->bm = bm;
930 return p;
931 }
932 return NULL; // BaseMetric is not yet specified
933 }
934 Definition *p2 = add_definition (op_ptr + 1);
935 if (p2 == NULL)
936 return NULL;
937 _def = dbe_strdup (_def);
938 op_ptr = strchr (_def, '/');
939 *op_ptr = 0;
940 Definition *p1 = add_definition (_def);
941 if (p1)
942 {
943 *op_ptr = '/';
944 Definition *p = new Definition (opDivide);
945 p->arg1 = p1;
946 p->arg2 = p2;
947 p->def = _def;
948 return p;
949 }
950 free (_def);
951 delete p1;
952 delete p2;
953 return NULL;
954 }
955
956 double
957 Definition::eval (long *indexes, TValue *values)
958 {
959 switch (op)
960 {
961 case opPrimitive:
962 return values[indexes[index]].to_double ();
963 case opDivide:
964 {
965 double x2 = arg2->eval (indexes, values);
966 if (x2 == 0)
967 return 0.;
968 double x1 = arg1->eval (indexes, values);
969 return x1 / x2;
970 }
971 default:
972 fprintf (stderr, GTXT ("unknown expression\n"));
973 return 0.;
974 }
975 }