1 /* Copyright (C) 2021-2024 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 "DbeSession.h"
23 #include "FileData.h"
24 #include "StringBuilder.h"
25 #include "i18n.h"
26 #include "util.h"
27 #include "IOActivity.h"
28 #include "MetricList.h"
29 #include "Application.h"
30 #include "Experiment.h"
31 #include "DbeView.h"
32 #include "Exp_Layout.h"
33 #include "i18n.h"
34
IOActivity(DbeView * _dbev)35 IOActivity::IOActivity (DbeView *_dbev)
36 {
37 dbev = _dbev;
38 fDataHash = NULL;
39 fDataTotal = NULL;
40 fDataObjs = NULL;
41 fDataObjsFile = NULL;
42 hasFile = false;
43 fDataObjsVfd = NULL;
44 hasVfd = false;
45 fDataObjsCallStack = NULL;
46 hasCallStack = false;
47 fDataCalStkMap = NULL;
48 fDataVfdMap = NULL;
49 hist_data_file_all = NULL;
50 hist_data_vfd_all = NULL;
51 hist_data_callstack_all = NULL;
52 }
53
54 void
reset()55 IOActivity::reset ()
56 {
57 int numExps = dbeSession->nexps ();
58 FileData *fData = NULL;
59 DefaultMap<int64_t, FileData*>* fDataMap;
60 for (int k = 0; k < numExps; k++)
61 {
62 Experiment *exp = dbeSession->get_exp (k);
63 fDataMap = exp->getFDataMap ();
64 if (fDataMap == NULL)
65 continue;
66
67 fDataObjs = fDataMap->values ();
68 if (fDataObjs == NULL)
69 continue;
70 int numFiles = fDataObjs->size ();
71 for (int j = 0; j < numFiles; j++)
72 {
73 fData = fDataObjs->fetch (j);
74 fData->init ();
75 }
76 }
77
78 delete fDataHash;
79 fDataHash = NULL;
80 delete fDataTotal;
81 fDataTotal = NULL;
82
83 delete fDataObjsFile;
84 fDataObjsFile = NULL;
85 hasFile = false;
86
87 delete fDataObjsVfd;
88 fDataObjsVfd = NULL;
89 hasVfd = false;
90
91 delete fDataObjsCallStack;
92 fDataObjsCallStack = NULL;
93 hasCallStack = false;
94
95 delete fDataObjs;
96 fDataObjs = NULL;
97 delete fDataCalStkMap;
98 fDataCalStkMap = NULL;
99 delete fDataVfdMap;
100 fDataVfdMap = NULL;
101
102 // These three pointers are deleted by DbeView
103 // They are named iofile_data, iovfd_data, and iocs_data
104 hist_data_file_all = NULL;
105 hist_data_vfd_all = NULL;
106 hist_data_callstack_all = NULL;
107 }
108
109 void
createHistItemTotals(Hist_data * hist_data,MetricList * mlist,Histable::Type hType,bool empty)110 IOActivity::createHistItemTotals (Hist_data *hist_data, MetricList *mlist,
111 Histable::Type hType, bool empty)
112 {
113 int mIndex;
114 Metric *mtr;
115 Hist_data::HistItem *hi;
116 FileData *fData = NULL;
117
118 if (fDataTotal == NULL)
119 {
120 fDataTotal = new FileData (TOTAL_FILENAME);
121 fDataTotal->setHistType (hType);
122 fDataTotal->setVirtualFd (VIRTUAL_FD_TOTAL);
123 fDataTotal->id = 0;
124 }
125
126 fData = new FileData (fDataTotal);
127 fData->setHistType (hType);
128 hi = hist_data->append_hist_item (fData);
129 Vec_loop (Metric *, mlist->get_items (), mIndex, mtr)
130 {
131 if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ())
132 continue;
133
134 Metric::Type mtype = mtr->get_type ();
135 ValueTag vType = mtr->get_vtype ();
136 hist_data->total->value[mIndex].tag = vType;
137 hi->value[mIndex].tag = vType;
138 double prec = (double) NANOSEC;
139 switch (mtype)
140 {
141 case BaseMetric::IO_READ_BYTES:
142 if (!empty)
143 {
144 hist_data->total->value[mIndex].ll = fDataTotal->getReadBytes ();
145 hi->value[mIndex].ll = fDataTotal->getReadBytes ();
146 }
147 else
148 {
149 hist_data->total->value[mIndex].ll = 0;
150 hi->value[mIndex].ll = 0;
151 }
152 break;
153 case BaseMetric::IO_READ_CNT:
154 if (!empty)
155 {
156 hist_data->total->value[mIndex].ll = fDataTotal->getReadCnt ();
157 hi->value[mIndex].ll = fDataTotal->getReadCnt ();
158 }
159 else
160 {
161 hist_data->total->value[mIndex].ll = 0;
162 hi->value[mIndex].ll = 0;
163 }
164 break;
165 case BaseMetric::IO_READ_TIME:
166 if (!empty)
167 {
168 hist_data->total->value[mIndex].d =
169 (double) fDataTotal->getReadTime () / prec;
170 hi->value[mIndex].d = hist_data->total->value[mIndex].d;
171 }
172 else
173 {
174 hist_data->total->value[mIndex].d = 0.0;
175 hi->value[mIndex].d = 0.0;
176 }
177 break;
178 case BaseMetric::IO_WRITE_BYTES:
179 if (!empty)
180 {
181 hist_data->total->value[mIndex].ll = fDataTotal->getWriteBytes ();
182 hi->value[mIndex].ll = fDataTotal->getWriteBytes ();
183 }
184 else
185 {
186 hist_data->total->value[mIndex].ll = 0;
187 hi->value[mIndex].ll = 0;
188 }
189 break;
190 case BaseMetric::IO_WRITE_CNT:
191 if (!empty)
192 {
193 hist_data->total->value[mIndex].ll = fDataTotal->getWriteCnt ();
194 hi->value[mIndex].ll = fDataTotal->getWriteCnt ();
195 }
196 else
197 {
198 hist_data->total->value[mIndex].ll = 0;
199 hi->value[mIndex].ll = 0;
200 }
201 break;
202 case BaseMetric::IO_WRITE_TIME:
203 if (!empty)
204 {
205 hist_data->total->value[mIndex].d =
206 (double) fDataTotal->getWriteTime () / prec;
207 hi->value[mIndex].d = hist_data->total->value[mIndex].d;
208 }
209 else
210 {
211 hist_data->total->value[mIndex].d = 0.0;
212 hi->value[mIndex].d = 0.0;
213 }
214 break;
215 case BaseMetric::IO_OTHER_CNT:
216 if (!empty)
217 {
218 hist_data->total->value[mIndex].ll = fDataTotal->getOtherCnt ();
219 hi->value[mIndex].ll = fDataTotal->getOtherCnt ();
220 }
221 else
222 {
223 hist_data->total->value[mIndex].ll = 0;
224 hi->value[mIndex].ll = 0;
225 }
226 break;
227 case BaseMetric::IO_OTHER_TIME:
228 if (!empty)
229 {
230 hist_data->total->value[mIndex].d =
231 (double) fDataTotal->getOtherTime () / prec;
232 hi->value[mIndex].d = hist_data->total->value[mIndex].d;
233 }
234 else
235 {
236 hist_data->total->value[mIndex].d = 0.0;
237 hi->value[mIndex].d = 0.0;
238 }
239 break;
240 case BaseMetric::IO_ERROR_CNT:
241 if (!empty)
242 {
243 hist_data->total->value[mIndex].ll = fDataTotal->getErrorCnt ();
244 hi->value[mIndex].ll = fDataTotal->getErrorCnt ();
245 }
246 else
247 {
248 hist_data->total->value[mIndex].ll = 0;
249 hi->value[mIndex].ll = 0;
250 }
251 break;
252 case BaseMetric::IO_ERROR_TIME:
253 if (!empty)
254 {
255 hist_data->total->value[mIndex].d = (double) fDataTotal->getErrorTime () / prec;
256 hi->value[mIndex].d = hist_data->total->value[mIndex].d;
257 }
258 else
259 {
260 hist_data->total->value[mIndex].d = 0.0;
261 hi->value[mIndex].d = 0.0;
262 }
263 break;
264 default:
265 break;
266 }
267 }
268 }
269
270 void
computeHistTotals(Hist_data * hist_data,MetricList * mlist)271 IOActivity::computeHistTotals (Hist_data *hist_data, MetricList *mlist)
272 {
273 int mIndex;
274 Metric *mtr;
275 Vec_loop (Metric *, mlist->get_items (), mIndex, mtr)
276 {
277 if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ())
278 continue;
279
280 Metric::Type mtype = mtr->get_type ();
281 ValueTag vType = mtr->get_vtype ();
282 hist_data->total->value[mIndex].tag = vType;
283 double prec = (double) NANOSEC;
284 switch (mtype)
285 {
286 case BaseMetric::IO_READ_BYTES:
287 hist_data->total->value[mIndex].ll = fDataTotal->getReadBytes ();
288 break;
289 case BaseMetric::IO_READ_CNT:
290 hist_data->total->value[mIndex].ll = fDataTotal->getReadCnt ();
291 break;
292 case BaseMetric::IO_READ_TIME:
293 hist_data->total->value[mIndex].d =
294 (double) fDataTotal->getReadTime () / prec;
295 break;
296 case BaseMetric::IO_WRITE_BYTES:
297 hist_data->total->value[mIndex].ll = fDataTotal->getWriteBytes ();
298 break;
299 case BaseMetric::IO_WRITE_CNT:
300 hist_data->total->value[mIndex].ll = fDataTotal->getWriteCnt ();
301 break;
302 case BaseMetric::IO_WRITE_TIME:
303 hist_data->total->value[mIndex].d =
304 (double) fDataTotal->getWriteTime () / prec;
305 break;
306 case BaseMetric::IO_OTHER_CNT:
307 hist_data->total->value[mIndex].ll = fDataTotal->getOtherCnt ();
308 break;
309 case BaseMetric::IO_OTHER_TIME:
310 hist_data->total->value[mIndex].d =
311 (double) fDataTotal->getOtherTime () / prec;
312 break;
313 case BaseMetric::IO_ERROR_CNT:
314 hist_data->total->value[mIndex].ll = fDataTotal->getErrorCnt ();
315 break;
316 case BaseMetric::IO_ERROR_TIME:
317 hist_data->total->value[mIndex].d =
318 (double) fDataTotal->getErrorTime () / prec;
319 break;
320 default:
321 break;
322 }
323 }
324 }
325
326 void
computeHistData(Hist_data * hist_data,MetricList * mlist,Hist_data::Mode mode,Histable * selObj)327 IOActivity::computeHistData (Hist_data *hist_data, MetricList *mlist,
328 Hist_data::Mode mode, Histable *selObj)
329 {
330
331 Hist_data::HistItem *hi = NULL;
332 int numObjs = fDataObjs->size ();
333 int numMetrics = mlist->get_items ()->size ();
334
335 for (int i = 0; i < numObjs; i++)
336 {
337 FileData *fData = fDataObjs->fetch (i);
338 if (mode == Hist_data::ALL)
339 hi = hist_data->append_hist_item (fData);
340 else if (mode == Hist_data::SELF)
341 {
342 if (fData->id == selObj->id)
343 hi = hist_data->append_hist_item (fData);
344 else
345 continue;
346 }
347
348 for (int mIndex = 0; mIndex < numMetrics; mIndex++)
349 {
350 Metric *mtr = mlist->get_items ()->fetch (mIndex);
351 if (!mtr->is_visible () && !mtr->is_tvisible ()
352 && !mtr->is_pvisible ())
353 continue;
354
355 Metric::Type mtype = mtr->get_type ();
356 ValueTag vType = mtr->get_vtype ();
357 hi->value[mIndex].tag = vType;
358
359 double prec = (double) NANOSEC;
360 switch (mtype)
361 {
362 case BaseMetric::IO_READ_BYTES:
363 hi->value[mIndex].ll = fData->getReadBytes ();
364 break;
365 case BaseMetric::IO_READ_CNT:
366 hi->value[mIndex].ll = fData->getReadCnt ();
367 break;
368 case BaseMetric::IO_READ_TIME:
369 hi->value[mIndex].d = (double) fData->getReadTime () / prec;
370 break;
371 case BaseMetric::IO_WRITE_BYTES:
372 hi->value[mIndex].ll = fData->getWriteBytes ();
373 break;
374 case BaseMetric::IO_WRITE_CNT:
375 hi->value[mIndex].ll = fData->getWriteCnt ();
376 break;
377 case BaseMetric::IO_WRITE_TIME:
378 hi->value[mIndex].d = (double) fData->getWriteTime () / prec;
379 break;
380 case BaseMetric::IO_OTHER_CNT:
381 hi->value[mIndex].ll = fData->getOtherCnt ();
382 break;
383 case BaseMetric::IO_OTHER_TIME:
384 hi->value[mIndex].d = (double) fData->getOtherTime () / prec;
385 break;
386 case BaseMetric::IO_ERROR_CNT:
387 hi->value[mIndex].ll = fData->getErrorCnt ();
388 break;
389 case BaseMetric::IO_ERROR_TIME:
390 hi->value[mIndex].d = (double) fData->getErrorTime () / prec;
391 break;
392 default:
393 break;
394 }
395 }
396 }
397 }
398
399 Hist_data *
compute_metrics(MetricList * mlist,Histable::Type type,Hist_data::Mode mode,Histable * selObj)400 IOActivity::compute_metrics (MetricList *mlist, Histable::Type type,
401 Hist_data::Mode mode, Histable *selObj)
402 {
403
404 // it's already there, just return it
405 if (mode == Hist_data::ALL)
406 {
407 if (type == Histable::IOACTFILE && hist_data_file_all)
408 return hist_data_file_all;
409 else if (type == Histable::IOACTVFD && hist_data_vfd_all)
410 return hist_data_vfd_all;
411 else if (type == Histable::IOCALLSTACK && hist_data_callstack_all)
412 return hist_data_callstack_all;
413 }
414
415 bool has_data = false;
416 Hist_data *hist_data = NULL;
417 VMode viewMode = dbev->get_view_mode ();
418
419 switch (type)
420 {
421 case Histable::IOACTVFD:
422 if (!hasVfd)
423 computeData (type);
424
425 // computeData() creates fDataObjsVfd
426 // fDataObjsVfd contains the list of vfd objects
427 if (fDataObjsVfd != NULL)
428 {
429 // fDataObjs is used in other methods
430 fDataObjs = fDataObjsVfd;
431 has_data = true;
432 }
433 else
434 has_data = false;
435
436 if (has_data && mode == Hist_data::ALL && hist_data_vfd_all == NULL)
437 {
438 hist_data_vfd_all = new Hist_data (mlist, type, mode, true);
439 hist_data = hist_data_vfd_all;
440 }
441 else if (has_data)
442 hist_data = new Hist_data (mlist, type, mode, false);
443 else
444 {
445 hist_data = new Hist_data (mlist, type, mode, false);
446 createHistItemTotals (hist_data, mlist, type, true);
447 return hist_data;
448 }
449 break;
450 case Histable::IOACTFILE:
451 if (!hasFile)
452 computeData (type);
453
454 // computeData() creates fDataObjsFile
455 // fDataObjsFile contains the list of file objects
456 if (fDataObjsFile != NULL)
457 {
458 fDataObjs = fDataObjsFile;
459 has_data = true;
460 }
461 else
462 has_data = false;
463
464 if (has_data && mode == Hist_data::ALL && hist_data_file_all == NULL)
465 {
466 hist_data_file_all = new Hist_data (mlist, type, mode, true);
467 hist_data = hist_data_file_all;
468 }
469 else if (has_data)
470 hist_data = new Hist_data (mlist, type, mode, false);
471 else
472 {
473 hist_data = new Hist_data (mlist, type, mode, false);
474 createHistItemTotals (hist_data, mlist, type, true);
475 return hist_data;
476 }
477 break;
478 case Histable::IOCALLSTACK:
479 if (!hasCallStack)
480 computeCallStack (type, viewMode);
481
482 // computeCallStack() creates fDataObjsCallStack
483 // fDataObjsCallStack contains the list of call stack objects
484 if (fDataObjsCallStack != NULL)
485 {
486 fDataObjs = fDataObjsCallStack;
487 has_data = true;
488 }
489 else
490 has_data = false;
491
492 if (has_data && (mode == Hist_data::ALL) && (hist_data_callstack_all == NULL))
493 {
494 hist_data_callstack_all = new Hist_data (mlist, type, mode, true);
495 hist_data = hist_data_callstack_all;
496 }
497 else if (has_data)
498 hist_data = new Hist_data (mlist, type, mode, false);
499 else
500 {
501 hist_data = new Hist_data (mlist, type, mode, false);
502 createHistItemTotals (hist_data, mlist, type, true);
503 return hist_data;
504 }
505 break;
506 default:
507 fprintf (stderr,
508 "IOActivity cannot process data due to wrong Histable (type=%d) \n",
509 type);
510 abort ();
511 }
512
513 if (mode == Hist_data::ALL || (mode == Hist_data::SELF && selObj->id == 0))
514 createHistItemTotals (hist_data, mlist, type, false);
515 else
516 computeHistTotals (hist_data, mlist);
517 computeHistData (hist_data, mlist, mode, selObj);
518
519 // Determine by which metric to sort if any
520 bool rev_sort = mlist->get_sort_rev ();
521 int sort_ind = -1;
522 int nmetrics = mlist->get_items ()->size ();
523 for (int mind = 0; mind < nmetrics; mind++)
524 if (mlist->get_sort_ref_index () == mind)
525 sort_ind = mind;
526
527 hist_data->sort (sort_ind, rev_sort);
528 hist_data->compute_minmax ();
529 return hist_data;
530 }
531
532 void
computeData(Histable::Type type)533 IOActivity::computeData (Histable::Type type)
534 {
535 bool has_iodata = false;
536 reset ();
537 int64_t histableId = 0; // It is used by fDataAggr only
538 // fData uses vfd for histable id
539
540 fDataHash = new HashMap<char*, FileData*>;
541 FileData *fData = NULL;
542 FileData *fDataAggr = NULL;
543
544 fDataTotal = new FileData (TOTAL_FILENAME);
545 fDataTotal->setHistType (type);
546 fDataTotal->setVirtualFd (VIRTUAL_FD_TOTAL);
547 fDataTotal->id = histableId++;
548
549 FileData *fDataStdin = new FileData (STDIN_FILENAME);
550 fDataStdin->setFileDes (STDIN_FD);
551 fDataStdin->setHistType (type);
552 fDataStdin->setFsType ("N/A");
553 fDataStdin->id = histableId++;
554
555 FileData *fDataStdout = new FileData (STDOUT_FILENAME);
556 fDataStdout->setFileDes (STDOUT_FD);
557 fDataStdout->setHistType (type);
558 fDataStdout->setFsType ("N/A");
559 fDataStdout->id = histableId++;
560
561 FileData *fDataStderr = new FileData (STDERR_FILENAME);
562 fDataStderr->setFileDes (STDERR_FD);
563 fDataStderr->setHistType (type);
564 fDataStderr->setFsType ("N/A");
565 fDataStderr->id = histableId++;
566
567 FileData *fDataOtherIO = new FileData (OTHERIO_FILENAME);
568 fDataOtherIO->setFileDes (OTHERIO_FD);
569 fDataOtherIO->setHistType (type);
570 fDataOtherIO->setFsType ("N/A");
571 fDataOtherIO->id = histableId++;
572
573 DefaultMap<int64_t, FileData*>* fDataMap;
574 fDataObjsFile = NULL;
575 fDataObjsVfd = NULL;
576
577 // get the list of io events from DbeView
578 int numExps = dbeSession->nexps ();
579
580 for (int k = 0; k < numExps; k++)
581 {
582 DataView *ioPkts = dbev->get_filtered_events (k, DATA_IOTRACE);
583 if (ioPkts == NULL || ioPkts->getSize () <= 0)
584 continue;
585 Experiment *exp = dbeSession->get_exp (k);
586 fDataMap = exp->getFDataMap ();
587 if (fDataMap == NULL)
588 continue;
589 delete fDataVfdMap;
590 fDataVfdMap = new DefaultMap<long, FileData*>;
591
592 long sz = ioPkts->getSize ();
593 for (long i = 0; i < sz; ++i)
594 {
595 hrtime_t event_duration = ioPkts->getLongValue (PROP_EVT_TIME, i);
596 int64_t nByte = ioPkts->getLongValue (PROP_IONBYTE, i);
597 IOTrace_type ioType = (IOTrace_type) ioPkts->getIntValue (PROP_IOTYPE, i);
598 int64_t vFd = ioPkts->getLongValue (PROP_IOVFD, i);
599 if (vFd >= 0)
600 {
601 fData = fDataMap->get (vFd);
602 if (fData == NULL)
603 continue;
604 }
605 else
606 continue;
607
608 if (fDataVfdMap->get (vFd) == NULL)
609 fDataVfdMap->put (vFd, fData);
610
611 switch (ioType)
612 {
613 case READ_TRACE:
614 fData->addReadEvent (event_duration, nByte);
615 // Set the Histable id for IOVFD
616 fData->id = fData->getVirtualFd ();
617 fDataTotal->addReadEvent (event_duration, nByte);
618 fDataTotal->setReadStat (event_duration, nByte);
619 break;
620 case WRITE_TRACE:
621 fData->addWriteEvent (event_duration, nByte);
622 // Set the Histable id for IOVFD
623 fData->id = fData->getVirtualFd ();
624 fDataTotal->addWriteEvent (event_duration, nByte);
625 fDataTotal->setWriteStat (event_duration, nByte);
626 break;
627 case OPEN_TRACE:
628 fData->addOtherEvent (event_duration);
629 // Set the Histable id for IOVFD
630 fData->id = fData->getVirtualFd ();
631 fDataTotal->addOtherEvent (event_duration);
632 break;
633 case CLOSE_TRACE:
634 case OTHERIO_TRACE:
635 fData->addOtherEvent (event_duration);
636 // Set the Histable id for IOVFD
637 fData->id = fData->getVirtualFd ();
638 fDataTotal->addOtherEvent (event_duration);
639 break;
640 case READ_TRACE_ERROR:
641 case WRITE_TRACE_ERROR:
642 case OPEN_TRACE_ERROR:
643 case CLOSE_TRACE_ERROR:
644 case OTHERIO_TRACE_ERROR:
645 fData->addErrorEvent (event_duration);
646 // Set the Histable id for IOVFD
647 fData->id = fData->getVirtualFd ();
648 fDataTotal->addErrorEvent (event_duration);
649 break;
650
651 case IOTRACETYPE_LAST:
652 break;
653 }
654
655 if (type == Histable::IOACTFILE)
656 {
657 fDataAggr = fDataHash->get (fData->getFileName ());
658 if (fDataAggr == NULL)
659 {
660 bool setInfo = false;
661 if (vFd == VIRTUAL_FD_STDIN)
662 fDataAggr = fDataStdin;
663 else if (vFd == VIRTUAL_FD_STDOUT)
664 fDataAggr = fDataStdout;
665 else if (vFd == VIRTUAL_FD_STDERR)
666 fDataAggr = fDataStderr;
667 else if (vFd == VIRTUAL_FD_OTHERIO)
668 fDataAggr = fDataOtherIO;
669 else
670 {
671 fDataAggr = new FileData (fData->getFileName ());
672 setInfo = true;
673 }
674 fDataHash->put (fData->getFileName (), fDataAggr);
675
676 if (setInfo)
677 {
678 fDataAggr->setFsType (fData->getFsType ());
679 fDataAggr->setHistType (type);
680 // Set the Histable id for aggregated file name
681 fDataAggr->id = histableId;
682 fDataAggr->setVirtualFd (histableId);
683 histableId++;
684 }
685 }
686
687 fDataAggr->setFileDesList (fData->getFileDes ());
688 fDataAggr->setVirtualFds (fData->getVirtualFd ());
689 switch (ioType)
690 {
691 case READ_TRACE:
692 fDataAggr->addReadEvent (event_duration, nByte);
693 break;
694 case WRITE_TRACE:
695 fDataAggr->addWriteEvent (event_duration, nByte);
696 break;
697 case OPEN_TRACE:
698 fDataAggr->addOtherEvent (event_duration);
699 break;
700 case CLOSE_TRACE:
701 case OTHERIO_TRACE:
702 fDataAggr->addOtherEvent (event_duration);
703 break;
704 case READ_TRACE_ERROR:
705 case WRITE_TRACE_ERROR:
706 case OPEN_TRACE_ERROR:
707 case CLOSE_TRACE_ERROR:
708 case OTHERIO_TRACE_ERROR:
709 fDataAggr->addErrorEvent (event_duration);
710 break;
711 case IOTRACETYPE_LAST:
712 break;
713 }
714 }
715 has_iodata = true;
716 }
717 if (sz > 0)
718 {
719 if (fDataObjsVfd == NULL)
720 fDataObjsVfd = new Vector<FileData*>;
721 fDataObjsVfd->addAll (fDataVfdMap->values ());
722 hasVfd = true;
723 }
724 }
725 if (has_iodata && type == Histable::IOACTFILE)
726 {
727 fDataObjsFile = fDataHash->values ()->copy ();
728 hasFile = true;
729 }
730 }
731
732 void
computeCallStack(Histable::Type type,VMode viewMode)733 IOActivity::computeCallStack (Histable::Type type, VMode viewMode)
734 {
735 bool has_data = false;
736 int64_t stackIndex = 0;
737 FileData *fData = NULL;
738 delete fDataCalStkMap;
739 fDataCalStkMap = new DefaultMap<void*, FileData*>;
740 delete fDataTotal;
741 fDataTotal = new FileData (TOTAL_FILENAME);
742 fDataTotal->setHistType (type);
743
744 // There is no call stack for total, use the index for id
745 fDataTotal->id = stackIndex++;
746
747 // get the list of io events from DbeView
748 int numExps = dbeSession->nexps ();
749 for (int k = 0; k < numExps; k++)
750 {
751 DataView *ioPkts = dbev->get_filtered_events (k, DATA_IOTRACE);
752 if (ioPkts == NULL || ioPkts->getSize () <= 0)
753 continue;
754 long sz = ioPkts->getSize ();
755 for (long i = 0; i < sz; ++i)
756 {
757 hrtime_t event_duration = ioPkts->getLongValue (PROP_EVT_TIME, i);
758 int64_t nByte = ioPkts->getLongValue (PROP_IONBYTE, i);
759 void *stackId = getStack (viewMode, ioPkts, i);
760 IOTrace_type ioType =
761 (IOTrace_type) ioPkts->getIntValue (PROP_IOTYPE, i);
762 int64_t vFd = ioPkts->getLongValue (PROP_IOVFD, i);
763
764 if (stackId != NULL && vFd > 0)
765 {
766 fData = fDataCalStkMap->get (stackId);
767 if (fData == NULL)
768 {
769 char *stkName = dbe_sprintf (GTXT ("Stack 0x%llx"),
770 (unsigned long long) stackId);
771 fData = new FileData (stkName);
772 fDataCalStkMap->put (stackId, fData);
773 fData->id = (int64_t) stackId;
774 fData->setVirtualFd (stackIndex);
775 stackIndex++;
776 fData->setHistType (type);
777 }
778 }
779 else
780 continue;
781
782 switch (ioType)
783 {
784 case READ_TRACE:
785 fData->addReadEvent (event_duration, nByte);
786 fDataTotal->addReadEvent (event_duration, nByte);
787 fDataTotal->setReadStat (event_duration, nByte);
788 break;
789 case WRITE_TRACE:
790 fData->addWriteEvent (event_duration, nByte);
791 fDataTotal->addWriteEvent (event_duration, nByte);
792 fDataTotal->setWriteStat (event_duration, nByte);
793 break;
794 case OPEN_TRACE:
795 fData->addOtherEvent (event_duration);
796 fDataTotal->addOtherEvent (event_duration);
797 break;
798 case CLOSE_TRACE:
799 case OTHERIO_TRACE:
800 fData->addOtherEvent (event_duration);
801 fDataTotal->addOtherEvent (event_duration);
802 break;
803 case READ_TRACE_ERROR:
804 case WRITE_TRACE_ERROR:
805 case OPEN_TRACE_ERROR:
806 fData->addErrorEvent (event_duration);
807 fDataTotal->addErrorEvent (event_duration);
808 break;
809 case CLOSE_TRACE_ERROR:
810 case OTHERIO_TRACE_ERROR:
811 fData->addErrorEvent (event_duration);
812 fDataTotal->addErrorEvent (event_duration);
813 break;
814 case IOTRACETYPE_LAST:
815 break;
816 }
817 has_data = true;
818 }
819 }
820 if (has_data)
821 {
822 fDataObjsCallStack = fDataCalStkMap->values ()->copy ();
823 hasCallStack = true;
824 }
825 }
826