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 35IOActivity::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 54void 55IOActivity::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 109void 110IOActivity::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 270void 271IOActivity::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 326void 327IOActivity::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 399Hist_data * 400IOActivity::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 532void 533IOActivity::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 732void 733IOActivity::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