This makes sure that profiler threads are properly included in sample data on
Linux. This was previously working because sample capture was performed
system-wide. Now samples are only captured in client context, which includes
all spawned threads. Since this inclusion only works for threads which will be
spawned after the trace starts, no thread can be created before sampling setup
is done.
The C++11 spec states in [basic.stc.thread] thread storage duration:
2. A variable with thread storage duration shall be initialized before its
first odr-use (3.2) and, if constructed, shall be destroyed on thread exit.
Previously Tracy relied on the TLS data being initialized:
- During thread creation (MSVC).
- Or during first use in a thread, but the initialization was performed for
the whole TLS block.
It seems that new compilers are more granular with how they perform the
initialization, hence rpmalloc init has to be checked before each allocation,
as it cannot be "folded" into, for example, initialization of the profiler
itself.
This codepath, involving a workaround for GCC < 8.4, called 'new' and
'delete' directly, which could cause infinite recursion when
user-provided versions of those functions were themselves using Tracy
functionality.
Now, this codepath uses Tracy's internal allocator.
See issues #194, #196
Because of the layout difference between messageFat and
messageColorFat, this was referencing the text member
3-bytes offset from where it should have been.
This is to ensure that thread local structures have been properly
initialized (lock-free queue buffers are thread local), as capturing
callstack involves allocating memory from rpmalloc, which must be
initialized in each thread before allocation.