ff4ff35918
Red Bear OS is a full fork. All sources must be available from git clone with zero network access. Removed gitignore rules that excluded fetched source trees under recipes/*/source/, local/recipes/kde/*/source/, local/recipes/qt/*/source/, and vendor source trees. Build artifacts (target/, build/, source.tar, *.o, *.so) remain excluded. 127291 files added — kernel, relibc, base, bootloader, pkgar, all KDE/Qt frameworks, mesa, wayland, DRM drivers, and every other recipe source.
826 lines
22 KiB
C++
826 lines
22 KiB
C++
/* 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;
|
|
}
|
|
}
|