diff --git a/cmake/config.cmake b/cmake/config.cmake index d563c225a1..ec655cbcff 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -12,7 +12,11 @@ if (NOT NO_ISA_EXTENSIONS) endif() endif() if(WIN32) - add_compile_options(/arch:AVX2) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") + add_compile_options(-mavx2) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/arch:AVX2) + endif() endif() endif() @@ -30,7 +34,9 @@ endif() if(WIN32) add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) - add_compile_options(/MP) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_compile_options(/MP) + endif() endif() if(EMSCRIPTEN) @@ -38,7 +44,10 @@ if(EMSCRIPTEN) endif() if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT EMSCRIPTEN) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) + # gcc on windows can't handle section count resulting during compilation of profiler/src/profiler/TracyMicroArchitecture.cpp + if(NOT WIN32 OR (WIN32 AND NOT ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"))) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) + endif() endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/cmake/server.cmake b/cmake/server.cmake index a76d1c1340..cc3a9a924a 100644 --- a/cmake/server.cmake +++ b/cmake/server.cmake @@ -30,6 +30,9 @@ list(TRANSFORM TRACY_SERVER_SOURCES PREPEND "${TRACY_SERVER_DIR}/") add_library(TracyServer STATIC EXCLUDE_FROM_ALL ${TRACY_COMMON_SOURCES} ${TRACY_SERVER_SOURCES}) target_include_directories(TracyServer PUBLIC ${TRACY_COMMON_DIR} ${TRACY_SERVER_DIR}) target_link_libraries(TracyServer PUBLIC TracyCapstone libzstd PPQSort::PPQSort) +if(WIN32) + target_link_libraries(TracyServer PRIVATE Ws2_32) +endif() if(NO_STATISTICS) target_compile_definitions(TracyServer PUBLIC TRACY_NO_STATISTICS) endif() diff --git a/import/src/import-chrome.cpp b/import/src/import-chrome.cpp index 936d37d936..6f20d8de84 100644 --- a/import/src/import-chrome.cpp +++ b/import/src/import-chrome.cpp @@ -11,9 +11,11 @@ #include #include -#ifdef _MSC_VER +#if defined _MSC_VER || (defined _WIN32 && defined __GNUC__) +// all checked compilers contain _stat64 # define stat64 _stat64 #endif + #if defined __APPLE__ # define stat64 stat #endif diff --git a/import/src/import-fuchsia.cpp b/import/src/import-fuchsia.cpp index 785979c198..7c87211596 100644 --- a/import/src/import-fuchsia.cpp +++ b/import/src/import-fuchsia.cpp @@ -20,8 +20,9 @@ #include #include -#ifdef _MSC_VER -#define stat64 _stat64 +#if defined _MSC_VER || (defined _WIN32 && defined __GNUC__) +// all checked compilers contain _stat64 +# define stat64 _stat64 #endif #if defined __APPLE__ #define stat64 stat diff --git a/profiler/src/profiler/TracyView_FindZone.cpp b/profiler/src/profiler/TracyView_FindZone.cpp index f6cf6ee95a..c57bfe3058 100644 --- a/profiler/src/profiler/TracyView_FindZone.cpp +++ b/profiler/src/profiler/TracyView_FindZone.cpp @@ -307,6 +307,7 @@ void View::DrawFindZone() if( ImGui::Button( ICON_FA_BAN " Clear" ) ) { + m_findZone.pattern[0] = '\0'; m_findZone.Reset(); } ImGui::SameLine(); diff --git a/profiler/src/stb_image.h b/profiler/src/stb_image.h index a632d54351..aadab972b1 100644 --- a/profiler/src/stb_image.h +++ b/profiler/src/stb_image.h @@ -622,7 +622,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #ifndef STBI_NO_THREAD_LOCALS #if defined(__cplusplus) && __cplusplus >= 201103L #define STBI_THREAD_LOCAL thread_local - #elif defined(__GNUC__) && __GNUC__ < 5 + #elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) #define STBI_THREAD_LOCAL __thread #elif defined(_MSC_VER) #define STBI_THREAD_LOCAL __declspec(thread) @@ -631,7 +631,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #endif #ifndef STBI_THREAD_LOCAL - #if defined(__GNUC__) + #if defined(__GNUC__) && !defined(__clang__) #define STBI_THREAD_LOCAL __thread #endif #endif @@ -660,13 +660,13 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #endif #ifdef _MSC_VER -#define STBI_HAS_LROTL -#endif - -#ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) + #define stbi_lrot(x,y) _lrotl(x,y) +#elif defined __clang__ + // 32bit version of function as stb image uses this function to rotate 32bit integers + #define stbi_lrot(x,y) __builtin_rotateleft32(x,y) #else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) + // gcc does not provide builtin rotate left funciton for C++ (__builtin_stdc_rotate_left is available only in C) + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) #endif #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) diff --git a/public/TracyClient.cpp b/public/TracyClient.cpp index 6224f48bfe..e50f1abaa3 100644 --- a/public/TracyClient.cpp +++ b/public/TracyClient.cpp @@ -51,6 +51,7 @@ #endif #ifdef _MSC_VER +// for gcc and clang added with linker options # pragma comment(lib, "ws2_32.lib") # pragma comment(lib, "dbghelp.lib") # pragma comment(lib, "advapi32.lib") diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index 22830765e5..1e6c8c6345 100644 --- a/public/client/TracyProfiler.cpp +++ b/public/client/TracyProfiler.cpp @@ -12,6 +12,7 @@ # include "../common/TracyUwp.hpp" # ifndef _MSC_VER # include +# include # endif #else # include @@ -115,6 +116,12 @@ extern "C" typedef LONG (WINAPI *t_RtlGetVersion)( PRTL_OSVERSIONINFOW ); extern "C" typedef BOOL (WINAPI *t_GetLogicalProcessorInformationEx)( LOGICAL_PROCESSOR_RELATIONSHIP, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD ); extern "C" typedef char* (WINAPI *t_WineGetVersion)(); extern "C" typedef char* (WINAPI *t_WineGetBuildId)(); + +# if defined __GNUC__ + // _WIN32 +# include +#endif + #else # include # include @@ -1481,7 +1488,36 @@ Profiler::Profiler() m_safeSendBuffer = (char*)tracy_malloc( SafeSendBufferSize ); -#ifndef _WIN32 +#if defined _WIN32 && defined __GNUC__ + + m_pipeBufSize = (int)(ptrdiff_t)SafeSendBufferSize; + + { // scope for temporary variable originalHandlesCount + int originalHandlesCount = _getmaxstdio(); + + while(_pipe(m_pipe, m_pipeBufSize, _O_BINARY) != 0) + { + if ((errno == EMFILE) || (errno == ENFILE)) + { + // safe upper bound for exceptional situations + if(_getmaxstdio() > (originalHandlesCount + 10)) + { + throw std::runtime_error("Failed to create communication pipe!"); + } + + // as described by Raymond Chen (https://devblogs.microsoft.com/oldnewthing/20070718-00/?p=25963) + // max number of handles in windows is 10000, + // _getmaxstdio() at the start returns 512, so no fear of too much handles + _setmaxstdio(_getmaxstdio() + 1); + } + else + { + m_pipeBufSize /= 2; + } + } + } + +#elif !defined _WIN32 pipe(m_pipe); # if defined __APPLE__ || defined BSD // FreeBSD/XNU don't have F_SETPIPE_SZ, so use the default @@ -1646,6 +1682,10 @@ Profiler::~Profiler() #ifndef _WIN32 close( m_pipe[0] ); close( m_pipe[1] ); +#elif defined __GNUC__ + // _WIN32 + _close(m_pipe[0]); + _close(m_pipe[1]); #endif tracy_free( m_safeSendBuffer ); @@ -3132,6 +3172,7 @@ char* Profiler::SafeCopyProlog( const char* data, size_t size ) if( size > SafeSendBufferSize ) buf = (char*)tracy_malloc( size ); #ifdef _WIN32 + # ifdef _MSC_VER __try { @@ -3141,9 +3182,37 @@ char* Profiler::SafeCopyProlog( const char* data, size_t size ) { success = false; } -# else - memcpy( buf, data, size ); +# elif defined __GNUC__ + // Send through the pipe to ensure safe reads on compilers with no __try/__except + for( size_t offset = 0; offset != size; /*in loop*/ ) + { + size_t sendsize = size - offset; + int result1, result2; + + // ENOSPC indicates that there is no more space to execute write operation + // other possible values: + // EBADF - invalid file descriptor or not opened for writing + // EINVAL - null buffer or odd number of bytes in unicode mode + while( ( result1 = _write( m_pipe[1], data + offset, sendsize ) ) < 0 && errno != ENOSPC ) { /* retry */ } + if( result1 < 0 ) + { + success = false; + break; + } + + // EBADF - errno set to this value if pipe is not opened for reading or locked + // other possible values: + // EINVAL - result1 > INT_MAX + while( ( result2 = _read( m_pipe[0], buf + offset, result1 ) ) < 0 && errno != EBADF ) { /* retry */ } + if( result2 != result1 ) + { + success = false; + break; + } + offset += result1; + } # endif + #else // Send through the pipe to ensure safe reads for( size_t offset = 0; offset != size; /*in loop*/ ) diff --git a/public/client/TracyProfiler.hpp b/public/client/TracyProfiler.hpp index 8d16905860..7326af0462 100644 --- a/public/client/TracyProfiler.hpp +++ b/public/client/TracyProfiler.hpp @@ -1067,6 +1067,10 @@ class Profiler #if defined _WIN32 void* m_prevHandler; + #if defined __GNUC__ + int m_pipe[2]; + int m_pipeBufSize; + #endif #else int m_pipe[2]; int m_pipeBufSize; diff --git a/public/common/TracySocket.cpp b/public/common/TracySocket.cpp index bdba361965..6938fcff4a 100644 --- a/public/common/TracySocket.cpp +++ b/public/common/TracySocket.cpp @@ -22,6 +22,7 @@ # endif # define poll WSAPoll # ifdef _MSC_VER + // for gcc and clang added with linker options # pragma comment(lib, "ws2_32.lib") # endif #else diff --git a/public/common/tracy_lz4.cpp b/public/common/tracy_lz4.cpp index 15d0990f82..cff579c57b 100644 --- a/public/common/tracy_lz4.cpp +++ b/public/common/tracy_lz4.cpp @@ -345,7 +345,7 @@ namespace tracy * environments. This is needed when decompressing the Linux Kernel, for example. */ #if !defined(LZ4_memcpy) -# if defined(__GNUC__) && (__GNUC__ >= 4) +# if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) # define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) # else # define LZ4_memcpy(dst, src, size) memcpy(dst, src, size) diff --git a/public/common/tracy_lz4.hpp b/public/common/tracy_lz4.hpp index 672c2feb24..ff149ba54d 100644 --- a/public/common/tracy_lz4.hpp +++ b/public/common/tracy_lz4.hpp @@ -81,7 +81,7 @@ * Control library symbols visibility. */ #ifndef LZ4LIB_VISIBILITY -# if defined(__GNUC__) && (__GNUC__ >= 4) +# if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) # define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) # else # define LZ4LIB_VISIBILITY diff --git a/public/common/tracy_lz4hc.cpp b/public/common/tracy_lz4hc.cpp index eec7239e05..bd0199353c 100644 --- a/public/common/tracy_lz4hc.cpp +++ b/public/common/tracy_lz4hc.cpp @@ -162,7 +162,10 @@ int LZ4HC_countBack(const BYTE* const ip, const BYTE* const match, #if defined(_MSC_VER) # define LZ4HC_rotl32(x,r) _rotl(x,r) +#elif defined(__clang__) +# define LZ4HC_rotl32(x,r) __builtin_rotateleft32(x,r) #else +// gcc does not provide builtin rotate left funciton for C++ (__builtin_stdc_rotate_left is available only in C) # define LZ4HC_rotl32(x,r) ((x << r) | (x >> (32 - r))) #endif diff --git a/server/TracyFileRead.hpp b/server/TracyFileRead.hpp index 988c7ae17e..5404ee342d 100644 --- a/server/TracyFileRead.hpp +++ b/server/TracyFileRead.hpp @@ -15,7 +15,8 @@ #include #include -#ifdef _MSC_VER +#if defined _MSC_VER || (defined _WIN32 && defined __GNUC__) +// MSCV, gcc and clang compilers contain _stat64 # define stat64 _stat64 #endif #if defined __APPLE__ || defined __FreeBSD__ diff --git a/server/tracy_robin_hood.h b/server/tracy_robin_hood.h index 65f6fc1146..6dbcb9e82b 100644 --- a/server/tracy_robin_hood.h +++ b/server/tracy_robin_hood.h @@ -818,6 +818,7 @@ struct hash::value>::type> { } #if defined(__GNUC__) && !defined(__clang__) +// clang does not recognize -Wuseless-cast option # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wuseless-cast" #endif diff --git a/server/tracy_xxhash.h b/server/tracy_xxhash.h index a18e8c762d..da07976123 100644 --- a/server/tracy_xxhash.h +++ b/server/tracy_xxhash.h @@ -373,11 +373,19 @@ extern "C" { /*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(WIN32) && (defined(_MSC_VER) || defined(__GNUC__)) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT -# define XXH_PUBLIC_API __declspec(dllexport) +# if defined(__GNUC__) +# define XXH_PUBLIC_API __attribute__((dllexport)) +# else +# define XXH_PUBLIC_API __declspec(dllexport) +# endif # elif XXH_IMPORT -# define XXH_PUBLIC_API __declspec(dllimport) +# if defined(__GNUC__) +# define XXH_PUBLIC_API __attribute__((dllimport)) +# else +# define XXH_PUBLIC_API __declspec(dllimport) +# endif # endif # else # define XXH_PUBLIC_API /* do nothing */ @@ -449,11 +457,19 @@ extern "C" { /* specific declaration modes for Windows */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(WIN32) && (defined(_MSC_VER) || defined(__GNUC__)) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT -# define XXH_PUBLIC_API __declspec(dllexport) +# if defined(__GNUC__) +# __attribute__((dllexport)) +# elif +# define XXH_PUBLIC_API __declspec(dllexport) +# endif # elif XXH_IMPORT -# define XXH_PUBLIC_API __declspec(dllimport) +# if defined(__GNUC__) +# __attribute__((dllimport)) +# elif +# define XXH_PUBLIC_API __declspec(dllimport) +# endif # endif # else # define XXH_PUBLIC_API /* do nothing */ @@ -2413,6 +2429,7 @@ static int XXH_isLittleEndian(void) */ #if XXH_HAS_BUILTIN(__builtin_unreachable) +// gcc and clang support this builtin # define XXH_UNREACHABLE() __builtin_unreachable() #elif defined(_MSC_VER) @@ -2450,6 +2467,7 @@ static int XXH_isLittleEndian(void) # define XXH_rotl32(x,r) _rotl(x,r) # define XXH_rotl64(x,r) _rotl64(x,r) #else +// gcc does not provide builtin rotate left funciton for C++ (__builtin_stdc_rotate_left is available only in C) # define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) # define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r)))) #endif @@ -2464,7 +2482,8 @@ static int XXH_isLittleEndian(void) */ #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap32 _byteswap_ulong -#elif XXH_GCC_VERSION >= 403 +#elif XXH_GCC_VERSION >= 403 || defined __clang__ +// XXH_GCC_VERSION >= 403 should be equivalent to if defined __GNUC__ # define XXH_swap32 __builtin_bswap32 #else static xxh_u32 XXH_swap32 (xxh_u32 x) @@ -3012,7 +3031,8 @@ static xxh_u64 XXH_read64(const void* memPtr) #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap64 _byteswap_uint64 -#elif XXH_GCC_VERSION >= 403 +#elif XXH_GCC_VERSION >= 403 || defined __clang__ +// XXH_GCC_VERSION >= 403 should be equivalent to if defined __GNUC__ # define XXH_swap64 __builtin_bswap64 #else static xxh_u64 XXH_swap64(xxh_u64 x) @@ -3953,7 +3973,7 @@ do { \ # elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ # include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ # define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) -# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# elif ( defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) ) || defined (__clang__) # define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) # else # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ diff --git a/test/stb_image.h b/test/stb_image.h index 5e807a0a6e..d2e3ba74d3 100644 --- a/test/stb_image.h +++ b/test/stb_image.h @@ -621,7 +621,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #ifndef STBI_NO_THREAD_LOCALS #if defined(__cplusplus) && __cplusplus >= 201103L #define STBI_THREAD_LOCAL thread_local - #elif defined(__GNUC__) && __GNUC__ < 5 + #elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) #define STBI_THREAD_LOCAL __thread #elif defined(_MSC_VER) #define STBI_THREAD_LOCAL __declspec(thread) @@ -630,7 +630,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch #endif #ifndef STBI_THREAD_LOCAL - #if defined(__GNUC__) + #if defined(__GNUC__) && !defined(__clang__) #define STBI_THREAD_LOCAL __thread #endif #endif @@ -658,14 +658,15 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #define STBI_NOTUSED(v) (void)sizeof(v) #endif -#ifdef _MSC_VER -#define STBI_HAS_LROTL -#endif -#ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) +#ifdef _MSC_VER + #define stbi_lrot(x,y) _lrotl(x,y) +#elif defined __clang__ + // 32bit version of function as stb image uses this function to rotate 32bit integers + #define stbi_lrot(x,y) __builtin_rotateleft32(x,y) #else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) + // gcc does not provide builtin rotate left funciton for C++ (__builtin_stdc_rotate_left is available only in C) + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) #endif #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))