tracy/client
Bartosz Taudul 9f2ffb05ac
Check if memory can be allocated in a thread.
Consider running the following code with operator new and delete overloaded to
track allocations with call stacks:

std::thread( []({ thread_local std::string str; });

Each call stack requires a memory allocation to be performed by the profiler,
to make the stack available at a later time. When the thread is created, the
TLS block is initialized and the std::string buffer can be allocated. To track
this allocation, rpmalloc has to be initialized. This initialization also
happens within the TLS block.

Now, when the thread exits, the heap managed by rpmalloc may be released first
during the TLS block destruction (and if the destruction is performed in
reverse creation order, then it *will* be destroyed first, as rpmalloc was
initialized only after the std::string initialization, to track the allocation
performed within). The next thing to happen is destruction of std::string and
release of the memory block it contains.

The release is tracked by the profiler, and as mentioned earlier, to save the
call stack for later use, a memory allocation is needed. But the allocator is
no longer available in this thread, because rpmalloc was released just before!

As a solution to this issue, profiler will detect whether the allocator is
still available and will ignore the call stack, if it's not. The other
solution is to disable the rpmalloc thread cleanup, which may potentially
cause leak-like behavior, in case a large number of threads is spawned and
destroyed.

Note that this is not a water-tight solution. Other functions will still want
to allocate memory for call stacks, but it is rather unlikely that such calls
would be performed during TLS block destruction. It is also possible that the
event queue will run out of allocated space for events at this very moment,
and in such a case the allocator will also fail.
2022-02-14 17:55:46 +01:00
..
tracy_concurrentqueue.h Change thread id size from 64 to 32 bits. 2021-10-08 00:42:52 +02:00
tracy_rpmalloc.cpp Keep track of rpmalloc thread shutdown state. 2022-02-14 17:52:33 +01:00
tracy_rpmalloc.hpp Mark rprealloc as a part of Tracy API. 2020-12-27 14:11:45 +01:00
tracy_SPSCQueue.h Silence padding warnings, as this is intended behaviour 2022-01-26 21:08:54 +02:00
TracyAlloc.cpp Fix rpmalloc init for shared libraries. 2021-06-13 12:15:36 +02:00
TracyArmCpuTable.hpp Update ARM CPU parts list. 2021-06-04 19:41:59 +02:00
TracyCallstack.cpp Fix potentially unitialized value warning 2022-01-26 21:08:54 +02:00
TracyCallstack.h Move TRACY_UWP define to own header 2022-02-10 20:26:45 +01:00
TracyCallstack.hpp Call RtlWalkFrameChain directly from inlined function. 2022-01-01 17:33:39 +01:00
TracyDebug.hpp Add debug print macros. 2021-05-21 01:47:31 +02:00
TracyDxt1.cpp Mask out alpha channel on SSE and AVX2 paths. 2020-07-20 13:58:35 +02:00
TracyDxt1.hpp Experimental DXT1 compressor. 2019-06-27 19:14:51 +02:00
TracyFastVector.hpp Don't init rpmalloc, if we know it has been done already. 2021-06-10 01:48:11 +02:00
TracyLock.hpp Order of lock events is now always well-defined. 2020-07-26 13:54:40 +02:00
TracyProfiler.cpp Add rpmalloc thread state accessor. 2022-02-14 17:53:27 +01:00
TracyProfiler.hpp Check if memory can be allocated in a thread. 2022-02-14 17:55:46 +01:00
TracyRingBuffer.hpp Keep ring buffer size unsigned. 2021-12-21 20:24:52 +01:00
TracyScoped.hpp Use the possibly-synchronous macros in C++ zones. 2021-10-09 14:58:33 +02:00
TracyStringHelpers.hpp Move inline string copy helpers to a separate header. 2021-10-22 21:53:46 +02:00
TracySysTime.cpp Drop support for Cygwin. 2021-10-07 23:28:40 +02:00
TracySysTime.hpp Drop support for Cygwin. 2021-10-07 23:28:40 +02:00
TracySysTrace.cpp Don't process ring buffers when not connected in on-demand mode. 2022-01-31 20:53:10 +01:00
TracySysTrace.hpp Move TRACY_UWP define to own header 2022-02-10 20:26:45 +01:00
TracyThread.hpp Drop support for Cygwin. 2021-10-07 23:28:40 +02:00