137 lines
3.6 KiB
C++
137 lines
3.6 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include "script/script_profiler.h"
|
|
#include "platform.h"
|
|
#include "log/log.h"
|
|
|
|
using namespace GS::Script;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
Profiler::FunctionProfile *Profiler::GetFunctionProfile(const char *source, const char *func, int line, FunctionProfile *caller)
|
|
{
|
|
// Check for profiled function.
|
|
FunctionProfile *profile = NULL;
|
|
ListForeachPtr(FunctionProfile *, f_profile, function_map)
|
|
if (
|
|
(f_profile->func == func) &&
|
|
(f_profile->caller_function == caller)
|
|
)
|
|
{
|
|
profile = f_profile;
|
|
break;
|
|
}
|
|
|
|
// Create a new function profile.
|
|
if (!profile)
|
|
{
|
|
profile = new FunctionProfile(source, func, line);
|
|
if (!profile)
|
|
__LOG_E__ << "Failed to allocate a new function profile.\n";
|
|
|
|
// Register caller.
|
|
profile->caller_function = caller;
|
|
|
|
// Add the newly created function as a child of the caller function profile.
|
|
if (caller)
|
|
caller->callee_function.Add(profile);
|
|
|
|
function_map.Add(profile);
|
|
}
|
|
return profile;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Profiler::Start(const char *session_id)
|
|
{
|
|
id = session_id;
|
|
function_map.Clear();
|
|
function_list.Clear();
|
|
|
|
current_function_profile = NULL;
|
|
|
|
profiler_clock = Platform::Get().GetClock();
|
|
total_clock = 0;
|
|
|
|
profiling = true;
|
|
}
|
|
int Profiler::GetChildTotalClock(FunctionProfile *profile)
|
|
{
|
|
int child_total_clock = 0;
|
|
ListForeachPtr(FunctionProfile *, c_profile, profile->callee_function)
|
|
child_total_clock += GetChildTotalClock(c_profile);
|
|
return profile->self_clock + child_total_clock;
|
|
}
|
|
void Profiler::End()
|
|
{
|
|
ListForeachPtr(FunctionProfile *, f_profile, function_map)
|
|
f_profile->total_clock = GetChildTotalClock(f_profile);
|
|
|
|
// Build the function list from the call graph function map.
|
|
ListForeachPtr(FunctionProfile *, f_profile, function_map)
|
|
{
|
|
// Check list if function is already present.
|
|
FunctionProfile *profile = NULL;
|
|
ListForeachPtr(FunctionProfile *, l_profile, function_list)
|
|
if (l_profile->func == f_profile->func)
|
|
{
|
|
profile = l_profile;
|
|
break;
|
|
}
|
|
|
|
// If not, create a new list entry.
|
|
if (!profile)
|
|
{
|
|
profile = new FunctionProfile(f_profile->source.c_str(), f_profile->func.c_str(), f_profile->line);
|
|
function_list.Add(profile);
|
|
}
|
|
|
|
// Merge this function contribution.
|
|
profile->hit_count += f_profile->hit_count;
|
|
profile->self_clock += f_profile->self_clock;
|
|
profile->total_clock += f_profile->total_clock;
|
|
}
|
|
|
|
profiling = false;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Profiler::Update(int type, FunctionProfile *profile)
|
|
{
|
|
// Update clock.
|
|
int current_clock = Platform::Get().GetClock(),
|
|
dt_clock = current_clock - profiler_clock;
|
|
profiler_clock = current_clock;
|
|
|
|
// Update current profile.
|
|
if (current_function_profile)
|
|
{
|
|
current_function_profile->Update(dt_clock, 0);
|
|
total_clock += dt_clock;
|
|
}
|
|
|
|
// Get profile.
|
|
switch (type)
|
|
{
|
|
case 'c':
|
|
current_function_profile = profile;
|
|
current_function_profile->Hit();
|
|
break;
|
|
|
|
case 'r':
|
|
current_function_profile = NULL;
|
|
break;
|
|
case 'l':
|
|
break;
|
|
}
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
Profiler::Profiler() : profiling(false), current_function_profile(NULL) {}
|