| /* Copyright (C) 2021-2024 Free Software Foundation, Inc. | |
| Contributed by Oracle. | |
| This file is part of GNU Binutils. | |
| This program is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 3, or (at your option) | |
| any later version. | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with this program; if not, write to the Free Software | |
| Foundation, 51 Franklin Street - Fifth Floor, Boston, | |
| MA 02110-1301, USA. */ | |
| #include "config.h" | |
| #include "DbeSession.h" | |
| #include "FileData.h" | |
| #include "StringBuilder.h" | |
| #include "i18n.h" | |
| #include "util.h" | |
| #include "IOActivity.h" | |
| #include "MetricList.h" | |
| #include "Application.h" | |
| #include "Experiment.h" | |
| #include "DbeView.h" | |
| #include "Exp_Layout.h" | |
| #include "i18n.h" | |
| IOActivity::IOActivity (DbeView *_dbev) | |
| { | |
| dbev = _dbev; | |
| fDataHash = NULL; | |
| fDataTotal = NULL; | |
| fDataObjs = NULL; | |
| fDataObjsFile = NULL; | |
| hasFile = false; | |
| fDataObjsVfd = NULL; | |
| hasVfd = false; | |
| fDataObjsCallStack = NULL; | |
| hasCallStack = false; | |
| fDataCalStkMap = NULL; | |
| fDataVfdMap = NULL; | |
| hist_data_file_all = NULL; | |
| hist_data_vfd_all = NULL; | |
| hist_data_callstack_all = NULL; | |
| } | |
| void | |
| IOActivity::reset () | |
| { | |
| int numExps = dbeSession->nexps (); | |
| FileData *fData = NULL; | |
| DefaultMap<int64_t, FileData*>* fDataMap; | |
| for (int k = 0; k < numExps; k++) | |
| { | |
| Experiment *exp = dbeSession->get_exp (k); | |
| fDataMap = exp->getFDataMap (); | |
| if (fDataMap == NULL) | |
| continue; | |
| fDataObjs = fDataMap->values (); | |
| if (fDataObjs == NULL) | |
| continue; | |
| int numFiles = fDataObjs->size (); | |
| for (int j = 0; j < numFiles; j++) | |
| { | |
| fData = fDataObjs->fetch (j); | |
| fData->init (); | |
| } | |
| } | |
| delete fDataHash; | |
| fDataHash = NULL; | |
| delete fDataTotal; | |
| fDataTotal = NULL; | |
| delete fDataObjsFile; | |
| fDataObjsFile = NULL; | |
| hasFile = false; | |
| delete fDataObjsVfd; | |
| fDataObjsVfd = NULL; | |
| hasVfd = false; | |
| delete fDataObjsCallStack; | |
| fDataObjsCallStack = NULL; | |
| hasCallStack = false; | |
| delete fDataObjs; | |
| fDataObjs = NULL; | |
| delete fDataCalStkMap; | |
| fDataCalStkMap = NULL; | |
| delete fDataVfdMap; | |
| fDataVfdMap = NULL; | |
| // These three pointers are deleted by DbeView | |
| // They are named iofile_data, iovfd_data, and iocs_data | |
| hist_data_file_all = NULL; | |
| hist_data_vfd_all = NULL; | |
| hist_data_callstack_all = NULL; | |
| } | |
| void | |
| IOActivity::createHistItemTotals (Hist_data *hist_data, MetricList *mlist, | |
| Histable::Type hType, bool empty) | |
| { | |
| int mIndex; | |
| Metric *mtr; | |
| Hist_data::HistItem *hi; | |
| FileData *fData = NULL; | |
| if (fDataTotal == NULL) | |
| { | |
| fDataTotal = new FileData (TOTAL_FILENAME); | |
| fDataTotal->setHistType (hType); | |
| fDataTotal->setVirtualFd (VIRTUAL_FD_TOTAL); | |
| fDataTotal->id = 0; | |
| } | |
| fData = new FileData (fDataTotal); | |
| fData->setHistType (hType); | |
| hi = hist_data->append_hist_item (fData); | |
| Vec_loop (Metric *, mlist->get_items (), mIndex, mtr) | |
| { | |
| if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ()) | |
| continue; | |
| Metric::Type mtype = mtr->get_type (); | |
| ValueTag vType = mtr->get_vtype (); | |
| hist_data->total->value[mIndex].tag = vType; | |
| hi->value[mIndex].tag = vType; | |
| double prec = (double) NANOSEC; | |
| switch (mtype) | |
| { | |
| case BaseMetric::IO_READ_BYTES: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].ll = fDataTotal->getReadBytes (); | |
| hi->value[mIndex].ll = fDataTotal->getReadBytes (); | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].ll = 0; | |
| hi->value[mIndex].ll = 0; | |
| } | |
| break; | |
| case BaseMetric::IO_READ_CNT: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].ll = fDataTotal->getReadCnt (); | |
| hi->value[mIndex].ll = fDataTotal->getReadCnt (); | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].ll = 0; | |
| hi->value[mIndex].ll = 0; | |
| } | |
| break; | |
| case BaseMetric::IO_READ_TIME: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getReadTime () / prec; | |
| hi->value[mIndex].d = hist_data->total->value[mIndex].d; | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].d = 0.0; | |
| hi->value[mIndex].d = 0.0; | |
| } | |
| break; | |
| case BaseMetric::IO_WRITE_BYTES: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].ll = fDataTotal->getWriteBytes (); | |
| hi->value[mIndex].ll = fDataTotal->getWriteBytes (); | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].ll = 0; | |
| hi->value[mIndex].ll = 0; | |
| } | |
| break; | |
| case BaseMetric::IO_WRITE_CNT: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].ll = fDataTotal->getWriteCnt (); | |
| hi->value[mIndex].ll = fDataTotal->getWriteCnt (); | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].ll = 0; | |
| hi->value[mIndex].ll = 0; | |
| } | |
| break; | |
| case BaseMetric::IO_WRITE_TIME: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getWriteTime () / prec; | |
| hi->value[mIndex].d = hist_data->total->value[mIndex].d; | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].d = 0.0; | |
| hi->value[mIndex].d = 0.0; | |
| } | |
| break; | |
| case BaseMetric::IO_OTHER_CNT: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].ll = fDataTotal->getOtherCnt (); | |
| hi->value[mIndex].ll = fDataTotal->getOtherCnt (); | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].ll = 0; | |
| hi->value[mIndex].ll = 0; | |
| } | |
| break; | |
| case BaseMetric::IO_OTHER_TIME: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getOtherTime () / prec; | |
| hi->value[mIndex].d = hist_data->total->value[mIndex].d; | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].d = 0.0; | |
| hi->value[mIndex].d = 0.0; | |
| } | |
| break; | |
| case BaseMetric::IO_ERROR_CNT: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].ll = fDataTotal->getErrorCnt (); | |
| hi->value[mIndex].ll = fDataTotal->getErrorCnt (); | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].ll = 0; | |
| hi->value[mIndex].ll = 0; | |
| } | |
| break; | |
| case BaseMetric::IO_ERROR_TIME: | |
| if (!empty) | |
| { | |
| hist_data->total->value[mIndex].d = (double) fDataTotal->getErrorTime () / prec; | |
| hi->value[mIndex].d = hist_data->total->value[mIndex].d; | |
| } | |
| else | |
| { | |
| hist_data->total->value[mIndex].d = 0.0; | |
| hi->value[mIndex].d = 0.0; | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| void | |
| IOActivity::computeHistTotals (Hist_data *hist_data, MetricList *mlist) | |
| { | |
| int mIndex; | |
| Metric *mtr; | |
| Vec_loop (Metric *, mlist->get_items (), mIndex, mtr) | |
| { | |
| if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ()) | |
| continue; | |
| Metric::Type mtype = mtr->get_type (); | |
| ValueTag vType = mtr->get_vtype (); | |
| hist_data->total->value[mIndex].tag = vType; | |
| double prec = (double) NANOSEC; | |
| switch (mtype) | |
| { | |
| case BaseMetric::IO_READ_BYTES: | |
| hist_data->total->value[mIndex].ll = fDataTotal->getReadBytes (); | |
| break; | |
| case BaseMetric::IO_READ_CNT: | |
| hist_data->total->value[mIndex].ll = fDataTotal->getReadCnt (); | |
| break; | |
| case BaseMetric::IO_READ_TIME: | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getReadTime () / prec; | |
| break; | |
| case BaseMetric::IO_WRITE_BYTES: | |
| hist_data->total->value[mIndex].ll = fDataTotal->getWriteBytes (); | |
| break; | |
| case BaseMetric::IO_WRITE_CNT: | |
| hist_data->total->value[mIndex].ll = fDataTotal->getWriteCnt (); | |
| break; | |
| case BaseMetric::IO_WRITE_TIME: | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getWriteTime () / prec; | |
| break; | |
| case BaseMetric::IO_OTHER_CNT: | |
| hist_data->total->value[mIndex].ll = fDataTotal->getOtherCnt (); | |
| break; | |
| case BaseMetric::IO_OTHER_TIME: | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getOtherTime () / prec; | |
| break; | |
| case BaseMetric::IO_ERROR_CNT: | |
| hist_data->total->value[mIndex].ll = fDataTotal->getErrorCnt (); | |
| break; | |
| case BaseMetric::IO_ERROR_TIME: | |
| hist_data->total->value[mIndex].d = | |
| (double) fDataTotal->getErrorTime () / prec; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| void | |
| IOActivity::computeHistData (Hist_data *hist_data, MetricList *mlist, | |
| Hist_data::Mode mode, Histable *selObj) | |
| { | |
| Hist_data::HistItem *hi = NULL; | |
| int numObjs = fDataObjs->size (); | |
| int numMetrics = mlist->get_items ()->size (); | |
| for (int i = 0; i < numObjs; i++) | |
| { | |
| FileData *fData = fDataObjs->fetch (i); | |
| if (mode == Hist_data::ALL) | |
| hi = hist_data->append_hist_item (fData); | |
| else if (mode == Hist_data::SELF) | |
| { | |
| if (fData->id == selObj->id) | |
| hi = hist_data->append_hist_item (fData); | |
| else | |
| continue; | |
| } | |
| for (int mIndex = 0; mIndex < numMetrics; mIndex++) | |
| { | |
| Metric *mtr = mlist->get_items ()->fetch (mIndex); | |
| if (!mtr->is_visible () && !mtr->is_tvisible () | |
| && !mtr->is_pvisible ()) | |
| continue; | |
| Metric::Type mtype = mtr->get_type (); | |
| ValueTag vType = mtr->get_vtype (); | |
| hi->value[mIndex].tag = vType; | |
| double prec = (double) NANOSEC; | |
| switch (mtype) | |
| { | |
| case BaseMetric::IO_READ_BYTES: | |
| hi->value[mIndex].ll = fData->getReadBytes (); | |
| break; | |
| case BaseMetric::IO_READ_CNT: | |
| hi->value[mIndex].ll = fData->getReadCnt (); | |
| break; | |
| case BaseMetric::IO_READ_TIME: | |
| hi->value[mIndex].d = (double) fData->getReadTime () / prec; | |
| break; | |
| case BaseMetric::IO_WRITE_BYTES: | |
| hi->value[mIndex].ll = fData->getWriteBytes (); | |
| break; | |
| case BaseMetric::IO_WRITE_CNT: | |
| hi->value[mIndex].ll = fData->getWriteCnt (); | |
| break; | |
| case BaseMetric::IO_WRITE_TIME: | |
| hi->value[mIndex].d = (double) fData->getWriteTime () / prec; | |
| break; | |
| case BaseMetric::IO_OTHER_CNT: | |
| hi->value[mIndex].ll = fData->getOtherCnt (); | |
| break; | |
| case BaseMetric::IO_OTHER_TIME: | |
| hi->value[mIndex].d = (double) fData->getOtherTime () / prec; | |
| break; | |
| case BaseMetric::IO_ERROR_CNT: | |
| hi->value[mIndex].ll = fData->getErrorCnt (); | |
| break; | |
| case BaseMetric::IO_ERROR_TIME: | |
| hi->value[mIndex].d = (double) fData->getErrorTime () / prec; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| Hist_data * | |
| IOActivity::compute_metrics (MetricList *mlist, Histable::Type type, | |
| Hist_data::Mode mode, Histable *selObj) | |
| { | |
| // it's already there, just return it | |
| if (mode == Hist_data::ALL) | |
| { | |
| if (type == Histable::IOACTFILE && hist_data_file_all) | |
| return hist_data_file_all; | |
| else if (type == Histable::IOACTVFD && hist_data_vfd_all) | |
| return hist_data_vfd_all; | |
| else if (type == Histable::IOCALLSTACK && hist_data_callstack_all) | |
| return hist_data_callstack_all; | |
| } | |
| bool has_data = false; | |
| Hist_data *hist_data = NULL; | |
| VMode viewMode = dbev->get_view_mode (); | |
| switch (type) | |
| { | |
| case Histable::IOACTVFD: | |
| if (!hasVfd) | |
| computeData (type); | |
| // computeData() creates fDataObjsVfd | |
| // fDataObjsVfd contains the list of vfd objects | |
| if (fDataObjsVfd != NULL) | |
| { | |
| // fDataObjs is used in other methods | |
| fDataObjs = fDataObjsVfd; | |
| has_data = true; | |
| } | |
| else | |
| has_data = false; | |
| if (has_data && mode == Hist_data::ALL && hist_data_vfd_all == NULL) | |
| { | |
| hist_data_vfd_all = new Hist_data (mlist, type, mode, true); | |
| hist_data = hist_data_vfd_all; | |
| } | |
| else if (has_data) | |
| hist_data = new Hist_data (mlist, type, mode, false); | |
| else | |
| { | |
| hist_data = new Hist_data (mlist, type, mode, false); | |
| createHistItemTotals (hist_data, mlist, type, true); | |
| return hist_data; | |
| } | |
| break; | |
| case Histable::IOACTFILE: | |
| if (!hasFile) | |
| computeData (type); | |
| // computeData() creates fDataObjsFile | |
| // fDataObjsFile contains the list of file objects | |
| if (fDataObjsFile != NULL) | |
| { | |
| fDataObjs = fDataObjsFile; | |
| has_data = true; | |
| } | |
| else | |
| has_data = false; | |
| if (has_data && mode == Hist_data::ALL && hist_data_file_all == NULL) | |
| { | |
| hist_data_file_all = new Hist_data (mlist, type, mode, true); | |
| hist_data = hist_data_file_all; | |
| } | |
| else if (has_data) | |
| hist_data = new Hist_data (mlist, type, mode, false); | |
| else | |
| { | |
| hist_data = new Hist_data (mlist, type, mode, false); | |
| createHistItemTotals (hist_data, mlist, type, true); | |
| return hist_data; | |
| } | |
| break; | |
| case Histable::IOCALLSTACK: | |
| if (!hasCallStack) | |
| computeCallStack (type, viewMode); | |
| // computeCallStack() creates fDataObjsCallStack | |
| // fDataObjsCallStack contains the list of call stack objects | |
| if (fDataObjsCallStack != NULL) | |
| { | |
| fDataObjs = fDataObjsCallStack; | |
| has_data = true; | |
| } | |
| else | |
| has_data = false; | |
| if (has_data && (mode == Hist_data::ALL) && (hist_data_callstack_all == NULL)) | |
| { | |
| hist_data_callstack_all = new Hist_data (mlist, type, mode, true); | |
| hist_data = hist_data_callstack_all; | |
| } | |
| else if (has_data) | |
| hist_data = new Hist_data (mlist, type, mode, false); | |
| else | |
| { | |
| hist_data = new Hist_data (mlist, type, mode, false); | |
| createHistItemTotals (hist_data, mlist, type, true); | |
| return hist_data; | |
| } | |
| break; | |
| default: | |
| fprintf (stderr, | |
| "IOActivity cannot process data due to wrong Histable (type=%d) \n", | |
| type); | |
| abort (); | |
| } | |
| if (mode == Hist_data::ALL || (mode == Hist_data::SELF && selObj->id == 0)) | |
| createHistItemTotals (hist_data, mlist, type, false); | |
| else | |
| computeHistTotals (hist_data, mlist); | |
| computeHistData (hist_data, mlist, mode, selObj); | |
| // Determine by which metric to sort if any | |
| bool rev_sort = mlist->get_sort_rev (); | |
| int sort_ind = -1; | |
| int nmetrics = mlist->get_items ()->size (); | |
| for (int mind = 0; mind < nmetrics; mind++) | |
| if (mlist->get_sort_ref_index () == mind) | |
| sort_ind = mind; | |
| hist_data->sort (sort_ind, rev_sort); | |
| hist_data->compute_minmax (); | |
| return hist_data; | |
| } | |
| void | |
| IOActivity::computeData (Histable::Type type) | |
| { | |
| bool has_iodata = false; | |
| reset (); | |
| int64_t histableId = 0; // It is used by fDataAggr only | |
| // fData uses vfd for histable id | |
| fDataHash = new HashMap<char*, FileData*>; | |
| FileData *fData = NULL; | |
| FileData *fDataAggr = NULL; | |
| fDataTotal = new FileData (TOTAL_FILENAME); | |
| fDataTotal->setHistType (type); | |
| fDataTotal->setVirtualFd (VIRTUAL_FD_TOTAL); | |
| fDataTotal->id = histableId++; | |
| FileData *fDataStdin = new FileData (STDIN_FILENAME); | |
| fDataStdin->setFileDes (STDIN_FD); | |
| fDataStdin->setHistType (type); | |
| fDataStdin->setFsType ("N/A"); | |
| fDataStdin->id = histableId++; | |
| FileData *fDataStdout = new FileData (STDOUT_FILENAME); | |
| fDataStdout->setFileDes (STDOUT_FD); | |
| fDataStdout->setHistType (type); | |
| fDataStdout->setFsType ("N/A"); | |
| fDataStdout->id = histableId++; | |
| FileData *fDataStderr = new FileData (STDERR_FILENAME); | |
| fDataStderr->setFileDes (STDERR_FD); | |
| fDataStderr->setHistType (type); | |
| fDataStderr->setFsType ("N/A"); | |
| fDataStderr->id = histableId++; | |
| FileData *fDataOtherIO = new FileData (OTHERIO_FILENAME); | |
| fDataOtherIO->setFileDes (OTHERIO_FD); | |
| fDataOtherIO->setHistType (type); | |
| fDataOtherIO->setFsType ("N/A"); | |
| fDataOtherIO->id = histableId++; | |
| DefaultMap<int64_t, FileData*>* fDataMap; | |
| fDataObjsFile = NULL; | |
| fDataObjsVfd = NULL; | |
| // get the list of io events from DbeView | |
| int numExps = dbeSession->nexps (); | |
| for (int k = 0; k < numExps; k++) | |
| { | |
| DataView *ioPkts = dbev->get_filtered_events (k, DATA_IOTRACE); | |
| if (ioPkts == NULL || ioPkts->getSize () <= 0) | |
| continue; | |
| Experiment *exp = dbeSession->get_exp (k); | |
| fDataMap = exp->getFDataMap (); | |
| if (fDataMap == NULL) | |
| continue; | |
| delete fDataVfdMap; | |
| fDataVfdMap = new DefaultMap<long, FileData*>; | |
| long sz = ioPkts->getSize (); | |
| for (long i = 0; i < sz; ++i) | |
| { | |
| hrtime_t event_duration = ioPkts->getLongValue (PROP_EVT_TIME, i); | |
| int64_t nByte = ioPkts->getLongValue (PROP_IONBYTE, i); | |
| IOTrace_type ioType = (IOTrace_type) ioPkts->getIntValue (PROP_IOTYPE, i); | |
| int64_t vFd = ioPkts->getLongValue (PROP_IOVFD, i); | |
| if (vFd >= 0) | |
| { | |
| fData = fDataMap->get (vFd); | |
| if (fData == NULL) | |
| continue; | |
| } | |
| else | |
| continue; | |
| if (fDataVfdMap->get (vFd) == NULL) | |
| fDataVfdMap->put (vFd, fData); | |
| switch (ioType) | |
| { | |
| case READ_TRACE: | |
| fData->addReadEvent (event_duration, nByte); | |
| // Set the Histable id for IOVFD | |
| fData->id = fData->getVirtualFd (); | |
| fDataTotal->addReadEvent (event_duration, nByte); | |
| fDataTotal->setReadStat (event_duration, nByte); | |
| break; | |
| case WRITE_TRACE: | |
| fData->addWriteEvent (event_duration, nByte); | |
| // Set the Histable id for IOVFD | |
| fData->id = fData->getVirtualFd (); | |
| fDataTotal->addWriteEvent (event_duration, nByte); | |
| fDataTotal->setWriteStat (event_duration, nByte); | |
| break; | |
| case OPEN_TRACE: | |
| fData->addOtherEvent (event_duration); | |
| // Set the Histable id for IOVFD | |
| fData->id = fData->getVirtualFd (); | |
| fDataTotal->addOtherEvent (event_duration); | |
| break; | |
| case CLOSE_TRACE: | |
| case OTHERIO_TRACE: | |
| fData->addOtherEvent (event_duration); | |
| // Set the Histable id for IOVFD | |
| fData->id = fData->getVirtualFd (); | |
| fDataTotal->addOtherEvent (event_duration); | |
| break; | |
| case READ_TRACE_ERROR: | |
| case WRITE_TRACE_ERROR: | |
| case OPEN_TRACE_ERROR: | |
| case CLOSE_TRACE_ERROR: | |
| case OTHERIO_TRACE_ERROR: | |
| fData->addErrorEvent (event_duration); | |
| // Set the Histable id for IOVFD | |
| fData->id = fData->getVirtualFd (); | |
| fDataTotal->addErrorEvent (event_duration); | |
| break; | |
| case IOTRACETYPE_LAST: | |
| break; | |
| } | |
| if (type == Histable::IOACTFILE) | |
| { | |
| fDataAggr = fDataHash->get (fData->getFileName ()); | |
| if (fDataAggr == NULL) | |
| { | |
| bool setInfo = false; | |
| if (vFd == VIRTUAL_FD_STDIN) | |
| fDataAggr = fDataStdin; | |
| else if (vFd == VIRTUAL_FD_STDOUT) | |
| fDataAggr = fDataStdout; | |
| else if (vFd == VIRTUAL_FD_STDERR) | |
| fDataAggr = fDataStderr; | |
| else if (vFd == VIRTUAL_FD_OTHERIO) | |
| fDataAggr = fDataOtherIO; | |
| else | |
| { | |
| fDataAggr = new FileData (fData->getFileName ()); | |
| setInfo = true; | |
| } | |
| fDataHash->put (fData->getFileName (), fDataAggr); | |
| if (setInfo) | |
| { | |
| fDataAggr->setFsType (fData->getFsType ()); | |
| fDataAggr->setHistType (type); | |
| // Set the Histable id for aggregated file name | |
| fDataAggr->id = histableId; | |
| fDataAggr->setVirtualFd (histableId); | |
| histableId++; | |
| } | |
| } | |
| fDataAggr->setFileDesList (fData->getFileDes ()); | |
| fDataAggr->setVirtualFds (fData->getVirtualFd ()); | |
| switch (ioType) | |
| { | |
| case READ_TRACE: | |
| fDataAggr->addReadEvent (event_duration, nByte); | |
| break; | |
| case WRITE_TRACE: | |
| fDataAggr->addWriteEvent (event_duration, nByte); | |
| break; | |
| case OPEN_TRACE: | |
| fDataAggr->addOtherEvent (event_duration); | |
| break; | |
| case CLOSE_TRACE: | |
| case OTHERIO_TRACE: | |
| fDataAggr->addOtherEvent (event_duration); | |
| break; | |
| case READ_TRACE_ERROR: | |
| case WRITE_TRACE_ERROR: | |
| case OPEN_TRACE_ERROR: | |
| case CLOSE_TRACE_ERROR: | |
| case OTHERIO_TRACE_ERROR: | |
| fDataAggr->addErrorEvent (event_duration); | |
| break; | |
| case IOTRACETYPE_LAST: | |
| break; | |
| } | |
| } | |
| has_iodata = true; | |
| } | |
| if (sz > 0) | |
| { | |
| if (fDataObjsVfd == NULL) | |
| fDataObjsVfd = new Vector<FileData*>; | |
| fDataObjsVfd->addAll (fDataVfdMap->values ()); | |
| hasVfd = true; | |
| } | |
| } | |
| if (has_iodata && type == Histable::IOACTFILE) | |
| { | |
| fDataObjsFile = fDataHash->values ()->copy (); | |
| hasFile = true; | |
| } | |
| } | |
| void | |
| IOActivity::computeCallStack (Histable::Type type, VMode viewMode) | |
| { | |
| bool has_data = false; | |
| int64_t stackIndex = 0; | |
| FileData *fData = NULL; | |
| delete fDataCalStkMap; | |
| fDataCalStkMap = new DefaultMap<void*, FileData*>; | |
| delete fDataTotal; | |
| fDataTotal = new FileData (TOTAL_FILENAME); | |
| fDataTotal->setHistType (type); | |
| // There is no call stack for total, use the index for id | |
| fDataTotal->id = stackIndex++; | |
| // get the list of io events from DbeView | |
| int numExps = dbeSession->nexps (); | |
| for (int k = 0; k < numExps; k++) | |
| { | |
| DataView *ioPkts = dbev->get_filtered_events (k, DATA_IOTRACE); | |
| if (ioPkts == NULL || ioPkts->getSize () <= 0) | |
| continue; | |
| long sz = ioPkts->getSize (); | |
| for (long i = 0; i < sz; ++i) | |
| { | |
| hrtime_t event_duration = ioPkts->getLongValue (PROP_EVT_TIME, i); | |
| int64_t nByte = ioPkts->getLongValue (PROP_IONBYTE, i); | |
| void *stackId = getStack (viewMode, ioPkts, i); | |
| IOTrace_type ioType = | |
| (IOTrace_type) ioPkts->getIntValue (PROP_IOTYPE, i); | |
| int64_t vFd = ioPkts->getLongValue (PROP_IOVFD, i); | |
| if (stackId != NULL && vFd > 0) | |
| { | |
| fData = fDataCalStkMap->get (stackId); | |
| if (fData == NULL) | |
| { | |
| char *stkName = dbe_sprintf (GTXT ("Stack 0x%llx"), | |
| (unsigned long long) stackId); | |
| fData = new FileData (stkName); | |
| fDataCalStkMap->put (stackId, fData); | |
| fData->id = (int64_t) stackId; | |
| fData->setVirtualFd (stackIndex); | |
| stackIndex++; | |
| fData->setHistType (type); | |
| } | |
| } | |
| else | |
| continue; | |
| switch (ioType) | |
| { | |
| case READ_TRACE: | |
| fData->addReadEvent (event_duration, nByte); | |
| fDataTotal->addReadEvent (event_duration, nByte); | |
| fDataTotal->setReadStat (event_duration, nByte); | |
| break; | |
| case WRITE_TRACE: | |
| fData->addWriteEvent (event_duration, nByte); | |
| fDataTotal->addWriteEvent (event_duration, nByte); | |
| fDataTotal->setWriteStat (event_duration, nByte); | |
| break; | |
| case OPEN_TRACE: | |
| fData->addOtherEvent (event_duration); | |
| fDataTotal->addOtherEvent (event_duration); | |
| break; | |
| case CLOSE_TRACE: | |
| case OTHERIO_TRACE: | |
| fData->addOtherEvent (event_duration); | |
| fDataTotal->addOtherEvent (event_duration); | |
| break; | |
| case READ_TRACE_ERROR: | |
| case WRITE_TRACE_ERROR: | |
| case OPEN_TRACE_ERROR: | |
| fData->addErrorEvent (event_duration); | |
| fDataTotal->addErrorEvent (event_duration); | |
| break; | |
| case CLOSE_TRACE_ERROR: | |
| case OTHERIO_TRACE_ERROR: | |
| fData->addErrorEvent (event_duration); | |
| fDataTotal->addErrorEvent (event_duration); | |
| break; | |
| case IOTRACETYPE_LAST: | |
| break; | |
| } | |
| has_data = true; | |
| } | |
| } | |
| if (has_data) | |
| { | |
| fDataObjsCallStack = fDataCalStkMap->values ()->copy (); | |
| hasCallStack = true; | |
| } | |
| } |