33#pragma comment (lib,"winmm")
46 HGLOBAL h=GlobalAlloc(GMEM_FIXED,numBytes);
61 GlobalFree((HGLOBAL)oldPtr);
66 HGLOBAL h=GlobalReAlloc((HGLOBAL)oldPtr,newSize,0);
71 h=GlobalAlloc(GMEM_FIXED,newSize);
74 unsigned oldSize=GlobalSize((HGLOBAL)oldPtr);
75 memcpy((
void *)h,oldPtr,oldSize<newSize?oldSize:newSize);
76 GlobalFree((HGLOBAL)oldPtr);
85 GlobalFree((HGLOBAL)ptr);
90static _int64 GetClockCyclesFast(
void)
98 "[ file [ frame_name [ fold_threshold ] ] ]");
105 for (
int k=0;k<3;k++)
108 unsigned timeEnd=timeGetTime()+2;
109 while (timeGetTime()<timeEnd);
112 _int64 start,startQPC,endQPC;
113 QueryPerformanceCounter((LARGE_INTEGER *)&startQPC);
116 while (timeGetTime()<timeEnd);
121 if (QueryPerformanceCounter((LARGE_INTEGER *)&endQPC))
124 QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
125 n[k]=(n[k]*freq)/(endQPC-startQPC);
134 _int64 d01=n[1]-n[0],d02=n[2]-n[0],
d12=n[2]-n[1];
141 avg=d01<
d12?n[0]+n[1]:n[1]+n[2];
145 avg=d02<
d12?n[0]+n[2]:n[1]+n[2];
150 return ((avg/2+500000)/1000000)*1000000;
153unsigned Profile::m_rec;
154char **Profile::m_recNames;
155unsigned Profile::m_names;
156Profile::FrameName *Profile::m_frameNames;
157_int64 Profile::m_clockCycles=GetClockCyclesFast();
158Profile::PatternListEntry *Profile::firstPatternEntry;
159Profile::PatternListEntry *Profile::lastPatternEntry;
168 for (
unsigned k=0;k<m_names;++k)
169 if (!strcmp(range,m_frameNames[k].name))
176 strcpy(m_frameNames[k].name,range);
177 m_frameNames[k].frames=0;
178 m_frameNames[k].isRecording=
false;
179 m_frameNames[k].doAppend=
false;
180 m_frameNames[k].lastGlobalIndex=-1;
184 if (m_frameNames[k].isRecording)
188 m_frameNames[k].isRecording=
true;
189 m_frameNames[k].doAppend=
false;
193 for (PatternListEntry *cur=firstPatternEntry;cur;cur=cur->next)
195 if (SimpleMatch(range,cur->pattern))
196 active=cur->isActive;
203 DASSERT(m_frameNames[k].funcIndex>=0);
206 DASSERT(m_frameNames[k].highIndex>=0);
210 m_frameNames[k].funcIndex=-1;
211 m_frameNames[k].highIndex=-1;
222 for (
unsigned k=0;k<m_names;++k)
223 if (!strcmp(range,m_frameNames[k].name))
233 if (m_frameNames[k].isRecording)
238 m_frameNames[k].isRecording=
true;
239 m_frameNames[k].doAppend=
true;
243 for (PatternListEntry *cur=firstPatternEntry;cur;cur=cur->next)
245 if (SimpleMatch(range,cur->pattern))
246 active=cur->isActive;
253 DASSERT(m_frameNames[k].funcIndex>=0);
256 DASSERT(m_frameNames[k].highIndex>=0);
260 m_frameNames[k].funcIndex=-1;
261 m_frameNames[k].highIndex=-1;
272 for (
unsigned k=0;k<m_names;++k)
273 if (!strcmp(range,m_frameNames[k].name))
276 DFAIL_IF(!m_frameNames[k].isRecording)
return;
279 m_frameNames[k].isRecording=
false;
282 m_frameNames[k].funcIndex>=0 ||
284 m_frameNames[k].highIndex>=0
289 if (!m_frameNames[k].doAppend||
290 m_frameNames[k].lastGlobalIndex<0)
293 m_frameNames[k].lastGlobalIndex=m_rec;
296 wsprintf(m_recNames[m_rec++],
"%s:%i",range,++m_frameNames[k].frames);
299 atIndex=m_frameNames[k].lastGlobalIndex;
301 if (m_frameNames[k].funcIndex>=0)
303 if (m_frameNames[k].highIndex>=0)
311 for (
unsigned k=0;k<m_names;++k)
312 if (m_frameNames[k].isRecording)
324 return frame>=m_rec?
NULL:m_recNames[frame];
337 return m_clockCycles;
341 const char *name,
const char *arg)
346bool Profile::SimpleMatch(
const char *str,
const char *pattern)
350 while (*str&&*pattern)
356 if (SimpleMatch(str++,pattern))
358 return *str==*pattern;
362 if (*str++!=*pattern++)
367 return *str==*pattern;
370static void ProfileShutdown(
void)
379 cmd.RunResultFunctions();
__forceinline void ProfileGetTime(__int64 &t)
static bool AddCommands(const char *cmdgroup, DebugCmdInterface *cmdif)
Adds a new command group.
static void AddResultFunction(ProfileResultInterface *(*func)(int, const char *const *), const char *name, const char *arg)
static int FrameStart(void)
static void FrameEnd(int which, int mixIndex)
static void ClearTotals(void)
static void Shutdown(void)
static unsigned GetFrameCount(void)
Determines the number of known (recorded) range frames.
static void AddResultFunction(ProfileResultInterface *(*func)(int, const char *const *), const char *name, const char *arg)
Add the given result function interface.
static void StartRange(const char *range=0)
Starts range recording.
static bool IsEnabled(void)
Determines if any range recording is enabled or not.
static _int64 GetClockCyclesPerSecond(void)
Determines number of CPU clock cycles per second.
static void ClearTotals(void)
Resets all 'total' counter values to 0.
static void AppendRange(const char *range=0)
Appends profile data to the last recorded frame of the given range.
static const char * GetFrameName(unsigned frame)
Determines the range name of a recorded range frame.
static void StopRange(const char *range=0)
Stops range recording.
static int FrameStart(void)
static void ClearTotals(void)
static void Shutdown(void)
static void FrameEnd(int which, int mixIndex)
static ProfileResultInterface * Create(int argn, const char *const *)
#define DCRASH_RELEASE(msg)
void * ProfileReAllocMemory(void *oldPtr, unsigned newSize)
void * ProfileAllocMemory(unsigned numBytes)
void ProfileFreeMemory(void *ptr)
void * ProfileReAllocMemory(void *oldPtr, unsigned newSize)
void * ProfileAllocMemory(unsigned numBytes)