Add a lock watching achievement.

This commit is contained in:
Bartosz Taudul
2026-10-12 23:19:44 +02:00
parent 273dedf4b2
commit 97a08ea670
5 changed files with 29 additions and 1 deletions

View File

@@ -1590,6 +1590,7 @@ To set a category for the section, start the section with the \texttt{TracySecti
You can describe each of the categories you want to use with the \texttt{TracySectionSetup(category, fmt, ...)} macro. Section categories with no name set will automatically be assigned a name based on the identifier (e.g., \emph{Category 0}).
\subsection{Marking locks}
\label{markinglocks}
Modern programs must use multi-threading to achieve the full performance capability of the CPU. However, correct execution requires claiming exclusive access to data shared between threads. When many threads want to simultaneously enter the same critical section, the application's multi-threaded performance advantage nullifies. To help solve this problem, Tracy can collect and display lock interactions in threads.

View File

@@ -218,6 +218,7 @@ Embed(PROFILER_FILES TextInstrumentationStatistics src/achievements/Instrumentat
Embed(PROFILER_FILES TextInstrumentFrames src/achievements/InstrumentFrames.md TEXT)
Embed(PROFILER_FILES TextIntro src/achievements/Intro.md TEXT)
Embed(PROFILER_FILES TextLoadTrace src/achievements/LoadTrace.md TEXT)
Embed(PROFILER_FILES TextLocks src/achievements/Locks.md TEXT)
Embed(PROFILER_FILES TextManual src/achievements/Manual.md TEXT)
Embed(PROFILER_FILES TextMemory src/achievements/Memory.md TEXT)
Embed(PROFILER_FILES TextPlots src/achievements/Plots.md TEXT)

View File

@@ -0,0 +1,13 @@
# Watch locks
When something runs slowly, the thread may not be working at all: it could be waiting on a mutex. To see that, declare your synchronization objects with the [Tracy wrappers](#markinglocks) instead of the raw type: `TracyLockable( std::mutex, resourceMutex )` for exclusive locks and `TracySharedLockable( std::shared_mutex, assetLock )` for shared ones. The `*N` variants, such as `TracyLockableN( std::mutex, resourceMutex, "Assets" )`, let you pick the name the lock is displayed under. Code that receives a lock reference works with the wrappers through `LockableBase`/`SharedLockableBase`:
```c++
void Update( LockableBase( std::mutex )& mutex )
{
std::lock_guard guard( mutex );
// ...
}
```
Instrumented locks show up as lanes in each thread's timeline row. Hover over a lock event to see the important information, for example which threads are blocking it and which ones it blocks, then left-click the event to open the [Lock info window](#lockwindow), with the lock's location, type, and event count. Middle-click an event to zoom the view to its extent. Wrap a few of your mutexes, profile the application, and click through your first lock. Try it out!

View File

@@ -14,6 +14,7 @@
#include "data/TextInstrumentationStatistics.hpp"
#include "data/TextIntro.hpp"
#include "data/TextLoadTrace.hpp"
#include "data/TextLocks.hpp"
#include "data/TextManual.hpp"
#include "data/TextMemory.hpp"
#include "data/TextPlots.hpp"
@@ -62,6 +63,15 @@ AchievementItem ai_trackMemory = {
AchievementItem* ac_memoryItems[] = { &ai_trackMemory, nullptr };
AchievementCategory ac_memory = { "memory", "Memory", ac_memoryItems };
AchievementItem ai_watchLocks = {
.id = "watchLocks",
.name = "Watch locks",
.text = Unpack( TextLocks )
};
AchievementItem* ac_locksItems[] = { &ai_watchLocks, nullptr };
AchievementCategory ac_locks = { "locks", "Locks", ac_locksItems };
AchievementItem ai_100million = {
.id = "100million",
@@ -109,7 +119,7 @@ AchievementItem* ac_instrumentationIntroItems[] = {
nullptr
};
AchievementItem* ac_instrumentationIntroUnlock[] = { &ai_trackMemory, nullptr };
AchievementItem* ac_instrumentationIntroUnlock[] = { &ai_trackMemory, &ai_watchLocks, nullptr };
AchievementItem ai_instrumentationIntro = {
.id = "instrumentationIntro",
@@ -217,6 +227,7 @@ AchievementCategory* AchievementCategories[] = {
&ac_instrumentation,
&ac_sampling,
&ac_memory,
&ac_locks,
nullptr
};

View File

@@ -125,6 +125,7 @@ void View::DrawLockHeader( uint32_t id, const LockMap& lockmap, const SourceLoca
if( IsMouseClicked( ImGuiMouseButton_Left ) )
{
if( s_config.achievements ) Achieve( "watchLocks" );
m_lockInfoWindow = id;
}
if( IsMouseClicked( ImGuiMouseButton_Middle ) )
@@ -193,6 +194,7 @@ int View::DrawLocks( const TimelineContext& ctx, const std::vector<std::unique_p
{
if( IsMouseClicked( ImGuiMouseButton_Left ) )
{
if( s_config.achievements ) Achieve( "watchLocks" );
m_lockInfoWindow = lock.id;
}
if( IsMouseClicked( ImGuiMouseButton_Middle ) )