| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- /*
- ** 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_highlevel.cpp $
- // $Author: mhoffe $
- // $Revision: #2 $
- // $DateTime: 2003/08/14 13:43:29 $
- //
- // ©2003 Electronic Arts
- //
- // High level profiling
- //////////////////////////////////////////////////////////////////////////////
- #include "_pch.h"
- #include <new>
- #include <stdio.h>
- // our own fast critical section
- static ProfileFastCS cs;
- //////////////////////////////////////////////////////////////////////////////
- // ProfileHighLevel::Id
- void ProfileHighLevel::Id::Increment(double add)
- {
- if (m_idPtr)
- m_idPtr->Increment(add);
- }
- void ProfileHighLevel::Id::SetMax(double max)
- {
- if (m_idPtr)
- m_idPtr->Maximum(max);
- }
- const char *ProfileHighLevel::Id::GetName(void) const
- {
- return m_idPtr?m_idPtr->GetName():NULL;
- }
- const char *ProfileHighLevel::Id::GetDescr(void) const
- {
- return m_idPtr?m_idPtr->GetDescr():NULL;
- }
- const char *ProfileHighLevel::Id::GetUnit(void) const
- {
- return m_idPtr?m_idPtr->GetUnit():NULL;
- }
- const char *ProfileHighLevel::Id::GetCurrentValue(void) const
- {
- return m_idPtr?m_idPtr->AsString(m_idPtr->GetCurrentValue()):NULL;
- }
- const char *ProfileHighLevel::Id::GetValue(unsigned frame) const
- {
- double v;
- if (!m_idPtr||!m_idPtr->GetFrameValue(frame,v))
- return NULL;
- return m_idPtr->AsString(v);
- }
- const char *ProfileHighLevel::Id::GetTotalValue(void) const
- {
- return m_idPtr?m_idPtr->AsString(m_idPtr->GetTotalValue()):NULL;
- }
- //////////////////////////////////////////////////////////////////////////////
- // ProfileHighLevel::Block
- ProfileHighLevel::Block::Block(const char *name)
- {
- DFAIL_IF(!name) return;
- m_idTime=AddProfile(name,NULL,"msec",6,-4);
- char help[256];
- strncpy(help,name,sizeof(help));
- help[sizeof(help)-1-2]=0;
- strcat(help,".c");
- AddProfile(help,NULL,"calls",6,0).Increment();
- ProfileGetTime(m_start);
- }
- ProfileHighLevel::Block::~Block()
- {
- _int64 end;
- ProfileGetTime(end);
- end-=m_start;
- m_idTime.Increment(double(end)/(double)Profile::GetClockCyclesPerSecond());
- }
- //////////////////////////////////////////////////////////////////////////////
- // ProfileId
- // profile ID stuff
- ProfileId *ProfileId::first;
- int ProfileId::curFrame;
- unsigned ProfileId::frameRecordMask;
- char ProfileId::stringBuf[ProfileId::STRING_BUFFER_SIZE];
- unsigned ProfileId::stringBufUnused;
- ProfileId::ProfileId(const char *name, const char *descr, const char *unit, int precision, int exp10)
- {
- m_next=first; first=this;
- m_name=(char *)ProfileAllocMemory(strlen(name)+1);
- strcpy(m_name,name);
- if (descr)
- {
- m_descr=(char *)ProfileAllocMemory(strlen(descr)+1);
- strcpy(m_descr,descr);
- }
- else
- m_descr=NULL;
- if (unit)
- {
- m_unit=(char *)ProfileAllocMemory(strlen(unit)+1);
- strcpy(m_unit,unit);
- }
- else
- m_unit=NULL;
- m_precision=precision;
- m_exp10=exp10;
- m_curVal=m_totalVal=0.;
- m_recFrameVal=NULL;
- m_firstFrame=curFrame;
- m_valueMode=Unknown;
- }
- void ProfileId::Increment(double add)
- {
- DFAIL_IF(m_valueMode!=Unknown&&m_valueMode!=ModeIncrement)
- return;
- m_valueMode=ModeIncrement;
- m_curVal+=add;
- m_totalVal+=add;
- if (frameRecordMask)
- {
- unsigned mask=frameRecordMask;
- for (unsigned i=0;i<MAX_FRAME_RECORDS;i++)
- {
- if (mask&1)
- m_frameVal[i]+=add;
- if (!(mask>>=1))
- break;
- }
- }
- }
- void ProfileId::Maximum(double max)
- {
- DFAIL_IF(m_valueMode!=Unknown&&m_valueMode!=ModeMaximum)
- return;
- m_valueMode=ModeMaximum;
- if (max>m_curVal)
- m_curVal=max;
- if (max>m_totalVal)
- m_totalVal=max;
- if (frameRecordMask)
- {
- unsigned mask=frameRecordMask;
- for (unsigned i=0;i<MAX_FRAME_RECORDS;i++)
- {
- if (mask&1)
- {
- if (max>m_frameVal[i])
- m_frameVal[i]=max;
- }
- if (!(mask>>=1))
- break;
- }
- }
- }
- const char *ProfileId::AsString(double v) const
- {
- char help1[10],help[40];
- wsprintf(help1,"%%%i.lf",m_precision);
-
- double mul=1.0;
- int k;
- for (k=m_exp10;k<0;k++) mul*=10.0;
- for (;k>0;k--) mul/=10.0;
- unsigned len=_snprintf(help,sizeof(help),help1,v*mul)+1;
- ProfileFastCS::Lock lock(cs);
- if (stringBufUnused+len>STRING_BUFFER_SIZE)
- stringBufUnused=0;
- char *ret=stringBuf+stringBufUnused;
- memcpy(ret,help,len);
- stringBufUnused+=len;
- return ret;
- }
- int ProfileId::FrameStart(void)
- {
- ProfileFastCS::Lock lock(cs);
- for (unsigned i=0;i<MAX_FRAME_RECORDS;i++)
- if (!(frameRecordMask&(1<<i)))
- break;
- if (i==MAX_FRAME_RECORDS)
- return -1;
- for (ProfileId *p=first;p;p=p->m_next)
- p->m_frameVal[i]=0.;
- frameRecordMask|=1<<i;
- return i;
- }
- void ProfileId::FrameEnd(int which, int mixIndex)
- {
- DFAIL_IF(which<0||which>=MAX_FRAME_RECORDS)
- return;
- DFAIL_IF(!(frameRecordMask&(1<<which)))
- return;
- DFAIL_IF(mixIndex>=curFrame)
- return;
- ProfileFastCS::Lock lock(cs);
-
- frameRecordMask^=1<<which;
- if (mixIndex<0)
- {
- // new frame
- curFrame++;
- for (ProfileId *p=first;p;p=p->m_next)
- {
- p->m_recFrameVal=(double *)ProfileReAllocMemory(p->m_recFrameVal,sizeof(double)*(curFrame-p->m_firstFrame));
- p->m_recFrameVal[curFrame-p->m_firstFrame-1]=p->m_frameVal[which];
- }
- }
- else
- {
- // append data
- for (ProfileId *p=first;p;p=p->m_next)
- {
- if (p->m_firstFrame>mixIndex)
- continue;
- double &val=p->m_recFrameVal[mixIndex-p->m_firstFrame];
- switch(p->m_valueMode)
- {
- case ProfileId::Unknown:
- break;
- case ProfileId::ModeIncrement:
- val+=p->m_frameVal[which];
- break;
- case ProfileId::ModeMaximum:
- if (p->m_frameVal[which]>val)
- val=p->m_frameVal[which];
- break;
- default:
- DFAIL();
- }
- }
- }
- }
- void ProfileId::Shutdown(void)
- {
- if (frameRecordMask)
- {
- for (unsigned i=0;i<MAX_FRAME_RECORDS;i++)
- if (frameRecordMask&(1<<i))
- FrameEnd(i,-1);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // ProfileHighLevel
- ProfileHighLevel::Id ProfileHighLevel::AddProfile(const char *name, const char *descr, const char *unit, int precision, int exp10)
- {
- // check if there is already an ID with the given name...
- Id id;
- if (FindProfile(name,id))
- return id;
- // checks...
- DFAIL_IF(!name) return id;
- // no, allocate one
- ProfileFastCS::Lock lock(cs);
- id.m_idPtr=new (ProfileAllocMemory(sizeof(ProfileId))) ProfileId(name,descr,unit,precision,exp10);
- return id;
- }
- bool ProfileHighLevel::EnumProfile(unsigned index, Id &id)
- {
- ProfileFastCS::Lock lock(cs);
- for (ProfileId *cur=ProfileId::GetFirst();cur&&index--;cur=cur->GetNext());
- id.m_idPtr=cur;
- return cur!=NULL;
- }
- bool ProfileHighLevel::FindProfile(const char *name, Id &id)
- {
- DFAIL_IF(!name) return false;
- ProfileFastCS::Lock lock(cs);
- for (ProfileId *cur=ProfileId::GetFirst();cur;cur=cur->GetNext())
- if (!strcmp(name,cur->GetName()))
- {
- id.m_idPtr=cur;
- return true;
- }
- id.m_idPtr=NULL;
- return false;
- }
- ProfileHighLevel::ProfileHighLevel(void)
- {
- }
- ProfileHighLevel ProfileHighLevel::Instance;
|