TracySystem.cpp (4495B)
1 #if defined _MSC_VER || defined __CYGWIN__ || defined _WIN32 2 # ifndef WIN32_LEAN_AND_MEAN 3 # define WIN32_LEAN_AND_MEAN 4 # endif 5 # ifndef NOMINMAX 6 # define NOMINMAX 7 # endif 8 #endif 9 #if defined _WIN32 || defined __CYGWIN__ 10 # include <windows.h> 11 #else 12 # include <pthread.h> 13 # include <string.h> 14 # include <unistd.h> 15 #endif 16 17 #ifdef __linux__ 18 # ifndef __ANDROID__ 19 # include <syscall.h> 20 # endif 21 # include <fcntl.h> 22 #endif 23 24 #ifdef __MINGW32__ 25 # define __STDC_FORMAT_MACROS 26 #endif 27 #include <inttypes.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 31 #include "TracySystem.hpp" 32 33 #ifdef TRACY_ENABLE 34 # include <atomic> 35 # include "TracyAlloc.hpp" 36 #endif 37 38 namespace tracy 39 { 40 41 #ifdef TRACY_ENABLE 42 struct ThreadNameData 43 { 44 uint64_t id; 45 const char* name; 46 ThreadNameData* next; 47 }; 48 TRACY_API std::atomic<ThreadNameData*>& GetThreadNameData(); 49 TRACY_API void InitRPMallocThread(); 50 #endif 51 52 void SetThreadName( const char* name ) 53 { 54 #if defined _WIN32 || defined __CYGWIN__ 55 # if defined NTDDI_WIN10_RS2 && NTDDI_VERSION >= NTDDI_WIN10_RS2 56 wchar_t buf[256]; 57 mbstowcs( buf, name, 256 ); 58 SetThreadDescription( GetCurrentThread(), buf ); 59 # elif defined _MSC_VER 60 const DWORD MS_VC_EXCEPTION=0x406D1388; 61 # pragma pack( push, 8 ) 62 struct THREADNAME_INFO 63 { 64 DWORD dwType; 65 LPCSTR szName; 66 DWORD dwThreadID; 67 DWORD dwFlags; 68 }; 69 # pragma pack(pop) 70 71 DWORD ThreadId = GetCurrentThreadId(); 72 THREADNAME_INFO info; 73 info.dwType = 0x1000; 74 info.szName = name; 75 info.dwThreadID = ThreadId; 76 info.dwFlags = 0; 77 78 __try 79 { 80 RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); 81 } 82 __except(EXCEPTION_EXECUTE_HANDLER) 83 { 84 } 85 # endif 86 #elif defined _GNU_SOURCE && !defined __EMSCRIPTEN__ && !defined __CYGWIN__ 87 { 88 const auto sz = strlen( name ); 89 if( sz <= 15 ) 90 { 91 pthread_setname_np( pthread_self(), name ); 92 } 93 else 94 { 95 char buf[16]; 96 memcpy( buf, name, 15 ); 97 buf[15] = '\0'; 98 pthread_setname_np( pthread_self(), buf ); 99 } 100 } 101 #endif 102 #ifdef TRACY_ENABLE 103 { 104 InitRPMallocThread(); 105 const auto sz = strlen( name ); 106 char* buf = (char*)tracy_malloc( sz+1 ); 107 memcpy( buf, name, sz ); 108 buf[sz+1] = '\0'; 109 auto data = (ThreadNameData*)tracy_malloc( sizeof( ThreadNameData ) ); 110 data->id = detail::GetThreadHandleImpl(); 111 data->name = buf; 112 data->next = GetThreadNameData().load( std::memory_order_relaxed ); 113 while( !GetThreadNameData().compare_exchange_weak( data->next, data, std::memory_order_release, std::memory_order_relaxed ) ) {} 114 } 115 #endif 116 } 117 118 const char* GetThreadName( uint64_t id ) 119 { 120 static char buf[256]; 121 #ifdef TRACY_ENABLE 122 auto ptr = GetThreadNameData().load( std::memory_order_relaxed ); 123 while( ptr ) 124 { 125 if( ptr->id == id ) 126 { 127 return ptr->name; 128 } 129 ptr = ptr->next; 130 } 131 #else 132 # if defined _WIN32 || defined __CYGWIN__ 133 # if defined NTDDI_WIN10_RS2 && NTDDI_VERSION >= NTDDI_WIN10_RS2 134 auto hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)id ); 135 if( hnd != 0 ) 136 { 137 PWSTR tmp; 138 GetThreadDescription( hnd, &tmp ); 139 auto ret = wcstombs( buf, tmp, 256 ); 140 CloseHandle( hnd ); 141 if( ret != 0 ) 142 { 143 return buf; 144 } 145 } 146 # endif 147 # elif defined __GLIBC__ && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined __CYGWIN__ 148 if( pthread_getname_np( (pthread_t)id, buf, 256 ) == 0 ) 149 { 150 return buf; 151 } 152 # elif defined __linux__ 153 int cs, fd; 154 char path[32]; 155 # ifdef __ANDROID__ 156 int tid = gettid(); 157 # else 158 int tid = (int) syscall( SYS_gettid ); 159 # endif 160 snprintf( path, sizeof( path ), "/proc/self/task/%d/comm", tid ); 161 sprintf( buf, "%" PRIu64, id ); 162 # ifndef __ANDROID__ 163 pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &cs ); 164 # endif 165 if ( ( fd = open( path, O_RDONLY ) ) > 0) { 166 int len = read( fd, buf, 255 ); 167 if( len > 0 ) 168 { 169 buf[len] = 0; 170 if( len > 1 && buf[len-1] == '\n' ) 171 { 172 buf[len-1] = 0; 173 } 174 } 175 close( fd ); 176 } 177 # ifndef __ANDROID__ 178 pthread_setcancelstate( cs, 0 ); 179 # endif 180 return buf; 181 # endif 182 #endif 183 sprintf( buf, "%" PRIu64, id ); 184 return buf; 185 } 186 187 }