summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2025-09-29 16:29:19 +0800
committerErik Kundiman <erik@megapahit.org>2025-10-01 16:56:56 +0800
commita954d290674db08ecaf3c1e6484a0cb6647b88b5 (patch)
tree3b672bac3e7d6807cd485ad5f041f69a5c729f46 /indra/llcommon
parente6eaa7e29990431b5207dbb4f8ae5560cf884acb (diff)
parenta6d4c1d394eef2cea41f6c6bcd751fec746ec17d (diff)
Merge tag 'Second_Life_Release#a6d4c1d3-2025.07' into 2025.07
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/fsyspath.h47
-rw-r--r--indra/llcommon/linden_common.h6
-rw-r--r--indra/llcommon/llapp.cpp4
-rw-r--r--indra/llcommon/llcommon.cpp72
-rw-r--r--indra/llcommon/llerror.cpp2
-rw-r--r--indra/llcommon/llfasttimer.cpp2
-rw-r--r--indra/llcommon/llfasttimer.h62
-rw-r--r--indra/llcommon/llfile.cpp38
-rw-r--r--indra/llcommon/llmd5.cpp9
-rw-r--r--indra/llcommon/llmemory.h53
-rw-r--r--indra/llcommon/llpreprocessor.h38
-rw-r--r--indra/llcommon/llprocessor.cpp6
-rw-r--r--indra/llcommon/llprocessor.h15
-rw-r--r--indra/llcommon/llprofiler.h32
-rw-r--r--indra/llcommon/llsys.cpp9
-rw-r--r--indra/llcommon/llthreadsafequeue.h6
-rw-r--r--indra/llcommon/tests/stringize_test.cpp12
18 files changed, 228 insertions, 186 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index e8c51c4c8e..55dde5dc42 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -11,7 +11,6 @@ include(LLSharedLibs)
include(ZLIBNG)
include(Tracy)
-
set(llcommon_SOURCE_FILES
apply.cpp
commoncontrol.cpp
diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h
index e9c96edce3..2c900c02a7 100644
--- a/indra/llcommon/fsyspath.h
+++ b/indra/llcommon/fsyspath.h
@@ -12,7 +12,10 @@
#if ! defined(LL_FSYSPATH_H)
#define LL_FSYSPATH_H
+#include <boost/iterator/transform_iterator.hpp>
#include <filesystem>
+#include <string>
+#include <string_view>
// While std::filesystem::path can be directly constructed from std::string on
// both Posix and Windows, that's not what we want on Windows. Per
@@ -33,37 +36,43 @@
// char"), the "native narrow encoding" isn't UTF-8, so file paths containing
// non-ASCII characters get mangled.
//
-// Once we're building with C++20, we could pass a UTF-8 std::string through a
-// vector<char8_t> to engage std::filesystem::path's own UTF-8 conversion. But
-// sigh, as of 2024-04-03 we're not yet there.
-//
-// Anyway, encapsulating the important UTF-8 conversions in our own subclass
-// allows us to migrate forward to C++20 conventions without changing
-// referencing code.
+// Encapsulating the important UTF-8 conversions in our own subclass allows us
+// to migrate forward to C++20 conventions without changing referencing code.
class fsyspath: public std::filesystem::path
{
using super = std::filesystem::path;
+ // In C++20 (__cpp_lib_char8_t), std::filesystem::u8path() is deprecated.
+ // std::filesystem::path(iter, iter) performs UTF-8 conversions when the
+ // value_type of the iterators is char8_t. While we could copy into a
+ // temporary std::u8string and from there into std::filesystem::path, to
+ // minimize string copying we'll define a transform_iterator that accepts
+ // a std::string_view::iterator and dereferences to char8_t.
+ struct u8ify
+ {
+ char8_t operator()(char c) const { return char8_t(c); }
+ };
+ using u8iter = boost::transform_iterator<u8ify, std::string_view::iterator>;
+
public:
// default
fsyspath() {}
- // construct from UTF-8 encoded std::string
- fsyspath(const std::string& path): super(std::filesystem::u8path(path)) {}
- // construct from UTF-8 encoded const char*
- fsyspath(const char* path): super(std::filesystem::u8path(path)) {}
+ // construct from UTF-8 encoded string
+ fsyspath(const std::string& path): fsyspath(std::string_view(path)) {}
+ fsyspath(const char* path): fsyspath(std::string_view(path)) {}
+ fsyspath(std::string_view path):
+ super(u8iter(path.begin(), u8ify()), u8iter(path.end(), u8ify()))
+ {}
// construct from existing path
fsyspath(const super& path): super(path) {}
- fsyspath& operator=(const super& p) { super::operator=(p); return *this; }
- fsyspath& operator=(const std::string& p)
- {
- super::operator=(std::filesystem::u8path(p));
- return *this;
- }
- fsyspath& operator=(const char* p)
+ fsyspath& operator=(const super& p) { super::operator=(p); return *this; }
+ fsyspath& operator=(const std::string& p) { return (*this) = std::string_view(p); }
+ fsyspath& operator=(const char* p) { return (*this) = std::string_view(p); }
+ fsyspath& operator=(std::string_view p)
{
- super::operator=(std::filesystem::u8path(p));
+ assign(u8iter(p.begin(), u8ify()), u8iter(p.end(), u8ify()));
return *this;
}
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index a918caa2e8..a41af153fe 100644
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
@@ -28,12 +28,6 @@
#define LL_LINDEN_COMMON_H
#include "llprofiler.h"
-#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling
-void *tracy_aligned_malloc(size_t size, size_t alignment);
-void tracy_aligned_free(void *memblock);
-#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y))
-#define _aligned_free(X) tracy_aligned_free((X))
-#endif
// *NOTE: Please keep includes here to a minimum!
//
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 08a43983d3..c532620daa 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -229,7 +229,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
if(wargv[ii][1] == '-') ++offset;
#if LL_WINDOWS
- name.assign(utf16str_to_utf8str(&wargv[ii][offset]));
+ name.assign(ll_convert_wide_to_string(&wargv[ii][offset]));
#else
name.assign(wstring_to_utf8str(&wargv[ii][offset]));
#endif
@@ -253,7 +253,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
++ii;
#if LL_WINDOWS
- value.assign(utf16str_to_utf8str((wargv[ii])));
+ value.assign(ll_convert_wide_to_string((wargv[ii])));
#else
value.assign(wstring_to_utf8str((wargv[ii])));
#endif
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 84b35749cc..7a22eaf203 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -33,23 +33,23 @@
#include "lltracethreadrecorder.h"
#include "llcleanup.h"
-thread_local bool gProfilerEnabled = false;
-
-#if (TRACY_ENABLE)
+#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY && TRACY_ENABLE
// Override new/delete for tracy memory profiling
void* ll_tracy_new(size_t size)
{
- void* ptr;
- if (gProfilerEnabled)
- {
- //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
- ptr = (malloc)(size);
- }
- else
+ void* ptr = (malloc)(size);
+ if (!ptr)
{
- ptr = (malloc)(size);
+ throw std::bad_alloc();
}
+ LL_PROFILE_ALLOC(ptr, 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();
@@ -58,6 +58,18 @@ void* ll_tracy_new(size_t 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)
{
return ll_tracy_new(size);
@@ -68,18 +80,14 @@ void* operator new[](std::size_t count)
return ll_tracy_new(count);
}
-void ll_tracy_delete(void* ptr)
+void* operator new(size_t size, std::align_val_t align)
{
- LL_PROFILE_FREE(ptr);
- if (gProfilerEnabled)
- {
- //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
- (free)(ptr);
- }
- else
- {
- (free)(ptr);
- }
+ 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) noexcept
@@ -92,27 +100,17 @@ void operator delete[](void* ptr) noexcept
ll_tracy_delete(ptr);
}
-// C-style malloc/free can't be so easily overridden, so we define tracy versions and use
-// a pre-processor #define in linden_common.h to redirect to them. The parens around the native
-// functions below prevents recursive substitution by the preprocessor.
-//
-// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at
-// you, Havok), so we'll only capture the aligned version.
-
-void *tracy_aligned_malloc(size_t size, size_t alignment)
+void operator delete(void *ptr, std::align_val_t align) noexcept
{
- auto ptr = ll_aligned_malloc_fallback(size, alignment);
- if (ptr) LL_PROFILE_ALLOC(ptr, size);
- return ptr;
+ ll_tracy_aligned_delete(ptr);
}
-void tracy_aligned_free(void *memblock)
+void operator delete[](void* ptr, std::align_val_t align) noexcept
{
- LL_PROFILE_FREE(memblock);
- ll_aligned_free_fallback(memblock);
+ ll_tracy_aligned_delete(ptr);
}
-#endif
+#endif // TRACY_ENABLE && !LL_PROFILER_ENABLE_TRACY_OPENGL
//static
bool LLCommon::sAprInitialized = false;
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index d834098994..3411e9c6bb 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -79,7 +79,7 @@ namespace {
//
if (s.size())
{
- OutputDebugString(utf8str_to_utf16str(s).c_str());
+ OutputDebugString(ll_convert<std::wstring>(s).c_str());
OutputDebugString(TEXT("\n"));
}
}
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 7ceb57336e..be0cab36e3 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -64,7 +64,7 @@ bool BlockTimer::sLog = false;
std::string BlockTimer::sLogName = "";
bool BlockTimer::sMetricLog = false;
-#if LL_LINUX
+#if LL_LINUX || (LL_DARWIN && LL_ARM64)
U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution
#else
U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 8499655bfa..fde168b022 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -30,9 +30,14 @@
#include "llinstancetracker.h"
#include "lltrace.h"
#include "lltreeiterators.h"
+#include "llprocessor.h"
+#if LL_X86 || LL_X86_64
#if LL_WINDOWS
#include <intrin.h>
+#else
+#include <x86intrin.h>
+#endif
#endif
#define LL_FAST_TIMER_ON 1
@@ -68,35 +73,10 @@ public:
//
// Windows implementation of CPU clock
//
-
- //
- // NOTE: put back in when we aren't using platform sdk anymore
- //
- // because MS has different signatures for these functions in winnt.h
- // need to rename them to avoid conflicts
- //#define _interlockedbittestandset _renamed_interlockedbittestandset
- //#define _interlockedbittestandreset _renamed_interlockedbittestandreset
- //#include <intrin.h>
- //#undef _interlockedbittestandset
- //#undef _interlockedbittestandreset
-
- //inline U32 getCPUClockCount32()
- //{
- // U64 time_stamp = __rdtsc();
- // return (U32)(time_stamp >> 8);
- //}
- //
- //// return full timer value, *not* shifted by 8 bits
- //inline U64 getCPUClockCount64()
- //{
- // return __rdtsc();
- //}
-
-
+#if LL_FASTTIMER_USE_RDTSC
// shift off lower 8 bits for lower resolution but longer term timing
// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
-#if LL_FASTTIMER_USE_RDTSC
static U32 getCPUClockCount32()
{
#if _M_ARM64
@@ -181,23 +161,39 @@ public:
#endif // (LL_LINUX) && !(defined(__i386__) || defined(__amd64__))
+/*
+#if LL_DARWIN && LL_ARM64
+ //
+ // Mac implementation of CPU clock - non-x86.
+ //
+ static U64 getCPUClockCount64()
+ {
+ return clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
+ }
+
+ static U32 getCPUClockCount32()
+ {
+ return (U32)(getCPUClockCount64() >> 8);
+ }
+#endif // LL_DARWIN && LL_ARM64
+*/
+
#if (LL_LINUX || LL_DARWIN || __FreeBSD__) && (defined(__i386__) || defined(__amd64__))
//
// Mac+Linux FAST x86 implementation of CPU clock
+ //
+#if LL_FASTTIMER_USE_RDTSC
static U32 getCPUClockCount32()
{
- U32 low(0),high(0);
- __asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
- return (low>>8) | (high<<24);
+ U64 time_stamp = __rdtsc() >> 8U;
+ return static_cast<U32>(time_stamp);
}
static U64 getCPUClockCount64()
{
- U32 low(0),high(0);
- __asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
- return (U64)low | ( ((U64)high) << 32);
+ return static_cast<U64>(__rdtsc());
}
-
+#endif
#endif
static BlockTimerStatHandle& getRootTimeBlock();
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index d0bc8f7652..53659ac13f 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -178,8 +178,7 @@ int LLFile::mkdir(const std::string& dirname, int perms)
{
#if LL_WINDOWS
// permissions are ignored on Windows
- std::string utf8dirname = dirname;
- llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname);
+ std::wstring utf16dirname = ll_convert<std::wstring>(dirname);
int rc = _wmkdir(utf16dirname.c_str());
#else
int rc = ::mkdir(dirname.c_str(), (mode_t)perms);
@@ -201,8 +200,7 @@ int LLFile::rmdir(const std::string& dirname)
{
#if LL_WINDOWS
// permissions are ignored on Windows
- std::string utf8dirname = dirname;
- llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname);
+ std::wstring utf16dirname = ll_convert<std::wstring>(dirname);
int rc = _wrmdir(utf16dirname.c_str());
#else
int rc = ::rmdir(dirname.c_str());
@@ -214,10 +212,8 @@ int LLFile::rmdir(const std::string& dirname)
LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfinder: ignore */
{
#if LL_WINDOWS
- std::string utf8filename = filename;
- std::string utf8mode = std::string(mode);
- llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
- llutf16string utf16mode = utf8str_to_utf16str(utf8mode);
+ std::wstring utf16filename = ll_convert<std::wstring>(filename);
+ std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
return _wfopen(utf16filename.c_str(),utf16mode.c_str());
#else
return ::fopen(filename.c_str(),mode); /* Flawfinder: ignore */
@@ -227,10 +223,8 @@ LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawf
LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag)
{
#if LL_WINDOWS
- std::string utf8filename = filename;
- std::string utf8mode = std::string(mode);
- llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
- llutf16string utf16mode = utf8str_to_utf16str(utf8mode);
+ std::wstring utf16filename = ll_convert<std::wstring>(filename);
+ std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
return _wfsopen(utf16filename.c_str(),utf16mode.c_str(),sharingFlag);
#else
llassert(0);//No corresponding function on non-windows
@@ -270,8 +264,7 @@ std::string LLFile::getContents(const std::string& filename)
int LLFile::remove(const std::string& filename, int supress_error)
{
#if LL_WINDOWS
- std::string utf8filename = filename;
- llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
+ std::wstring utf16filename = ll_convert<std::wstring>(filename);
int rc = _wremove(utf16filename.c_str());
#else
int rc = ::remove(filename.c_str());
@@ -282,10 +275,8 @@ int LLFile::remove(const std::string& filename, int supress_error)
int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error)
{
#if LL_WINDOWS
- std::string utf8filename = filename;
- std::string utf8newname = newname;
- llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
- llutf16string utf16newname = utf8str_to_utf16str(utf8newname);
+ std::wstring utf16filename = ll_convert<std::wstring>(filename);
+ std::wstring utf16newname = ll_convert<std::wstring>(newname);
int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
#else
int rc = ::rename(filename.c_str(),newname.c_str());
@@ -327,8 +318,7 @@ bool LLFile::copy(const std::string& from, const std::string& to)
int LLFile::stat(const std::string& filename, llstat* filestatus)
{
#if LL_WINDOWS
- std::string utf8filename = filename;
- llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
+ std::wstring utf16filename = ll_convert<std::wstring>(filename);
int rc = _wstat(utf16filename.c_str(),filestatus);
#else
int rc = ::stat(filename.c_str(),filestatus);
@@ -453,14 +443,14 @@ llifstream::llifstream() {}
// explicit
llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
- std::ifstream(utf8str_to_utf16str( _Filename ).c_str(),
+ std::ifstream(ll_convert<std::wstring>( _Filename ).c_str(),
_Mode | ios_base::in)
{
}
void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
- std::ifstream::open(utf8str_to_utf16str(_Filename).c_str(),
+ std::ifstream::open(ll_convert<std::wstring>(_Filename).c_str(),
_Mode | ios_base::in);
}
@@ -472,14 +462,14 @@ llofstream::llofstream() {}
// explicit
llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
- std::ofstream(utf8str_to_utf16str( _Filename ).c_str(),
+ std::ofstream(ll_convert<std::wstring>( _Filename ).c_str(),
_Mode | ios_base::out)
{
}
void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
{
- std::ofstream::open(utf8str_to_utf16str( _Filename ).c_str(),
+ std::ofstream::open(ll_convert<std::wstring>( _Filename ).c_str(),
_Mode | ios_base::out);
}
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index e999b8f597..c8ca586e7f 100644
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
@@ -255,6 +255,11 @@ void LLMD5::raw_digest(unsigned char* s) const
memcpy(s, digest, 16); /* Flawfinder: ignore */
}
+#if LL_DARWIN
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
void LLMD5::hex_digest(char* s) const
{
if (!finalized)
@@ -273,6 +278,10 @@ void LLMD5::hex_digest(char* s) const
s[32] = '\0';
}
+#if LL_DARWIN
+#pragma clang diagnostic pop
+#endif
+
std::ostream& operator<<(std::ostream& stream, const LLMD5& context)
{
char s[33]; /* Flawfinder: ignore */
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index d5802b9d95..c06ae93766 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -235,8 +235,6 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
#if defined(LL_WINDOWS)
void* ret = _aligned_malloc(size, 32);
-#elif defined(LL_DARWIN)
- void* ret = ll_aligned_malloc_fallback( size, 32 );
#else
void *ret;
if (0 != posix_memalign(&ret, 32, size))
@@ -252,8 +250,31 @@ inline void ll_aligned_free_32(void *p)
LL_PROFILE_FREE(p);
#if defined(LL_WINDOWS)
_aligned_free(p);
-#elif defined(LL_DARWIN)
- ll_aligned_free_fallback( p );
+#else
+ free(p); // posix_memalign() is compatible with heap deallocator
+#endif
+}
+
+inline void* ll_aligned_malloc_64(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
+#if defined(LL_WINDOWS)
+ void* ret = _aligned_malloc(size, 64);
+#else
+ void *ret;
+ if (0 != posix_memalign(&ret, 64, size))
+ return nullptr;
+#endif
+ LL_PROFILE_ALLOC(ret, size);
+ return ret;
+}
+
+inline void ll_aligned_free_64(void *p)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
+ LL_PROFILE_FREE(p);
+#if defined(LL_WINDOWS)
+ _aligned_free(p);
#else
free(p); // posix_memalign() is compatible with heap deallocator
#endif
@@ -265,19 +286,23 @@ LL_FORCE_INLINE void* ll_aligned_malloc(size_t size)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
void* ret;
- if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0)
+ if constexpr (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0)
{
ret = malloc(size);
LL_PROFILE_ALLOC(ret, size);
}
- else if (ALIGNMENT == 16)
+ else if constexpr (ALIGNMENT == 16)
{
ret = ll_aligned_malloc_16(size);
}
- else if (ALIGNMENT == 32)
+ else if constexpr (ALIGNMENT == 32)
{
ret = ll_aligned_malloc_32(size);
}
+ else if constexpr (ALIGNMENT == 64)
+ {
+ ret = ll_aligned_malloc_64(size);
+ }
else
{
ret = ll_aligned_malloc_fallback(size, ALIGNMENT);
@@ -289,16 +314,20 @@ template<size_t ALIGNMENT>
LL_FORCE_INLINE void ll_aligned_free(void* ptr)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
- if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
+ if constexpr (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
{
LL_PROFILE_FREE(ptr);
free(ptr);
}
- else if (ALIGNMENT == 16)
+ else if constexpr (ALIGNMENT == 16)
{
ll_aligned_free_16(ptr);
}
- else if (ALIGNMENT == 32)
+ else if constexpr (ALIGNMENT == 32)
+ {
+ return ll_aligned_free_32(ptr);
+ }
+ else if constexpr (ALIGNMENT == 64)
{
return ll_aligned_free_32(ptr);
}
@@ -314,6 +343,9 @@ LL_FORCE_INLINE void ll_aligned_free(void* ptr)
inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
+#if defined(LL_ARM64)
+ memcpy(dst, src, bytes);
+#else
assert(src != NULL);
assert(dst != NULL);
assert(bytes > 0);
@@ -379,6 +411,7 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __
dst += 16;
src += 16;
}
+#endif
}
#ifndef __DEBUG_PRIVATE_MEM__
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 268109e8b7..cbcaf47cd2 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -78,6 +78,23 @@
#endif
#endif
+// Set up CPU architecture defines
+#if LL_MSVC && defined(_M_ARM64)
+# define LL_ARM64 1
+#elif LL_GNUC && (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__) )
+# define LL_X86_64 1
+# define LL_X86 1
+#elif LL_GNUC && ( defined(__i386__) )
+# define LL_X86 1
+#endif
+
// Deal with minor differences on Unixy OSes.
#if LL_DARWIN || LL_LINUX || __FreeBSD__
// Different name, same functionality.
@@ -120,11 +137,8 @@
#if LL_WINDOWS
#define LL_DLLEXPORT __declspec(dllexport)
#define LL_DLLIMPORT __declspec(dllimport)
-#elif LL_LINUX
-#define LL_DLLEXPORT __attribute__ ((visibility("default")))
-#define LL_DLLIMPORT
#else
-#define LL_DLLEXPORT
+#define LL_DLLEXPORT __attribute__ ((visibility("default")))
#define LL_DLLIMPORT
#endif // LL_WINDOWS
@@ -169,11 +183,7 @@
#define LL_TO_STRING_HELPER(x) #x
#define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
-#if _M_ARM64
#define LL_TO_WSTRING_HELPER(x) L## #x
-#else
-#define LL_TO_WSTRING_HELPER(x) L#x
-#endif
#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)
#define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
#define LL_GLUE_IMPL(x, y) x##y
@@ -193,4 +203,16 @@
#define LL_PRETTY_FUNCTION __PRETTY_FUNCTION__
#endif
+#if LL_ARM64
+#define GLM_FORCE_NEON 1
+#else
+#define GLM_FORCE_SSE2 1
+#endif
+
+#if LL_ARM64
+#define KDU_NEON_INTRINSICS 1
+#else
+#define KDU_X86_INTRINSICS 1
+#endif
+
#endif // not LL_LINDEN_PREPROCESSOR_H
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 7f2276ca2a..2b6e4be1c8 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -680,14 +680,14 @@ public:
setInfo(eFrequency, (F64)frequency / (F64)1000000);
}
- virtual ~LLProcessorInfoDarwinImpl() {}
+ virtual ~LLProcessorInfoDarwinImpl() = default;
private:
int getSysctlInt(const char* name)
{
int result = 0;
size_t len = sizeof(int);
- int error = sysctlbyname(name, (void*)&result, &len, NULL, 0);
+ int error = sysctlbyname(name, (void*)&result, &len, nullptr, 0);
return error == -1 ? 0 : result;
}
@@ -695,7 +695,7 @@ private:
{
uint64_t value = 0;
size_t size = sizeof(value);
- int result = sysctlbyname(name, (void*)&value, &size, NULL, 0);
+ int result = sysctlbyname(name, (void*)&value, &size, nullptr, 0);
if ( result == 0 )
{
if ( size == sizeof( uint64_t ) )
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index f8ccf686c8..b955f7f55c 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -28,20 +28,7 @@
#ifndef LLPROCESSOR_H
#define LLPROCESSOR_H
#include "llunits.h"
-
-#if 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__) )
-# define LL_X86_64 1
-# define LL_X86 1
-#elif LL_GNUC && ( defined(__i386__) )
-# define LL_X86 1
-#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) )
-# define LL_PPC 1
-#endif
+#include "llpreprocessor.h"
class LLProcessorInfoImpl;
diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
index 9267c5cbda..e0f3cf1b73 100644
--- a/indra/llcommon/llprofiler.h
+++ b/indra/llcommon/llprofiler.h
@@ -74,23 +74,18 @@
#define LL_PROFILER_CONFIGURATION 0
#endif
-extern thread_local bool gProfilerEnabled;
-
#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 "tracy/Tracy.hpp"
- // Enable OpenGL profiling
- #define LL_PROFILER_ENABLE_TRACY_OPENGL 0
-
// Enable RenderDoc labeling
- #define LL_PROFILER_ENABLE_RENDER_DOC 0
+ //#define LL_PROFILER_ENABLE_RENDER_DOC 0
#endif
#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY
#define LL_PROFILER_FRAME_END FrameMark
- #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true;
+ #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name );
#define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true );
#define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true );
#define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB
@@ -133,7 +128,7 @@ extern thread_local bool gProfilerEnabled;
#endif
#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER
#define LL_PROFILER_FRAME_END FrameMark
- #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true;
+ #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name );
#define LL_RECORD_BLOCK_TIME(name) ZoneNamedN(___tracy_scoped_zone, #name, true); const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
#define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true );
#define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB
@@ -180,23 +175,20 @@ extern thread_local bool gProfilerEnabled;
#endif // LL_PROFILER
#if LL_PROFILER_ENABLE_TRACY_OPENGL
-#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name)
-#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color)
+#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name)
+#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color)
#define LL_PROFILER_GPU_COLLECT TracyGpuCollect
#define LL_PROFILER_GPU_CONTEXT TracyGpuContext
-
-// disable memory tracking (incompatible with GPU tracing
-#define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size);
-#define LL_PROFILE_FREE(ptr) (void)(ptr);
+#define LL_PROFILER_GPU_CONTEXT_NAMED TracyGpuContextName
#else
-#define LL_PROFILE_GPU_ZONE(name) (void)name;
-#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color;
+#define LL_PROFILE_GPU_ZONE(name) (void)name;
+#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color;
#define LL_PROFILER_GPU_COLLECT
#define LL_PROFILER_GPU_CONTEXT
+#define LL_PROFILER_GPU_CONTEXT_NAMED(name) (void)name;
+#endif // LL_PROFILER_ENABLE_TRACY_OPENGL
-#define LL_LABEL_OBJECT_GL(type, name, length, label)
-
-#if !LL_DARWIN && LL_PROFILER_CONFIGURATION > 1
+#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY
#define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size)
#define LL_PROFILE_FREE(ptr) TracyFree(ptr)
#else
@@ -204,8 +196,6 @@ extern thread_local bool gProfilerEnabled;
#define LL_PROFILE_FREE(ptr) (void)(ptr);
#endif
-#endif
-
#if LL_PROFILER_ENABLE_RENDER_DOC
#define LL_LABEL_OBJECT_GL(type, name, length, label) glObjectLabel(type, name, length, label)
#else
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 5c35aeb476..2c46c59aa5 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -197,6 +197,9 @@ LLOSInfo::LLOSInfo() :
GetSystemInfo(&si); //if it fails get regular system info
//(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load)
+#pragma warning(push)
+#pragma warning(disable : 4996) // ignore 'deprecated.' GetVersionEx is deprecated
+
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
@@ -215,6 +218,8 @@ LLOSInfo::LLOSInfo() :
}
}
+#pragma warning(pop)
+
S32 ubr = 0; // Windows 10 Update Build Revision, can be retrieved from a registry
if (mMajorVer == 10)
{
@@ -1332,7 +1337,7 @@ bool gunzip_file(const std::string& srcfile, const std::string& dstfile)
S32 bytes = 0;
tmpfile = dstfile + ".t";
#ifdef LL_WINDOWS
- llutf16string utf16filename = utf8str_to_utf16str(srcfile);
+ std::wstring utf16filename = ll_convert<std::wstring>(srcfile);
src = gzopen_w(utf16filename.c_str(), "rb");
#else
src = gzopen(srcfile.c_str(), "rb");
@@ -1376,7 +1381,7 @@ bool gzip_file(const std::string& srcfile, const std::string& dstfile)
tmpfile = dstfile + ".t";
#ifdef LL_WINDOWS
- llutf16string utf16filename = utf8str_to_utf16str(tmpfile);
+ std::wstring utf16filename = ll_convert<std::wstring>(tmpfile);
dst = gzopen_w(utf16filename.c_str(), "wb");
#else
dst = gzopen(tmpfile.c_str(), "wb");
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 85fcbbacac..6532439dd9 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -452,11 +452,9 @@ ElementT LLThreadSafeQueue<ElementT, QueueT>::pop(void)
// so we can finish draining the queue.
pop_result popped = pop_(lock1, value);
if (popped == POPPED)
-#if LL_LINUX
return value;
-#else
- return std::move(value);
-#endif
+ // don't use std::move when returning local value because
+ // it prevents the compiler from optimizing with copy elision
// Once the queue is DONE, there will never be any more coming.
if (popped == DONE)
diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp
index a3ce7f8e3d..3f99041592 100644
--- a/indra/llcommon/tests/stringize_test.cpp
+++ b/indra/llcommon/tests/stringize_test.cpp
@@ -110,6 +110,17 @@ namespace tut
void stringize_object::test<3>()
{
//Tests rely on validity of wstring_to_utf8str()
+#if LL_WINDOWS // Windows wstring is a 2byte UTF16 type
+ ensure_equals(ll_convert<std::string>(wstringize(c)), ll_convert<std::string>(std::wstring(L"c")));
+ ensure_equals(ll_convert<std::string>(wstringize(s)), ll_convert<std::string>(std::wstring(L"17")));
+ ensure_equals(ll_convert<std::string>(wstringize(i)), ll_convert<std::string>(std::wstring(L"34")));
+ ensure_equals(ll_convert<std::string>(wstringize(l)), ll_convert<std::string>(std::wstring(L"68")));
+ ensure_equals(ll_convert<std::string>(wstringize(f)), ll_convert<std::string>(std::wstring(L"3.14159")));
+ ensure_equals(ll_convert<std::string>(wstringize(d)), ll_convert<std::string>(std::wstring(L"3.14159")));
+ ensure_equals(ll_convert<std::string>(wstringize(abc)), ll_convert<std::string>(std::wstring(L"abc def")));
+ ensure_equals(ll_convert<std::string>(wstringize(abc)), ll_convert<std::string>(wstringize(abc.c_str())));
+ ensure_equals(ll_convert<std::string>(wstringize(def)), ll_convert<std::string>(std::wstring(L"def ghi")));
+#else
ensure_equals(wstring_to_utf8str(wstringize(c)), wstring_to_utf8str(L"c"));
ensure_equals(wstring_to_utf8str(wstringize(s)), wstring_to_utf8str(L"17"));
ensure_equals(wstring_to_utf8str(wstringize(i)), wstring_to_utf8str(L"34"));
@@ -119,6 +130,7 @@ namespace tut
ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(L"abc def"));
ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(wstringize(abc.c_str())));
ensure_equals(wstring_to_utf8str(wstringize(def)), wstring_to_utf8str(L"def ghi"));
+#endif
// ensure_equals(wstring_to_utf8str(wstringize(llsd)), wstring_to_utf8str(L"{'abc':'abc def','d':r3.14159,'i':i34}"));
}
} // namespace tut