Merged in tillrathmann/tracy_for_multi_dll_projects (pull request #19)

Support for multi-DLL projects.
This commit is contained in:
Till Rathmann 2018-08-01 08:46:02 +00:00 committed by Bartosz Taudul
commit 468b8d4526
6 changed files with 137 additions and 5 deletions

View File

@ -59,6 +59,14 @@ If you don't want to perform a complete application life-time capture, you may d
On Unix make sure you are linking your application with libpthread and libdl. On Unix make sure you are linking your application with libpthread and libdl.
#### Initial client setup for multi-DLL projects
In projects that consist of multiple DLLs / shared objects things are a bit different. Compiling TracyClient.cpp into every DLL is no option because this would result in several instances of the Tracy objects lying around in the process. We rather need to pass the instances of them to the different DLLs to be reused there.
For that you need a main DLL to which your executable and the other DLLs link. If that doesn't exist you have to create one explicitly for Tracy. Link the executable and all DLLs which you want to profile to this DLL.
Add `tracy/TracyClient.cpp` to the source files list of the main DLL and `tracy/TracyClientDLL.cpp` to the source files lists of the executable and the other DLLs.
#### Running the server #### Running the server
The easiest way to get going is to build the standalone server, available in the `standalone` directory. You can connect to localhost or remote clients and view the collected data right away. The easiest way to get going is to build the standalone server, available in the `standalone` directory. You can connect to localhost or remote clients and view the collected data right away.

View File

@ -4,7 +4,9 @@
// //
// For fast integration, compile and // For fast integration, compile and
// link with this source file (and none // link with this source file (and none
// other). // other) in your executable (or in the
// main DLL / shared object on multi-DLL
// projects).
// //
// Define TRACY_ENABLE to enable profiler. // Define TRACY_ENABLE to enable profiler.

73
TracyClientDLL.cpp Normal file
View File

@ -0,0 +1,73 @@
//
// Tracy profiler
// ----------------
//
// On multi-DLL projects compile and
// link with this source file (and none
// other) in the executable and in
// DLLs / shared objects that link to
// the main DLL.
//
// Define TRACY_ENABLE to enable profiler.
#include "common/TracySystem.cpp"
#ifdef TRACY_ENABLE
#include "client/TracyProfiler.hpp"
#include "client/concurrentqueue.h"
#include "common/TracyQueue.hpp"
namespace tracy
{
#ifdef _MSC_VER
# define DLL_IMPORT __declspec(dllimport)
#else
# define DLL_IMPORT
#endif
DLL_IMPORT moodycamel::ConcurrentQueue<QueueItem>::ExplicitProducer* get_token();
DLL_IMPORT void*(*get_rpmalloc())(size_t size);
DLL_IMPORT void(*get_rpfree())(void* ptr);
DLL_IMPORT Profiler& get_profiler();
#if defined TRACY_HW_TIMER && __ARM_ARCH >= 6
DLL_IMPORT int64_t(*get_GetTimeImpl())();
int64_t(*GetTimeImpl)() = get_GetTimeImpl();
#endif
#ifdef TRACY_COLLECT_THREAD_NAMES
DLL_IMPORT std::atomic<ThreadNameData*>& get_threadNameData();
DLL_IMPORT void(*get_rpmalloc_thread_initialize())();
std::atomic<ThreadNameData*>& s_threadNameData = get_threadNameData();
void(*rpmalloc_thread_initialize_fpt)() = get_rpmalloc_thread_initialize();
void rpmalloc_thread_initialize(void)
{
rpmalloc_thread_initialize_fpt();
}
#endif
static void*(*rpmalloc_fpt)(size_t size) = get_rpmalloc();
static void(*rpfree_fpt)(void* ptr) = get_rpfree();
RPMALLOC_RESTRICT void* rpmalloc(size_t size)
{
return rpmalloc_fpt(size);
}
void rpfree(void* ptr)
{
rpfree_fpt(ptr);
}
Profiler& s_profiler = get_profiler();
thread_local ProducerWrapper s_token { get_token() };
}
#endif

View File

@ -176,14 +176,63 @@ VkCtxWrapper init_order(104) s_vkCtx { nullptr };
#ifdef TRACY_COLLECT_THREAD_NAMES #ifdef TRACY_COLLECT_THREAD_NAMES
struct ThreadNameData; struct ThreadNameData;
std::atomic<ThreadNameData*> init_order(104) s_threadNameData( nullptr ); static std::atomic<ThreadNameData*> init_order(104) s_threadNameDataInstance( nullptr );
std::atomic<ThreadNameData*>& s_threadNameData = s_threadNameDataInstance;
#endif #endif
#ifdef TRACY_ON_DEMAND #ifdef TRACY_ON_DEMAND
thread_local LuaZoneState init_order(104) s_luaZoneState { 0, false }; thread_local LuaZoneState init_order(104) s_luaZoneState { 0, false };
#endif #endif
Profiler init_order(105) s_profiler; static Profiler init_order(105) s_profilerInstance;
Profiler& s_profiler = s_profilerInstance;
#ifdef _MSC_VER
# define DLL_EXPORT __declspec(dllexport)
#else
# define DLL_EXPORT __attribute__((visibility("default")))
#endif
// DLL exports to enable TracyClientDLL.cpp to retrieve the instances of Tracy objects and functions
DLL_EXPORT moodycamel::ConcurrentQueue<QueueItem>::ExplicitProducer* get_token()
{
return s_token.ptr;
}
DLL_EXPORT void*(*get_rpmalloc())(size_t size)
{
return rpmalloc;
}
DLL_EXPORT void(*get_rpfree())(void* ptr)
{
return rpfree;
}
#if defined TRACY_HW_TIMER && __ARM_ARCH >= 6
DLL_EXPORT int64_t(*get_GetTimeImpl())()
{
return GetTimeImpl;
}
#endif
DLL_EXPORT Profiler& get_profiler()
{
return s_profiler;
}
#ifdef TRACY_COLLECT_THREAD_NAMES
DLL_EXPORT std::atomic<ThreadNameData*>& get_threadNameData()
{
return s_threadNameData;
}
DLL_EXPORT void(*get_rpmalloc_thread_initialize())()
{
return rpmalloc_thread_initialize;
}
#endif
enum { BulkSize = TargetFrameSize / QueueItemSize }; enum { BulkSize = TargetFrameSize / QueueItemSize };

View File

@ -80,7 +80,7 @@ extern int64_t (*GetTimeImpl)();
#endif #endif
class Profiler; class Profiler;
extern Profiler s_profiler; extern Profiler& s_profiler;
class Profiler class Profiler
{ {

View File

@ -33,7 +33,7 @@ struct ThreadNameData
const char* name; const char* name;
ThreadNameData* next; ThreadNameData* next;
}; };
extern std::atomic<ThreadNameData*> s_threadNameData; extern std::atomic<ThreadNameData*>& s_threadNameData;
#endif #endif
void SetThreadName( std::thread& thread, const char* name ) void SetThreadName( std::thread& thread, const char* name )