mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

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 }