!F (Profiling) (DEV-7030) Rewrite of the profiling system to have a unified interface...
[CRYENGINE.git] / Code / CryEngine / CrySystem / Profiling / CryProfilingSystem.cpp
blob5182bbed9cedfd8836174369f22111dafae4a081
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "CryProfilingSystem.h"
5 #include "BootProfiler.h"
6 #include <CrySystem/IConsole.h>
7 #include <CryThreading/IThreadManager.h>
9 #if CRY_PLATFORM_WINDOWS
10 # include <psapi.h>
11 #endif
13 // CryMemoryManager.cpp
14 extern int64 CryMemoryGetThreadAllocatedSize();
16 // debugging of profiler
17 #if 0
18 #define CRY_PROFILER_ASSERT(...) if(!(__VA_ARGS__)) __debugbreak(); //assert(__VA_ARGS__)
19 #else
20 #define CRY_PROFILER_ASSERT(...)
21 #endif
23 // measuring the overhead also increases the overhead (by ~0.5ms main thread time)
24 #define CRY_PROFILER_MEASURE_OVERHEAD 1
26 #define PROF_CVAR_THREAD "profile_exclusiveThreadId"
27 threadID CCryProfilingSystem::s_exclusiveThread = 0;
28 #define PROF_CVAR_VERBOSITY "profile_verbosity"
29 int CCryProfilingSystem::s_verbosity = 10;
30 #define PROF_CVAR_SUBSYSTEM "profile_subsystemMask"
31 int64 CCryProfilingSystem::s_subsystemFilterMask = 0;
32 float CCryProfilingSystem::profile_peak_tolerance = 0;
33 int CCryProfilingSystem::profile_value = TIME;
35 #define CRY_PROFILER_MAX_DEPTH 64
36 // tracks nesting level of profiling sections
37 static thread_local int tls_profilingStackDepth = 0;
38 static thread_local SProfilingSection* tls_currentSections[CRY_PROFILER_MAX_DEPTH];
40 //! RAII struct for measuring profiling overhead
41 struct CCryProfilingSystem::AutoTimer
43 AutoTimer(CCryProfilingSystem* _pProfSystem) :
44 timeStamp(CryGetTicks())
45 #if CRY_PROFILER_MEASURE_OVERHEAD
46 , overheadAccumulator(&_pProfSystem->m_profilingOverhead.m_accumulator)
47 #endif
50 #if CRY_PROFILER_MEASURE_OVERHEAD
51 ~AutoTimer()
53 CryInterlockedAdd(overheadAccumulator, CryGetTicks() - timeStamp);
55 #endif
57 const int64 timeStamp;
59 #if CRY_PROFILER_MEASURE_OVERHEAD
60 private:
61 int64* overheadAccumulator;
62 #endif
65 static int64 GetFrequency_ProfilerInternal()
67 LARGE_INTEGER freq;
68 if (QueryPerformanceFrequency(&freq))
69 return freq.QuadPart;
71 CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Couldn't determine performance counter frequency! Profiling times will likely be wrong.");
72 return 1000;
75 CCryProfilingSystem::CCryProfilingSystem()
76 : m_enabled(true)
77 , m_trackingPaused(false)
78 , m_willPause(false)
79 , m_lastTotalPageFaults(0)
80 , m_MsPerTick(1000.0f / GetFrequency_ProfilerInternal())
81 , m_pBootProfiler(nullptr)
83 assert(s_pInstance == nullptr);
84 s_pInstance = this;
87 CCryProfilingSystem::~CCryProfilingSystem()
89 Stop();
90 s_pInstance = nullptr;
93 void CCryProfilingSystem::ProfilingSystemFilterCvarChangedCallback(ICVar* pCvar)
95 if (s_pInstance == nullptr)
96 return;
98 if (strcmp(PROF_CVAR_SUBSYSTEM, pCvar->GetName()) == 0)
99 s_pInstance->s_subsystemFilterMask = pCvar->GetI64Val();
100 else if (strcmp(PROF_CVAR_VERBOSITY, pCvar->GetName()) == 0)
101 s_pInstance->s_verbosity = pCvar->GetIVal();
102 else if (strcmp(PROF_CVAR_THREAD, pCvar->GetName()) == 0)
103 s_pInstance->s_exclusiveThread = (threadID)pCvar->GetI64Val();
104 else
106 assert(!"Unrecognized CVar!");
109 s_pInstance->ReapplyTrackerFilter();
112 void CCryProfilingSystem::FilterSubsystemCommand(IConsoleCmdArgs* args)
114 if (s_pInstance == nullptr)
115 return;
117 if (args->GetArgCount() < 3)
119 CryLog("Too few arguments. Usage: %s [0,1] System1 System2 ..", args->GetArg(0));
120 return;
123 bool enable;
124 if (strcmp("0", args->GetArg(1)) == 0)
125 enable = false;
126 else if (strcmp("1", args->GetArg(1)) == 0)
127 enable = true;
128 else
130 CryLog("First argument has to be 0 or 1.");
131 return;
134 int64 changeMask = 0;
135 for (int arg = 2; arg < args->GetArgCount(); ++arg)
137 bool found = false;
138 for (int subsystemId = 0; subsystemId < EProfiledSubsystem::PROFILE_LAST_SUBSYSTEM; ++subsystemId)
140 if (stricmp(args->GetArg(arg), s_pInstance->GetModuleName((EProfiledSubsystem)subsystemId)) == 0)
142 changeMask |= int64(1) << subsystemId;
143 found = true;
144 break;
147 if(!found)
148 CryLog("Unknown Subsystem name '%s'.", args->GetArg(arg));
151 if(changeMask)
153 ICVar* pCvar = gEnv->pConsole->GetCVar(PROF_CVAR_SUBSYSTEM);
154 int64 newMask = enable ? (pCvar->GetI64Val() | changeMask) : (pCvar->GetI64Val() & ~changeMask);
155 pCvar->Set(newMask);
156 CryLog("Subsystem mask is now set to 0x%" PRIx64 ".", newMask);
160 void CCryProfilingSystem::FilterThreadCommand(struct IConsoleCmdArgs* args)
162 if (s_pInstance == nullptr)
163 return;
165 if (args->GetArgCount() != 2)
167 CryLog("Incorrect number of arguments. Usage: %s ThreadName", args->GetArg(0));
168 return;
171 threadID tid = gEnv->pThreadManager->GetThreadId(args->GetArg(1));
172 if (tid)
174 ICVar* pCvar = gEnv->pConsole->GetCVar(PROF_CVAR_THREAD);
175 pCvar->Set((int64)tid);
177 else
178 CryLog("Thread not found.");
181 void CCryProfilingSystem::StopPofilingCommand(struct IConsoleCmdArgs* args)
183 if (s_pInstance)
184 s_pInstance->Stop();
187 void CCryProfilingSystem::RegisterCVars()
189 REGISTER_INT64_CB(PROF_CVAR_SUBSYSTEM, 0, VF_BITFIELD,
190 "Set the bitmask for filtering out subsystems from profiling. Set a bit to 1 to exclude to corresponding system from the profile."
191 , ProfilingSystemFilterCvarChangedCallback);
193 REGISTER_INT64_CB(PROF_CVAR_THREAD, 0, VF_NULL,
194 "Allows filtering the profiling based on thread id. Only the thread with the given id will be included in the profile."
195 , ProfilingSystemFilterCvarChangedCallback);
196 REGISTER_COMMAND("profile_exclusiveThread", FilterThreadCommand, VF_NULL,
197 "Allows filtering the profiling based on thread name. Only the thread with the given name will be included in the profile.");
199 ICVar* pVerbosityVar = REGISTER_INT_CB(PROF_CVAR_VERBOSITY, s_verbosity, VF_NULL,
200 "Sets the depth up to which profiling information will be gathered.\n"
201 "Higher values lead to more detailed profiling information, but also slightly increase performance costs."
202 , ProfilingSystemFilterCvarChangedCallback);
203 pVerbosityVar->SetMaxValue(CRY_PROFILER_MAX_DEPTH);
205 string filterSubsystemHelp = "Allows to turn on/off the profiling filter for subsystems by name. First parameter indicates if you want to enable or disable filtering."
206 " Use 1 to enable filtering, i.e. exclude the subsystem from profiling; otherwise use 0. After that you can give the names of the subsystems you want to set the filter for.\n"
207 "E.g. 'profile_filterSubsystem 1 AI Renderer' will exclude the AI and rendering systems from profiling.\n"
208 "Available subsystem names are: ";
209 for (int subsystemId = 0; subsystemId < EProfiledSubsystem::PROFILE_LAST_SUBSYSTEM; ++subsystemId)
211 filterSubsystemHelp.append(GetModuleName((EProfiledSubsystem) subsystemId));
212 if (subsystemId != EProfiledSubsystem::PROFILE_LAST_SUBSYSTEM - 1)
213 filterSubsystemHelp.append(", ");
216 REGISTER_COMMAND("profile_filterSubsystem", FilterSubsystemCommand, VF_NULL, filterSubsystemHelp.c_str());
217 REGISTER_COMMAND("profile_stop", StopPofilingCommand, VF_NULL, "Terminates the profiling session. (Cannot be restarted. Use the 'Scroll Lock' key for un/pausing.)");
219 REGISTER_CVAR(profile_peak_tolerance, 5.0f, VF_NULL, "Profiler Peaks Tolerance in Milliseconds."
220 " If the self time of a section in one frame exceeds its average by more than the tolerance a peak is logged.");
223 ICVar* pvar = REGISTER_CVAR(profile_value, TIME, VF_NULL,
224 "Allows to set the value that should be profiled. Set to 0 for time and to 1 for allocated memory.\n"
225 "Only use time profiling with the 'profile X' commands. Otherwise, e.g. Bootprofiler and Statoscope would give unexpected results.");
226 pvar->SetMinValue(TIME);
227 pvar->SetMaxValue(MEMORY);
231 void CCryProfilingSystem::Stop()
233 AutoTimer timer(this);
234 AutoWriteLock autoLock(m_trackerLock);
235 if (m_enabled)
237 m_enabled = false;
238 stl::free_container(m_activeTrackers);
239 stl::free_container(m_excludedTrackers);
240 stl::free_container(m_FrameListeners);
241 m_pBootProfiler = nullptr;
245 bool CCryProfilingSystem::IsStopped() const
247 return !m_enabled;
250 void CCryProfilingSystem::PauseRecording(bool pause)
252 // actual pausing is triggered at frame end
253 m_willPause = pause;
256 bool CCryProfilingSystem::IsPaused() const
258 return m_trackingPaused;
261 void CCryProfilingSystem::StartThread() {}
263 void CCryProfilingSystem::EndThread() {}
265 void CCryProfilingSystem::AddFrameListener(ICryProfilerFrameListener* pListener)
267 AutoWriteLock autoLock(m_trackerLock);
268 if (m_enabled)
270 m_FrameListeners.push_back(pListener);
274 void CCryProfilingSystem::SetBootProfiler(CBootProfiler* pProf)
276 m_pBootProfiler = pProf;
279 void CCryProfilingSystem::RemoveFrameListener(ICryProfilerFrameListener* pListener)
281 AutoTimer timer(this);
282 AutoWriteLock autoLock(m_trackerLock);
283 stl::find_and_erase(m_FrameListeners, pListener);
286 void CCryProfilingSystem::DescriptionCreated(SProfilingSectionDescription* pDesc)
288 pDesc->color_argb = GenerateColorBasedOnName(pDesc->szEventname);
291 void CCryProfilingSystem::DescriptionDestroyed(SProfilingSectionDescription* pDesc)
293 AutoTimer timer(this);
294 AutoWriteLock lock(m_trackerLock);
296 SProfilingSectionTracker* pTracker = (SProfilingSectionTracker*) pDesc->customData;
297 while (pTracker)
299 bool erased = false;
300 if (pTracker->isActive)
301 erased = stl::find_and_erase(m_activeTrackers, pTracker);
302 else
303 erased = stl::find_and_erase(m_excludedTrackers, pTracker);
304 CRY_PROFILER_ASSERT(erased);
306 SProfilingSectionTracker* tmp = pTracker;
307 pTracker = pTracker->pNextThreadTracker;
308 delete tmp;
310 pDesc->customData = 0;
313 SProfilingSectionTracker* CCryProfilingSystem::AddTracker(const SProfilingSectionDescription* pDesc, threadID tid)
315 AutoWriteLock autoLock(m_trackerLock);
317 // look up to ensure there is not already a tracker for the current thread
318 SProfilingSectionTracker* pTracker = (SProfilingSectionTracker*)pDesc->customData;
319 while (pTracker && pTracker->threadId != tid)
320 pTracker = pTracker->pNextThreadTracker;
322 if (pTracker)
323 return pTracker;
325 // didn't find any, so create one
326 pTracker = new SProfilingSectionTracker(pDesc, tid);
328 pTracker->isActive = !IsExcludedByFilter(pTracker);
329 if (pTracker->isActive)
330 m_activeTrackers.push_back(pTracker);
331 else
332 m_excludedTrackers.push_back(pTracker);
334 // link new tracker into list
335 pTracker->pNextThreadTracker = (SProfilingSectionTracker*) pDesc->customData;
336 pDesc->customData = (uintptr_t) pTracker;
338 return pTracker;
341 bool CCryProfilingSystem::StartSection(SProfilingSection* pSection)
343 if (!m_enabled)
344 return false;
345 AutoTimer timer(this);
347 if (tls_profilingStackDepth >= s_verbosity)
348 return false;
350 #if CRY_PROFILER_COMBINE_JOB_TRACKERS
351 const threadID currentTID = (gEnv->pJobManager && JobManager::IsWorkerThread()) ? CRY_PROFILER_JOB_THREAD_ID : CryGetCurrentThreadId();
352 #else
353 const threadID currentTID = CryGetCurrentThreadId();
354 #endif
356 SProfilingSectionTracker* pTracker = nullptr;
358 AutoReadLock autoLock(m_trackerLock);
360 // look for tracker in the description's custom data
361 pTracker = (SProfilingSectionTracker*)pSection->pDescription->customData;
362 while (pTracker && pTracker->threadId != currentTID)
363 pTracker = pTracker->pNextThreadTracker;
365 // did not find a tracker, so create a new one
366 if (pTracker == nullptr)
368 // AddTracker() write-locks internally
369 m_trackerLock.RUnlock();
370 pTracker = AddTracker(pSection->pDescription, currentTID);
371 m_trackerLock.RLock();
374 CRY_PROFILER_ASSERT(pTracker);
376 // no tracking on excluded sections
377 if (!pTracker->isActive)
378 return false;
379 if (!m_trackingPaused)
380 ++pTracker->count;
382 // use section custom data to store tracker, so we don't have to look it up again later
383 pSection->customData = (uintptr_t) pTracker;
385 if(profile_value == MEMORY)
386 pSection->startValue = CryMemoryGetThreadAllocatedSize();
387 else
388 pSection->startValue = timer.timeStamp;
390 #if defined(ENABLE_LOADING_PROFILER)
391 if (m_pBootProfiler)
392 m_pBootProfiler->OnSectionStart(*pSection);
393 #endif
395 tls_currentSections[tls_profilingStackDepth] = pSection;
396 ++tls_profilingStackDepth;
397 return true;
400 void CCryProfilingSystem::EndSection(SProfilingSection* pSection)
402 if (!m_enabled)
403 return;
404 AutoTimer timer(this);
406 // We need to finish sections that were started before pausing, so we pop before checking for m_trackingPaused
407 --tls_profilingStackDepth;
408 CRY_PROFILER_ASSERT(tls_profilingStackDepth >= 0);
409 CRY_PROFILER_ASSERT(tls_currentSections[tls_profilingStackDepth] == pSection);
411 // calculate measurements
412 SProfilingSectionEnd sectionEnd;
413 if (profile_value == MEMORY)
415 sectionEnd.totalValue = CryMemoryGetThreadAllocatedSize() - pSection->startValue;
416 sectionEnd.selfValue = sectionEnd.totalValue - pSection->childExcludeValue;
418 else
420 sectionEnd.totalValue = timer.timeStamp - pSection->startValue;
421 CRY_PROFILER_ASSERT(sectionEnd.totalValue >= 0);
423 sectionEnd.selfValue = sectionEnd.totalValue - pSection->childExcludeValue;
424 CRY_PROFILER_ASSERT(sectionEnd.selfValue >= 0);
427 #if defined(ENABLE_LOADING_PROFILER)
428 if (m_pBootProfiler)
429 m_pBootProfiler->OnSectionEnd(*pSection, sectionEnd);
430 #endif
432 if (!m_trackingPaused)
434 SProfilingSection* const pParentSection = tls_profilingStackDepth > 0 ? tls_currentSections[tls_profilingStackDepth - 1] : nullptr;
435 SProfilingSectionTracker* const pTracker = (SProfilingSectionTracker*)pSection->customData;
436 #if CRY_PROFILER_COMBINE_JOB_TRACKERS
437 CRY_PROFILER_ASSERT(pTracker->threadId == CryGetCurrentThreadId() || (JobManager::IsWorkerThread() && pTracker->threadId == CRY_PROFILER_JOB_THREAD_ID));
438 #else
439 CRY_PROFILER_ASSERT(pTracker->threadId == CryGetCurrentThreadId());
440 #endif
442 if (pParentSection != nullptr)
444 pParentSection->childExcludeValue += sectionEnd.totalValue;
447 // update tracker
448 pTracker->totalValue += sectionEnd.totalValue;
449 pTracker->selfValue += sectionEnd.selfValue;
450 if (profile_value == MEMORY)
451 pTracker->peakSelfValue = max(pTracker->peakSelfValue, SMemoryUpdateTraits::ToFloat(sectionEnd.selfValue));
452 else
453 pTracker->peakSelfValue = max(pTracker->peakSelfValue, STickUpdateTraits::ToFloat(sectionEnd.selfValue));
457 void CCryProfilingSystem::StartFrame()
459 if (!m_enabled)
460 return;
461 #if defined(ENABLE_LOADING_PROFILER)
462 AutoTimer timer(this);
464 if (m_pBootProfiler)
465 m_pBootProfiler->OnFrameStart();
466 #endif
469 void CCryProfilingSystem::EndFrame()
471 if (IsStopped())
472 return;
473 AutoTimer timer(this);
475 const float blendFactor = gEnv->pTimer->GetProfileFrameBlending();
477 #if CRY_PLATFORM_WINDOWS
478 typedef BOOL(WINAPI * TGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
479 static TGetProcessMemoryInfo pfGetProcessMemoryInfo = nullptr;
480 static bool s_missingPsapiDll = false;
482 if (!pfGetProcessMemoryInfo)
484 if (!s_missingPsapiDll)
486 HMODULE hPsapiModule = ::LoadLibraryA("psapi.dll");
487 if (hPsapiModule)
489 pfGetProcessMemoryInfo = (TGetProcessMemoryInfo)(::GetProcAddress(hPsapiModule, "GetProcessMemoryInfo"));
491 else
492 s_missingPsapiDll = true;
496 if (pfGetProcessMemoryInfo)
498 PROCESS_MEMORY_COUNTERS pc;
499 pfGetProcessMemoryInfo(GetCurrentProcess(), &pc, sizeof(pc));
500 m_pageFaultsPerFrame = pc.PageFaultCount - m_lastTotalPageFaults;
501 m_pageFaultsPerFrame.CommitSample<SCountUpdateTraits>(blendFactor);
502 m_lastTotalPageFaults = pc.PageFaultCount;
504 #endif
506 m_profilingOverhead.CommitSample<STickUpdateTraits>(blendFactor);
507 if (!m_trackingPaused)
509 { AutoWriteLock autoLock(m_trackerLock);
510 for (SProfilingSectionTracker* pTracker : m_activeTrackers)
511 CommitFrame(pTracker, blendFactor);
513 for (SProfilingSectionTracker* pTracker : m_activeTrackers)
514 CheckForPeak(timer.timeStamp, pTracker);
517 { AutoReadLock autoLock(m_trackerLock);
518 for (ICryProfilerFrameListener* pProfiler : m_FrameListeners)
519 pProfiler->OnFrameEnd(timer.timeStamp, this);
521 for (SProfilingSectionTracker* pTracker : m_activeTrackers)
522 pTracker->peakSelfValue = 0;
526 #if defined(ENABLE_LOADING_PROFILER)
527 if (m_pBootProfiler)
528 m_pBootProfiler->OnFrameEnd();
529 #endif
531 // pause was requested or no one is listening for the results
532 m_trackingPaused = m_willPause || m_FrameListeners.empty();
535 void CCryProfilingSystem::RecordMarker(SProfilingMarker* pMarker)
537 if (!m_enabled || m_pBootProfiler == nullptr)
538 return;
539 AutoTimer timer(this);
541 if (IsExcludedByFilter(pMarker))
542 return;
544 if(pMarker->pDescription->color_argb == 0)
546 pMarker->pDescription->color_argb = GenerateColorBasedOnName(pMarker->pDescription->szMarkername);
549 #if defined(ENABLE_LOADING_PROFILER)
550 m_pBootProfiler->OnMarker(timer.timeStamp, *pMarker);
551 #endif
554 const CCryProfilingSystem::TrackerList* CCryProfilingSystem::GetActiveTrackers() const
556 return &m_activeTrackers;
559 const CCryProfilingSystem::PeakList* CCryProfilingSystem::GetPeakRecords() const
561 return &m_peaks;
564 void CCryProfilingSystem::CheckForPeak(int64 time, SProfilingSectionTracker* pTracker)
566 float average = pTracker->selfValue.Average();
567 float peakValue = pTracker->selfValue.Latest();
569 if ((peakValue - average) > profile_peak_tolerance)
571 SPeakRecord peak;
572 peak.pTracker = pTracker;
573 peak.peakValue = peakValue;
574 peak.averageValue = average;
575 peak.variance = pTracker->selfValue.Variance();
576 peak.count = pTracker->count;
578 peak.pageFaults = m_pageFaultsPerFrame.CurrentRaw();
579 peak.frame = gEnv->nMainFrameID;
580 peak.timeSeconds = time * m_MsPerTick * 0.001f;
581 peak.waiting = pTracker->pDescription->isWaiting;
583 m_peaks.push_front_overwrite(peak);
587 void CCryProfilingSystem::CommitFrame(SProfilingSectionTracker* pTracker, float blendFactor)
589 pTracker->count.CommitSample<SCountUpdateTraits>(blendFactor);
590 if(profile_value == TIME)
592 pTracker->selfValue.CommitSample<STickUpdateTraits>(blendFactor);
593 pTracker->totalValue.CommitSample<STickUpdateTraits>(blendFactor);
595 else
597 pTracker->selfValue.CommitSample<SMemoryUpdateTraits>(blendFactor);
598 pTracker->totalValue.CommitSample<SMemoryUpdateTraits>(blendFactor);
602 bool CCryProfilingSystem::IsExcludedByFilter(const SProfilingSectionTracker* pTracker) const
604 if ((int64(1) << (uint8) pTracker->pDescription->subsystem) & s_subsystemFilterMask)
605 return true;
607 if (s_exclusiveThread != 0 && pTracker->threadId != s_exclusiveThread)
608 return true;
610 return false;
613 bool CCryProfilingSystem::IsExcludedByFilter(const SProfilingMarker* pMarker) const
615 if ((int64(1) << (uint8)pMarker->pDescription->subsystem) & s_subsystemFilterMask)
616 return true;
618 if (s_exclusiveThread != 0 && pMarker->threadId != s_exclusiveThread)
619 return true;
621 return false;
624 void CCryProfilingSystem::ReapplyTrackerFilter()
626 AutoTimer timer(this);
628 TrackerList activeTrackers;
629 TrackerList excludedTrackers;
631 { AutoReadLock autoLock(m_trackerLock);
633 activeTrackers.reserve(m_activeTrackers.size() + m_excludedTrackers.size());
634 excludedTrackers.reserve(m_activeTrackers.size() + m_excludedTrackers.size());
636 for (SProfilingSectionTracker* pTracker : m_activeTrackers)
638 pTracker->isActive = !IsExcludedByFilter(pTracker);
639 if (pTracker->isActive)
640 activeTrackers.push_back(pTracker);
641 else
642 excludedTrackers.push_back(pTracker);
645 const float blendFactor = gEnv->pTimer->GetProfileFrameBlending();
646 for (SProfilingSectionTracker* pTracker : m_excludedTrackers)
648 pTracker->isActive = !IsExcludedByFilter(pTracker);
649 if (pTracker->isActive)
651 CommitFrame(pTracker, blendFactor);
652 activeTrackers.push_back(pTracker);
654 else
655 excludedTrackers.push_back(pTracker);
659 { AutoWriteLock autoLock(m_trackerLock);
661 m_activeTrackers = activeTrackers;
662 m_excludedTrackers = excludedTrackers;
666 void CCryProfilingSystem::AcquireReadAccess()
668 m_trackerLock.RLock();
671 void CCryProfilingSystem::ReleaseReadAccess()
673 m_trackerLock.RUnlock();
676 CCryProfilingSystem* CCryProfilingSystem::s_pInstance = nullptr;
678 bool CCryProfilingSystem::StartSectionStatic(SProfilingSection* pSection)
680 return s_pInstance->StartSection(pSection);
683 void CCryProfilingSystem::EndSectionStatic(SProfilingSection* pSection)
685 s_pInstance->EndSection(pSection);
688 void CCryProfilingSystem::RecordMarkerStatic(SProfilingMarker* pMarker)
690 s_pInstance->RecordMarker(pMarker);
693 const char* CCryProfilingSystem::GetModuleName(const SProfilingSectionTracker* pTracker) const
695 return GetModuleName(pTracker->pDescription->subsystem);
698 const CSamplerStats<TProfilingCount>& CCryProfilingSystem::PageFaultsPerFrame() const
700 return m_pageFaultsPerFrame;