Merge pull request #649 from michaeldleslie/support_qnx

Add basic QNX support
This commit is contained in:
Bartosz Taudul 2023-10-30 23:44:58 +01:00 committed by GitHub
commit 0b21b2f3b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 20 deletions

View File

@ -373,6 +373,7 @@ Tracy Profiler supports MSVC, GCC, and clang. You will need to use a reasonably
\item WSL (x64) \item WSL (x64)
\item OSX (x64) \item OSX (x64)
\item iOS (ARM, ARM64) \item iOS (ARM, ARM64)
\item QNX (x64)
\end{itemize} \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: 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] \begin{table}[h]
\centering \centering
\begin{tabular}[h]{c|c|c|c|c|c|c} \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} \\ \hline \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 \\ Profiling program init & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & \faCheck & \faCheck \\
CPU zones & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ CPU zones & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\
Locks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ Locks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\
Plots & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ Plots & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\
Messages & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ Messages & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\
Memory & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ Memory & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faTimes \\
GPU zones (OpenGL) & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & \\ % GPU zones fields intentionally left blank for BSDs
GPU zones (Vulkan) & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \\ GPU zones (OpenGL) & \faCheck & \faCheck & \faCheck & \faPoo & \faPoo & & \faTimes \\
Call stacks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ GPU zones (Vulkan) & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & & \faTimes \\
Symbol resolution & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ Call stacks & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faTimes \\
Crash handling & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes \\ Symbol resolution & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\
CPU usage probing & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck \\ Crash handling & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes & \faTimes \\
Context switches & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ CPU usage probing & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faCheck & \faTimes \\
Wait stacks & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ Context switches & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\
CPU topology information & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes \\ Wait stacks & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\
Call stack sampling & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ CPU topology information & \faCheck & \faCheck & \faCheck & \faTimes & \faTimes & \faTimes & \faTimes \\
Hardware sampling & \faCheck{}\textsuperscript{\emph{a}} & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes \\ Call stack sampling & \faCheck & \faCheck & \faCheck & \faTimes & \faPoo & \faTimes & \faTimes \\
VSync capture & \faCheck & \faCheck & \faTimes & \faTimes & \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} \end{tabular}
\vspace{1em} \vspace{1em}

View File

@ -66,6 +66,8 @@ static const char* GetOsInfo()
sprintf( buf, "BSD (NetBSD)" ); sprintf( buf, "BSD (NetBSD)" );
#elif defined __OpenBSD__ #elif defined __OpenBSD__
sprintf( buf, "BSD (OpenBSD)" ); sprintf( buf, "BSD (OpenBSD)" );
#elif defined __QNX__
sprintf( buf, "QNX" );
#else #else
sprintf( buf, "unknown" ); sprintf( buf, "unknown" );
#endif #endif

View File

@ -45,6 +45,14 @@
# include <vector> # include <vector>
#endif #endif
#ifdef __QNX__
# include <stdint.h>
# include <stdio.h>
# include <string.h>
# include <sys/syspage.h>
# include <sys/stat.h>
#endif
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
#include <atomic> #include <atomic>
@ -115,6 +123,10 @@ extern "C" typedef BOOL (WINAPI *t_GetLogicalProcessorInformationEx)( LOGICAL_PR
# include <mutex> # include <mutex>
#endif #endif
#ifdef __QNX__
extern char* __progname;
#endif
namespace tracy namespace tracy
{ {
@ -400,6 +412,8 @@ static const char* GetProcessName()
#elif defined __APPLE__ || defined BSD #elif defined __APPLE__ || defined BSD
auto buf = getprogname(); auto buf = getprogname();
if( buf ) processName = buf; if( buf ) processName = buf;
#elif defined __QNX__
processName = __progname;
#endif #endif
return processName; return processName;
} }
@ -437,6 +451,10 @@ static const char* GetProcessExecutablePath()
static char buf[1024]; static char buf[1024];
readlink( "/proc/curproc/exe", buf, 1024 ); readlink( "/proc/curproc/exe", buf, 1024 );
return buf; return buf;
#elif defined __QNX__
static char buf[_PC_PATH_MAX + 1];
_cmdname(buf);
return buf;
#else #else
return nullptr; return nullptr;
#endif #endif
@ -515,6 +533,8 @@ static const char* GetHostInfo()
ptr += sprintf( ptr, "OS: BSD (NetBSD)\n" ); ptr += sprintf( ptr, "OS: BSD (NetBSD)\n" );
#elif defined __OpenBSD__ #elif defined __OpenBSD__
ptr += sprintf( ptr, "OS: BSD (OpenBSD)\n" ); ptr += sprintf( ptr, "OS: BSD (OpenBSD)\n" );
#elif defined __QNX__
ptr += sprintf( ptr, "OS: QNX\n" );
#else #else
ptr += sprintf( ptr, "OS: unknown\n" ); ptr += sprintf( ptr, "OS: unknown\n" );
#endif #endif
@ -687,6 +707,21 @@ static const char* GetHostInfo()
size_t sz = sizeof( memSize ); size_t sz = sizeof( memSize );
sysctlbyname( "hw.physmem", &memSize, &sz, nullptr, 0 ); sysctlbyname( "hw.physmem", &memSize, &sz, nullptr, 0 );
ptr += sprintf( ptr, "RAM: %zu MB\n", memSize / 1024 / 1024 ); 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 #else
ptr += sprintf( ptr, "RAM: unknown\n" ); ptr += sprintf( ptr, "RAM: unknown\n" );
#endif #endif
@ -1684,6 +1719,10 @@ void Profiler::Worker()
new(m_broadcast) UdpBroadcast(); new(m_broadcast) UdpBroadcast();
# ifdef TRACY_ONLY_LOCALHOST # ifdef TRACY_ONLY_LOCALHOST
const char* addr = "127.255.255.255"; 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 # else
const char* addr = "255.255.255.255"; const char* addr = "255.255.255.255";
# endif # endif

View File

@ -28,6 +28,9 @@
# include <sys/thr.h> # include <sys/thr.h>
#elif defined __NetBSD__ || defined __DragonFly__ #elif defined __NetBSD__ || defined __DragonFly__
# include <sys/lwp.h> # include <sys/lwp.h>
#elif defined __QNX__
# include <process.h>
# include <sys/neutrino.h>
#endif #endif
#ifdef __MINGW32__ #ifdef __MINGW32__
@ -78,6 +81,8 @@ TRACY_API uint32_t GetThreadHandleImpl()
return lwp_gettid(); return lwp_gettid();
#elif defined __OpenBSD__ #elif defined __OpenBSD__
return getthrid(); return getthrid();
#elif defined __QNX__
return (uint32_t) gettid();
#elif defined __EMSCRIPTEN__ #elif defined __EMSCRIPTEN__
// Not supported, but let it compile. // Not supported, but let it compile.
return 0; return 0;
@ -176,6 +181,21 @@ TRACY_API void SetThreadName( const char* name )
#endif #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 #endif
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
{ {
@ -255,6 +275,11 @@ TRACY_API const char* GetThreadName( uint32_t id )
pthread_setcancelstate( cs, 0 ); pthread_setcancelstate( cs, 0 );
# endif # endif
return buf; return buf;
#elif defined __QNX__
static char qnxNameBuf[_NTO_THREAD_NAME_MAX + 1] = {0};
if (pthread_getname_np(static_cast<int>(id), qnxNameBuf, _NTO_THREAD_NAME_MAX) == 0) {
return qnxNameBuf;
};
#endif #endif
sprintf( buf, "%" PRIu32, id ); sprintf( buf, "%" PRIu32, id );