summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorBrad Kittenbrink <brad@lindenlab.com>2022-11-28 14:33:27 -0800
committerBrad Kittenbrink <brad@lindenlab.com>2022-11-28 14:33:27 -0800
commit0b188ac04ecdb1d620a427eacbf5fc089e0accc8 (patch)
tree76f6afe9424d79bab8d30060d49aec3166d96ec8 /indra/llcommon
parente9cd2b320ea2ecaab88e4904f7c81746ea617fea (diff)
parentc8f08f232a28f4e08b4acf525f0d316a101a0e27 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-528
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt11
-rw-r--r--indra/llcommon/llalignedarray.h10
-rw-r--r--indra/llcommon/llcoros.cpp37
-rw-r--r--indra/llcommon/llcoros.h35
-rw-r--r--indra/llcommon/llmemory.cpp8
-rw-r--r--indra/llcommon/llprocessor.cpp139
-rw-r--r--indra/llcommon/llprocessor.h5
-rw-r--r--indra/llcommon/llrefcount.cpp2
-rw-r--r--indra/llcommon/llsys.cpp90
-rw-r--r--indra/llcommon/llsys.h12
-rw-r--r--indra/llcommon/llsys_objc.h33
-rw-r--r--indra/llcommon/llsys_objc.mm64
-rw-r--r--indra/llcommon/threadpool.cpp1
-rw-r--r--indra/llcommon/threadpool.h4
-rw-r--r--indra/llcommon/workqueue.h8
15 files changed, 408 insertions, 51 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 59aa731af2..df65828d02 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -266,6 +266,11 @@ 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)
+endif (DARWIN)
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
@@ -313,12 +318,6 @@ target_link_libraries(
${TRACY_LIBRARY}
)
-if (DARWIN)
- include(CMakeFindFrameworks)
- find_library(CARBON_LIBRARY Carbon)
- target_link_libraries(llcommon ${CARBON_LIBRARY})
-endif (DARWIN)
-
add_dependencies(llcommon stage_third_party_libs)
if (LL_TESTS)
diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
index b68e9e0f82..da9d98c16c 100644
--- a/indra/llcommon/llalignedarray.h
+++ b/indra/llcommon/llalignedarray.h
@@ -116,14 +116,20 @@ void LLAlignedArray<T, alignment>::resize(U32 size)
template <class T, U32 alignment>
T& LLAlignedArray<T, alignment>::operator[](int idx)
{
- llassert(idx < mElementCount);
+ if(idx >= mElementCount || idx < 0)
+ {
+ LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
+ }
return mArray[idx];
}
template <class T, U32 alignment>
const T& LLAlignedArray<T, alignment>::operator[](int idx) const
{
- llassert(idx < mElementCount);
+ if (idx >= mElementCount || idx < 0)
+ {
+ LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
+ }
return mArray[idx];
}
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c2d353b0fc..14bfb98629 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -35,6 +35,7 @@
// STL headers
// std headers
#include <atomic>
+#include <stdexcept>
// external library headers
#include <boost/bind.hpp>
#include <boost/fiber/fiber.hpp>
@@ -214,6 +215,22 @@ std::string LLCoros::logname()
return data.mName.empty()? data.getKey() : data.mName;
}
+void LLCoros::saveException(const std::string& name, std::exception_ptr exc)
+{
+ mExceptionQueue.emplace(name, exc);
+}
+
+void LLCoros::rethrow()
+{
+ if (! mExceptionQueue.empty())
+ {
+ ExceptionData front = mExceptionQueue.front();
+ mExceptionQueue.pop();
+ LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL;
+ std::rethrow_exception(front.exception);
+ }
+}
+
void LLCoros::setStackSize(S32 stacksize)
{
LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
@@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
-void LLCoros::winlevel(const std::string& name, const callable_t& callable)
+void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
{
__try
{
- toplevelTryWrapper(name, callable);
+ LLCoros::toplevelTryWrapper(name, callable);
}
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
@@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)
throw std::exception(integer_string);
}
}
-
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
@@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
+#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
- // crash, hopefully informatively.
+ // crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
+#else
+ // Stash any OTHER kind of uncaught exception in the rethrow() queue
+ // to be rethrown by the main fiber.
+ LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
+ << name << LL_ENDL;
+ LLCoros::instance().saveException(name, std::current_exception());
+#endif
}
}
@@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
- // Can not use __try in functions that require unwinding, so use one more wrapper
- winlevel(name, callable);
+ // Because SEH can's have unwinding, need to call a wrapper
+ // 'try' is inside SEH handling to not catch LLContinue
+ sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index a94cfca19f..dbff921f16 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -38,6 +38,8 @@
#include "llinstancetracker.h"
#include <boost/function.hpp>
#include <string>
+#include <exception>
+#include <queue>
// e.g. #include LLCOROS_MUTEX_HEADER
#define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp>
@@ -156,6 +158,19 @@ public:
* LLCoros::launch()).
*/
static std::string getName();
+
+ /**
+ * rethrow() is called by the thread's main fiber to propagate an
+ * exception from any coroutine into the main fiber, where it can engage
+ * the normal unhandled-exception machinery, up to and including crash
+ * reporting.
+ *
+ * LLCoros maintains a queue of otherwise-uncaught exceptions from
+ * terminated coroutines. Each call to rethrow() pops the first of those
+ * and rethrows it. When the queue is empty (normal case), rethrow() is a
+ * no-op.
+ */
+ void rethrow();
/**
* This variation returns a name suitable for log messages: the explicit
@@ -292,13 +307,27 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
+ void toplevelTryWrapper(const std::string& name, const callable_t& callable);
#if LL_WINDOWS
- void winlevel(const std::string& name, const callable_t& callable);
+ void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
#endif
- void toplevelTryWrapper(const std::string& name, const callable_t& callable);
- void toplevel(std::string name, callable_t callable);
+ void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
+ void saveException(const std::string& name, std::exception_ptr exc);
+
+ struct ExceptionData
+ {
+ ExceptionData(const std::string& nm, std::exception_ptr exc):
+ name(nm),
+ exception(exc)
+ {}
+ // name of coroutine that originally threw this exception
+ std::string name;
+ // the thrown exception
+ std::exception_ptr exception;
+ };
+ std::queue<ExceptionData> mExceptionQueue;
S32 mStackSize;
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 849867586a..d6ae1284d3 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -212,11 +212,9 @@ U64 LLMemory::getCurrentRSS()
mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
{
-// residentSize = basicInfo.resident_size;
- // Although this method is defined to return the "resident set size,"
- // in fact what callers want from it is the total virtual memory
- // consumed by the application.
- residentSize = basicInfo.virtual_size;
+ residentSize = basicInfo.resident_size;
+ // 64-bit macos apps allocate 32 GB or more at startup, and this is reflected in virtual_size.
+ // basicInfo.virtual_size is not what we want.
}
else
{
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 818df07bb2..4a1a81f083 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -118,7 +118,11 @@ namespace
eMONTIOR_MWAIT=33,
eCPLDebugStore=34,
eThermalMonitor2=35,
- eAltivec=36
+ eAltivec=36,
+ eSSE3S_Features = 37,
+ eSSE4_1_Features = 38,
+ eSSE4_2_Features = 39,
+ eSSE4a_Features = 40,
};
const char* cpu_feature_names[] =
@@ -161,7 +165,11 @@ namespace
"CPL Qualified Debug Store",
"Thermal Monitor 2",
- "Altivec"
+ "Altivec",
+ "SSE3S Instructions",
+ "SSE4.1 Instructions",
+ "SSE4.2 Instructions",
+ "SSE4a Instructions",
};
std::string intel_CPUFamilyName(int composed_family)
@@ -250,6 +258,31 @@ public:
return hasExtension(cpu_feature_names[eSSE2_Ext]);
}
+ bool hasSSE3() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ bool hasSSE3S() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ bool hasSSE41() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ bool hasSSE42() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ bool hasSSE4a() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+
bool hasAltivec() const
{
return hasExtension("Altivec");
@@ -473,6 +506,12 @@ private:
*((int*)(cpu_vendor+4)) = cpu_info[3];
*((int*)(cpu_vendor+8)) = cpu_info[2];
setInfo(eVendor, cpu_vendor);
+ std::string cmp_vendor(cpu_vendor);
+ bool is_amd = false;
+ if (cmp_vendor == "AuthenticAMD")
+ {
+ is_amd = true;
+ }
// Get the information associated with each valid Id
for(unsigned int i=0; i<=ids; ++i)
@@ -504,6 +543,7 @@ private:
if(cpu_info[2] & 0x8)
{
+ // intel specific SSE3 suplements
setExtension(cpu_feature_names[eMONTIOR_MWAIT]);
}
@@ -516,7 +556,22 @@ private:
{
setExtension(cpu_feature_names[eThermalMonitor2]);
}
-
+
+ if (cpu_info[2] & 0x200)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_info[2] & 0x80000)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_info[2] & 0x100000)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
unsigned int feature_info = (unsigned int) cpu_info[3];
for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
{
@@ -543,8 +598,17 @@ private:
__cpuid(cpu_info, i);
// Interpret CPU brand string and cache information.
- if (i == 0x80000002)
- memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ if (i == 0x80000001)
+ {
+ if (is_amd)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+ }
+ else if (i == 0x80000002)
+ {
+ memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ }
else if (i == 0x80000003)
memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info));
else if (i == 0x80000004)
@@ -690,6 +754,41 @@ private:
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
setConfig(eExtFeatureBits, ext_feature_infos[0]);
+
+
+ char cpu_features[1024];
+ len = sizeof(cpu_features);
+ memset(cpu_features, 0, len);
+ sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0);
+
+ std::string cpu_features_str(cpu_features);
+ cpu_features_str = " " + cpu_features_str + " ";
+
+ if (cpu_features_str.find(" SSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (cpu_features_str.find(" SSSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4A ") != std::string::npos)
+ {
+ // Not supposed to happen?
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
}
};
@@ -800,6 +899,31 @@ private:
{
setExtension(cpu_feature_names[eSSE2_Ext]);
}
+
+ if (flags.find(" pni ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (flags.find(" ssse3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (flags.find(" sse4_1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (flags.find(" sse4_2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (flags.find(" sse4a ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
# endif // LL_X86
}
@@ -860,6 +984,11 @@ LLProcessorInfo::~LLProcessorInfo() {}
F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
+bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); }
+bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
+bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
+bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
+bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index b77eb22c3a..1a473ddc97 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -54,6 +54,11 @@ public:
F64MegahertzImplicit getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
+ bool hasSSE3() const;
+ bool hasSSE3S() const;
+ bool hasSSE41() const;
+ bool hasSSE42() const;
+ bool hasSSE4a() const;
bool hasAltivec() const;
std::string getCPUFamilyName() const;
std::string getCPUBrandName() const;
diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
index 5cbd346411..6852b5536a 100644
--- a/indra/llcommon/llrefcount.cpp
+++ b/indra/llcommon/llrefcount.cpp
@@ -30,7 +30,7 @@
#include "llerror.h"
// maximum reference count before sounding memory leak alarm
-const S32 gMaxRefCount = 65536;
+const S32 gMaxRefCount = S32_MAX;
LLRefCount::LLRefCount(const LLRefCount& other)
: mRef(0)
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 9b6bb3826c..a8b5c7b3a8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -64,6 +64,7 @@ using namespace llsd;
# include <psapi.h> // GetPerformanceInfo() et al.
# include <VersionHelpers.h>
#elif LL_DARWIN
+# include "llsys_objc.h"
# include <errno.h>
# include <sys/sysctl.h>
# include <sys/utsname.h>
@@ -74,12 +75,6 @@ using namespace llsd;
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
-
-// disable warnings about Gestalt calls being deprecated
-// until Apple get's on the ball and provides an alternative
-//
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@@ -278,12 +273,9 @@ LLOSInfo::LLOSInfo() :
{
const char * DARWIN_PRODUCT_NAME = "Mac OS X";
- SInt32 major_version, minor_version, bugfix_version;
- OSErr r1 = Gestalt(gestaltSystemVersionMajor, &major_version);
- OSErr r2 = Gestalt(gestaltSystemVersionMinor, &minor_version);
- OSErr r3 = Gestalt(gestaltSystemVersionBugFix, &bugfix_version);
+ S32 major_version, minor_version, bugfix_version = 0;
- if((r1 == noErr) && (r2 == noErr) && (r3 == noErr))
+ if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version))
{
mMajorVer = major_version;
mMinorVer = minor_version;
@@ -597,6 +589,11 @@ LLCPUInfo::LLCPUInfo()
// proc.WriteInfoTextFile("procInfo.txt");
mHasSSE = proc.hasSSE();
mHasSSE2 = proc.hasSSE2();
+ mHasSSE3 = proc.hasSSE3();
+ mHasSSE3S = proc.hasSSE3S();
+ mHasSSE41 = proc.hasSSE41();
+ mHasSSE42 = proc.hasSSE42();
+ mHasSSE4a = proc.hasSSE4a();
mHasAltivec = proc.hasAltivec();
mCPUMHz = (F64)proc.getCPUFrequency();
mFamily = proc.getCPUFamilyName();
@@ -609,6 +606,35 @@ LLCPUInfo::LLCPUInfo()
}
mCPUString = out.str();
LLStringUtil::trim(mCPUString);
+
+ if (mHasSSE)
+ {
+ mSSEVersions.append("1");
+ }
+ if (mHasSSE2)
+ {
+ mSSEVersions.append("2");
+ }
+ if (mHasSSE3)
+ {
+ mSSEVersions.append("3");
+ }
+ if (mHasSSE3S)
+ {
+ mSSEVersions.append("3S");
+ }
+ if (mHasSSE41)
+ {
+ mSSEVersions.append("4.1");
+ }
+ if (mHasSSE42)
+ {
+ mSSEVersions.append("4.2");
+ }
+ if (mHasSSE4a)
+ {
+ mSSEVersions.append("4a");
+ }
}
bool LLCPUInfo::hasAltivec() const
@@ -626,6 +652,31 @@ bool LLCPUInfo::hasSSE2() const
return mHasSSE2;
}
+bool LLCPUInfo::hasSSE3() const
+{
+ return mHasSSE3;
+}
+
+bool LLCPUInfo::hasSSE3S() const
+{
+ return mHasSSE3S;
+}
+
+bool LLCPUInfo::hasSSE41() const
+{
+ return mHasSSE41;
+}
+
+bool LLCPUInfo::hasSSE42() const
+{
+ return mHasSSE42;
+}
+
+bool LLCPUInfo::hasSSE4a() const
+{
+ return mHasSSE4a;
+}
+
F64 LLCPUInfo::getMHz() const
{
return mCPUMHz;
@@ -636,6 +687,11 @@ std::string LLCPUInfo::getCPUString() const
return mCPUString;
}
+const LLSD& LLCPUInfo::getSSEVersions() const
+{
+ return mSSEVersions;
+}
+
void LLCPUInfo::stream(std::ostream& s) const
{
// gather machine information.
@@ -645,6 +701,11 @@ void LLCPUInfo::stream(std::ostream& s) const
// CPU's attributes regardless of platform
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
+ s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl;
+ s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl;
+ s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl;
+ s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl;
+ s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl;
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
s << "->mCPUMHz: " << mCPUMHz << std::endl;
s << "->mCPUString: " << mCPUString << std::endl;
@@ -1341,10 +1402,3 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
if (dst != NULL) gzclose(dst);
return retval;
}
-
-#if LL_DARWIN
-// disable warnings about Gestalt calls being deprecated
-// until Apple get's on the ball and provides an alternative
-//
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index cb92cb0ac6..5ffbf5a732 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -80,10 +80,16 @@ public:
void stream(std::ostream& s) const;
std::string getCPUString() const;
+ const LLSD& getSSEVersions() const;
bool hasAltivec() const;
bool hasSSE() const;
bool hasSSE2() const;
+ bool hasSSE3() const;
+ bool hasSSE3S() const;
+ bool hasSSE41() const;
+ bool hasSSE42() const;
+ bool hasSSE4a() const;
F64 getMHz() const;
// Family is "AMD Duron" or "Intel Pentium Pro"
@@ -92,10 +98,16 @@ public:
private:
bool mHasSSE;
bool mHasSSE2;
+ bool mHasSSE3;
+ bool mHasSSE3S;
+ bool mHasSSE41;
+ bool mHasSSE42;
+ bool mHasSSE4a;
bool mHasAltivec;
F64 mCPUMHz;
std::string mFamily;
std::string mCPUString;
+ LLSD mSSEVersions;
};
//=============================================================================
diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h
new file mode 100644
index 0000000000..35599a574b
--- /dev/null
+++ b/indra/llcommon/llsys_objc.h
@@ -0,0 +1,33 @@
+/**
+ * @file llsys_objc.h
+ * @brief Header file for llsys_objc.mm
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSYS_OBJC_H
+#define LL_LLSYS_OBJC_H
+
+bool LLGetDarwinOSInfo(int &major, int &minor, int &patch);
+
+
+#endif // LL_LLSYS_OBJC_H
diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm
new file mode 100644
index 0000000000..cdb1e320d5
--- /dev/null
+++ b/indra/llcommon/llsys_objc.mm
@@ -0,0 +1,64 @@
+/**
+ * @file llsys_objc.mm
+ * @brief obj-c implementation of the system information functions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#import "llsys_objc.h"
+#import <AppKit/AppKit.h>
+
+static int intAtStringIndex(NSArray *array, int index)
+{
+ return [(NSString *)[array objectAtIndex:index] integerValue];
+}
+
+bool LLGetDarwinOSInfo(int &major, int &minor, int &patch)
+{
+ if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8)
+ {
+ NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+ major = osVersion.majorVersion;
+ minor = osVersion.minorVersion;
+ patch = osVersion.patchVersion;
+ }
+ else
+ {
+ NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:
+ @"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
+ NSArray* versions = [versionString componentsSeparatedByString:@"."];
+ NSUInteger count = [versions count];
+ if (count > 0)
+ {
+ major = intAtStringIndex(versions, 0);
+ if (count > 1)
+ {
+ minor = intAtStringIndex(versions, 1);
+ if (count > 2)
+ {
+ patch = intAtStringIndex(versions, 2);
+ }
+ }
+ }
+ }
+ return true;
+}
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp
index ba914035e2..d5adf11264 100644
--- a/indra/llcommon/threadpool.cpp
+++ b/indra/llcommon/threadpool.cpp
@@ -22,6 +22,7 @@
#include "stringize.h"
LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity):
+ super(name),
mQueue(name, capacity),
mName("ThreadPool:" + name),
mThreadCount(threads)
diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h
index b79c9b9090..f8eec3b457 100644
--- a/indra/llcommon/threadpool.h
+++ b/indra/llcommon/threadpool.h
@@ -22,8 +22,10 @@
namespace LL
{
- class ThreadPool
+ class ThreadPool: public LLInstanceTracker<ThreadPool, std::string>
{
+ private:
+ using super = LLInstanceTracker<ThreadPool, std::string>;
public:
/**
* Pass ThreadPool a string name. This can be used to look up the
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
index 96574a18b9..70fd65bd0c 100644
--- a/indra/llcommon/workqueue.h
+++ b/indra/llcommon/workqueue.h
@@ -403,7 +403,7 @@ namespace LL
[result = std::forward<CALLABLE>(callable)(),
callback = std::move(callback)]
()
- { callback(std::move(result)); };
+ mutable { callback(std::move(result)); };
}
};
@@ -449,7 +449,7 @@ namespace LL
callable = std::move(callable),
callback = std::move(callback)]
()
- {
+ mutable {
// Use postMaybe() below in case this originating WorkQueue
// has been closed or destroyed. Remember, the outer lambda is
// now running on a thread servicing the target WorkQueue, and
@@ -513,7 +513,7 @@ namespace LL
// We dare to bind a reference to Promise because it's
// specifically designed for cross-thread communication.
[&promise, callable = std::move(callable)]()
- {
+ mutable {
try
{
// call the caller's callable and trigger promise with result
@@ -542,7 +542,7 @@ namespace LL
time,
// &promise is designed for cross-thread access
[&promise, callable = std::move(callable)]()
- {
+ mutable {
try
{
callable();