diff options
Diffstat (limited to 'indra/llcommon')
45 files changed, 411 insertions, 387 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index daa1def726..f8c24368b2 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -68,7 +68,7 @@ set(llcommon_SOURCE_FILES llmetricperformancetester.cpp llmortician.cpp llmutex.cpp - llptrto.cpp + llptrto.cpp llpredicate.cpp llprocess.cpp llprocessor.cpp @@ -108,7 +108,7 @@ set(llcommon_SOURCE_FILES workqueue.cpp StackWalker.cpp ) - + set(llcommon_HEADER_FILES CMakeLists.txt @@ -255,14 +255,28 @@ set(llcommon_HEADER_FILES workqueue.h StackWalker.h ) - + if (DARWIN) list(APPEND llcommon_HEADER_FILES llsys_objc.h) list(APPEND llcommon_SOURCE_FILES llsys_objc.mm) + + set_source_files_properties( + llsys_objc.mm + PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE + ) endif (DARWIN) if (USE_TRACY) list(APPEND llcommon_SOURCE_FILES llprofiler.cpp) + + # Skip precompiled headers on these files due to special compilation needs + set_source_files_properties( + llfasttimer.cpp + llprofiler.cpp + PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE + ) endif () list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) @@ -280,8 +294,12 @@ target_link_libraries( ll::sse2neon ) -target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(llcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(llcommon PRIVATE ${CMAKE_SOURCE_DIR}/llmath) + +if (USE_PRECOMPILED_HEADERS) + target_precompile_headers(llcommon REUSE_FROM llprecompiled) +endif () add_dependencies(llcommon stage_third_party_libs) diff --git a/indra/llcommon/StackWalker.cpp b/indra/llcommon/StackWalker.cpp index e9ae1723fb..77ae4db4bd 100644 --- a/indra/llcommon/StackWalker.cpp +++ b/indra/llcommon/StackWalker.cpp @@ -785,6 +785,8 @@ private: case 8: //SymVirtual: szSymType = "Virtual"; break; + case NumSymTypes: + break; } } LPCSTR pdbName = Module.LoadedImageName; diff --git a/indra/llcommon/classic_callback.h b/indra/llcommon/classic_callback.h index 009c25d67c..8a6ac7f7ff 100644 --- a/indra/llcommon/classic_callback.h +++ b/indra/llcommon/classic_callback.h @@ -184,8 +184,8 @@ protected: template <typename SIGNATURE, typename USERDATA=void*, typename CALLABLE=void(*)()> auto makeClassicCallback(CALLABLE&& callable) { - return std::move(ClassicCallback<SIGNATURE, USERDATA, CALLABLE> - (std::forward<CALLABLE>(callable))); + return ClassicCallback<SIGNATURE, USERDATA, CALLABLE> + (std::forward<CALLABLE>(callable)); } /***************************************************************************** diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c532620daa..73b50d0a50 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -58,14 +58,6 @@ void setup_signals(); void default_unix_signal_handler(int signum, siginfo_t *info, void *); -#if LL_LINUX -#else -// Called by breakpad exception handler after the minidump has been generated. -bool unix_post_minidump_callback(const char *dump_dir, - const char *minidump_id, - void *context, bool succeeded); -#endif - # if LL_DARWIN /* OSX doesn't support SIGRT* */ S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; @@ -720,47 +712,4 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) } } -bool unix_post_minidump_callback(const char *dump_dir, - const char *minidump_id, - void *context, bool succeeded) -{ - // Copy minidump file path into fixed buffer in the app instance to avoid - // heap allocations in a crash handler. - - // path format: <dump_dir>/<minidump_id>.dmp - auto dirPathLength = strlen(dump_dir); - auto idLength = strlen(minidump_id); - - // The path must not be truncated. - llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); - - char * path = LLApp::instance()->getMiniDumpFilename(); - auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; - strncpy(path, dump_dir, remaining); - remaining -= dirPathLength; - path += dirPathLength; - if (remaining > 0 && dirPathLength > 0 && path[-1] != '/') - { - *path++ = '/'; - --remaining; - } - if (remaining > 0) - { - strncpy(path, minidump_id, remaining); - remaining -= idLength; - path += idLength; - strncpy(path, ".dmp", remaining); - } - - LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; - LLApp::runErrorHandler(); - -#ifndef LL_RELEASE_FOR_DOWNLOAD - clear_signals(); - return false; -#else - return true; -#endif -} #endif // !WINDOWS - diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 01763c49aa..ff5f262036 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -230,11 +230,11 @@ bool LLVolatileAPRPool::isFull() bool _ll_apr_warn_status(apr_status_t status, const char* file, int line) { if(APR_SUCCESS == status) return false; -#if !LL_LINUX + char buf[MAX_STRING]; /* Flawfinder: ignore */ apr_strerror(status, buf, sizeof(buf)); LL_WARNS("APR") << "APR: " << file << ":" << line << " " << buf << LL_ENDL; -#endif + return true; } diff --git a/indra/llcommon/llatomic.cpp b/indra/llcommon/llatomic.cpp index d200bb0406..cff5e01225 100644 --- a/indra/llcommon/llatomic.cpp +++ b/indra/llcommon/llatomic.cpp @@ -23,6 +23,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llatomic.h" //============================================================================ diff --git a/indra/llcommon/llcallbacklist.cpp b/indra/llcommon/llcallbacklist.cpp index 3d5d30bd90..8fb7823f04 100644 --- a/indra/llcommon/llcallbacklist.cpp +++ b/indra/llcommon/llcallbacklist.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llcallbacklist.h" #include "lleventtimer.h" #include "llerrorlegacy.h" diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 7a22eaf203..bf8801c46b 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -47,30 +47,13 @@ void* ll_tracy_new(size_t size) return ptr; } -void* ll_tracy_aligned_new(size_t size, size_t alignment) -{ - void* ptr = ll_aligned_malloc_fallback(size, alignment); - if (!ptr) - { - throw std::bad_alloc(); - } - LL_PROFILE_ALLOC(ptr, size); - return ptr; -} - void ll_tracy_delete(void* ptr) { LL_PROFILE_FREE(ptr); (free)(ptr); } -void ll_tracy_aligned_delete(void* ptr) -{ - LL_PROFILE_FREE(ptr); - ll_aligned_free_fallback(ptr); -} - -void* operator new(size_t size) +void* operator new(std::size_t size) { return ll_tracy_new(size); } @@ -80,24 +63,41 @@ void* operator new[](std::size_t count) return ll_tracy_new(count); } -void* operator new(size_t size, std::align_val_t align) +void operator delete(void *ptr) noexcept { - return ll_tracy_aligned_new(size, (size_t)align); + ll_tracy_delete(ptr); } -void* operator new[](std::size_t count, std::align_val_t align) +void operator delete[](void* ptr) noexcept { - return ll_tracy_aligned_new(count, (size_t)align); + ll_tracy_delete(ptr); } -void operator delete(void *ptr) noexcept +#if !defined(LL_LINUX) + +void* ll_tracy_aligned_new(size_t size, size_t alignment) { - ll_tracy_delete(ptr); + void* ptr = ll_aligned_malloc_fallback(size, alignment); + if (!ptr) + { + throw std::bad_alloc(); + } + return ptr; } -void operator delete[](void* ptr) noexcept +void ll_tracy_aligned_delete(void* ptr) { - ll_tracy_delete(ptr); + ll_aligned_free_fallback(ptr); +} + +void* operator new(size_t size, std::align_val_t align) +{ + return ll_tracy_aligned_new(size, (size_t)align); +} + +void* operator new[](std::size_t count, std::align_val_t align) +{ + return ll_tracy_aligned_new(count, (size_t)align); } void operator delete(void *ptr, std::align_val_t align) noexcept @@ -110,6 +110,8 @@ void operator delete[](void* ptr, std::align_val_t align) noexcept ll_tracy_aligned_delete(ptr); } +#endif + #endif // TRACY_ENABLE && !LL_PROFILER_ENABLE_TRACY_OPENGL //static diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 5205699b92..b4cdf3cbda 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -131,11 +131,7 @@ void LLDate::toStream(std::ostream& s) const } s << std::dec << std::setfill('0'); -#if( LL_WINDOWS || __GNUC__ > 2) s << std::right; -#else - s.setf(ios::right); -#endif s << std::setw(4) << (exp_time.tm_year + 1900) << '-' << std::setw(2) << (exp_time.tm_mon + 1) << '-' << std::setw(2) << (exp_time.tm_mday) diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp index f9c14d7c24..45c01eb84a 100644 --- a/indra/llcommon/lldeadmantimer.cpp +++ b/indra/llcommon/lldeadmantimer.cpp @@ -25,6 +25,7 @@ * $/LicenseInfo$ */ +#include "linden_common.h" #include "lldeadmantimer.h" diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index 232987da14..0481e45351 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -28,6 +28,7 @@ #define LL_LLDEFS_H #include "stdtypes.h" +#include <cassert> #include <type_traits> // Often used array indices @@ -169,6 +170,38 @@ constexpr U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + // llclampb(a) // clamps a to [0 .. 255] // +// llless(d0, d1) safely compares d0 < d1 even if one is signed and the other +// is unsigned. A simple (d0 < d1) expression converts the signed operand to +// unsigned before comparing. If the signed operand is negative, that flips +// the negative value to a huge positive value, producing the wrong answer! +// llless() specifically addresses that case. +template <typename T0, typename T1> +constexpr bool llless(T0 d0, T1 d1) +{ + if constexpr (std::is_signed_v<T0> && ! std::is_signed_v<T1>) + { + // T0 signed, T1 unsigned: negative d0 is less than any unsigned d1 + if (d0 < 0) + return true; + // both are non-negative: explicitly cast to avoid C4018 + return std::make_unsigned_t<T0>(d0) < d1; + } + else if constexpr (! std::is_signed_v<T0> && std::is_signed_v<T1>) + { + // T0 unsigned, T1 signed: any unsigned d0 is greater than negative d1 + if (d1 < 0) + return false; + // both are non-negative: explicitly cast to avoid C4018 + return d0 < std::make_unsigned_t<T1>(d1); + } + else + { + // both T0 and T1 are signed, or both are unsigned: + // straightforward comparison works + return d0 < d1; + } +} + // recursion tail template <typename T> constexpr auto llmax(T data) @@ -180,7 +213,7 @@ template <typename T0, typename T1, typename... Ts> constexpr auto llmax(T0 d0, T1 d1, Ts... rest) { auto maxrest = llmax(d1, rest...); - return (d0 > maxrest)? d0 : maxrest; + return llless(maxrest, d0)? d0 : maxrest; } // recursion tail @@ -194,12 +227,28 @@ template <typename T0, typename T1, typename... Ts> constexpr auto llmin(T0 d0, T1 d1, Ts... rest) { auto minrest = llmin(d1, rest...); - return (d0 < minrest) ? d0 : minrest; + return llless(d0, minrest) ? d0 : minrest; } template <typename A, typename MIN, typename MAX> constexpr A llclamp(A a, MIN minval, MAX maxval) { + // The only troublesome case is if A is unsigned and either minval or + // maxval is both signed and negative. Casting a negative number to + // unsigned flips it to a huge positive number, making this llclamp() call + // ineffective. + if constexpr (! std::is_signed_v<A>) + { + if constexpr (std::is_signed_v<MIN>) + { + assert(minval >= 0); + } + if constexpr (std::is_signed_v<MAX>) + { + assert(maxval >= 0); + } + } + A aminval{ static_cast<A>(minval) }, amaxval{ static_cast<A>(maxval) }; if ( a < aminval ) { @@ -225,7 +274,7 @@ constexpr LLDATATYPE llclampb(LLDATATYPE a) } template <class LLDATATYPE> -inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) +constexpr void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) { std::swap(lhs, rhs); } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 3411e9c6bb..fc08ec8c8f 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -133,6 +133,7 @@ namespace { RecordToFile(const std::string& filename): mName(filename) { + showMultiline(true); mFile.open(filename.c_str(), std::ios_base::out | std::ios_base::app); if (!mFile) { @@ -344,6 +345,51 @@ namespace { } }; #endif + +#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY + class RecordToTracy : public LLError::Recorder + { + public: + RecordToTracy() + { + this->showMultiline(true); + this->showTags(false); + this->showLocation(false); + } + + virtual bool enabled() override { return LLError::getEnabledLogTypesMask() & 0x12; } + + virtual void recordMessage(LLError::ELevel level, const std::string& message) override + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; + switch (level) + { + case LLError::LEVEL_DEBUG: + { + TracyMessageC(message.c_str(), message.size(), tracy::Color::Turquoise); + break; + } + default: + case LLError::LEVEL_NONE: + case LLError::LEVEL_INFO: + { + TracyMessageC(message.c_str(), message.size(), tracy::Color::White); + break; + } + case LLError::LEVEL_WARN: + { + TracyMessageC(message.c_str(), message.size(), tracy::Color::Yellow); + break; + } + case LLError::LEVEL_ERROR: + { + TracyMessageC(message.c_str(), message.size(), tracy::Color::Red); + break; + } + } + } + }; +#endif } @@ -759,6 +805,11 @@ namespace LLError::addRecorder(recordToWinDebug); #endif +#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY + LLError::RecorderPtr recordToTracy(new RecordToTracy()); + LLError::addRecorder(recordToTracy); +#endif + LogControlFile& e = LogControlFile::fromDirectory(user_dir, app_dir); // NOTE: We want to explicitly load the file before we add it to the event timer diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 41893a35e5..343cc47e4c 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -91,13 +91,8 @@ const int LL_ERR_NOERR = 0; #define llverify(func) do {if (func) {}} while(0) #endif -#ifdef LL_WINDOWS #define LL_STATIC_ASSERT(func, msg) static_assert(func, msg) -#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(false, msg) -#else -#define LL_STATIC_ASSERT(func, msg) BOOST_STATIC_ASSERT(func) -#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && false); -#endif +#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(sizeof(type) != 0 && false, msg) /** Error Logging Facility diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 1c5fe9d2f5..c5a7a0e56b 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -387,6 +387,11 @@ void BlockTimer::logStats() } +#if defined(LL_GNUC) && GCC_VERSION >= 130000 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnonnull" +#endif + //static void BlockTimer::dumpCurTimes() { @@ -418,8 +423,12 @@ void BlockTimer::dumpCurTimes() << num_calls << " calls"; LL_INFOS() << out_str.str() << LL_ENDL; + } } -} + +#if defined(LL_GNUC) && GCC_VERSION >= 130000 +# pragma GCC diagnostic push +#endif //static void BlockTimer::writeLog(std::ostream& os) diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp index b4bcc80ac4..d606a6fdb9 100644 --- a/indra/llcommon/llfindlocale.cpp +++ b/indra/llcommon/llfindlocale.cpp @@ -134,7 +134,7 @@ accumulate_locstring(const char *str, FL_Locale *l) { return 0; } - +#ifndef LL_WINDOWS static int accumulate_env(const char *name, FL_Locale *l) { char *env; @@ -148,7 +148,7 @@ accumulate_env(const char *name, FL_Locale *l) { free(lang); free(country); free(variant); return 0; } - +#endif static void canonise_fl(FL_Locale *l) { diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 92b26354a1..5a7f27e688 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -28,6 +28,8 @@ #ifndef LL_LLINSTANCETRACKER_H #define LL_LLINSTANCETRACKER_H +#include "llpreprocessor.h" + #include <map> #include <set> #include <vector> @@ -244,6 +246,7 @@ public: } protected: + LL_UBSAN_SUPRESS_VPTR LLInstanceTracker(const KEY& key) { // We do not intend to manage the lifespan of this object with @@ -482,6 +485,7 @@ public: using key_snapshot_of = instance_snapshot_of<SUBCLASS>; protected: + LL_UBSAN_SUPRESS_VPTR LLInstanceTracker() { // Since we do not intend for this shared_ptr to manage lifespan, give diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index e36c1d0a4c..abb0df0b87 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -114,15 +114,6 @@ void LLKeyData::reset() mIgnoreMasks = false; } -LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) -{ - mMouse = rhs.mMouse; - mKey = rhs.mKey; - mMask = rhs.mMask; - mIgnoreMasks = rhs.mIgnoreMasks; - return *this; -} - bool LLKeyData::operator==(const LLKeyData& rhs) { if (mMouse != rhs.mMouse) return false; diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 1bbb2fadb5..0a9d4600cc 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -43,7 +43,6 @@ public: bool isEmpty() const; bool empty() const { return isEmpty(); }; void reset(); - LLKeyData& operator=(const LLKeyData& rhs); bool operator==(const LLKeyData& rhs); bool operator!=(const LLKeyData& rhs); diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index c8ca586e7f..b05fd2e21b 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -255,13 +255,15 @@ void LLMD5::raw_digest(unsigned char* s) const memcpy(s, digest, 16); /* Flawfinder: ignore */ } -#if LL_DARWIN +#if LL_CLANG #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif void LLMD5::hex_digest(char* s) const { + if(!s) return; + if (!finalized) { std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't " @@ -278,7 +280,7 @@ void LLMD5::hex_digest(char* s) const s[32] = '\0'; } -#if LL_DARWIN +#if LL_CLANG #pragma clang diagnostic pop #endif diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index ba48319a16..9617e30f0b 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -146,9 +146,6 @@ void LLMemory::updateMemoryInfo() LL_WARNS() << "task_info failed" << LL_ENDL; } #elif defined(LL_LINUX) - // Use sysinfo() to get the total physical memory. - struct sysinfo info; - sysinfo(&info); sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(LLMemory::getCurrentRSS())); // represents the RAM allocated by this process only (in line with the windows implementation) #else //not valid for other systems for now. diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index adc556d180..a25387d321 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -48,6 +48,9 @@ class LLMutex ; #define LL_ALIGN_OF __align_of__ #endif +#if defined(LL_X86_64) || defined(LL_ARM64) +#define LL_DEFAULT_HEAP_ALIGN 16 +#else #if LL_WINDOWS #define LL_DEFAULT_HEAP_ALIGN 8 #elif LL_DARWIN @@ -55,7 +58,7 @@ class LLMutex ; #elif LL_LINUX #define LL_DEFAULT_HEAP_ALIGN 8 #endif - +#endif LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); @@ -89,22 +92,6 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) (uintptr_t(address) + 0x3F) & ~0x3F); } -#if LL_LINUX || LL_DARWIN - -#define LL_ALIGN_PREFIX(x) -#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x))) - -#elif LL_WINDOWS - -#define LL_ALIGN_PREFIX(x) __declspec(align(x)) -#define LL_ALIGN_POSTFIX(x) - -#else -#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined" -#endif - -#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) - #define LL_ALIGN_NEW \ public: \ void* operator new(size_t size) \ @@ -127,7 +114,6 @@ public: \ ll_aligned_free_16(ptr); \ } - //------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------ // for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library @@ -143,6 +129,10 @@ public: \ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if defined(LL_WINDOWS) void* ret = _aligned_malloc(size, align); + #elif defined(LL_LINUX) + void *ret; + if (0 != posix_memalign(&ret, align, size)) + return nullptr; #else char* aligned = NULL; void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -165,6 +155,8 @@ public: \ LL_PROFILE_FREE(ptr); #if defined(LL_WINDOWS) _aligned_free(ptr); + #elif defined(LL_LINUX) + free(ptr); #else if (ptr) { @@ -179,10 +171,10 @@ public: \ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; -#if defined(LL_WINDOWS) +#if LL_DEFAULT_HEAP_ALIGN == 16 + void* ret = malloc(size); // default osx and 64-bit malloc is 16 byte aligned. +#elif defined(LL_WINDOWS) void* ret = _aligned_malloc(size, 16); -#elif defined(LL_DARWIN) - void* ret = malloc(size); // default osx malloc is 16 byte aligned. #else void *ret; if (0 != posix_memalign(&ret, 16, size)) @@ -196,10 +188,10 @@ inline void ll_aligned_free_16(void *p) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; LL_PROFILE_FREE(p); -#if defined(LL_WINDOWS) +#if LL_DEFAULT_HEAP_ALIGN == 16 + free(p); +#elif defined(LL_WINDOWS) _aligned_free(p); -#elif defined(LL_DARWIN) - return free(p); #else free(p); // posix_memalign() is compatible with heap deallocator #endif @@ -209,10 +201,10 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; LL_PROFILE_FREE(ptr); -#if defined(LL_WINDOWS) +#if LL_DEFAULT_HEAP_ALIGN == 16 + void* ret = realloc(ptr,size); // default osx and 64bit malloc is 16 byte aligned. +#elif defined(LL_WINDOWS) void* ret = _aligned_realloc(ptr, size, 16); -#elif defined(LL_DARWIN) - void* ret = realloc(ptr,size); // default osx malloc is 16 byte aligned. #else //FIXME: memcpy is SLOW void* ret = ll_aligned_malloc_16(size); diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index b2a9734548..104d3cc186 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -61,35 +61,48 @@ # define LL_UNLIKELY(EXPR) (EXPR) #endif - // Figure out differences between compilers -#if defined(__GNUC__) +#if defined(__MSVC_VER__) || defined(_MSC_VER) + #ifndef LL_MSVC + #define LL_MSVC 1 + #endif + + // Clang CL is MSVC-like but also supports its own macros + #if defined(__clang__) + #ifndef LL_CLANG + #define LL_CLANG 1 + #endif + #endif +#elif defined(__clang__) + #define CLANG_VERSION (__clang_major__ * 10000 \ + + __clang_minor__ * 100 \ + + __clang_patchlevel__) + #ifndef LL_CLANG + #define LL_CLANG 1 + #endif +#elif defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #ifndef LL_GNUC #define LL_GNUC 1 #endif -#elif defined(__MSVC_VER__) || defined(_MSC_VER) - #ifndef LL_MSVC - #define LL_MSVC 1 - #endif #endif // Set up CPU architecture defines #if LL_MSVC && defined(_M_ARM64) # define LL_ARM64 1 -#elif LL_GNUC && (defined(__arm64__) || defined(__aarch64__)) +#elif (LL_GNUC || LL_CLANG) && (defined(__arm64__) || defined(__aarch64__)) # define LL_ARM64 1 #elif LL_MSVC && _M_X64 # define LL_X86_64 1 # define LL_X86 1 #elif LL_MSVC && _M_IX86 # define LL_X86 1 -#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) +#elif (LL_GNUC || LL_CLANG) && ( defined(__amd64__) || defined(__x86_64__) ) # define LL_X86_64 1 # define LL_X86 1 -#elif LL_GNUC && ( defined(__i386__) ) +#elif (LL_GNUC || LL_CLANG) && ( defined(__i386__) ) # define LL_X86 1 #endif @@ -106,16 +119,6 @@ #endif -// Although thread_local is now a standard storage class, we can't just -// #define LL_THREAD_LOCAL as thread_local because the *usage* is different. -// We'll have to take the time to change LL_THREAD_LOCAL declarations by hand. -#if LL_WINDOWS -# define LL_THREAD_LOCAL __declspec(thread) -#else -# define LL_THREAD_LOCAL __thread -#endif - - #if defined(LL_WINDOWS) #define BOOST_REGEX_NO_LIB 1 #define CURL_STATICLIB 1 @@ -140,7 +143,7 @@ #define LL_DLLIMPORT #endif // LL_WINDOWS -#if __clang__ || ! defined(LL_WINDOWS) +#if LL_CLANG || ! defined(LL_WINDOWS) // Only on Windows, and only with the Microsoft compiler (vs. clang) is // wchar_t potentially not a distinct type. #define LL_WCHAR_T_NATIVE 1 @@ -201,6 +204,13 @@ #define LL_PRETTY_FUNCTION __PRETTY_FUNCTION__ #endif +// vptr warning supression funtionality for undefined behavior sanitizer +#if LL_CLANG || LL_GNUC +# define LL_UBSAN_SUPRESS_VPTR __attribute__((no_sanitize("vptr"))) +#else +# define LL_UBSAN_SUPRESS_VPTR +#endif + #if LL_ARM64 #define GLM_FORCE_NEON 1 #else diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 912e596c3f..2164fc1ad5 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -176,14 +176,14 @@ public: // In general, our streambuf might contain a number of different // physical buffers; iterate over those. bool keepwriting = true; - for (const_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end()); + for (auto bufi(boost::asio::buffer_sequence_begin(bufs)), bufend(boost::asio::buffer_sequence_end(bufs)); bufi != bufend && keepwriting; ++bufi) { // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents // Although apr_file_write() accepts const void*, we // manipulate const char* so we can increment the pointer. - const char* remainptr = boost::asio::buffer_cast<const char*>(*bufi); - std::size_t remainlen = boost::asio::buffer_size(*bufi); + const char* remainptr = static_cast<const char*>(bufi->data()); + std::size_t remainlen = bufi->size(); while (remainlen) { // Tackle the current buffer in discrete chunks. On @@ -377,14 +377,14 @@ public: // In general, the mutable_buffer_sequence returned by prepare() might // contain a number of different physical buffers; iterate over those. std::size_t tocommit(0); - for (mutable_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end()); + for (auto bufi(boost::asio::buffer_sequence_begin(bufs)), bufend(boost::asio::buffer_sequence_end(bufs)); bufi != bufend; ++bufi) { // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents - std::size_t toread(boost::asio::buffer_size(*bufi)); + std::size_t toread(bufi->size()); apr_size_t gotten(toread); apr_status_t err = apr_file_read(mPipe, - boost::asio::buffer_cast<void*>(*bufi), + bufi->data(), &gotten); // EAGAIN is exactly what we want from a nonblocking pipe. // Rather than waiting for data, it should return immediately. diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 718f471321..464578c2d9 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -741,7 +741,7 @@ private: // *NOTE:Mani - I didn't find any docs that assure me that machdep.cpu.feature_bits will always be // The feature bits I think it is. Here's a test: -#ifndef LL_RELEASE_FOR_DOWNLOAD +#if !defined(LL_RELEASE_FOR_DOWNLOAD) && !defined(LL_ARM64) #if defined(__i386__) && defined(__PIC__) /* %ebx may be the PIC register. */ #define __cpuid(level, a, b, c, d) \ @@ -808,6 +808,20 @@ private: }; #elif LL_LINUX + +// *NOTE:Mani - eww, macros! srry. +#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \ + if (!cpuinfo[cpuinfo_id].empty()) \ + { setInfo(llpi_id, cpuinfo[cpuinfo_id]);} + +#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \ + {\ + S32 result; \ + if (!cpuinfo[cpuinfo_id].empty() \ + && LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result)) \ + { setInfo(llpi_id, result);} \ + } + const char CPUINFO_FILE[] = "/proc/cpuinfo"; class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl @@ -819,8 +833,32 @@ public: } virtual ~LLProcessorInfoLinuxImpl() {} + private: + F64 getCPUMaxMHZ() + { + // Nicky: We just look into cpu0. In theory we could iterate over all cores + // "/sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq" + // But those should not fluctuate that much? + llifstream fIn{ "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" }; + + if( !fIn.is_open() ) + return 0.0; + + std::string strLine; + fIn >> strLine; + if( strLine.empty() ) + return 0.0l; + + F64 mhz {}; + if( !LLStringUtil::convertToF64(strLine, mhz ) ) + return 0.0; + + mhz = mhz / 1000.0; + return mhz; + } + void get_proc_cpuinfo() { std::map< std::string, std::string > cpuinfo; @@ -855,24 +893,17 @@ private: } # if LL_X86 -// *NOTE:Mani - eww, macros! srry. -#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \ - if (!cpuinfo[cpuinfo_id].empty()) \ - { setInfo(llpi_id, cpuinfo[cpuinfo_id]);} - -#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \ - {\ - S32 result; \ - if (!cpuinfo[cpuinfo_id].empty() \ - && LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result)) \ - { setInfo(llpi_id, result);} \ + F64 mhzFromSys = getCPUMaxMHZ(); + F64 mhzFromProc {}; + if( !LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhzFromProc ) ) + mhzFromProc = 0.0; + if (mhzFromSys > 1.0 && mhzFromSys > mhzFromProc ) + { + setInfo( eFrequency, mhzFromSys ); } - - F64 mhz; - if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) - && 200.0 < mhz && mhz < 10000.0) + else if ( 200.0 < mhzFromProc && mhzFromProc < 10000.0) { - setInfo(eFrequency,(F64)(mhz)); + setInfo(eFrequency,(F64)(mhzFromProc)); } LLPI_SET_INFO_STRING(eBrandName, "model name"); @@ -882,7 +913,7 @@ private: LLPI_SET_INFO_INT(eModel, "model"); - S32 family; + S32 family{}; if (!cpuinfo["cpu family"].empty() && LLStringUtil::convertToS32(cpuinfo["cpu family"], family)) { diff --git a/indra/llcommon/llprocinfo.cpp b/indra/llcommon/llprocinfo.cpp index 69be00e14a..9fe4af2103 100644 --- a/indra/llcommon/llprocinfo.cpp +++ b/indra/llcommon/llprocinfo.cpp @@ -25,6 +25,7 @@ * $/LicenseInfo$ */ +#include "linden_common.h" #include "llprocinfo.h" diff --git a/indra/llcommon/llprofiler.cpp b/indra/llcommon/llprofiler.cpp index bdddabf977..b2ac7723d4 100644 --- a/indra/llcommon/llprofiler.cpp +++ b/indra/llcommon/llprofiler.cpp @@ -25,6 +25,6 @@ * $/LicenseInfo$ */ -#include "linden_common.h" +#include "llpreprocessor.h" #include "TracyClient.cpp" diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 5fb32d6280..7c77d94475 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -76,7 +76,16 @@ #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER + #include "llpreprocessor.h" + +#if defined(LL_GNUC) && GCC_VERSION >= 130000 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnonnull" +#endif #include "tracy/Tracy.hpp" +#if defined(LL_GNUC) && GCC_VERSION >= 130000 +# pragma GCC diagnostic push +#endif // Enable RenderDoc labeling //#define LL_PROFILER_ENABLE_RENDER_DOC 0 diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp index 2c51e6f07f..513613f543 100644 --- a/indra/llcommon/llrand.cpp +++ b/indra/llcommon/llrand.cpp @@ -58,9 +58,26 @@ * to restore uniform distribution. */ -// gRandomGenerator is a stateful static object, which is therefore not +// pRandomGenerator is a stateful static object, which is therefore not // inherently thread-safe. -static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed()); +//We use a pointer to not construct a huge object in the TLS space, sadly this is necessary +// due to libcef.so on Linux being compiled with TLS model initial-exec (resulting in +// FLAG STATIC_TLS, see readelf libcef.so). CEFs own TLS objects + LLRandLagFib2281 then will exhaust the +// available TLS space, causing media failure. + +static thread_local std::unique_ptr< LLRandLagFib2281 > pRandomGenerator = nullptr; + +namespace { + F64 ll_internal_get_rand() + { + if( !pRandomGenerator ) + { + pRandomGenerator.reset(new LLRandLagFib2281(LLUUID::getRandomSeed( ) )); + } + + return(*pRandomGenerator)(); + } +} // no default implementation, only specific F64 and F32 specializations template <typename REAL> @@ -73,7 +90,7 @@ inline F64 ll_internal_random<F64>() // CPUs (or at least multi-threaded processes) seem to // occasionally give an obviously incorrect random number -- like // 5^15 or something. Sooooo, clamp it as described above. - F64 rv{ gRandomGenerator() }; + F64 rv{ ll_internal_get_rand() }; if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0); return rv; } @@ -85,7 +102,7 @@ inline F32 ll_internal_random<F32>() // Per Monty, it's important to clamp using the correct fmodf() rather // than expanding to F64 for fmod() and then truncating back to F32. Prior // to this change, we were getting sporadic ll_frand() == 1.0 results. - F32 rv{ narrow<F64>(gRandomGenerator()) }; + F32 rv{ narrow<F64>(ll_internal_get_rand()) }; if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f); return rv; } diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 77fe545c3f..ea6d6a308a 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -32,7 +32,6 @@ #include "llbase64.h" #include "llerror.h" -#include "../llmath/llmath.h" #include "llformat.h" #include "llsdserialize.h" #include "stringize.h" @@ -291,10 +290,10 @@ namespace }; LLSD::Boolean ImplReal::asBoolean() const - { return !llisnan(mValue) && mValue != 0.0; } + { return !std::isnan(mValue) && mValue != 0.0; } LLSD::Integer ImplReal::asInteger() const - { return !llisnan(mValue) ? (LLSD::Integer)mValue : 0; } + { return !std::isnan(mValue) ? (LLSD::Integer)mValue : 0; } LLSD::String ImplReal::asString() const { return llformat("%lg", mValue); } diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp index 655869a704..542a3c26e3 100644 --- a/indra/llcommon/llsdjson.cpp +++ b/indra/llcommon/llsdjson.cpp @@ -33,7 +33,6 @@ #include "llsdutil.h" #include "llerror.h" -#include "../llmath/llmath.h" #include <boost/json/src.hpp> diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 37af366a20..3cc960698e 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -1424,11 +1424,7 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, case LLSD::TypeBoolean: if(mBoolAlpha || -#if( LL_WINDOWS || __GNUC__ > 2) (ostr.flags() & std::ios::boolalpha) -#else - (ostr.flags() & 0x0100) -#endif ) { ostr << (data.asBoolean() @@ -2397,6 +2393,7 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size { case Z_NEED_DICT: ret = Z_DATA_ERROR; + [[fallthrough]]; case Z_DATA_ERROR: case Z_MEM_ERROR: inflateEnd(&strm); diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index dbd89118c9..fd01484128 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -503,7 +503,7 @@ bool filter_llsd_with_template( * Helpers for llsd_matches() *****************************************************************************/ // raw data used for LLSD::Type lookup -struct Data +struct LLSDData { LLSD::Type type; const char* name; @@ -534,7 +534,7 @@ public: { LL_PROFILE_ZONE_SCOPED; - for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di) + for (const LLSDData*di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di) { mMap[di->type] = di->name; } diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 0088eeec67..779d822970 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -523,18 +523,8 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) inline bool before(const std::type_info* lhs, const std::type_info* rhs) { -#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) - // If we're building on Linux with gcc, and it's either gcc 3.x or - // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on - // Mac too, and some people build with gcc on Windows (cygwin or mingw). - // On Linux, different load modules may produce different type_info* - // pointers for the same type. Have to compare name strings to get good - // results. - return strcmp(lhs->name(), rhs->name()) < 0; -#else // not Linux, or gcc 4.4+ // Just use before(), as we normally would return lhs->before(*rhs); -#endif } /** diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 270ca40086..e3335ca4aa 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -509,57 +509,46 @@ const S32 LLOSInfo::getOSBitness() const return mOSBitness; } -//static -U32 LLOSInfo::getProcessVirtualSizeKB() -{ - U32 virtual_size = 0; -#if LL_LINUX -# define STATUS_SIZE 2048 - LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); - if (status_filep) - { - S32 numRead = 0; - char buff[STATUS_SIZE]; /* Flawfinder: ignore */ +namespace { - size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); - buff[nbytes] = '\0'; + U32 readFromProcStat( std::string entryName ) + { + U32 val{}; +#if LL_LINUX + constexpr U32 STATUS_SIZE = 2048; - // All these guys return numbers in KB - char *memp = strstr(buff, "VmSize:"); - if (memp) + LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); + if (status_filep) { - numRead += sscanf(memp, "%*s %u", &virtual_size); + char buff[STATUS_SIZE]; /* Flawfinder: ignore */ + + size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); + buff[nbytes] = '\0'; + + // All these guys return numbers in KB + char *memp = strstr(buff, entryName.c_str()); + if (memp) + { + (void) sscanf(memp, "%*s %u", &val); + } + fclose(status_filep); } - fclose(status_filep); - } #endif - return virtual_size; + return val; + } + } //static -U32 LLOSInfo::getProcessResidentSizeKB() +U32 LLOSInfo::getProcessVirtualSizeKB() { - U32 resident_size = 0; -#if LL_LINUX - LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); - if (status_filep != NULL) - { - S32 numRead = 0; - char buff[STATUS_SIZE]; /* Flawfinder: ignore */ - - size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); - buff[nbytes] = '\0'; + return readFromProcStat( "VmSize:" ); +} - // All these guys return numbers in KB - char *memp = strstr(buff, "VmRSS:"); - if (memp) - { - numRead += sscanf(memp, "%*s %u", &resident_size); - } - fclose(status_filep); - } -#endif - return resident_size; +//static +U32 LLOSInfo::getProcessResidentSizeKB() +{ + return readFromProcStat( "VmRSS:" ); } //static @@ -724,7 +713,7 @@ public: void add(const LLSD::String& name, const T& value, typename boost::enable_if<boost::is_integral<T> >::type* = 0) { - mStats[name] = LLSD::Integer(value); + mStats[name] = LLSD::Integer(llmin<T>(value, S32_MAX)); } // Store every floating-point type as LLSD::Real. @@ -833,57 +822,8 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb) } #elif LL_LINUX - // mStatsMap is derived from MEMINFO_FILE: - // $ cat /proc/meminfo - // MemTotal: 4108424 kB - // MemFree: 1244064 kB - // Buffers: 85164 kB - // Cached: 1990264 kB - // SwapCached: 0 kB - // Active: 1176648 kB - // Inactive: 1427532 kB - // Active(anon): 529152 kB - // Inactive(anon): 15924 kB - // Active(file): 647496 kB - // Inactive(file): 1411608 kB - // Unevictable: 16 kB - // Mlocked: 16 kB - // HighTotal: 3266316 kB - // HighFree: 721308 kB - // LowTotal: 842108 kB - // LowFree: 522756 kB - // SwapTotal: 6384632 kB - // SwapFree: 6384632 kB - // Dirty: 28 kB - // Writeback: 0 kB - // AnonPages: 528820 kB - // Mapped: 89472 kB - // Shmem: 16324 kB - // Slab: 159624 kB - // SReclaimable: 145168 kB - // SUnreclaim: 14456 kB - // KernelStack: 2560 kB - // PageTables: 5560 kB - // NFS_Unstable: 0 kB - // Bounce: 0 kB - // WritebackTmp: 0 kB - // CommitLimit: 8438844 kB - // Committed_AS: 1271596 kB - // VmallocTotal: 122880 kB - // VmallocUsed: 65252 kB - // VmallocChunk: 52356 kB - // HardwareCorrupted: 0 kB - // HugePages_Total: 0 - // HugePages_Free: 0 - // HugePages_Rsvd: 0 - // HugePages_Surp: 0 - // Hugepagesize: 2048 kB - // DirectMap4k: 434168 kB - // DirectMap2M: 477184 kB - // (could also run 'free', but easier to read a file than run a program) - LLSD statsMap(loadStatsMap()); - - avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger(); + U64 phys = U64(getpagesize()) * U64(get_avphys_pages()); + avail_mem_kb = U64Bytes(phys); #else //do not know how to collect available memory info for other systems. //leave it blank here for now. @@ -1083,7 +1023,7 @@ LLSD LLMemoryInfo::loadStatsMap() } #elif LL_LINUX - std::ifstream meminfo(MEMINFO_FILE); + llifstream meminfo(MEMINFO_FILE); if (meminfo.is_open()) { // MemTotal: 4108424 kB @@ -1123,9 +1063,10 @@ LLSD LLMemoryInfo::loadStatsMap() LLSD::String key(matched[1].first, matched[1].second); LLSD::String value_str(matched[2].first, matched[2].second); LLSD::Integer value(0); + S64 intval = 0; try { - value = boost::lexical_cast<LLSD::Integer>(value_str); + intval = llclamp(boost::lexical_cast<S64>(value_str), S32_MIN, S32_MAX); } catch (const boost::bad_lexical_cast&) { @@ -1134,6 +1075,7 @@ LLSD LLMemoryInfo::loadStatsMap() << line << LL_ENDL; continue; } + value = LLSD::Integer(intval); // Store this statistic. stats.add(key, value); } diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 692941a892..e1f0d531cf 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -42,6 +42,10 @@ #include <sched.h> #endif +#if LL_DARWIN || LL_LINUX +#include <pthread.h> +#endif + #ifdef LL_WINDOWS @@ -56,25 +60,32 @@ typedef struct tagTHREADNAME_INFO DWORD dwFlags; // Reserved for future use, must be zero. } THREADNAME_INFO; #pragma pack(pop) +#endif -void set_thread_name( DWORD dwThreadID, const char* threadName) +void set_thread_name(const char* threadName) { +#if LL_WINDOWS THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; __try { - ::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info ); + ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR*)&info); } - __except(EXCEPTION_CONTINUE_EXECUTION) + __except (EXCEPTION_CONTINUE_EXECUTION) { } -} +#elif LL_DARWIN + std::string truncated_name(std::string_view(threadName).substr(0, 15)); + pthread_setname_np(truncated_name.c_str()); +#elif LL_LINUX + std::string truncated_name(std::string_view(threadName).substr(0, 15)); + pthread_setname_np(pthread_self(), truncated_name.c_str()); #endif - +} //---------------------------------------------------------------------------- // Usage: @@ -148,27 +159,12 @@ LL_COMMON_API bool assert_main_thread() return false; } -// this function has become moot -void LLThread::registerThreadID() {} - // // Handed to the APR thread creation function // void LLThread::threadRun() { -#ifdef LL_WINDOWS - set_thread_name(-1, mName.c_str()); - -#if 0 // probably a bad idea, see usage of SetThreadIdealProcessor in LLWindowWin32) - HANDLE hThread = GetCurrentThread(); - if (hThread) - { - SetThreadAffinityMask(hThread, (DWORD_PTR) 0xFFFFFFFFFFFFFFFE); - } -#endif - -#endif - + set_thread_name(mName.c_str()); LL_PROFILER_SET_THREAD_NAME( mName.c_str() ); // this is the first point at which we're actually running in the new thread diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 8794ac93aa..b97d479abc 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -28,10 +28,11 @@ #define LL_LLTHREAD_H #include "llapr.h" -#include "boost/intrusive_ptr.hpp" #include "llrefcount.h" #include <thread> +extern void set_thread_name(const char* threadName); + namespace LLTrace { class ThreadRecorder; @@ -86,11 +87,6 @@ public: id_t getID() const { return mID; } - // Called by threads *not* created via LLThread to register some - // internal state used by LLMutex. You must call this once early - // in the running thread to prevent collisions with the main thread. - static void registerThreadID(); - private: bool mPaused; std::thread::native_handle_type mNativeHandle; // for termination in case of issues diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index c23adca7e8..f010f0e961 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -32,11 +32,6 @@ #include "lltracethreadrecorder.h" #include "llthread.h" -inline F64 lerp(F64 a, F64 b, F64 u) -{ - return a + ((b - a) * u); -} - namespace LLTrace { @@ -302,7 +297,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat ) { t = (F64)active_accumulator->getSampleCount() / (F64)div; } - return lerp(accumulator.getMean(), active_accumulator->getMean(), t); + return std::lerp(accumulator.getMean(), active_accumulator->getMean(), t); } else { @@ -388,7 +383,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat ) { t = (F64)active_accumulator->getSampleCount() / (F64)div; } - return lerp(accumulator.getMean(), active_accumulator->getMean(), t); + return std::lerp(accumulator.getMean(), active_accumulator->getMean(), t); } else { diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index f1e4c2bc78..6b98a6bc49 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -38,6 +38,11 @@ typedef signed short S16; typedef unsigned short U16; typedef signed int S32; typedef unsigned int U32; +typedef long long int S64; +typedef long long unsigned int U64; + +#define S64L(a) (a##LL) +#define U64L(a) (a##ULL) // to express an index that might go negative // (ssize_t is provided by SOME compilers, don't collide) @@ -62,21 +67,6 @@ typedef wchar_t llwchar; #define LLWCHAR_IS_WCHAR_T 1 #endif -#if LL_WINDOWS -typedef signed __int64 S64; -// probably should be 'hyper' or similiar -#define S64L(a) (a) -typedef unsigned __int64 U64; -#define U64L(a) (a) -#else -typedef long long int S64; -typedef long long unsigned int U64; -#if LL_DARWIN || LL_LINUX -#define S64L(a) (a##LL) -#define U64L(a) (a##ULL) -#endif -#endif - typedef float F32; typedef double F64; @@ -121,10 +111,6 @@ typedef U8 LLPCode; #define LL_ARRAY_SIZE( _kArray ) ( sizeof( (_kArray) ) / sizeof( _kArray[0] ) ) -#if LL_LINUX && __GNUC__ <= 2 -typedef int intptr_t; -#endif - /***************************************************************************** * Narrowing *****************************************************************************/ diff --git a/indra/llcommon/tests/commonmisc_test.cpp b/indra/llcommon/tests/commonmisc_test.cpp index b1a284225e..80be26dfeb 100644 --- a/indra/llcommon/tests/commonmisc_test.cpp +++ b/indra/llcommon/tests/commonmisc_test.cpp @@ -503,7 +503,7 @@ namespace tut result_str = (const char*) result; ensure_equals("U64_to_str converted 1.4", val_str, result_str); - val = U64L(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615 + val = U64(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615 val_str = "18446744073709551615"; U64_to_str(val, result, sizeof(result)); result_str = (const char*) result; @@ -619,7 +619,7 @@ namespace tut val = U64_to_F64(U64L(2)); ensure_equals("U64_to_F64 converted 3.6", val, result); - result = U64L(0x7FFFFFFFFFFFFFFF) * 1.0L; // 0x7FFFFFFFFFFFFFFF + result = F64(0x7FFFFFFFFFFFFFFF) * 1.0; // 0x7FFFFFFFFFFFFFFF val = U64_to_F64(U64L(0x7FFFFFFFFFFFFFFF)); ensure_equals("U64_to_F64 converted 3.7", val, result); } diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp index 84eb41b5fe..0a4f0f38da 100644 --- a/indra/llcommon/tests/lldependencies_test.cpp +++ b/indra/llcommon/tests/lldependencies_test.cpp @@ -233,19 +233,7 @@ namespace tut StringList keys(make<StringList>(list_of("The")("brown")("dog.")("fox")("jumps")("lazy")("over")("quick")("the")("yellow"))); ensure_equals(instance_from_range<StringList>(deps.get_key_range()), keys); -#if (! defined(__GNUC__)) || (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - // This is the succinct way, works on modern compilers ensure_equals(instance_from_range<StringList>(make_transform_range(deps.get_range(), extract_key)), keys); -#else // gcc 3.3 - StringDeps::range got_range(deps.get_range()); - StringDeps::iterator kni = got_range.begin(), knend = got_range.end(); - StringList::iterator ki = keys.begin(), kend = keys.end(); - for ( ; kni != knend && ki != kend; ++kni, ++ki) - { - ensure_equals(kni->first, *ki); - } - ensure("get_range() returns proper length", kni == knend && ki == kend); -#endif // gcc 3.3 // blow off get_node_range() because they're all LLDependenciesEmpty instances } diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 3ec429530c..653f64f1b6 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -59,8 +59,10 @@ static const char* FieldName[] = namespace { -#ifdef __clang__ +#if defined(LL_CLANG) # pragma clang diagnostic ignored "-Wunused-function" +#elif defined(LL_GNUC) +# pragma GCC diagnostic ignored "-Wunused-function" #endif void test_that_error_h_includes_enough_things_to_compile_a_message() { diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 13422612d6..4a88d69ded 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -95,7 +95,7 @@ static std::string readfile(const std::string& pathname, const std::string& desc { use_desc = "in " + pathname; } - std::ifstream inf(pathname.c_str()); + llifstream inf(pathname.c_str()); std::string output; if (!std::getline(inf, output)) { @@ -126,6 +126,8 @@ void waitfor(LLProcess& proc, int timeout=60) { yield(); } + // Pump once more after the process exits to flush any final events such as EOF. + yield(0); std::string msg = "process took longer than " + std::to_string(timeout) + " seconds to terminate"; tut::ensure(msg, i < timeout); } @@ -137,6 +139,8 @@ void waitfor(LLProcess::handle h, const std::string& desc, int timeout=60) { yield(); } + // Pump once more after the process exits to flush any final events such as EOF. + yield(0); std::string msg = "process took longer than " + std::to_string(timeout) + " seconds to terminate"; tut::ensure(msg, i < timeout); } @@ -182,7 +186,7 @@ struct PythonProcessLauncher const char* APR_LOG = getenv("APR_LOG"); if (APR_LOG && *APR_LOG) { - std::ifstream inf(APR_LOG); + llifstream inf(APR_LOG); if (! inf.is_open()) { LL_WARNS() << "Couldn't open '" << APR_LOG << "'" << LL_ENDL; @@ -834,7 +838,7 @@ namespace tut // How do we know it's not terminated? By making it respond to // a specific stimulus in a specific way. { - std::ofstream outf(to.getName().c_str()); + llofstream outf(to.getName().c_str()); outf << "go"; } // flush and close. // now wait for the script to terminate... one way or another. @@ -897,7 +901,7 @@ namespace tut // How do we know it's not terminated? By making it respond to // a specific stimulus in a specific way. { - std::ofstream outf(to.getName().c_str()); + llofstream outf(to.getName().c_str()); outf << "go"; } // flush and close. // now wait for the script to terminate... one way or another. diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index fae9f7023f..ee315051d8 100644 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -2117,7 +2117,7 @@ namespace tut " f.write(lenformat.pack(len(serialized)))\n" " f.write(serialized)\n";}); - std::ifstream inf(file.getName().c_str()); + llifstream inf(file.getName().c_str()); LLSD item; try { diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp index b18712b8e9..f4366b2059 100644 --- a/indra/llcommon/tests/llstring_test.cpp +++ b/indra/llcommon/tests/llstring_test.cpp @@ -377,7 +377,7 @@ namespace tut { F32 value; std::string str_val("2147483647"); //0x7FFFFFFF - ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647); + ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647.f); str_val = "0"; ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0); @@ -399,7 +399,7 @@ namespace tut { F64 value; std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF - ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL); + ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807.0); str_val = "0"; ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F); diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index 451e60c083..6adbdffba8 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -78,6 +78,7 @@ void LL::ThreadPoolBase::start() std::string tname{ stringize(mName, ':', (i+1), '/', mThreadCount) }; mThreads.emplace_back(tname, [this, tname]() { + set_thread_name(tname.c_str()); LL_PROFILER_SET_THREAD_NAME(tname.c_str()); run(tname); }); |
