226 lines
5.8 KiB
C++
226 lines
5.8 KiB
C++
/*
|
|
** Command & Conquer Generals Zero Hour(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program 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 General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////EA-V1
|
|
// $File: //depot/GeneralsMD/Staging/code/Libraries/Source/profile/profile.h $
|
|
// $Author: mhoffe $
|
|
// $Revision: #4 $
|
|
// $DateTime: 2003/08/14 13:43:29 $
|
|
//
|
|
// ©2003 Electronic Arts
|
|
//
|
|
// Profiling module
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
#ifdef _MSC_VER
|
|
# pragma once
|
|
#endif
|
|
#ifndef PROFILE_H // Include guard
|
|
#define PROFILE_H
|
|
|
|
#if defined(_DEBUG) && defined(_INTERNAL)
|
|
#error "Only either _DEBUG or _INTERNAL should ever be defined"
|
|
#endif
|
|
|
|
// Define which libraries to use.
|
|
#if defined(_INTERNAL)
|
|
# pragma comment (lib,"profileinternal.lib")
|
|
#elif defined(_DEBUG)
|
|
# pragma comment (lib,"profiledebug.lib")
|
|
#elif defined(_PROFILE)
|
|
# pragma comment (lib,"profileprofile.lib")
|
|
#else
|
|
# pragma comment (lib,"profile.lib")
|
|
#endif
|
|
|
|
// include all our public header files (use double quotes here)
|
|
#include "profile_doc.h"
|
|
#include "profile_highlevel.h"
|
|
#include "profile_funclevel.h"
|
|
#include "profile_result.h"
|
|
|
|
/**
|
|
\brief Functions common to both profilers.
|
|
*/
|
|
class Profile
|
|
{
|
|
friend class ProfileCmdInterface;
|
|
|
|
// nobody can construct this class
|
|
Profile();
|
|
|
|
public:
|
|
|
|
/**
|
|
\brief Starts range recording.
|
|
|
|
\param range name of range to record, ==NULL for "frame"
|
|
*/
|
|
static void StartRange(const char *range=0);
|
|
|
|
/**
|
|
\brief Appends profile data to the last recorded frame
|
|
of the given range.
|
|
|
|
\param range name of range to record, ==NULL for "frame"
|
|
*/
|
|
static void AppendRange(const char *range=0);
|
|
|
|
/**
|
|
\brief Stops range recording.
|
|
|
|
\note After this call the recorded range data will be available
|
|
as a new range frame.
|
|
|
|
\param range name of range to record, ==NULL for "frame"
|
|
*/
|
|
static void StopRange(const char *range=0);
|
|
|
|
/**
|
|
\brief Determines if any range recording is enabled or not.
|
|
|
|
\return true if range profiling is enabled, false if not
|
|
*/
|
|
static bool IsEnabled(void);
|
|
|
|
/**
|
|
\brief Determines the number of known (recorded) range frames.
|
|
|
|
Note that if function level profiling is enabled then the number
|
|
of recorded high level frames is the same as the number of recorded
|
|
function level frames.
|
|
|
|
\return number of recorded range frames
|
|
*/
|
|
static unsigned GetFrameCount(void);
|
|
|
|
/**
|
|
\brief Determines the range name of a recorded range frame.
|
|
|
|
\note A unique number will be added to the frame name, separated by
|
|
a ':', e.g. 'frame:3'
|
|
|
|
\param frame number of recorded frame
|
|
\return range name
|
|
*/
|
|
static const char *GetFrameName(unsigned frame);
|
|
|
|
/**
|
|
\brief Resets all 'total' counter values to 0.
|
|
|
|
This function does not change any recorded frames.
|
|
*/
|
|
static void ClearTotals(void);
|
|
|
|
/**
|
|
\brief Determines number of CPU clock cycles per second.
|
|
|
|
\note This value is cached internally so this function is
|
|
quite fast.
|
|
|
|
\return number of CPU clock cycles per second
|
|
*/
|
|
static _int64 GetClockCyclesPerSecond(void);
|
|
|
|
/**
|
|
\brief Add the given result function interface.
|
|
|
|
\param func factory function
|
|
\param name factory name
|
|
\param arg description of optional parameters the factory function recognizes
|
|
*/
|
|
static void AddResultFunction(ProfileResultInterface* (*func)(int, const char * const *),
|
|
const char *name, const char *arg);
|
|
|
|
private:
|
|
/** \internal
|
|
|
|
\brief Simple recursive pattern matcher.
|
|
|
|
\param str string to match
|
|
\param pattern pattern, only wildcard valid is '*'
|
|
\return true if string matches pattern, false if not
|
|
*/
|
|
static bool SimpleMatch(const char *str, const char *pattern);
|
|
|
|
/// known frame names
|
|
struct FrameName
|
|
{
|
|
/// frame name
|
|
char *name;
|
|
|
|
/// number of recorded frames for this name
|
|
unsigned frames;
|
|
|
|
/// are we currently recording?
|
|
bool isRecording;
|
|
|
|
/// should current frame be appended to last frame with same name
|
|
bool doAppend;
|
|
|
|
/// internal index for function level profiler
|
|
int funcIndex;
|
|
|
|
/// internal index for high level profiler
|
|
int highIndex;
|
|
|
|
/// global frame number of last recorded frame for this range, -1 if none
|
|
int lastGlobalIndex;
|
|
};
|
|
|
|
/// \internal pattern list entry
|
|
struct PatternListEntry
|
|
{
|
|
/// next entry
|
|
PatternListEntry *next;
|
|
|
|
/// active (true) or inactive (false)?
|
|
bool isActive;
|
|
|
|
/// pattern itself (dynamic allocated memory)
|
|
char *pattern;
|
|
};
|
|
|
|
/** \internal
|
|
|
|
First pattern list list entry. A singly linked list is
|
|
okay for this because checking patterns is a costly
|
|
operation anyway and is therefore cached.
|
|
*/
|
|
static PatternListEntry *firstPatternEntry;
|
|
|
|
/// \internal last pattern list entry for fast additions to list at end
|
|
static PatternListEntry *lastPatternEntry;
|
|
|
|
/// number of recorded frames
|
|
static unsigned m_rec;
|
|
|
|
/// names of recorded frames
|
|
static char **m_recNames;
|
|
|
|
/// number of known frame names
|
|
static unsigned m_names;
|
|
|
|
/// list of known frame names
|
|
static FrameName *m_frameNames;
|
|
|
|
/// CPU clock cycles/second
|
|
static _int64 m_clockCycles;
|
|
};
|
|
|
|
#endif // PROFILE_H
|