In the JSON exception catch handler, m_jobsLock.lock() is called directly
on the mutex instead of through the jobsLock unique_lock. When the function
returns, jobsLock's destructor runs but it doesn't own the lock (it was
unlocked earlier at line 1134), and m_jobsLock is never released. This
causes a permanent deadlock the next time anything tries to acquire
m_jobsLock.
Move broadcast message parsing logic from profiler/src/main.cpp into
server/TracyBroadcast.cpp/hpp. This reduces code duplication and enables
reuse by other tools (e.g., multi-capture).
ParseBroadcastMessage() handles all broadcast protocol versions (0-3) and
returns std::optional<BroadcastMessage>. ClientUniqueID() generates a unique
identifier from IP address and port.
Co-authored-by: Grégoire Roussel <gregoire.roussel@wandercraft.eu>
Add option to configure the maximum tool reply size in the advanced
settings of the LLM assistant. The limit can be enabled/disabled via
a checkbox, with the value stored in bytes. The context-based limit
is now displayed alongside the configured limit for transparency.
External symbols checkbox now appears before kernel symbols, and kernel
is disabled when external is not selected since kernel symbols are a
subset of external symbols.
Introduce Windows ARM64(native) support across ToyPathTracer,
profiler, and server code paths when building with MSVC(_M_ARM64).
Key changes:
- MathSimd.h/Maths.h:
- Fix NEON movemask constants for MSVC/ARM64 by loading from a uint32_t[]
via vld1q_u32() and using vdupq_n_u32() for highbit.
- enkiTS/TaskScheduler.cpp:
- Provide Pause() implementation on _M_ARM64 using __yield().
- profiler/winmain.cpp:
- AVX feature checks to x86/x64 only and skip on ARM64.
- server/TracyPopcnt.hpp:
- Implement TracyCountBits using ARM NEON intrinsics.
- Implement TracyLzcnt using _BitScanReverse64().
The chat regenerate/trash button handling had a monolithic lock that
blocked the worker thread during token counting. The token counting
is performed by calling TracyLlmApi::Tokenize(), which issues a
blocking HTTP POST request to the LLM API - on the UI thread.
To avoid blocking both the worker and freezing the UI during HTTP
calls, the lock was split into m_jobsLock and m_chatLock. However,
this introduced a race condition.
For the assistant role (regenerate message action), the code:
1. Stops the current job and queues a new one (under m_jobsLock)
2. Releases the lock
3. Performs token counting via HTTP calls (no lock held)
4. Re-acquires m_jobsLock and stops m_currentJob again
Between steps 2 and 4, the worker thread can complete the old job
and pick up the newly queued job. The stop at step 4 then incorrectly
stops the new regenerate job instead of the old one.
Under the original monolithic lock, the worker couldn't access
m_currentJob until after step 4, so the stop always applied to the
correct job. After the split, the second stop became harmful for
the assistant case.
The fix makes the second stop conditional on user role only (thrash
action), since that's the case where no new job is queued and we
genuinely need to stop any running generation before the user edits
their message.