... as std::mutex instead. One is the mutex for the set of all files. Another is in Profiler.h, which is now back into CMakeLists because the header is included in one place. Maybe this utility will find more use again. Restored one other but commented out, as not necessary now, but need might be found to put it back again. The class ODLock was a misnamed thing not specific to the on-demand manager but used more widely as a thread synchronization utility, functioning as a mutex object. It was a mistake to remove all uses of it along with the rest of the on-demand system.
157 lines
4.2 KiB
C++
157 lines
4.2 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
Profiler.cpp
|
|
|
|
Created by Michael Chinen (mchinen) on 8/12/08
|
|
Audacity(R) is copyright (c) 1999-2008 Audacity Team.
|
|
License: GPL v2. See License.txt.
|
|
|
|
******************************************************************//**
|
|
|
|
\class Profiler
|
|
\brief A simple profiler to measure the average time lengths that a
|
|
particular task/function takes. Currently not thread-safe and not thread-smart,
|
|
but it will probably work fine if you use it on a high level.
|
|
|
|
\class TaskProfile
|
|
\brief a simple class to keep track of one task that may be called multiple times.
|
|
|
|
*//*******************************************************************/
|
|
|
|
#include "Audacity.h"
|
|
#include "Profiler.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <wx/crt.h>
|
|
|
|
///write to a profile at the end of the test.
|
|
Profiler::~Profiler()
|
|
{
|
|
if(mTasks.size())
|
|
{
|
|
//print everything out. append to a log.
|
|
FILE* log = fopen("AudacityProfilerLog.txt", "a");
|
|
time_t now;
|
|
|
|
time(&now);
|
|
wxFprintf(log,"Audacity Profiler Run, Ended at ");
|
|
wxFprintf(log,"%s",ctime(&now));
|
|
wxFprintf(log,"****************************************\n");
|
|
//print out the tasks
|
|
for(int i=0;i<(int)mTasks.size();i++)
|
|
{
|
|
if(mTasks[i]->mNumHits>0)
|
|
{
|
|
wxFprintf(log,"Task: %s\n(begins at line %d in %s)\n\n",mTasks[i]->mDescription.get(), mTasks[i]->mLine, mTasks[i]->mFileName.get());
|
|
wxFprintf(log,"Number of times run: %d\n",mTasks[i]->mNumHits);
|
|
wxFprintf(log,"Total run time (seconds): %f\n", (double)mTasks[i]->mCumTime/CLOCKS_PER_SEC);
|
|
wxFprintf(log,"Average run time (seconds): %f\n",mTasks[i]->ComputeAverageRunTime());
|
|
|
|
if(i < ((int)mTasks.size()) -1)
|
|
wxFprintf(log,"----------------------------\n");
|
|
}
|
|
}
|
|
wxFprintf(log,"\n****************************************\n\n\n");
|
|
|
|
fclose(log);
|
|
}
|
|
}
|
|
|
|
///start the task timer.
|
|
void Profiler::Begin(const char* fileName, int lineNum, const char* taskDescription)
|
|
{
|
|
std::lock_guard<std::mutex> guard{ mTasksMutex };
|
|
GetOrCreateTaskProfile(fileName,lineNum)->Begin(fileName,lineNum,taskDescription);
|
|
}
|
|
|
|
///end the task timer.
|
|
void Profiler::End(const char* fileName, int lineNum, const char* taskDescription)
|
|
{
|
|
std::lock_guard<std::mutex> guard{ mTasksMutex };
|
|
TaskProfile* tp;
|
|
tp=GetTaskProfileByDescription(taskDescription);
|
|
if(tp)
|
|
tp->End(fileName,lineNum,taskDescription);
|
|
}
|
|
|
|
///Gets the singleton instance
|
|
Profiler* Profiler::Instance()
|
|
{
|
|
static Profiler pro;
|
|
//this isn't 100% threadsafe but I think Okay for this purpose.
|
|
|
|
return &pro;
|
|
}
|
|
|
|
///find a taskProfile for the given task, otherwise create
|
|
TaskProfile* Profiler::GetOrCreateTaskProfile(const char* fileName, int lineNum)
|
|
{
|
|
for(int i=0;i<(int)mTasks.size();i++)
|
|
{
|
|
if(strcmp(fileName, mTasks[i]->mFileName.get())==0 && lineNum == mTasks[i]->mLine)
|
|
return mTasks[i].get();
|
|
}
|
|
|
|
auto tp = std::make_unique<TaskProfile>();
|
|
mTasks.push_back(std::move(tp));
|
|
return mTasks.back().get();
|
|
}
|
|
|
|
TaskProfile* Profiler::GetTaskProfileByDescription(const char* description)
|
|
{
|
|
for(int i=0;i<(int)mTasks.size();i++)
|
|
{
|
|
if(strcmp(description, mTasks[i]->mDescription.get())==0)
|
|
return mTasks[i].get();
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
///Task Profile
|
|
TaskProfile::TaskProfile()
|
|
{
|
|
mCumTime=0;
|
|
mNumHits=0;
|
|
}
|
|
|
|
TaskProfile::~TaskProfile()
|
|
{
|
|
}
|
|
|
|
///start the task timer.
|
|
void TaskProfile::Begin(const char* fileName, int lineNum, const char* taskDescription)
|
|
{
|
|
if(!mFileName)
|
|
{
|
|
mFileName.reinit( strlen(fileName) + 1 );
|
|
strcpy(mFileName.get(), fileName);
|
|
mDescription.reinit( strlen(taskDescription) + 1 );
|
|
strcpy(mDescription.get(), taskDescription);
|
|
mLine = lineNum;
|
|
}
|
|
|
|
mLastTime = clock();
|
|
|
|
}
|
|
|
|
///end the task timer.
|
|
void TaskProfile::End(const char* WXUNUSED(fileName), int WXUNUSED(lineNum), const char* WXUNUSED(taskDescription))
|
|
{
|
|
mCumTime += clock() - mLastTime;
|
|
mNumHits++;
|
|
}
|
|
|
|
double TaskProfile::ComputeAverageRunTime()
|
|
{
|
|
if(mNumHits)
|
|
return (double) ((double)mCumTime/CLOCKS_PER_SEC)/mNumHits;
|
|
else
|
|
return 0.0;
|
|
}
|