diff options
Diffstat (limited to 'plugins/Utils/mir_profiler.cpp')
-rw-r--r-- | plugins/Utils/mir_profiler.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/plugins/Utils/mir_profiler.cpp b/plugins/Utils/mir_profiler.cpp new file mode 100644 index 0000000000..b788fd2dd2 --- /dev/null +++ b/plugins/Utils/mir_profiler.cpp @@ -0,0 +1,178 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+// Disable "...truncated to '255' characters in the debug information" warnings
+#pragma warning(disable: 4786)
+
+
+#include "mir_profiler.h"
+#include "mir_log.h"
+
+#include <stdio.h>
+
+
+MProfiler::Block MProfiler::root;
+MProfiler::Block * MProfiler::current = &MProfiler::root;
+
+
+MProfiler::Block::Block()
+{
+ parent = NULL;
+ memset(&total, 0, sizeof(total));
+ started = false;
+}
+
+
+MProfiler::Block::~Block()
+{
+ Reset();
+}
+
+
+void MProfiler::Block::Reset()
+{
+ for(std::map<std::string, MProfiler::Block *>::iterator it = children.begin();
+ it != children.end(); ++it)
+ delete it->second;
+ children.clear();
+
+ memset(&total, 0, sizeof(total));
+ started = false;
+}
+
+
+void MProfiler::Block::Start()
+{
+ if (started)
+ return;
+
+ QueryPerformanceCounter(&start);
+ last_step = start;
+ started = true;
+}
+
+
+void MProfiler::Block::Step(const char *name)
+{
+ if (!started)
+ return;
+
+ LARGE_INTEGER end;
+ QueryPerformanceCounter(&end);
+
+ GetChild(name)->total.QuadPart += end.QuadPart - last_step.QuadPart;
+
+ last_step = end;
+}
+
+
+void MProfiler::Block::Stop()
+{
+ if (!started)
+ return;
+
+ LARGE_INTEGER end;
+ QueryPerformanceCounter(&end);
+
+ total.QuadPart += end.QuadPart - start.QuadPart;
+
+ started = false;
+}
+
+
+double MProfiler::Block::GetTimeMS() const
+{
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+
+ return total.QuadPart * 1000. / frequency.QuadPart;
+}
+
+
+MProfiler::Block * MProfiler::Block::GetChild(const char *name)
+{
+ MProfiler::Block *ret = children[name];
+ if (ret == NULL)
+ {
+ ret = new MProfiler::Block();
+ ret->name = name;
+ ret->parent = this;
+ children[name] = ret;
+ }
+ return ret;
+}
+
+
+void MProfiler::Reset()
+{
+ root.Reset();
+}
+
+void MProfiler::Start(const char *name)
+{
+ current = current->GetChild(name);
+ current->Start();
+}
+
+void MProfiler::Step(const char *name)
+{
+ current->Step(name);
+}
+
+void MProfiler::End()
+{
+ current->Stop();
+
+ if (current->parent != NULL)
+ {
+ current = current->parent;
+ QueryPerformanceCounter(¤t->last_step);
+ }
+}
+
+void MProfiler::Dump(const char *module)
+{
+ Dump(module, "", &root, -1, -1);
+}
+
+
+void MProfiler::Dump(const char *module, std::string prefix, Block *block, double parent, double total)
+{
+ for(std::map<std::string, MProfiler::Block *>::iterator it = block->children.begin();
+ it != block->children.end(); ++it)
+ {
+ Block *child = it->second;
+ double elapsed = child->GetTimeMS();
+
+ if (total > 0)
+ {
+ mlog(module, "Profiler", "%s%-20s\t%5.1lf\t[%3.0lf%%]\t[%3.0lf%%]", prefix.c_str(), it->first.c_str(),
+ elapsed, elapsed / parent * 100, elapsed / total * 100);
+ }
+ else
+ {
+ mlog(module, "Profiler", "%s%-20s\t%5.1lf", prefix.c_str(), it->first.c_str(),
+ elapsed);
+ }
+
+ Dump(module, prefix + " ", child, elapsed, total > 0 ? total : elapsed);
+ }
+}
+
|