summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt28
-rw-r--r--indra/llcommon/StackWalker.cpp2
-rw-r--r--indra/llcommon/classic_callback.h4
-rw-r--r--indra/llcommon/llapp.cpp51
-rw-r--r--indra/llcommon/llapr.cpp4
-rw-r--r--indra/llcommon/llatomic.cpp2
-rw-r--r--indra/llcommon/llcallbacklist.cpp2
-rw-r--r--indra/llcommon/llcommon.cpp54
-rw-r--r--indra/llcommon/lldate.cpp4
-rw-r--r--indra/llcommon/lldeadmantimer.cpp1
-rw-r--r--indra/llcommon/lldefs.h55
-rw-r--r--indra/llcommon/llerror.cpp51
-rw-r--r--indra/llcommon/llerror.h7
-rw-r--r--indra/llcommon/llfasttimer.cpp11
-rw-r--r--indra/llcommon/llfindlocale.cpp4
-rw-r--r--indra/llcommon/llinstancetracker.h4
-rw-r--r--indra/llcommon/llkeybind.cpp9
-rw-r--r--indra/llcommon/llkeybind.h1
-rw-r--r--indra/llcommon/llmd5.cpp6
-rw-r--r--indra/llcommon/llmemory.cpp3
-rw-r--r--indra/llcommon/llmemory.h46
-rw-r--r--indra/llcommon/llpreprocessor.h50
-rw-r--r--indra/llcommon/llprocess.cpp12
-rw-r--r--indra/llcommon/llprocessor.cpp67
-rw-r--r--indra/llcommon/llprocinfo.cpp1
-rw-r--r--indra/llcommon/llprofiler.cpp2
-rw-r--r--indra/llcommon/llprofiler.h9
-rw-r--r--indra/llcommon/llrand.cpp25
-rw-r--r--indra/llcommon/llsd.cpp5
-rw-r--r--indra/llcommon/llsdjson.cpp1
-rw-r--r--indra/llcommon/llsdserialize.cpp5
-rw-r--r--indra/llcommon/llsdutil.cpp4
-rw-r--r--indra/llcommon/llstl.h10
-rw-r--r--indra/llcommon/llsys.cpp132
-rw-r--r--indra/llcommon/llthread.cpp46
-rw-r--r--indra/llcommon/llthread.h8
-rw-r--r--indra/llcommon/lltracerecording.cpp9
-rw-r--r--indra/llcommon/stdtypes.h24
-rw-r--r--indra/llcommon/tests/commonmisc_test.cpp4
-rw-r--r--indra/llcommon/tests/lldependencies_test.cpp12
-rw-r--r--indra/llcommon/tests/llerror_test.cpp4
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp12
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp2
-rw-r--r--indra/llcommon/tests/llstring_test.cpp4
-rw-r--r--indra/llcommon/threadpool.cpp1
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);
});