diff --git a/manual/tracy.tex b/manual/tracy.tex index 3a1394bc..553ad6d4 100644 --- a/manual/tracy.tex +++ b/manual/tracy.tex @@ -373,6 +373,7 @@ Tracy Profiler supports MSVC, GCC, and clang. You will need to use a reasonably \item WSL (x64) \item OSX (x64) \item iOS (ARM, ARM64) +\item QNX (x64) \end{itemize} Moreover, the following platforms are not supported due to how secretive their owners are but were reported to be working after extending the system integration layer: @@ -864,26 +865,27 @@ Some features of the profiler are only available on selected platforms. Please r \begin{table}[h] \centering -\begin{tabular}[h]{c|c|c|c|c|c|c} -\textbf{Feature} & \textbf{Windows} & \textbf{Linux} & \textbf{Android} & \textbf{OSX} & \textbf{iOS} & \textbf{BSD} \\ \hline -Profiling program init & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & \faCheck \\ -CPU zones & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Locks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Plots & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Messages & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Memory & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -GPU zones (OpenGL) & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & \\ -GPU zones (Vulkan) & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \\ -Call stacks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Symbol resolution & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Crash handling & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes \\ -CPU usage probing & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ -Context switches & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ -Wait stacks & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ -CPU topology information & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes \\ -Call stack sampling & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ -Hardware sampling & \faCheck{}\textsuperscript{\emph{a}} & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ -VSync capture & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes & \faTimes \\ +\begin{tabular}[h]{c|c|c|c|c|c|c|c} +\textbf{Feature} & \textbf{Windows} & \textbf{Linux} & \textbf{Android} & \textbf{OSX} & \textbf{iOS} & \textbf{BSD} & \textbf{QNX} \\ \hline +Profiling program init & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & \faCheck & \faCheck \\ +CPU zones & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ +Locks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ +Plots & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ +Messages & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ +Memory & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faTimes \\ +% GPU zones fields intentionally left blank for BSDs +GPU zones (OpenGL) & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & & \faTimes \\ +GPU zones (Vulkan) & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & & \faTimes \\ +Call stacks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faTimes \\ +Symbol resolution & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ +Crash handling & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes & \faTimes \\ +CPU usage probing & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faTimes \\ +Context switches & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\ +Wait stacks & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\ +CPU topology information & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes & \faTimes \\ +Call stack sampling & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\ +Hardware sampling & \faCheck{}\textsuperscript{\emph{a}} & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\ +VSync capture & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes & \faTimes & \faTimes \\ \end{tabular} \vspace{1em} diff --git a/profiler/src/HttpRequest.cpp b/profiler/src/HttpRequest.cpp index 64445d94..62181b44 100644 --- a/profiler/src/HttpRequest.cpp +++ b/profiler/src/HttpRequest.cpp @@ -66,6 +66,8 @@ static const char* GetOsInfo() sprintf( buf, "BSD (NetBSD)" ); #elif defined __OpenBSD__ sprintf( buf, "BSD (OpenBSD)" ); +#elif defined __QNX__ + sprintf( buf, "QNX" ); #else sprintf( buf, "unknown" ); #endif diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index d438b844..a13e575a 100644 --- a/public/client/TracyProfiler.cpp +++ b/public/client/TracyProfiler.cpp @@ -45,6 +45,14 @@ # include #endif +#ifdef __QNX__ +# include +# include +# include +# include +# include +#endif + #include #include #include @@ -115,6 +123,10 @@ extern "C" typedef BOOL (WINAPI *t_GetLogicalProcessorInformationEx)( LOGICAL_PR # include #endif +#ifdef __QNX__ +extern char* __progname; +#endif + namespace tracy { @@ -400,6 +412,8 @@ static const char* GetProcessName() #elif defined __APPLE__ || defined BSD auto buf = getprogname(); if( buf ) processName = buf; +#elif defined __QNX__ + processName = __progname; #endif return processName; } @@ -437,6 +451,10 @@ static const char* GetProcessExecutablePath() static char buf[1024]; readlink( "/proc/curproc/exe", buf, 1024 ); return buf; +#elif defined __QNX__ + static char buf[_PC_PATH_MAX + 1]; + _cmdname(buf); + return buf; #else return nullptr; #endif @@ -515,6 +533,8 @@ static const char* GetHostInfo() ptr += sprintf( ptr, "OS: BSD (NetBSD)\n" ); #elif defined __OpenBSD__ ptr += sprintf( ptr, "OS: BSD (OpenBSD)\n" ); +#elif defined __QNX__ + ptr += sprintf( ptr, "OS: QNX\n" ); #else ptr += sprintf( ptr, "OS: unknown\n" ); #endif @@ -687,6 +707,21 @@ static const char* GetHostInfo() size_t sz = sizeof( memSize ); sysctlbyname( "hw.physmem", &memSize, &sz, nullptr, 0 ); ptr += sprintf( ptr, "RAM: %zu MB\n", memSize / 1024 / 1024 ); +#elif defined __QNX__ + struct asinfo_entry *entries = SYSPAGE_ENTRY(asinfo); + size_t count = SYSPAGE_ENTRY_SIZE(asinfo) / sizeof(struct asinfo_entry); + char *strings = SYSPAGE_ENTRY(strings)->data; + + uint64_t memSize = 0; + size_t i; + for (i = 0; i < count; i++) { + struct asinfo_entry *entry = &entries[i]; + if (strcmp(strings + entry->name, "ram") == 0) { + memSize += entry->end - entry->start + 1; + } + } + memSize = memSize / 1024 / 1024; + ptr += sprintf( ptr, "RAM: %llu MB\n", memSize); #else ptr += sprintf( ptr, "RAM: unknown\n" ); #endif @@ -1684,6 +1719,10 @@ void Profiler::Worker() new(m_broadcast) UdpBroadcast(); # ifdef TRACY_ONLY_LOCALHOST const char* addr = "127.255.255.255"; +# elif defined __QNX__ + // global broadcast address of 255.255.255.255 is not well-supported by QNX, + // use the interface broadcast address instead, e.g. "const char* addr = 192.168.1.255;" +# error Need to set an appropriate broadcast address for a QNX target. # else const char* addr = "255.255.255.255"; # endif diff --git a/public/common/TracySystem.cpp b/public/common/TracySystem.cpp index 9a477aa3..0e26aeca 100644 --- a/public/common/TracySystem.cpp +++ b/public/common/TracySystem.cpp @@ -28,6 +28,9 @@ # include #elif defined __NetBSD__ || defined __DragonFly__ # include +#elif defined __QNX__ +# include +# include #endif #ifdef __MINGW32__ @@ -78,6 +81,8 @@ TRACY_API uint32_t GetThreadHandleImpl() return lwp_gettid(); #elif defined __OpenBSD__ return getthrid(); +#elif defined __QNX__ + return (uint32_t) gettid(); #elif defined __EMSCRIPTEN__ // Not supported, but let it compile. return 0; @@ -176,6 +181,21 @@ TRACY_API void SetThreadName( const char* name ) #endif } } +#elif defined __QNX__ + { + const auto sz = strlen( name ); + if( sz <= _NTO_THREAD_NAME_MAX ) + { + pthread_setname_np( pthread_self(), name ); + } + else + { + char buf[_NTO_THREAD_NAME_MAX + 1]; + memcpy( buf, name, _NTO_THREAD_NAME_MAX ); + buf[_NTO_THREAD_NAME_MAX] = '\0'; + pthread_setname_np( pthread_self(), buf ); + } + }; #endif #ifdef TRACY_ENABLE { @@ -255,6 +275,11 @@ TRACY_API const char* GetThreadName( uint32_t id ) pthread_setcancelstate( cs, 0 ); # endif return buf; +#elif defined __QNX__ + static char qnxNameBuf[_NTO_THREAD_NAME_MAX + 1] = {0}; + if (pthread_getname_np(static_cast(id), qnxNameBuf, _NTO_THREAD_NAME_MAX) == 0) { + return qnxNameBuf; + }; #endif sprintf( buf, "%" PRIu32, id );