/*=========================================================================== * * Profile.CPP - Dave Humphrey (uesp@m0use.net), 23 November 2000 * *=========================================================================*/ /* Include Files */ #include "profile.h" /*=========================================================================== * * Begin Global Variables * *=========================================================================*/ /* Define and automatically open the profile log file */ CLogFile ProfileLog; boolean OpenLog = ProfileLog.Open("profile.log"); /* List of current profiles */ CProfileList ProfileList; /*=========================================================================== * End of Global Variables *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CProfileRecord::CProfileRecord()" /*=========================================================================== * * Class CProfileRecord Constructor * *=========================================================================*/ CProfileRecord::CProfileRecord () { pName = NULL; ProfileCount = 0; ProfileTime = 0; MaxTime = 0; MinTime = 0; } /*=========================================================================== * End of Class CProfileRecord Constructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CProfileRecord::CProfileRecord()" /*=========================================================================== * * Class CProfileRecord Constructor * *=========================================================================*/ CProfileRecord::CProfileRecord (const char* pString) { pName = CreateString(pString); ProfileCount = 0; ProfileTime = 0; MaxTime = 0; MinTime = 0; } /*=========================================================================== * End of Class CProfileRecord Constructor *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CProfileRecord::Destroy()" /*=========================================================================== * * Class CProfileRecord Method - void Destroy (void) * *=========================================================================*/ void CProfileRecord::Destroy (void) { DestroyPointerArray(pName); ProfileCount = 0; ProfileTime = 0; MaxTime = 0; MinTime = 0; } /*=========================================================================== * End of Class Method CProfileRecord::Destroy() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CProfileRecord::AddProfileTime()" /*=========================================================================== * * Class CProfileRecord Method - void AddProfileTime (const profile_t Profile) * * Adds a profile time to the current record. * *=========================================================================*/ void CProfileRecord::AddProfileTime (const profile_t Profile) { profile_time_t DiffTime = Profile.EndTime - Profile.StartTime; ProfileTime += DiffTime; ProfileCount++; /* Compute the max/min time values */ if (ProfileCount == 1) { MaxTime = DiffTime; MinTime = DiffTime; } else if (DiffTime > MaxTime) MaxTime = DiffTime; else if (DiffTime < MinTime) MinTime = DiffTime; } /*=========================================================================== * End of Class Method CProfileRecord::AddProfileTime() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CProfileRecord::OutputProfile()" /*=========================================================================== * * Class CProfileRecord Method - boolean OutputProfile (FILE* pFileHandle) * * Outputs the current profile information of the record to the given * file stream. If the input file handle is NULL, the current profile * log file is used. Returns FALSE on any error. * *=========================================================================*/ boolean CProfileRecord::OutputProfile (FILE* pFileHandle) { float Count; float Seconds; float Rate; float Frequency; int Result; /* Ensure a valid file handle */ if (pFileHandle == NULL) { pFileHandle = ProfileLog.GetFileHandle(); CHECK_POINTER(pFileHandle, FALSE); } /* Output counter values */ switch (ProfileTime.CountType) { /* Use the peroformance counter */ case PROFILE_PERFORMANCE_COUNTER: { #ifdef _WIN32 LARGE_INTEGER Freq; Count = (float) ProfileTime.TimerCount.QuadPart; Result = QueryPerformanceFrequency(&Freq); if (!Result || Freq.QuadPart == 0) Frequency = (float) 1.0; else Frequency = (float) Freq.QuadPart; #else ProfileLog.Printf ("\t%s: Performance counter not available on this platform!", GetNiceName()); return (FALSE); #endif break; } /* Use the regular clock timer */ case PROFILE_CLOCK_COUNTER: Count = (float) ProfileTime.ClockCount; Frequency = (float) CLOCKS_PER_SEC; break; /* Unknown timer type */ default: ProfileLog.Printf ("\t%s: Invalid timer type specified!", GetNiceName()); break; } /* Compute the rate and total profile time */ Seconds = Count / Frequency; Rate = ((float) ProfileCount) / Seconds; /* Output the result to the file stream */ Result = fprintf (pFileHandle, "\t%s: Total %g sec (%ld calls), %g calls/sec (%g sec/call) (Min/Max Times = %g / %g sec)\n", GetNiceName(), Seconds, ProfileCount, Rate, 1.0/Rate, (float)MinTime/Frequency, (float)MaxTime/Frequency); if (Result < 0) { SET_EXT_ERROR(ERR_WRITE); return (FALSE); } return (TRUE); } /*=========================================================================== * End of Class Method CProfileRecord::OutputProfile() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "CProfileRecord::operator =()" /*=========================================================================== * * Class CProfileRecord Method - CProfileRecord& operator =(Record) * * Overloaded copy operator. * *=========================================================================*/ CProfileRecord& CProfileRecord::operator =(const CProfileRecord& Record) { SetName(Record.GetName()); ProfileTime = Record.GetProfileTime(); ProfileCount = Record.GetProfileCount(); MaxTime = Record.GetMaxTime(); MinTime = Record.GetMinTime(); return (*this); } /*=========================================================================== * End of Class Method CProfileRecord::operator =() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "GetProfileTime()" /*=========================================================================== * * Function - void GetProfileTime (ProfileTime); * * Get the current profile counter value. * *=========================================================================*/ void GetProfileTime (profile_time_t& ProfileTime) { /* Attempt to use the performance counter */ #ifdef _WIN32 boolean Result; /* Attempt to get the performance timer count */ Result = QueryPerformanceCounter(&ProfileTime.TimerCount); /* Set the counter type and return on success */ if (Result) { ProfileTime.CountType = PROFILE_PERFORMANCE_COUNTER; return; } #endif ProfileTime.ClockCount = clock(); ProfileTime.CountType = PROFILE_CLOCK_COUNTER; } /*=========================================================================== * End of Function GetProfileTime() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "OutputProfile()" /*=========================================================================== * * Function - void OutputProfile (Profile, pString); * * Outputs a profile statistics to the profile log file. * *=========================================================================*/ void OutputProfile (profile_t& Profile, const char* pString) { /* Ensure valid count types */ if (Profile.EndTime.CountType != Profile.StartTime.CountType) { ProfileLog.Printf ("PROFILE %s: Times are not in the same timer units!", pString); return; } /* Output counter values */ switch (Profile.EndTime.CountType) { /* Use the peroformance counter */ case PROFILE_PERFORMANCE_COUNTER: { #ifdef _WIN32 LARGE_INTEGER Diff; LARGE_INTEGER Freq; boolean Result; Diff.QuadPart = Profile.EndTime.TimerCount.QuadPart - Profile.StartTime.TimerCount.QuadPart; Result = QueryPerformanceFrequency(&Freq); if (Result) ProfileLog.Printf ("PROFILE %s: %.4f sec (%I64d counts)", pString, (float)Diff.QuadPart / (float)Freq.QuadPart, Diff.QuadPart); else ProfileLog.Printf ("PROFILE %s: %I64d counts", pString, (long) Diff.QuadPart); #else ProfileLog.Printf ("PROFILE %s: Performance counter not available on this platform!", pString); #endif break; } /* Use the regular clock timer */ case PROFILE_CLOCK_COUNTER: { clock_t Diff = Profile.EndTime.ClockCount - Profile.StartTime.ClockCount; ProfileLog.Printf ("PROFILE %s: %.4f sec", pString, (float)Diff / (float)CLOCKS_PER_SEC); break; } /* Unknown timer type */ default: ProfileLog.Printf ("PROFILE %s: Invalid timer type specified!", pString); break; } } /*=========================================================================== * End of Function OutputProfile() *=========================================================================*/ #undef __FUNC__ #define __FUNC__ "OutputProfileList()" /*=========================================================================== * * Function - boolean OutputProfileList (FILE* pFileHandle) * * Outputs the results of the ProfileList to the given file stream. Returns * FALSE on any error. If the input file stream is NULL, the current * ProfileLog file is used. * *=========================================================================*/ boolean OutputProfileList (FILE* pFileHandle) { CProfileRecord* pProfileRecord; boolean Result; /* Ensure a valid file handle */ if (pFileHandle == NULL) { pFileHandle = ProfileLog.GetFileHandle(); CHECK_POINTER(pFileHandle, FALSE); } /* Start at the head of the list */ pProfileRecord = ProfileList.GetHeadData(); while (pProfileRecord != NULL) { Result = pProfileRecord->OutputProfile(pFileHandle); if (!Result) return (FALSE); pProfileRecord = ProfileList.GetNext(); } return (TRUE); } /*=========================================================================== * End of Function OutputProfileList() *=========================================================================*/