1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 MartiƱo Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "profiler.h"
#ifdef SL_PROFILE
#include <stdexcept>
#include "leak_dumper.h"
using namespace std;
namespace Shared{ namespace Util{
// =====================================================
// class Section
// =====================================================
Section::Section(const string &name){
this->name= name;
milisElapsed= 0;
parent= NULL;
}
Section *Section::getChild(const string &name){
SectionContainer::iterator it;
for(it= children.begin(); it!=children.end(); ++it){
if((*it)->getName()==name){
return *it;
}
}
return NULL;
}
void Section::print(FILE *outStream, int tabLevel){
float percent= (parent==NULL || parent->milisElapsed==0)? 100.0f: 100.0f*milisElapsed/parent->milisElapsed;
//string pname= parent==NULL? "": parent->getName();
for(int i=0; i<tabLevel; ++i)
fprintf(outStream, "\t");
fprintf(outStream, "%s: ", name.c_str());
fprintf(outStream, "%d ms, ", milisElapsed);
fprintf(outStream, "%.1f%s\n", percent, "%");
SectionContainer::iterator it;
for(it= children.begin(); it!=children.end(); ++it){
(*it)->print(outStream, tabLevel+1);
}
}
// =====================================================
// class Profiler
// =====================================================
Profiler::Profiler(){
rootSection= new Section("Root");
currSection= rootSection;
rootSection->start();
}
Profiler::~Profiler(){
rootSection->stop();
string profileLog = "profiler.log";
if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
profileLog = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + profileLog;
}
else {
string userData = config.getString("UserData_Root","");
if(userData != "") {
endPathWithSlash(userData);
}
profileLog = userData + profileLog;
}
#ifdef WIN32
FILE* f= = _wfopen(utf8_decode(profileLog).c_str(), L"w");
#else
FILE *f= fopen(profileLog.c_str(), "w");
#endif
if(f==NULL)
throw megaglest_runtime_error("Can not open file: " + profileLog);
fprintf(f, "Profiler Results\n\n");
rootSection->print(f);
fclose(f);
}
Profiler &Profiler::getInstance(){
static Profiler profiler;
return profiler;
}
void Profiler::sectionBegin(const string &name){
Section *childSection= currSection->getChild(name);
if(childSection==NULL){
childSection= new Section(name);
currSection->addChild(childSection);
childSection->setParent(currSection);
}
currSection= childSection;
childSection->start();
}
void Profiler::sectionEnd(const string &name){
if(name==currSection->getName()){
currSection->stop();
currSection= currSection->getParent();
}
else{
throw megaglest_runtime_error("Profile: Leaving section is not current section: "+name);
}
}
}};//end namespace
#endif
|