void  TrackingKymoView::DeleteSameTData(std::set<unsigned int> samet_selection)
{
	std::set<unsigned int>::iterator sel_iter = samet_selection.begin();
	TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashc[*sel_iter]);
	int new_id = this->GetMaxId()+1;

	// first find the trace line in the data to erase it:
	std::vector<TraceLine*>* trace_lines  = m_tobj->GetTraceLinesPointer();
	std::vector<TraceLine*>::iterator trace_lines_iter;
	for(trace_lines_iter = trace_lines->begin() ;trace_lines_iter!= trace_lines->end(); ++trace_lines_iter)
	{
		if(tline->GetId() == (*trace_lines_iter)->GetId())
		{
			trace_lines->erase(trace_lines_iter);
			break;
		}
	}

	printf("I am here\n");

	TraceLine * tline_tmp = new TraceLine();
	tline_tmp = tline;
	sel_iter = samet_selection.begin();
	while(sel_iter != samet_selection.end())
	{
		TraceBit tb1 = tline->subtrace_hash[*sel_iter].at(0);
		TraceBit tb2 = tline->subtrace_hash[*sel_iter].at(1);
		int maxtime = MAX(tb1.time,tb2.time);
		tline_tmp = this->DeleteTlineRecursive(tline_tmp,*sel_iter,new_id,maxtime);
		++new_id;
		++sel_iter;
	}
	trace_lines->push_back(tline_tmp);

}
Beispiel #2
0
// for code lines
InstrItem::InstrItem(InstrView* iv, QTreeWidget* parent,
		     Addr addr, bool inside,
		     const QString& code, const QString& cmd,
		     const QString& args, TraceInstr* instr)
    : QTreeWidgetItem(parent)
{
  _view = iv;
  _addr = addr;
  _instr = instr;
  _instrCall = 0;
  _instrJump = 0;
  _inside = inside;

  setTextAlignment(0, Qt::AlignRight);
  setTextAlignment(1, Qt::AlignRight);
  setTextAlignment(2, Qt::AlignRight);

  if (args == "...")
      setText(0, args);
  else
      setText(0, addr.pretty());
  setText(4, code);
  setText(5, cmd);
  setText(6, args);

  TraceLine* l;
  if (instr && (l = instr->line()))
      setText(7, l->name());

  updateGroup();
  updateCost();
}
Beispiel #3
0
void SourceView::context(QListViewItem* i, const QPoint & p, int c)
{
  QPopupMenu popup;

  // Menu entry:
  TraceLineCall* lc = i ? ((SourceItem*) i)->lineCall() : 0;
  TraceLineJump* lj = i ? ((SourceItem*) i)->lineJump() : 0;
  TraceFunction* f = lc ? lc->call()->called() : 0;
  TraceLine* line = lj ? lj->lineTo() : 0;

  if (f) {
    QString name = f->name();
    if ((int)name.length()>Configuration::maxSymbolLength())
      name = name.left(Configuration::maxSymbolLength()) + "...";
    popup.insertItem(i18n("Go to '%1'").arg(name), 93);
    popup.insertSeparator();
  }
  else if (line) {
    popup.insertItem(i18n("Go to Line %1").arg(line->name()), 93);
    popup.insertSeparator();
  }

  if ((c == 1) || (c == 2)) {
    addCostMenu(&popup);
    popup.insertSeparator();
  }
  addGoMenu(&popup);

  int r = popup.exec(p);
  if (r == 93) {
    if (f) activated(f);
    if (line) activated(line);
  }
}
void TrackingKymoView::GenerateTracks()
{
	printf("Started GenerateTracks\n");
//	std::vector<std::vector<ftk::LabelImageFeatures>> *f = m_model->getFeatures();
	std::vector< std::vector<ftk::IntrinsicFeatures> > *f = &myfeatures;
	int max_track_num = 0;
	for(int cox=0; cox< f->size(); cox++)
	{
		for(int coy =0; coy < (*f)[cox].size(); coy ++)
		{
			max_track_num = MAX((*f)[cox][coy].num,max_track_num);
		}
	}
	printf("Computed max_track_num = %d\n",max_track_num);
	double time_offset  = 5;//(m_model->getRawImagePointer(0)->GetLargestPossibleRegion().GetSize()[2])*3;//*((*f)[0][0].spacing[2]);


	printf("About to start creating tobj\n");
	m_tobj = new TraceObject();
	for(int counter= 0; counter<= max_track_num; counter++)
	{
		TraceLine *tline = new TraceLine();
		bool once = false;
		for(int cox=0; cox< f->size(); cox++)
		{
			for(int coy =0; coy < (*f)[cox].size(); coy ++)
			{
				if((*f)[cox][coy].num == counter)
				{
					TraceBit tbit;
					tbit.x = (*f)[cox][coy].Centroid[0]*1.0;
					tbit.y = (*f)[cox][coy].Centroid[1]*1.0;
					tbit.z = ((*f)[cox][coy].time)*(time_offset);
					tbit.time = (*f)[cox][coy].time;
						
					tbit.id = (*f)[cox][coy].num;
					printf("About to add TraceBit\n");
					tline->AddTraceBit(tbit);
					once = true;
				}
			}
		}
		if(once)
		{
			m_tobj->GetTraceLinesPointer()->push_back(tline);
			printf("Added one tline\n");
		}
		else
		{
			delete tline;
		}
	}
	printf("Finished GenerateTracks() \n");
	return;
} 
void  TrackingKymoView::DeleteDiffTData(std::set<unsigned int> difft_selection)
{
	std::set<unsigned int>::iterator sel_iter;
	for(sel_iter = difft_selection.begin(); sel_iter!= difft_selection.end(); ++sel_iter)
	{
		unsigned int vtk_cell_id = *sel_iter;
		
		TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashc[vtk_cell_id]);
		std::cout<<"deleting cell:"<<vtk_cell_id<<" with id: "<<tline->GetId()<<std::endl;
		TraceBit tb1 = tline->subtrace_hash[vtk_cell_id].at(0);
		TraceBit tb2 = tline->subtrace_hash[vtk_cell_id].at(1);
		int maxtime = MAX(tb1.time,tb2.time);

		std::vector<TraceLine*>* trace_lines  = m_tobj->GetTraceLinesPointer();
		std::vector<TraceLine*>::iterator trace_lines_iter;
		for(trace_lines_iter = trace_lines->begin() ;trace_lines_iter!= trace_lines->end(); ++trace_lines_iter)
		{
			if(tline->GetId() == (*trace_lines_iter)->GetId())
			{
				int new_id = this->GetMaxId()+1;
				trace_lines->erase(trace_lines_iter);
				TraceLine::TraceBitsType::iterator tbit_iter = tline->GetTraceBitIteratorBegin();
				TraceLine * new_tline1 = new TraceLine();
				TraceLine * new_tline2 = new TraceLine();
				ObjectSelection::Point point;
				
				while(tbit_iter != tline->GetTraceBitIteratorEnd())
				{
					if((*tbit_iter).time < maxtime)
					{
						new_tline1->AddTraceBit(*tbit_iter);
					}
					else 
					{
						point.id = tbit_iter->id;
						point.time = tbit_iter->time;
						(*tbit_iter).id = new_id;
						point.new_id = new_id;
						points_from_delete.push_back(point);
						new_tline2->AddTraceBit(*tbit_iter);
					}
					++tbit_iter;
				}
				trace_lines->push_back(new_tline1);
				new_tline2->SetId(new_id);
				trace_lines->push_back(new_tline2);
				break;
			}
		}
	}

}
void TrackingKymoView::DeleteAndRelabelData(void)
{
	if(TSelection.empty()) return;
	
	std::vector<unsigned int> tmp_selection;
	std::set<unsigned int> samet_selection;	// list of sub-tracks selected within the same track
	//std::set<unsigned int> difft_selection;
	std::map<int, std::set<unsigned int> > selection_map;

	std::set<unsigned int>::iterator sel_iter;

	for(sel_iter = TSelection.begin(); sel_iter!= TSelection.end(); ++sel_iter)
		tmp_selection.push_back(*sel_iter);

	// figure out the number of different selected tracks:
	std::set<int> selected_ids;
	for(int i = 0; i< tmp_selection.size(); ++i)
	{
		TraceLine *tline1 = reinterpret_cast<TraceLine*>(m_tobj->hashc[tmp_selection.at(i)]);
		selected_ids.insert(tline1->GetId());
	}
	std::set<int>::iterator sel_ids_iter;
	for(sel_ids_iter = selected_ids.begin(); sel_ids_iter!= selected_ids.end(); ++sel_ids_iter)
	{
		std::set<unsigned int> samet_selection;
		for(int i = 0; i< tmp_selection.size(); ++i)
		{
			TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashc[tmp_selection.at(i)]);
			int id = tline->GetId();
			if(tline->GetId() == *sel_ids_iter)
				samet_selection.insert(tmp_selection.at(i));
		}
		selection_map[*sel_ids_iter] = samet_selection;
	}
	std::map<int, std::set<unsigned int> >::iterator select_map_iter;
	for(select_map_iter = selection_map.begin(); select_map_iter!= selection_map.end(); ++select_map_iter)
	{
		if(!(*select_map_iter).second.empty()&& (*select_map_iter).second.size()>1)
			this->DeleteSameTData((*select_map_iter).second);
		else if(!(*select_map_iter).second.empty()&& (*select_map_iter).second.size()==1)
			this->DeleteDiffTData((*select_map_iter).second);
	}
	if(!points_from_delete.empty())
	{
		Selection->SelectPoints(points_from_delete);
		points_from_delete.clear();
	}

	
}
void NVMain::PrintPreTrace( NVMainRequest *request )
{
    /*
     *  Here we can generate a data trace to use with trace-based testing later.
     */
    if( p->PrintPreTrace || p->EchoPreTrace )
    {
        TraceLine tl;

        tl.SetLine( request->address,
                    request->type,
                    GetEventQueue( )->GetCurrentCycle( ),
                    request->data,
                    request->threadId 
                  );

        preTracer->SetNextAccess( &tl );
    }
}
Beispiel #8
0
/**
 * The main import function...
 */
int CachegrindLoader::loadInternal(TraceData* data,
                                   QIODevice* device, const QString& filename)
{
    if (!data || !device) return 0;

    _data = data;
    _filename = filename;
    _lineNo = 0;

    loadStart(_filename);

    FixFile file(device, _filename);
    if (!file.exists()) {
        loadFinished(QStringLiteral("File does not exist"));
        return 0;
    }

    int statusProgress = 0;

#if USE_FIXCOST
    // FixCost Memory Pool
    FixPool* pool = _data->fixPool();
#endif

    _part = 0;
    partsAdded = 0;
    prepareNewPart();

    FixString line;
    char c;

    // current position
    nextLineType  = SelfCost;
    // default if there is no "positions:" line
    hasLineInfo = true;
    hasAddrInfo = false;

    while (file.nextLine(line)) {

        _lineNo++;

#if TRACE_LOADER
        qDebug() << "[CachegrindLoader] " << _filename << ":" << _lineNo
                 << " - '" << QString(line) << "'";
#endif

        // if we cannot strip a character, this was an empty line
        if (!line.first(c)) continue;

        if (c <= '9') {

            if (c == '#') continue;

            // parse position(s)
            if (!parsePosition(line, currentPos)) {
                error(QStringLiteral("Invalid position specification '%1'").arg(line));
                continue;
            }

            // go through after big switch
        }
        else { // if (c > '9')

            line.stripFirst(c);

            /* in order of probability */
            switch(c) {

            case 'f':

                // fl=
                if (line.stripPrefix("l=")) {

                    setFile(line);
                    // this is the default for new functions
                    currentFunctionFile = currentFile;
                    continue;
                }

                // fi=, fe=
                if (line.stripPrefix("i=") ||
                    line.stripPrefix("e=")) {

                    setFile(line);
                    continue;
                }

                // fn=
                if (line.stripPrefix("n=")) {

                    if (currentFile != currentFunctionFile)
                        currentFile = currentFunctionFile;
                    setFunction(line);

                    // on a new function, update status
                    int progress = (int)(100.0 * file.current() / file.len() +.5);
                    if (progress != statusProgress) {
                        statusProgress = progress;

                        /* When this signal is connected, it most probably
         * should lead to GUI update. Thus, when multiple
         * "long operations" (like file loading) are in progress,
         * this can temporarly switch to another operation.
         */
                        loadProgress(statusProgress);
                    }

                    continue;
                }

                break;

            case 'c':
                // cob=
                if (line.stripPrefix("ob=")) {
                    setCalledObject(line);
                    continue;
                }

                // cfi= / cfl=
                if (line.stripPrefix("fl=") ||
                    line.stripPrefix("fi=")) {
                    setCalledFile(line);
                    continue;
                }

                // cfn=
                if (line.stripPrefix("fn=")) {

                    setCalledFunction(line);
                    continue;
                }

                // calls=
                if (line.stripPrefix("alls=")) {
                    // ignore long lines...
                    line.stripUInt64(currentCallCount);
                    nextLineType = CallCost;
                    continue;
                }

                // cmd:
                if (line.stripPrefix("md:")) {
                    QString command = QString(line).trimmed();
                    if (!_data->command().isEmpty() &&
                        _data->command() != command) {

                        error(QStringLiteral("Redefined command, was '%1'").arg(_data->command()));
                    }
                    _data->setCommand(command);
                    continue;
                }

                // creator:
                if (line.stripPrefix("reator:")) {
                    // ignore ...
                    continue;
                }

                break;

            case 'j':

                // jcnd=
                if (line.stripPrefix("cnd=")) {
                    bool valid;

                    valid = line.stripUInt64(jumpsFollowed) &&
                            line.stripPrefix("/") &&
                            line.stripUInt64(jumpsExecuted) &&
                            parsePosition(line, targetPos);

                    if (!valid) {
                        error(QStringLiteral("Invalid line after 'jcnd'"));
                    }
                    else
                        nextLineType = CondJump;
                    continue;
                }

                if (line.stripPrefix("ump=")) {
                    bool valid;

                    valid = line.stripUInt64(jumpsExecuted) &&
                            parsePosition(line, targetPos);

                    if (!valid) {
                        error(QStringLiteral("Invalid line after 'jump'"));
                    }
                    else
                        nextLineType = BoringJump;
                    continue;
                }

                // jfi=
                if (line.stripPrefix("fi=")) {
                    currentJumpToFile = compressedFile(line);
                    continue;
                }

                // jfn=
                if (line.stripPrefix("fn=")) {

                    if (!currentJumpToFile) {
                        // !=0 as functions needs file
                        currentJumpToFile = currentFile;
                    }

                    currentJumpToFunction =
                            compressedFunction(line,
                                               currentJumpToFile,
                                               currentObject);
                    continue;
                }

                break;

            case 'o':

                // ob=
                if (line.stripPrefix("b=")) {
                    setObject(line);
                    continue;
                }

                break;

            case '#':
                continue;

            case 'a':
                // "arch: arm"
                if (line.stripPrefix("rch: arm")) {
                    TraceData::Arch a = _data->architecture();
                    if ((a != TraceData::ArchUnknown) &&
                        (a != TraceData::ArchARM)) {
                        error(QStringLiteral("Redefined architecture!"));
                    }
                    _data->setArchitecture(TraceData::ArchARM);
                    continue;
                }
                break;

            case 't':

                // totals:
                if (line.stripPrefix("otals:")) continue;

                // thread:
                if (line.stripPrefix("hread:")) {
                    prepareNewPart();
                    _part->setThreadID(QString(line).toInt());
                    continue;
                }

                // timeframe (BB):
                if (line.stripPrefix("imeframe (BB):")) {
                    _part->setTimeframe(line);
                    continue;
                }

                break;

            case 'd':

                // desc:
                if (line.stripPrefix("esc:")) {

                    line.stripSurroundingSpaces();

                    // desc: Trigger:
                    if (line.stripPrefix("Trigger:")) {
                        _part->setTrigger(line);
                    }

                    continue;
                }
                break;

            case 'e':

                // events:
                if (line.stripPrefix("vents:")) {
                    prepareNewPart();
                    mapping = _data->eventTypes()->createMapping(line);
                    _part->setEventMapping(mapping);
                    continue;
                }

                // event:<name>[=<formula>][:<long name>]
                if (line.stripPrefix("vent:")) {
                    line.stripSurroundingSpaces();

                    FixString e, f, l;
                    if (!line.stripName(e)) {
                        error(QStringLiteral("Invalid event"));
                        continue;
                    }
                    line.stripSpaces();
                    if (!line.stripFirst(c)) continue;

                    if (c=='=') f = line.stripUntil(':');
                    line.stripSpaces();

                    // add to known cost types
                    if (line.isEmpty()) line = e;
                    EventType::add(new EventType(e,line,f));
                    continue;
                }
                break;

            case 'p':

                // part:
                if (line.stripPrefix("art:")) {
                    prepareNewPart();
                    _part->setPartNumber(QString(line).toInt());
                    continue;
                }

                // pid:
                if (line.stripPrefix("id:")) {
                    prepareNewPart();
                    _part->setProcessID(QString(line).toInt());
                    continue;
                }

                // positions:
                if (line.stripPrefix("ositions:")) {
                    prepareNewPart();
                    QString positions(line);
                    hasLineInfo = positions.contains(QStringLiteral("line"));
                    hasAddrInfo = positions.contains(QStringLiteral("instr"));
                    continue;
                }
                break;

            case 'v':

                // version:
                if (line.stripPrefix("ersion:")) {
                    // ignore for now
                    continue;
                }
                break;

            case 's':

                // summary:
                if (line.stripPrefix("ummary:")) {
                    if (!mapping) {
                        error(QStringLiteral("No event line found. Skipping file"));
                        delete _part;
                        return false;
                    }

                    _part->totals()->set(mapping, line);
                    continue;
                }

            case 'r':

                // rcalls= (deprecated)
                if (line.stripPrefix("calls=")) {
                    // handle like normal calls: we need the sum of call count
                    // recursive cost is discarded in cycle detection
                    line.stripUInt64(currentCallCount);
                    nextLineType = CallCost;

                    warning(QStringLiteral("Old file format using deprecated 'rcalls'"));
                    continue;
                }
                break;

            default:
                break;
            }

            error(QStringLiteral("Invalid line '%1%2'").arg(c).arg(line));
            continue;
        }

        if (!mapping) {
            error(QStringLiteral("No event line found. Skipping file"));
            delete _part;
            return false;
        }

        // for a cost line, we always need a current function
        ensureFunction();



        if (!currentFunctionSource ||
            (currentFunctionSource->file() != currentFile)) {
            currentFunctionSource = currentFunction->sourceFile(currentFile,
                                                                true);
        }

#if !USE_FIXCOST
        if (hasAddrInfo) {
            if (!currentInstr ||
                (currentInstr->addr() != currentPos.fromAddr)) {
                currentInstr = currentFunction->instr(currentPos.fromAddr,
                                                      true);

                if (!currentInstr) {
                    error(QString("Invalid address '%1'").arg(currentPos.fromAddr.toString()));

                    continue;
                }

                currentPartInstr = currentInstr->partInstr(_part,
                                                           currentPartFunction);
            }
        }

        if (hasLineInfo) {
            if (!currentLine ||
                (currentLine->lineno() != currentPos.fromLine)) {

                currentLine = currentFunctionSource->line(currentPos.fromLine,
                                                          true);
                currentPartLine = currentLine->partLine(_part,
                                                        currentPartFunction);
            }
            if (hasAddrInfo && currentInstr)
                currentInstr->setLine(currentLine);
        }
#endif

#if TRACE_LOADER
        qDebug() << _filename << ":" << _lineNo;
        qDebug() << "  currentInstr "
                 << (currentInstr ? qPrintable(currentInstr->toString()) : ".");
        qDebug() << "  currentLine "
                 << (currentLine ? qPrintable(currentLine->toString()) : ".")
                 << "( file " << currentFile->name() << ")";
        qDebug() << "  currentFunction "
                 << qPrintable(currentFunction->prettyName());
        qDebug() << "  currentCalled "
                 << (currentCalledFunction ? qPrintable(currentCalledFunction->prettyName()) : ".");
#endif

        // create cost item

        if (nextLineType == SelfCost) {

#if USE_FIXCOST
            new (pool) FixCost(_part, pool,
                               currentFunctionSource,
                               currentPos,
                               currentPartFunction,
                               line);
#else
            if (hasAddrInfo) {
                TracePartInstr* partInstr;
                partInstr = currentInstr->partInstr(_part, currentPartFunction);

                if (hasLineInfo) {
                    // we need to set <line> back after reading for the line
                    int l = line.len();
                    const char* s = line.ascii();

                    partInstr->addCost(mapping, line);
                    line.set(s,l);
                }
                else
                    partInstr->addCost(mapping, line);
            }

            if (hasLineInfo) {
                TracePartLine* partLine;
                partLine = currentLine->partLine(_part, currentPartFunction);
                partLine->addCost(mapping, line);
            }
#endif

            if (!line.isEmpty()) {
                error(QStringLiteral("Garbage at end of cost line ('%1')").arg(line));
            }
        }
        else if (nextLineType == CallCost) {
            nextLineType = SelfCost;

            TraceCall* calling = currentFunction->calling(currentCalledFunction);
            TracePartCall* partCalling =
                    calling->partCall(_part, currentPartFunction,
                                      currentCalledPartFunction);

#if USE_FIXCOST
            FixCallCost* fcc;
            fcc = new (pool) FixCallCost(_part, pool,
                                         currentFunctionSource,
                                         hasLineInfo ? currentPos.fromLine : 0,
                                         hasAddrInfo ? currentPos.fromAddr : Addr(0),
                                         partCalling,
                                         currentCallCount, line);
            fcc->setMax(_data->callMax());
            _data->updateMaxCallCount(fcc->callCount());
#else
            if (hasAddrInfo) {
                TraceInstrCall* instrCall;
                TracePartInstrCall* partInstrCall;

                instrCall = calling->instrCall(currentInstr);
                partInstrCall = instrCall->partInstrCall(_part, partCalling);
                partInstrCall->addCallCount(currentCallCount);

                if (hasLineInfo) {
                    // we need to set <line> back after reading for the line
                    int l = line.len();
                    const char* s = line.ascii();

                    partInstrCall->addCost(mapping, line);
                    line.set(s,l);
                }
                else
                    partInstrCall->addCost(mapping, line);

                // update maximum of call cost
                _data->callMax()->maxCost(partInstrCall);
                _data->updateMaxCallCount(partInstrCall->callCount());
            }

            if (hasLineInfo) {
                TraceLineCall* lineCall;
                TracePartLineCall* partLineCall;

                lineCall = calling->lineCall(currentLine);
                partLineCall = lineCall->partLineCall(_part, partCalling);

                partLineCall->addCallCount(currentCallCount);
                partLineCall->addCost(mapping, line);

                // update maximum of call cost
                _data->callMax()->maxCost(partLineCall);
                _data->updateMaxCallCount(partLineCall->callCount());
            }
#endif
            currentCalledFile = 0;
            currentCalledPartFile = 0;
            currentCalledObject = 0;
            currentCalledPartObject = 0;
            currentCallCount = 0;

            if (!line.isEmpty()) {
                error(QStringLiteral("Garbage at end of call cost line ('%1')").arg(line));
            }
        }
        else { // (nextLineType == BoringJump || nextLineType == CondJump)

            TraceFunctionSource* targetSource;

            if (!currentJumpToFunction)
                currentJumpToFunction = currentFunction;

            targetSource = (currentJumpToFile) ?
                               currentJumpToFunction->sourceFile(currentJumpToFile, true) :
                               currentFunctionSource;

#if USE_FIXCOST
            new (pool) FixJump(_part, pool,
                               /* source */
                               hasLineInfo ? currentPos.fromLine : 0,
                               hasAddrInfo ? currentPos.fromAddr : 0,
                               currentPartFunction,
                               currentFunctionSource,
                               /* target */
                               hasLineInfo ? targetPos.fromLine : 0,
                               hasAddrInfo ? targetPos.fromAddr : Addr(0),
                               currentJumpToFunction,
                               targetSource,
                               (nextLineType == CondJump),
                               jumpsExecuted, jumpsFollowed);
#else
            if (hasAddrInfo) {
                TraceInstr* jumpToInstr;
                TraceInstrJump* instrJump;
                TracePartInstrJump* partInstrJump;

                jumpToInstr = currentJumpToFunction->instr(targetPos.fromAddr,
                                                           true);
                instrJump = currentInstr->instrJump(jumpToInstr,
                                                    (nextLineType == CondJump));
                partInstrJump = instrJump->partInstrJump(_part);
                partInstrJump->addExecutedCount(jumpsExecuted);
                if (nextLineType == CondJump)
                    partInstrJump->addFollowedCount(jumpsFollowed);
            }

            if (hasLineInfo) {
                TraceLine* jumpToLine;
                TraceLineJump* lineJump;
                TracePartLineJump* partLineJump;

                jumpToLine = targetSource->line(targetPos.fromLine, true);
                lineJump = currentLine->lineJump(jumpToLine,
                                                 (nextLineType == CondJump));
                partLineJump = lineJump->partLineJump(_part);

                partLineJump->addExecutedCount(jumpsExecuted);
                if (nextLineType == CondJump)
                    partLineJump->addFollowedCount(jumpsFollowed);
            }
#endif

            if (0) {
                qDebug() << _filename << ":" << _lineNo
                         << " - jump from 0x" << currentPos.fromAddr.toString()
                         << " (line " << currentPos.fromLine
                         << ") to 0x" << targetPos.fromAddr.toString()
                         << " (line " << targetPos.fromLine << ")";

                if (nextLineType == BoringJump)
                    qDebug() << " Boring Jump, count " << jumpsExecuted.pretty();
                else
                    qDebug() << " Cond. Jump, followed " << jumpsFollowed.pretty()
                             << ", executed " << jumpsExecuted.pretty();
            }

            nextLineType = SelfCost;
            currentJumpToFunction = 0;
            currentJumpToFile = 0;

            if (!line.isEmpty()) {
                error(QStringLiteral("Garbage at end of jump cost line ('%1')").arg(line));
            }

        }
    }

    loadFinished();

    if (mapping) {
        _part->invalidate();
        _part->totals()->clear();
        _part->totals()->addCost(_part);
        data->addPart(_part);
        partsAdded++;
    }
    else {
        delete _part;
    }

    device->close();

    return partsAdded;
}
Beispiel #9
0
/* If sourceList is empty we set the source file name into the header,
 * else this code is of a inlined function, and we add "inlined from..."
 */
void SourceView::fillSourceFile(TraceFunctionSource* sf, int fileno)
{
  if (!sf) return;

  if (0) qDebug("Selected Item %s", 
		_selectedItem ? _selectedItem->name().ascii() : "(none)");

  TraceLineMap::Iterator lineIt, lineItEnd;
  int nextCostLineno = 0, lastCostLineno = 0;

  bool validSourceFile = (!sf->file()->name().isEmpty());

  TraceLine* sLine = 0;
  if (_selectedItem) {
    if (_selectedItem->type() == TraceItem::Line)
      sLine = (TraceLine*) _selectedItem;
    if (_selectedItem->type() == TraceItem::Instr)
      sLine = ((TraceInstr*)_selectedItem)->line();
  }

  if (validSourceFile) {
      TraceLineMap* lineMap = sf->lineMap();
      if (lineMap) {
	  lineIt    = lineMap->begin();
	  lineItEnd = lineMap->end();
	  // get first line with cost of selected type
	  while(lineIt != lineItEnd) {
	    if (&(*lineIt) == sLine) break;
	    if ((*lineIt).hasCost(_costType)) break;
	    if (_costType2 && (*lineIt).hasCost(_costType2)) break;
	    ++lineIt;
	  }

	  nextCostLineno     = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno();
	  if (nextCostLineno<0) {
	    kdError() << "SourceView::fillSourceFile: Negative line number "
		      << nextCostLineno << endl
		      << "  Function '" << sf->function()->name() << "'" << endl
		      << "  File '" << sf->file()->name() << "'" << endl;
	    nextCostLineno = 0;
	  }
	    
      }

      if (nextCostLineno == 0) {
	  new SourceItem(this, this, fileno, 0, false,
			 i18n("There is no cost of current selected type associated"));
	  new SourceItem(this, this, fileno, 1, false,
			 i18n("with any source line of this function in file"));
	  new SourceItem(this, this, fileno, 2, false,
			 QString("    '%1'").arg(sf->function()->prettyName()));
	  new SourceItem(this, this, fileno, 3, false,
			 i18n("Thus, no annotated source can be shown."));
	  return;
      }
  }

  QString filename = sf->file()->shortName();
  QString dir = sf->file()->directory();
  if (!dir.isEmpty())
    filename = dir + "/" + filename;

  if (nextCostLineno>0) {
    // we have debug info... search for source file
    if (!QFile::exists(filename)) {
      QStringList list = Configuration::sourceDirs(_data,
						   sf->function()->object());
      QStringList::Iterator it;

      for ( it = list.begin(); it != list.end(); ++it ) {
        dir = *it;
        if (checkFileExistance(dir, sf->file()->shortName())) break;
      }

      if (it == list.end())
	  nextCostLineno = 0;
      else {
        filename = dir + "/" + sf->file()->shortName();
        // no need to search again
        sf->file()->setDirectory(dir);
      }
    }
  }

  // do it here, because the source directory could have been set before
  if (childCount()==0) {
    setColumnText(4, validSourceFile ?
                  i18n("Source ('%1')").arg(filename) :
                  i18n("Source (unknown)"));
  }
  else {
    new SourceItem(this, this, fileno, 0, true,
                   validSourceFile ?
                   i18n("--- Inlined from '%1' ---").arg(filename) :
                   i18n("--- Inlined from unknown source ---"));
  }

  if (nextCostLineno == 0) {
    new SourceItem(this, this, fileno, 0, false,
                   i18n("There is no source available for the following function:"));
    new SourceItem(this, this, fileno, 1, false,
                   QString("    '%1'").arg(sf->function()->prettyName()));
    if (sf->file()->name().isEmpty()) {
      new SourceItem(this, this, fileno, 2, false,
                     i18n("This is because no debug information is present."));
      new SourceItem(this, this, fileno, 3, false,
                     i18n("Recompile source and redo the profile run."));
      if (sf->function()->object()) {
        new SourceItem(this, this, fileno, 4, false,
                       i18n("The function is located in this ELF object:"));
        new SourceItem(this, this, fileno, 5, false,
                       QString("    '%1'")
                       .arg(sf->function()->object()->prettyName()));
      }
    }
    else {
      new SourceItem(this, this, fileno, 2, false,
                     i18n("This is because its source file cannot be found:"));
      new SourceItem(this, this, fileno, 3, false,
                     QString("    '%1'").arg(sf->file()->name()));
      new SourceItem(this, this, fileno, 4, false,
                     i18n("Add the folder of this file to the source folder list."));
      new SourceItem(this, this, fileno, 5, false,
                     i18n("The list can be found in the configuration dialog."));
    }
    return;
  }


  // initialisation for arrow drawing
  // create sorted list of jumps (for jump arrows)
  TraceLineMap::Iterator it = lineIt, nextIt;
  _lowList.clear();
  _highList.clear();
  while(1) {

      nextIt = it;
      ++nextIt;
      while(nextIt != lineItEnd) {
	if (&(*nextIt) == sLine) break;
	if ((*nextIt).hasCost(_costType)) break;
	if (_costType2 && (*nextIt).hasCost(_costType2)) break;
	++nextIt;
      }

      TraceLineJumpList jlist = (*it).lineJumps();
      TraceLineJump* lj;
      for (lj=jlist.first();lj;lj=jlist.next()) {
	  if (lj->executedCount()==0) continue;
	  // skip jumps to next source line with cost
	  //if (lj->lineTo() == &(*nextIt)) continue;

	  _lowList.append(lj);
	  _highList.append(lj);
      }
      it = nextIt;
      if (it == lineItEnd) break;
  }
  _lowList.sort();
  _highList.sort();
  _lowList.first(); // iterators to list start
  _highList.first();
  _jump.resize(0);


  char buf[256];
  bool inside = false, skipLineWritten = true;
  int readBytes;
  int fileLineno = 0;
  SubCost most = 0;

  TraceLine* currLine;
  SourceItem *si, *si2, *item = 0, *first = 0, *selected = 0;
  QFile file(filename);
  if (!file.open(IO_ReadOnly)) return;
  while (1) {
    readBytes=file.readLine(buf, sizeof( buf ));
    if (readBytes<=0) {
      // for nice empty 4 lines after function with EOF
      buf[0] = 0;
    }

    if (readBytes >= (int) sizeof( buf )) {
      qDebug("%s:%d  Line too long\n",
	     sf->file()->name().ascii(), fileLineno);
    }
    else if ((readBytes>0) && (buf[readBytes-1] == '\n'))
      buf[readBytes-1] = 0;


    // keep fileLineno inside [lastCostLineno;nextCostLineno]
    fileLineno++;
    if (fileLineno == nextCostLineno) {
	currLine = &(*lineIt);

	// get next line with cost of selected type
	++lineIt;
	while(lineIt != lineItEnd) {
	  if (&(*lineIt) == sLine) break;
	  if ((*lineIt).hasCost(_costType)) break;
	  if (_costType2 && (*lineIt).hasCost(_costType2)) break;
	  ++lineIt;
	}

	lastCostLineno = nextCostLineno;
	nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno();
    }
    else
	currLine = 0;

    // update inside
    if (!inside) {
	if (currLine) inside = true;
    }
    else {
	if ( (fileLineno > lastCostLineno) &&
	     ((nextCostLineno == 0) ||
	      (fileLineno < nextCostLineno - Configuration::noCostInside()) ))
	    inside = false;
    }

    int context = Configuration::context();

    if ( ((lastCostLineno==0) || (fileLineno > lastCostLineno + context)) &&
	 ((nextCostLineno==0) || (fileLineno < nextCostLineno - context))) {
	if (lineIt == lineItEnd) break;

	if (!skipLineWritten) {
	    skipLineWritten = true;
	    // a "skipping" line: print "..." instead of a line number
	    strcpy(buf,"...");
	}
	else
	    continue;
    }
    else
	skipLineWritten = false;

    si = new SourceItem(this, this, 
			fileno, fileLineno, inside, QString(buf),
                        currLine);

    if (!currLine) continue;

    if (!selected && (currLine == sLine)) selected = si;
    if (!first) first = si;

    if (currLine->subCost(_costType) > most) {
      item = si;
      most = currLine->subCost(_costType);
    }

    si->setOpen(true);
    TraceLineCallList list = currLine->lineCalls();
    TraceLineCall* lc;
    for (lc=list.first();lc;lc=list.next()) {
	if ((lc->subCost(_costType)==0) &&
	    (lc->subCost(_costType2)==0)) continue;

      if (lc->subCost(_costType) > most) {
        item = si;
        most = lc->subCost(_costType);
      }

      si2 = new SourceItem(this, si, fileno, fileLineno, currLine, lc);

      if (!selected && (lc->call()->called() == _selectedItem))
	  selected = si2;
    }

    TraceLineJumpList jlist = currLine->lineJumps();
    TraceLineJump* lj;
    for (lj=jlist.first();lj;lj=jlist.next()) {
	if (lj->executedCount()==0) continue;

	new SourceItem(this, si, fileno, fileLineno, currLine, lj);
    }
  }

  if (selected) item = selected;
  if (item) first = item;
  if (first) {
      ensureItemVisible(first);
      _inSelectionUpdate = true;
      setCurrentItem(first);
      _inSelectionUpdate = false;
  }

  file.close();

  // for arrows: go down the list according to list sorting
  sort();
  QListViewItem *item1, *item2;
  for (item1=firstChild();item1;item1 = item1->nextSibling()) {
      si = (SourceItem*)item1;
      updateJumpArray(si->lineno(), si, true, false);

      for (item2=item1->firstChild();item2;item2 = item2->nextSibling()) {
	  si2 = (SourceItem*)item2;
	  if (si2->lineJump())
	      updateJumpArray(si->lineno(), si2, false, true);
	  else
	      si2->setJumpArray(_jump);
      }
  }

  if (arrowLevels())
      setColumnWidth(3, 10 + 6*arrowLevels() + itemMargin() * 2);
  else
      setColumnWidth(3, 0);
}
bool TrackingKymoView::IsValidNodeConnection(void)
{
	if(NSelection.empty()|| NSelection.size()!=2) return false;
	std::set<unsigned int>::iterator node_vtk_ids_iter;
	std::vector<unsigned int> node_ids; 
	for(node_vtk_ids_iter = NSelection.begin(); node_vtk_ids_iter!= NSelection.end(); ++node_vtk_ids_iter)
	{
			TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashp[*node_vtk_ids_iter]);
			int tbit_time = tline->points_hash[*node_vtk_ids_iter].time;
			TraceLine::TraceBitsType::iterator tbit_iter = tline->GetTraceBitIteratorBegin();
			bool endNode = true;
			bool beginNode = true;
			std::vector<bool> tmp_vector;
			//bool singleNode = false;
			while(tbit_iter!=tline->GetTraceBitIteratorEnd())
			{
				if(tbit_iter->time > tbit_time)
					endNode = false;
				else if (tbit_iter->time < tbit_time)
					beginNode = false;
				++tbit_iter;
			}
			 tline->points_hash[*node_vtk_ids_iter].end = endNode;
			 tline->points_hash[*node_vtk_ids_iter].begin = beginNode;
			 node_ids.push_back(*node_vtk_ids_iter);
	}
	// now compare the two nodes:
	if(node_ids.size()!=2)
	{
		printf("something is up with the selection\n");
		return false;
	}
	TraceBit tbit1 = (reinterpret_cast<TraceLine*>(m_tobj->hashp[node_ids.at(0)]))->points_hash[node_ids.at(0)];
	TraceBit tbit2 = (reinterpret_cast<TraceLine*>(m_tobj->hashp[node_ids.at(1)]))->points_hash[node_ids.at(1)];
	bool isvalid = false;
	// one is at end and the other is at begin:
	if(tbit1.end == true && tbit1.begin == false && tbit2.end == false && tbit2.begin == true)
	{
		int timediff = (tbit2.time - tbit1.time);
		if( timediff >0 && timediff< 3)
			isvalid = true;
	}
	else if (tbit1.end == false && tbit1.begin == true && tbit2.end == true && tbit2.begin == false)
	{
		int timediff = (tbit1.time - tbit2.time);
		if( timediff >0 && timediff< 4)
			isvalid = true;
	}
	// one is at end or begin and the other is a single node:
	else if (tbit1.end == true && tbit1.begin == true && tbit2.end == true && tbit2.begin == false)
	{
		int timediff = (tbit1.time - tbit2.time);
		if( timediff >0 && timediff< 3)
			isvalid = true;
	}
	else if (tbit1.end == true && tbit1.begin == true && tbit2.end == false && tbit2.begin == true)
	{
		int timediff = (tbit2.time - tbit1.time);
		if( timediff >0 && timediff< 3)
			isvalid = true;
	}

	else if (tbit1.end == false && tbit1.begin == true && tbit2.end == true && tbit2.begin == true)
	{
		int timediff = (tbit1.time - tbit2.time);
		if( timediff >0 && timediff< 3)
			isvalid = true;
	}
	else if (tbit1.end == true && tbit1.begin == false && tbit2.end == true && tbit2.begin == true)
	{
		int timediff = (tbit2.time - tbit1.time);
		if( timediff >0 && timediff< 3)
			isvalid = true;
	}
	return isvalid;
}
int TraceMain::RunTrace( int argc, char *argv[] )
{
    Stats *stats = new Stats( );
    Config *config = new Config( );
    GenericTraceReader *trace = NULL;
    TraceLine *tl = new TraceLine( );
    SimInterface *simInterface = new NullInterface( );
    NVMain *nvmain = new NVMain( );
    EventQueue *mainEventQueue = new EventQueue( );
    GlobalEventQueue *globalEventQueue = new GlobalEventQueue( );
    TagGenerator *tagGenerator = new TagGenerator( 1000 );
    bool IgnoreData = false;
    bool EventDriven = false;

    uint64_t simulateCycles;
    uint64_t currentCycle;
    
    if( argc < 4 )
    {
        std::cout << "Usage: nvmain CONFIG_FILE TRACE_FILE CYCLES [PARAM=value ...]" 
            << std::endl;
        return 1;
    }

    /* Print out the command line that was provided. */
    std::cout << "NVMain command line is:" << std::endl;
    for( int curArg = 0; curArg < argc; ++curArg )
    {
        std::cout << argv[curArg] << " ";
    }
    std::cout << std::endl << std::endl;

    config->Read( argv[1] );
    config->SetSimInterface( simInterface );
    SetEventQueue( mainEventQueue );
    SetGlobalEventQueue( globalEventQueue );
    SetStats( stats );
    SetTagGenerator( tagGenerator );
    std::ofstream statStream;

    /* Allow for overriding config parameter values for trace simulations from command line. */
    if( argc > 4 )
    {
        for( int curArg = 4; curArg < argc; ++curArg )
        {
            std::string clParam, clValue, clPair;
            
            clPair = argv[curArg];
            clParam = clPair.substr( 0, clPair.find_first_of("="));
            clValue = clPair.substr( clPair.find_first_of("=") + 1, std::string::npos );

            std::cout << "Overriding " << clParam << " with '" << clValue << "'" << std::endl;

            config->SetValue( clParam, clValue );
        }
    }

    if( config->KeyExists( "StatsFile" ) )
    {
        statStream.open( config->GetString( "StatsFile" ).c_str(), 
                         std::ofstream::out | std::ofstream::app );
    }

    if( config->KeyExists( "IgnoreData" ) && config->GetString( "IgnoreData" ) == "true" )
    {
        IgnoreData = true;
    }

    config->GetBool( "EventDriven", EventDriven );

    /*  Add any specified hooks */
    std::vector<std::string>& hookList = config->GetHooks( );

    for( size_t i = 0; i < hookList.size( ); i++ )
    {
        std::cout << "Creating hook " << hookList[i] << std::endl;

        NVMObject *hook = HookFactory::CreateHook( hookList[i] );
        
        if( hook != NULL )
        {
            AddHook( hook );
            hook->SetParent( this );
            hook->Init( config );
        }
        else
        {
            std::cout << "Warning: Could not create a hook named `" 
                << hookList[i] << "'." << std::endl;
        }
    }

    AddChild( nvmain );
    nvmain->SetParent( this );

    globalEventQueue->SetFrequency( config->GetEnergy( "CPUFreq" ) * 1000000.0 );
    globalEventQueue->AddSystem( nvmain, config );

    simInterface->SetConfig( config, true );
    nvmain->SetConfig( config, "defaultMemory", true );

    std::cout << "traceMain (" << (void*)(this) << ")" << std::endl;
    nvmain->PrintHierarchy( );

    if( config->KeyExists( "TraceReader" ) )
        trace = TraceReaderFactory::CreateNewTraceReader( 
                config->GetString( "TraceReader" ) );
    else
        trace = TraceReaderFactory::CreateNewTraceReader( "NVMainTrace" );

    trace->SetTraceFile( argv[2] );

    if( argc == 3 )
        simulateCycles = 0;
    else
        simulateCycles = atoi( argv[3] );

    std::cout << "*** Simulating " << simulateCycles << " input cycles. (";

    /*
     *  The trace cycle is assumed to be the rate that the CPU/LLC is issuing. 
     *  Scale the simulation cycles to be the number of *memory cycles* to run.
     */
    simulateCycles = (uint64_t)ceil( ((double)(config->GetValue( "CPUFreq" )) 
                    / (double)(config->GetValue( "CLK" ))) * simulateCycles ); 

    std::cout << simulateCycles << " memory cycles) ***" << std::endl;

    currentCycle = 0;
    while( currentCycle <= simulateCycles || simulateCycles == 0 )
    {
        if( !trace->GetNextAccess( tl ) )
        {
            /* Force all modules to drain requests. */
            bool draining = Drain( );

            std::cout << "Could not read next line from trace file!" 
                << std::endl;

            /* Wait for requests to drain. */
            while( outstandingRequests > 0 )
            {
                if( EventDriven )
                    globalEventQueue->Cycle( 1 );
                else 
                    GetChild( )->Cycle( 1 );
              
                currentCycle++;

                /* Retry drain each cycle if it failed. */
                if( !draining )
                    draining = Drain( );
            }

            break;
        }

        NVMainRequest *request = new NVMainRequest( );
        
        request->address = tl->GetAddress( );
        request->type = tl->GetOperation( );
        request->bulkCmd = CMD_NOP;
        request->threadId = tl->GetThreadId( );
        if( !IgnoreData ) request->data = tl->GetData( );
        if( !IgnoreData ) request->oldData = tl->GetOldData( );
        request->status = MEM_REQUEST_INCOMPLETE;
        request->owner = (NVMObject *)this;
        
        /* 
         * If you want to ignore the cycles used in the trace file, just set
         * the cycle to 0. 
         */
        if( config->KeyExists( "IgnoreTraceCycle" ) 
                && config->GetString( "IgnoreTraceCycle" ) == "true" )
            tl->SetLine( tl->GetAddress( ), tl->GetOperation( ), 0, 
                         tl->GetData( ), tl->GetOldData( ), tl->GetThreadId( ) );

        if( request->type != READ && request->type != WRITE )
            std::cout << "traceMain: Unknown Operation: " << request->type 
                << std::endl;

        /* 
         * If the next operation occurs after the requested number of cycles,
         * we can quit. 
         */
        if( tl->GetCycle( ) > simulateCycles && simulateCycles != 0 )
        {
            if( EventDriven )
            {
                globalEventQueue->Cycle( simulateCycles - currentCycle );
                currentCycle += simulateCycles - currentCycle;

                break;
            }

            /* Just ride it out 'til the end. */
            while( currentCycle < simulateCycles )
            {
                GetChild( )->Cycle( 1 );
              
                currentCycle++;
            }

            break;
        }
        else
        {
            /* 
             *  If the command is in the past, it can be issued. This would 
             *  occur since the trace was probably generated with an inaccurate 
             *  memory *  simulator, so the cycles may not match up. Otherwise, 
             *  we need to wait.
             */
            if( tl->GetCycle( ) > currentCycle )
            {
                if( EventDriven )
                {
                    globalEventQueue->Cycle( tl->GetCycle() - currentCycle );
                    currentCycle = globalEventQueue->GetCurrentCycle( );
                }
                else
                {
                    /* Wait until currentCycle is the trace operation's cycle. */
                    while( currentCycle < tl->GetCycle( ) )
                    {
                        if( currentCycle >= simulateCycles && simulateCycles != 0 )
                            break;

                        GetChild( )->Cycle( 1 );

                        currentCycle++;
                    }
                }

                if( currentCycle >= simulateCycles && simulateCycles != 0 )
                    break;
            }

            /* 
             *  Wait for the memory controller to accept the next command.. 
             *  the trace reader is "stalling" until then.
             */
            while( !GetChild( )->IsIssuable( request ) )
            {
                if( currentCycle >= simulateCycles && simulateCycles != 0 )
                    break;

                if( EventDriven )
                {
                    globalEventQueue->Cycle( 1 );
                    currentCycle = globalEventQueue->GetCurrentCycle( );
                }
                else 
                {
                    GetChild( )->Cycle( 1 );
                    currentCycle++;
                }
            }

            outstandingRequests++;
            GetChild( )->IssueCommand( request );

            if( currentCycle >= simulateCycles && simulateCycles != 0 )
                break;
        }
    }       

    GetChild( )->CalculateStats( );
    std::ostream& refStream = (statStream.is_open()) ? statStream : std::cout;
    stats->PrintAll( refStream );

    std::cout << "Exiting at cycle " << currentCycle << " because simCycles " 
        << simulateCycles << " reached." << std::endl; 
    if( outstandingRequests > 0 )
        std::cout << "Note: " << outstandingRequests << " requests still in-flight."
                  << std::endl;

    delete config;
    delete stats;

    return 0;
}