Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix leaks inside ProfileDrawer and TimeProfiler. #1742

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 37 additions & 15 deletions rts/Game/UI/ProfileDrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@

ProfileDrawer* ProfileDrawer::instance = nullptr;

static constexpr float MAX_THREAD_HIST_TIME = 0.5f; // secs
static constexpr float MAX_FRAMES_HIST_TIME = 0.5f; // secs

static constexpr float MIN_X_COOR = 0.6f;
Expand Down Expand Up @@ -139,17 +138,11 @@ static void DrawBufferStats(const float2 pos)

static void DrawTimeSlices(
std::deque<TimeSlice>& frames,
const spring_time curTime,
const spring_time maxTime,
const float4& drawArea,
const float4& sliceColor
) {
RECOIL_DETAILED_TRACY_ZONE;
// remove old entries
while (!frames.empty() && (curTime - frames.front().second) > maxTime) {
frames.pop_front();
}

const float y1 = drawArea.y;
const float y2 = drawArea.w;

Expand Down Expand Up @@ -220,9 +213,10 @@ static void DrawThreadBarcode(TypedRenderBuffer<VA_TYPE_C >& rb)
font->glFormat(drawArea[0], drawArea[3], 0.7f, FONT_TOP | DBG_FONT_FLAGS | FONT_BUFFERED, "ThreadPool (%.1f seconds :: %u threads)", MAX_THREAD_HIST_TIME, numThreads);
}
{
// need to lock; DrawTimeSlice pop_front()'s old entries from
// threadProf while ~ScopedMtTimer can modify it concurrently
// Need to lock; CleanupOldThreadProfiles pop_front()'s old entries
// from threadProf while ~ScopedMtTimer can modify it concurrently.
profiler.ToggleLock(true);
profiler.CleanupOldThreadProfiles();

// bars for each pool-thread profile
// Create a virtual row at the top to give some space to see the threads without the title getting in the way.
Expand All @@ -233,7 +227,7 @@ static void DrawThreadBarcode(TypedRenderBuffer<VA_TYPE_C >& rb)
float drawArea2[4] = {drawArea[0], 0.0f, drawArea[2], 0.0f};
drawArea2[1] = drawArea[1] + ((drawArea[3] - drawArea[1]) / numRows) * i++;
drawArea2[3] = drawArea[1] + ((drawArea[3] - drawArea[1]) / numRows) * i - (4 * globalRendering->pixelY);
DrawTimeSlices(threadProf, curTime, maxTime, drawArea2, {1.0f, 0.0f, 0.0f, 0.6f});
DrawTimeSlices(threadProf, maxTime, drawArea2, {1.0f, 0.0f, 0.0f, 0.6f});
}

profiler.ToggleLock(false);
Expand Down Expand Up @@ -287,11 +281,11 @@ static void DrawFrameBarcode(TypedRenderBuffer<VA_TYPE_C >& rb)
, MAX_FRAMES_HIST_TIME
);

DrawTimeSlices(lgcFrames, curTime, maxTime, drawArea, {1.0f, 0.5f, 1.0f, 0.55f}); // gc frames
DrawTimeSlices(uusFrames, curTime, maxTime, drawArea, {1.0f, 1.0f, 0.0f, 0.90f}); // unsynced-update frames
DrawTimeSlices(swpFrames, curTime, maxTime, drawArea, {0.0f, 0.0f, 1.0f, 0.55f}); // video swap frames
DrawTimeSlices(vidFrames, curTime, maxTime, drawArea, {0.0f, 1.0f, 0.0f, 0.55f}); // video frames
DrawTimeSlices(simFrames, curTime, maxTime, drawArea, {1.0f, 0.0f, 0.0f, 0.55f}); // sim frames
DrawTimeSlices(lgcFrames, maxTime, drawArea, {1.0f, 0.5f, 1.0f, 0.55f}); // gc frames
DrawTimeSlices(uusFrames, maxTime, drawArea, {1.0f, 1.0f, 0.0f, 0.90f}); // unsynced-update frames
DrawTimeSlices(swpFrames, maxTime, drawArea, {0.0f, 0.0f, 1.0f, 0.55f}); // video swap frames
DrawTimeSlices(vidFrames, maxTime, drawArea, {0.0f, 1.0f, 0.0f, 0.55f}); // video frames
DrawTimeSlices(simFrames, maxTime, drawArea, {1.0f, 0.0f, 0.0f, 0.55f}); // sim frames

{
// draw 'feeder' (indicates current time pos)
Expand Down Expand Up @@ -654,3 +648,31 @@ void ProfileDrawer::DbgTimingInfo(DbgTimingInfoType type, const spring_time star
}
}

static void DiscardOldTimeSlices(
std::deque<TimeSlice>& frames,
const spring_time curTime,
const spring_time maxTime
) {
RECOIL_DETAILED_TRACY_ZONE;
// remove old entries
while (!frames.empty() && (curTime - frames.front().second) > maxTime) {
frames.pop_front();
}
}

void ProfileDrawer::Update()
{
RECOIL_DETAILED_TRACY_ZONE;
const spring_time curTime = spring_now();
const spring_time maxTime = spring_secs(MAX_FRAMES_HIST_TIME);

// cleanup old frame records
DiscardOldTimeSlices(lgcFrames, curTime, maxTime);
DiscardOldTimeSlices(uusFrames, curTime, maxTime);
DiscardOldTimeSlices(swpFrames, curTime, maxTime);
DiscardOldTimeSlices(vidFrames, curTime, maxTime);
DiscardOldTimeSlices(simFrames, curTime, maxTime);

// old ThreadProfile records get cleaned up inside TimeProfiler and DrawThreadBarcode
}

1 change: 1 addition & 0 deletions rts/Game/UI/ProfileDrawer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ProfileDrawer : public CEventClient
virtual bool MousePress(int x, int y, int button) override;
virtual bool IsAbove(int x, int y) override;
virtual void DbgTimingInfo(DbgTimingInfoType type, const spring_time start, const spring_time end) override;
virtual void Update() override;

private:
ProfileDrawer();
Expand Down
19 changes: 19 additions & 0 deletions rts/System/TimeProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ void CTimeProfiler::Update()
UpdateRaw();
ResortProfilesRaw();
RefreshProfilesRaw();
// Now cleanup old thread profiles, no need to do it if
// disabled since won't be accepting data.
CleanupOldThreadProfiles();
}

void CTimeProfiler::UpdateRaw()
Expand Down Expand Up @@ -328,6 +331,22 @@ void CTimeProfiler::RefreshProfilesRaw()
}
}

void CTimeProfiler::CleanupOldThreadProfiles()
{
#ifdef THREADPOOL
const spring_time curTime = spring_gettime();
const spring_time maxTime = spring_secs(MAX_THREAD_HIST_TIME);
const size_t numThreads = std::min(threadProfiles.size(), (size_t)ThreadPool::GetNumThreads());
size_t i = 0;

for (auto& threadProf: threadProfiles) {
if (i++ >= numThreads) break;
while (!threadProf.empty() && (curTime - threadProf.front().second) > maxTime) {
threadProf.pop_front();
}
}
#endif
}

const CTimeProfiler::TimeRecord& CTimeProfiler::GetTimeRecord(const char* name) const
{
Expand Down
3 changes: 3 additions & 0 deletions rts/System/TimeProfiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#define SCOPED_ONCE_TIMER(name) ZoneScopedNC(name, tracy::Color::Purple); ScopedOnceTimer __timer(name);

static constexpr float MAX_THREAD_HIST_TIME = 0.5f; // secs

class BasicTimer : public spring::noncopyable
{
public:
Expand Down Expand Up @@ -183,6 +185,7 @@ class CTimeProfiler
void ResortProfilesRaw();
void RefreshProfiles();
void RefreshProfilesRaw();
void CleanupOldThreadProfiles();

void SetEnabled(bool b) { enabled = b; }
void PrintProfilingInfo() const;
Expand Down