xref: /netbsd-src/external/gpl3/binutils/dist/gprofng/src/IOActivity.cc (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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